Botan 3.6.0
Crypto and TLS for C&
pcurves_solinas.h
Go to the documentation of this file.
1/*
2* (C) 2024 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#ifndef BOTAN_PCURVES_SOLINAS_REDC_HELPER_H_
8#define BOTAN_PCURVES_SOLINAS_REDC_HELPER_H_
9
10#include <botan/internal/mp_core.h>
11
12namespace Botan {
13
14/*
15Helpers for modular reduction of Solinas primes, such as P-256 and P-384.
16
17Instead of explicitly forming the various integers and adding/subtracting them
18row-by-row, we compute the entire sum in one pass, column by column. To prevent
19overflow/underflow the accumulator is a signed 64-bit integer, while the various
20limbs are (at least for all NIST curves aside from P-192) 32 bit integers.
21
22For more background on Solinas primes / Solinas reduction see
23
24* J. Solinas 'Generalized Mersenne Numbers'
25 <https://cacr.uwaterloo.ca/techreports/1999/corr99-39.pdf>
26* NIST SP 800-186 Appendix G.1
27 <https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-186.pdf>
28* Handbook of Elliptic And Hyperelliptic Curve Cryptography ยง 10.4.3
29
30*/
31
32template <WordType W>
33constexpr uint32_t get_uint32(const W xw[], size_t i) {
34 static_assert(WordInfo<W>::bits == 32 || WordInfo<W>::bits == 64);
35
36 if constexpr(WordInfo<W>::bits == 32) {
37 return xw[i];
38 } else {
39 return static_cast<uint32_t>(xw[i / 2] >> ((i % 2) * 32));
40 }
41}
42
43template <WordType W, size_t N>
45 public:
46 static_assert(WordInfo<W>::bits == 32 || WordInfo<W>::bits == 64);
47
48 static constexpr size_t N32 = N * (WordInfo<W>::bits / 32);
49
50 constexpr SolinasAccum(std::array<W, N>& r) : m_r(r), m_S(0), m_idx(0) {}
51
52 constexpr void accum(int64_t v) {
53 BOTAN_DEBUG_ASSERT(m_idx < N32);
54
55 m_S += v;
56 const uint32_t r = static_cast<uint32_t>(m_S);
57 m_S >>= 32;
58
59 if constexpr(WordInfo<W>::bits == 32) {
60 m_r[m_idx] = r;
61 } else {
62 m_r[m_idx / 2] |= static_cast<uint64_t>(r) << (32 * (m_idx % 2));
63 }
64
65 m_idx += 1;
66 }
67
68 constexpr W final_carry(int64_t C) {
69 m_S += C;
70 BOTAN_DEBUG_ASSERT(m_S >= 0);
71 return static_cast<W>(m_S);
72 }
73
74 private:
75 std::array<W, N>& m_r;
76 int64_t m_S;
77 size_t m_idx;
78};
79
80} // namespace Botan
81
82#endif
#define BOTAN_DEBUG_ASSERT(expr)
Definition assert.h:98
constexpr void accum(int64_t v)
static constexpr size_t N32
constexpr W final_carry(int64_t C)
constexpr SolinasAccum(std::array< W, N > &r)
constexpr uint32_t get_uint32(const W xw[], size_t i)