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