Botan 3.9.0
Crypto and TLS for C&
pcurves_secp256k1.cpp
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#include <botan/internal/pcurves_instance.h>
8
9#include <botan/internal/pcurves_wrap.h>
10
11namespace Botan::PCurve {
12
13namespace {
14
15namespace secp256k1 {
16
17template <typename Params>
18class Secp256k1Rep final {
19 public:
20 static constexpr auto P = Params::P;
21 static constexpr size_t N = Params::N;
22 typedef typename Params::W W;
23
24 static_assert(WordInfo<W>::bits >= 33);
25
26 static constexpr W C = 0x1000003d1;
27
28 constexpr static std::array<W, N> one() { return std::array<W, N>{1}; }
29
30 constexpr static std::array<W, N> redc(const std::array<W, 2 * N>& z) {
31 return redc_crandall<W, N, C>(std::span{z});
32 }
33
34 constexpr static std::array<W, N> to_rep(const std::array<W, N>& x) { return x; }
35
36 constexpr static std::array<W, N> wide_to_rep(const std::array<W, 2 * N>& x) { return redc(x); }
37
38 constexpr static std::array<W, N> from_rep(const std::array<W, N>& z) { return z; }
39};
40
41// clang-format off
42class Params final : public EllipticCurveParameters<
43 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
44 "0",
45 "7",
46 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
47 "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
48 "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"> {
49};
50
51// clang-format on
52using Secp256k1Base =
53 std::conditional_t<WordInfo<word>::bits >= 33, EllipticCurve<Params, Secp256k1Rep>, EllipticCurve<Params>>;
54
55class Curve final : public Secp256k1Base {
56 public:
57 // Return the square of the inverse of x
58 static constexpr FieldElement fe_invert2(const FieldElement& x) {
59 auto z = x.square();
60 z *= x;
61 auto t0 = z;
62 t0.square_n(2);
63 t0 *= z;
64 auto t1 = t0.square();
65 auto t2 = t1 * x;
66 t1 = t2;
67 t1.square_n(2);
68 t1 *= z;
69 auto t3 = t1;
70 t3.square_n(4);
71 t0 *= t3;
72 t3 = t0;
73 t3.square_n(11);
74 t0 *= t3;
75 t3 = t0;
76 t3.square_n(5);
77 t2 *= t3;
78 t3 = t2;
79 t3.square_n(27);
80 t2 *= t3;
81 t3 = t2;
82 t3.square_n(54);
83 t2 *= t3;
84 t3 = t2;
85 t3.square_n(108);
86 t2 *= t3;
87 t2.square_n(7);
88 t1 *= t2;
89 t1.square_n(23);
90 t0 *= t1;
91 t0.square_n(5);
92 t0 *= x;
93 t0.square_n(3);
94 z *= t0;
95 z.square_n(2);
96 return z;
97 }
98
99 static constexpr FieldElement fe_sqrt(const FieldElement& x) {
100 auto z = x.square();
101 z *= x;
102 auto t0 = z;
103 t0.square_n(2);
104 t0 *= z;
105 auto t1 = t0.square();
106 auto t2 = t1 * x;
107 t1 = t2;
108 t1.square_n(2);
109 t1 *= z;
110 auto t3 = t1;
111 t3.square_n(4);
112 t0 *= t3;
113 t3 = t0;
114 t3.square_n(11);
115 t0 *= t3;
116 t3 = t0;
117 t3.square_n(5);
118 t2 *= t3;
119 t3 = t2;
120 t3.square_n(27);
121 t2 *= t3;
122 t3 = t2;
123 t3.square_n(54);
124 t2 *= t3;
125 t3 = t2;
126 t3.square_n(108);
127 t2 *= t3;
128 t2.square_n(7);
129 t1 *= t2;
130 t1.square_n(23);
131 t0 *= t1;
132 t0.square_n(6);
133 z *= t0;
134 z.square_n(2);
135 return z;
136 }
137
138 static constexpr Scalar scalar_invert(const Scalar& x) {
139 auto z = x.square();
140 auto t2 = x * z;
141 auto t6 = t2 * z;
142 auto t5 = t6 * z;
143 auto t0 = t5 * z;
144 auto t3 = t0 * z;
145 auto t1 = t3 * z;
146 z = t1;
147 z.square_n(2);
148 z *= t3;
149 auto t4 = z.square();
150 auto t7 = t4 * x;
151 t4 = t7.square();
152 t4 *= x;
153 auto t9 = t4;
154 t9.square_n(3);
155 auto t10 = t9;
156 t10.square_n(2);
157 auto t11 = t10.square();
158 auto t8 = t11.square();
159 auto t12 = t8;
160 t12.square_n(7);
161 t11 *= t12;
162 t11.square_n(9);
163 t8 *= t11;
164 t11 = t8;
165 t11.square_n(6);
166 t10 *= t11;
167 t10.square_n(26);
168 t8 *= t10;
169 t10 = t8;
170 t10.square_n(4);
171 t9 *= t10;
172 t9.square_n(60);
173 t8 *= t9;
174 t7 *= t8;
175 t7.square_n(5);
176 t7 *= t3;
177 t7.square_n(3);
178 t7 *= t6;
179 t7.square_n(4);
180 t7 *= t6;
181 t7.square_n(4);
182 t7 *= t5;
183 t7.square_n(5);
184 t7 *= t1;
185 t7.square_n(2);
186 t7 *= t2;
187 t7.square_n(5);
188 t7 *= t5;
189 t7.square_n(6);
190 t7 *= t1;
191 t7.square_n(5);
192 t7 *= t3;
193 t7.square_n(4);
194 t7 *= t1;
195 t7.square_n(3);
196 t7 *= x;
197 t7.square_n(6);
198 t6 *= t7;
199 t6.square_n(10);
200 t6 *= t5;
201 t6.square_n(4);
202 t5 *= t6;
203 t5.square_n(9);
204 t4 *= t5;
205 t4.square_n(5);
206 t4 *= t0;
207 t4.square_n(6);
208 t3 *= t4;
209 t3.square_n(4);
210 t3 *= t1;
211 t3.square_n(5);
212 t2 *= t3;
213 t2.square_n(6);
214 t2 *= t1;
215 t2.square_n(10);
216 t1 *= t2;
217 t1.square_n(4);
218 t0 *= t1;
219 t0.square_n(6);
220 t0 *= x;
221 t0.square_n(8);
222 z *= t0;
223 return z;
224 }
225};
226
227} // namespace secp256k1
228
229} // namespace
230
231std::shared_ptr<const PrimeOrderCurve> PCurveInstance::secp256k1() {
233}
234
235} // namespace Botan::PCurve
static std::shared_ptr< const PrimeOrderCurve > instance()
constexpr std::array< W, N > redc_crandall(std::span< const W, 2 *N > z)
Definition mp_core.h:873