Bitcoin Core  27.99.0
P2P Digital Currency
main_impl.h
Go to the documentation of this file.
1 /***********************************************************************
2  * Distributed under the MIT software license, see the accompanying *
3  * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
4  ***********************************************************************/
5 
6 #ifndef SECP256K1_MODULE_ELLSWIFT_MAIN_H
7 #define SECP256K1_MODULE_ELLSWIFT_MAIN_H
8 
9 #include "../../../include/secp256k1.h"
10 #include "../../../include/secp256k1_ellswift.h"
11 #include "../../eckey.h"
12 #include "../../hash.h"
13 
15 static const secp256k1_fe secp256k1_ellswift_c1 = SECP256K1_FE_CONST(0x851695d4, 0x9a83f8ef, 0x919bb861, 0x53cbcb16, 0x630fb68a, 0xed0a766a, 0x3ec693d6, 0x8e6afa40);
17 static const secp256k1_fe secp256k1_ellswift_c2 = SECP256K1_FE_CONST(0x7ae96a2b, 0x657c0710, 0x6e64479e, 0xac3434e9, 0x9cf04975, 0x12f58995, 0xc1396c28, 0x719501ee);
19 static const secp256k1_fe secp256k1_ellswift_c3 = SECP256K1_FE_CONST(0x7ae96a2b, 0x657c0710, 0x6e64479e, 0xac3434e9, 0x9cf04975, 0x12f58995, 0xc1396c28, 0x719501ef);
21 static const secp256k1_fe secp256k1_ellswift_c4 = SECP256K1_FE_CONST(0x851695d4, 0x9a83f8ef, 0x919bb861, 0x53cbcb16, 0x630fb68a, 0xed0a766a, 0x3ec693d6, 0x8e6afa41);
22 
25  /* The implemented algorithm is the following (all operations in GF(p)):
26  *
27  * - Let c0 = sqrt(-3) = 0xa2d2ba93507f1df233770c2a797962cc61f6d15da14ecd47d8d27ae1cd5f852.
28  * - If u = 0, set u = 1.
29  * - If t = 0, set t = 1.
30  * - If u^3+7+t^2 = 0, set t = 2*t.
31  * - Let X = (u^3+7-t^2)/(2*t).
32  * - Let Y = (X+t)/(c0*u).
33  * - If x3 = u+4*Y^2 is a valid x coordinate, return it.
34  * - If x2 = (-X/Y-u)/2 is a valid x coordinate, return it.
35  * - Return x1 = (X/Y-u)/2 (which is now guaranteed to be a valid x coordinate).
36  *
37  * Introducing s=t^2, g=u^3+7, and simplifying x1=-(x2+u) we get:
38  *
39  * - Let c0 = ...
40  * - If u = 0, set u = 1.
41  * - If t = 0, set t = 1.
42  * - Let s = t^2
43  * - Let g = u^3+7
44  * - If g+s = 0, set t = 2*t, s = 4*s
45  * - Let X = (g-s)/(2*t).
46  * - Let Y = (X+t)/(c0*u) = (g+s)/(2*c0*t*u).
47  * - If x3 = u+4*Y^2 is a valid x coordinate, return it.
48  * - If x2 = (-X/Y-u)/2 is a valid x coordinate, return it.
49  * - Return x1 = -(x2+u).
50  *
51  * Now substitute Y^2 = -(g+s)^2/(12*s*u^2) and X/Y = c0*u*(g-s)/(g+s). This
52  * means X and Y do not need to be evaluated explicitly anymore.
53  *
54  * - ...
55  * - If g+s = 0, set s = 4*s.
56  * - If x3 = u-(g+s)^2/(3*s*u^2) is a valid x coordinate, return it.
57  * - If x2 = (-c0*u*(g-s)/(g+s)-u)/2 is a valid x coordinate, return it.
58  * - Return x1 = -(x2+u).
59  *
60  * Simplifying x2 using 2 additional constants:
61  *
62  * - Let c1 = (c0-1)/2 = 0x851695d49a83f8ef919bb86153cbcb16630fb68aed0a766a3ec693d68e6afa40.
63  * - Let c2 = (-c0-1)/2 = 0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee.
64  * - ...
65  * - If x2 = u*(c1*s+c2*g)/(g+s) is a valid x coordinate, return it.
66  * - ...
67  *
68  * Writing x3 as a fraction:
69  *
70  * - ...
71  * - If x3 = (3*s*u^3-(g+s)^2)/(3*s*u^2) ...
72  * - ...
73 
74  * Overall, we get:
75  *
76  * - Let c1 = 0x851695d49a83f8ef919bb86153cbcb16630fb68aed0a766a3ec693d68e6afa40.
77  * - Let c2 = 0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee.
78  * - If u = 0, set u = 1.
79  * - If t = 0, set s = 1, else set s = t^2.
80  * - Let g = u^3+7.
81  * - If g+s = 0, set s = 4*s.
82  * - If x3 = (3*s*u^3-(g+s)^2)/(3*s*u^2) is a valid x coordinate, return it.
83  * - If x2 = u*(c1*s+c2*g)/(g+s) is a valid x coordinate, return it.
84  * - Return x1 = -(x2+u).
85  */
86  secp256k1_fe u1, s, g, p, d, n, l;
87  u1 = *u;
89  secp256k1_fe_sqr(&s, t);
91  secp256k1_fe_sqr(&l, &u1); /* l = u^2 */
92  secp256k1_fe_mul(&g, &l, &u1); /* g = u^3 */
93  secp256k1_fe_add_int(&g, SECP256K1_B); /* g = u^3 + 7 */
94  p = g; /* p = g */
95  secp256k1_fe_add(&p, &s); /* p = g+s */
97  secp256k1_fe_mul_int(&s, 4);
98  /* Recompute p = g+s */
99  p = g; /* p = g */
100  secp256k1_fe_add(&p, &s); /* p = g+s */
101  }
102  secp256k1_fe_mul(&d, &s, &l); /* d = s*u^2 */
103  secp256k1_fe_mul_int(&d, 3); /* d = 3*s*u^2 */
104  secp256k1_fe_sqr(&l, &p); /* l = (g+s)^2 */
105  secp256k1_fe_negate(&l, &l, 1); /* l = -(g+s)^2 */
106  secp256k1_fe_mul(&n, &d, &u1); /* n = 3*s*u^3 */
107  secp256k1_fe_add(&n, &l); /* n = 3*s*u^3-(g+s)^2 */
108  if (secp256k1_ge_x_frac_on_curve_var(&n, &d)) {
109  /* Return x3 = n/d = (3*s*u^3-(g+s)^2)/(3*s*u^2) */
110  *xn = n;
111  *xd = d;
112  return;
113  }
114  *xd = p;
115  secp256k1_fe_mul(&l, &secp256k1_ellswift_c1, &s); /* l = c1*s */
116  secp256k1_fe_mul(&n, &secp256k1_ellswift_c2, &g); /* n = c2*g */
117  secp256k1_fe_add(&n, &l); /* n = c1*s+c2*g */
118  secp256k1_fe_mul(&n, &n, &u1); /* n = u*(c1*s+c2*g) */
119  /* Possible optimization: in the invocation below, p^2 = (g+s)^2 is computed,
120  * which we already have computed above. This could be deduplicated. */
121  if (secp256k1_ge_x_frac_on_curve_var(&n, &p)) {
122  /* Return x2 = n/p = u*(c1*s+c2*g)/(g+s) */
123  *xn = n;
124  return;
125  }
126  secp256k1_fe_mul(&l, &p, &u1); /* l = u*(g+s) */
127  secp256k1_fe_add(&n, &l); /* n = u*(c1*s+c2*g)+u*(g+s) */
128  secp256k1_fe_negate(xn, &n, 2); /* n = -u*(c1*s+c2*g)-u*(g+s) */
129 
131  /* Return x3 = n/p = -(u*(c1*s+c2*g)/(g+s)+u) */
132 }
133 
136  secp256k1_fe xn, xd;
138  secp256k1_fe_inv_var(&xd, &xd);
139  secp256k1_fe_mul(x, &xn, &xd);
140 }
141 
144  secp256k1_fe x;
147 }
148 
149 /* Try to complete an ElligatorSwift encoding (u, t) for X coordinate x, given u and x.
150  *
151  * There may be up to 8 distinct t values such that (u, t) decodes back to x, but also
152  * fewer, or none at all. Each such partial inverse can be accessed individually using a
153  * distinct input argument c (in range 0-7), and some or all of these may return failure.
154  * The following guarantees exist:
155  * - Given (x, u), no two distinct c values give the same successful result t.
156  * - Every successful result maps back to x through secp256k1_ellswift_xswiftec_var.
157  * - Given (x, u), all t values that map back to x can be reached by combining the
158  * successful results from this function over all c values, with the exception of:
159  * - this function cannot be called with u=0
160  * - no result with t=0 will be returned
161  * - no result for which u^3 + t^2 + 7 = 0 will be returned.
162  *
163  * The rather unusual encoding of bits in c (a large "if" based on the middle bit, and then
164  * using the low and high bits to pick signs of square roots) is to match the paper's
165  * encoding more closely: c=0 through c=3 match branches 1..4 in the paper, while c=4 through
166  * c=7 are copies of those with an additional negation of sqrt(w).
167  */
168 static int secp256k1_ellswift_xswiftec_inv_var(secp256k1_fe *t, const secp256k1_fe *x_in, const secp256k1_fe *u_in, int c) {
169  /* The implemented algorithm is this (all arithmetic, except involving c, is mod p):
170  *
171  * - If (c & 2) = 0:
172  * - If (-x-u) is a valid X coordinate, fail.
173  * - Let s=-(u^3+7)/(u^2+u*x+x^2).
174  * - If s is not square, fail.
175  * - Let v=x.
176  * - If (c & 2) = 2:
177  * - Let s=x-u.
178  * - If s is not square, fail.
179  * - Let r=sqrt(-s*(4*(u^3+7)+3*u^2*s)); fail if it doesn't exist.
180  * - If (c & 1) = 1 and r = 0, fail.
181  * - If s=0, fail.
182  * - Let v=(r/s-u)/2.
183  * - Let w=sqrt(s).
184  * - If (c & 5) = 0: return -w*(c3*u + v).
185  * - If (c & 5) = 1: return w*(c4*u + v).
186  * - If (c & 5) = 4: return w*(c3*u + v).
187  * - If (c & 5) = 5: return -w*(c4*u + v).
188  */
189  secp256k1_fe x = *x_in, u = *u_in, g, v, s, m, r, q;
190  int ret;
191 
194 
195  VERIFY_CHECK(c >= 0 && c < 8);
197 
198  if (!(c & 2)) {
199  /* c is in {0, 1, 4, 5}. In this case we look for an inverse under the x1 (if c=0 or
200  * c=4) formula, or x2 (if c=1 or c=5) formula. */
201 
202  /* If -u-x is a valid X coordinate, fail. This would yield an encoding that roundtrips
203  * back under the x3 formula instead (which has priority over x1 and x2, so the decoding
204  * would not match x). */
205  m = x; /* m = x */
206  secp256k1_fe_add(&m, &u); /* m = u+x */
207  secp256k1_fe_negate(&m, &m, 2); /* m = -u-x */
208  /* Test if (-u-x) is a valid X coordinate. If so, fail. */
209  if (secp256k1_ge_x_on_curve_var(&m)) return 0;
210 
211  /* Let s = -(u^3 + 7)/(u^2 + u*x + x^2) [first part] */
212  secp256k1_fe_sqr(&s, &m); /* s = (u+x)^2 */
213  secp256k1_fe_negate(&s, &s, 1); /* s = -(u+x)^2 */
214  secp256k1_fe_mul(&m, &u, &x); /* m = u*x */
215  secp256k1_fe_add(&s, &m); /* s = -(u^2 + u*x + x^2) */
216 
217  /* Note that at this point, s = 0 is impossible. If it were the case:
218  * s = -(u^2 + u*x + x^2) = 0
219  * => u^2 + u*x + x^2 = 0
220  * => (u + 2*x) * (u^2 + u*x + x^2) = 0
221  * => 2*x^3 + 3*x^2*u + 3*x*u^2 + u^3 = 0
222  * => (x + u)^3 + x^3 = 0
223  * => x^3 = -(x + u)^3
224  * => x^3 + B = (-u - x)^3 + B
225  *
226  * However, we know x^3 + B is square (because x is on the curve) and
227  * that (-u-x)^3 + B is not square (the secp256k1_ge_x_on_curve_var(&m)
228  * test above would have failed). This is a contradiction, and thus the
229  * assumption s=0 is false. */
231 
232  /* If s is not square, fail. We have not fully computed s yet, but s is square iff
233  * -(u^3+7)*(u^2+u*x+x^2) is square (because a/b is square iff a*b is square and b is
234  * nonzero). */
235  secp256k1_fe_sqr(&g, &u); /* g = u^2 */
236  secp256k1_fe_mul(&g, &g, &u); /* g = u^3 */
237  secp256k1_fe_add_int(&g, SECP256K1_B); /* g = u^3+7 */
238  secp256k1_fe_mul(&m, &s, &g); /* m = -(u^3 + 7)*(u^2 + u*x + x^2) */
239  if (!secp256k1_fe_is_square_var(&m)) return 0;
240 
241  /* Let s = -(u^3 + 7)/(u^2 + u*x + x^2) [second part] */
242  secp256k1_fe_inv_var(&s, &s); /* s = -1/(u^2 + u*x + x^2) [no div by 0] */
243  secp256k1_fe_mul(&s, &s, &g); /* s = -(u^3 + 7)/(u^2 + u*x + x^2) */
244 
245  /* Let v = x. */
246  v = x;
247  } else {
248  /* c is in {2, 3, 6, 7}. In this case we look for an inverse under the x3 formula. */
249 
250  /* Let s = x-u. */
251  secp256k1_fe_negate(&m, &u, 1); /* m = -u */
252  s = m; /* s = -u */
253  secp256k1_fe_add(&s, &x); /* s = x-u */
254 
255  /* If s is not square, fail. */
256  if (!secp256k1_fe_is_square_var(&s)) return 0;
257 
258  /* Let r = sqrt(-s*(4*(u^3+7)+3*u^2*s)); fail if it doesn't exist. */
259  secp256k1_fe_sqr(&g, &u); /* g = u^2 */
260  secp256k1_fe_mul(&q, &s, &g); /* q = s*u^2 */
261  secp256k1_fe_mul_int(&q, 3); /* q = 3*s*u^2 */
262  secp256k1_fe_mul(&g, &g, &u); /* g = u^3 */
263  secp256k1_fe_mul_int(&g, 4); /* g = 4*u^3 */
264  secp256k1_fe_add_int(&g, 4 * SECP256K1_B); /* g = 4*(u^3+7) */
265  secp256k1_fe_add(&q, &g); /* q = 4*(u^3+7)+3*s*u^2 */
266  secp256k1_fe_mul(&q, &q, &s); /* q = s*(4*(u^3+7)+3*u^2*s) */
267  secp256k1_fe_negate(&q, &q, 1); /* q = -s*(4*(u^3+7)+3*u^2*s) */
268  if (!secp256k1_fe_is_square_var(&q)) return 0;
269  ret = secp256k1_fe_sqrt(&r, &q); /* r = sqrt(-s*(4*(u^3+7)+3*u^2*s)) */
270 #ifdef VERIFY
271  VERIFY_CHECK(ret);
272 #else
273  (void)ret;
274 #endif
275 
276  /* If (c & 1) = 1 and r = 0, fail. */
277  if (EXPECT((c & 1) && secp256k1_fe_normalizes_to_zero_var(&r), 0)) return 0;
278 
279  /* If s = 0, fail. */
280  if (EXPECT(secp256k1_fe_normalizes_to_zero_var(&s), 0)) return 0;
281 
282  /* Let v = (r/s-u)/2. */
283  secp256k1_fe_inv_var(&v, &s); /* v = 1/s [no div by 0] */
284  secp256k1_fe_mul(&v, &v, &r); /* v = r/s */
285  secp256k1_fe_add(&v, &m); /* v = r/s-u */
286  secp256k1_fe_half(&v); /* v = (r/s-u)/2 */
287  }
288 
289  /* Let w = sqrt(s). */
290  ret = secp256k1_fe_sqrt(&m, &s); /* m = sqrt(s) = w */
291  VERIFY_CHECK(ret);
292 
293  /* Return logic. */
294  if ((c & 5) == 0 || (c & 5) == 5) {
295  secp256k1_fe_negate(&m, &m, 1); /* m = -w */
296  }
297  /* Now m = {-w if c&5=0 or c&5=5; w otherwise}. */
299  /* u = {c4 if c&1=1; c3 otherwise}*u */
300  secp256k1_fe_add(&u, &v); /* u = {c4 if c&1=1; c3 otherwise}*u + v */
301  secp256k1_fe_mul(t, &m, &u);
302  return 1;
303 }
304 
310 static void secp256k1_ellswift_prng(unsigned char* out32, const secp256k1_sha256 *hasher, uint32_t cnt) {
311  secp256k1_sha256 hash = *hasher;
312  unsigned char buf4[4];
313 #ifdef VERIFY
314  size_t blocks = hash.bytes >> 6;
315 #endif
316  buf4[0] = cnt;
317  buf4[1] = cnt >> 8;
318  buf4[2] = cnt >> 16;
319  buf4[3] = cnt >> 24;
320  secp256k1_sha256_write(&hash, buf4, 4);
321  secp256k1_sha256_finalize(&hash, out32);
322 
323  /* Writing and finalizing together should trigger exactly one SHA256 compression. */
324  VERIFY_CHECK(((hash.bytes) >> 6) == (blocks + 1));
325 }
326 
333 static void secp256k1_ellswift_xelligatorswift_var(unsigned char *u32, secp256k1_fe *t, const secp256k1_fe *x, const secp256k1_sha256 *hasher) {
334  /* Pool of 3-bit branch values. */
335  unsigned char branch_hash[32];
336  /* Number of 3-bit values in branch_hash left. */
337  int branches_left = 0;
338  /* Field elements u and branch values are extracted from RNG based on hasher for consecutive
339  * values of cnt. cnt==0 is first used to populate a pool of 64 4-bit branch values. The 64
340  * cnt values that follow are used to generate field elements u. cnt==65 (and multiples
341  * thereof) are used to repopulate the pool and start over, if that were ever necessary.
342  * On average, 4 iterations are needed. */
343  uint32_t cnt = 0;
344  while (1) {
345  int branch;
346  secp256k1_fe u;
347  /* If the pool of branch values is empty, populate it. */
348  if (branches_left == 0) {
349  secp256k1_ellswift_prng(branch_hash, hasher, cnt++);
350  branches_left = 64;
351  }
352  /* Take a 3-bit branch value from the branch pool (top bit is discarded). */
353  --branches_left;
354  branch = (branch_hash[branches_left >> 1] >> ((branches_left & 1) << 2)) & 7;
355  /* Compute a new u value by hashing. */
356  secp256k1_ellswift_prng(u32, hasher, cnt++);
357  /* overflow is not a problem (we prefer uniform u32 over uniform u). */
359  /* Since u is the output of a hash, it should practically never be 0. We could apply the
360  * u=0 to u=1 correction here too to deal with that case still, but it's such a low
361  * probability event that we do not bother. */
363 
364  /* Find a remainder t, and return it if found. */
365  if (EXPECT(secp256k1_ellswift_xswiftec_inv_var(t, x, &u, branch), 0)) break;
366  }
367 }
368 
375 static void secp256k1_ellswift_elligatorswift_var(unsigned char *u32, secp256k1_fe *t, const secp256k1_ge *p, const secp256k1_sha256 *hasher) {
379  secp256k1_fe_negate(t, t, 1);
381  }
382 }
383 
387  hash->s[0] = 0xd1a6524bul;
388  hash->s[1] = 0x028594b3ul;
389  hash->s[2] = 0x96e42f4eul;
390  hash->s[3] = 0x1037a177ul;
391  hash->s[4] = 0x1b8fcb8bul;
392  hash->s[5] = 0x56023885ul;
393  hash->s[6] = 0x2560ede1ul;
394  hash->s[7] = 0xd626b715ul;
395 
396  hash->bytes = 64;
397 }
398 
399 int secp256k1_ellswift_encode(const secp256k1_context *ctx, unsigned char *ell64, const secp256k1_pubkey *pubkey, const unsigned char *rnd32) {
400  secp256k1_ge p;
401  VERIFY_CHECK(ctx != NULL);
402  ARG_CHECK(ell64 != NULL);
403  ARG_CHECK(pubkey != NULL);
404  ARG_CHECK(rnd32 != NULL);
405 
406  if (secp256k1_pubkey_load(ctx, &p, pubkey)) {
407  secp256k1_fe t;
408  unsigned char p64[64] = {0};
409  size_t ser_size;
410  int ser_ret;
411  secp256k1_sha256 hash;
412 
413  /* Set up hasher state; the used RNG is H(pubkey || "\x00"*31 || rnd32 || cnt++), using
414  * BIP340 tagged hash with tag "secp256k1_ellswift_encode". */
416  ser_ret = secp256k1_eckey_pubkey_serialize(&p, p64, &ser_size, 1);
417 #ifdef VERIFY
418  VERIFY_CHECK(ser_ret && ser_size == 33);
419 #else
420  (void)ser_ret;
421 #endif
422  secp256k1_sha256_write(&hash, p64, sizeof(p64));
423  secp256k1_sha256_write(&hash, rnd32, 32);
424 
425  /* Compute ElligatorSwift encoding and construct output. */
426  secp256k1_ellswift_elligatorswift_var(ell64, &t, &p, &hash); /* puts u in ell64[0..32] */
427  secp256k1_fe_get_b32(ell64 + 32, &t); /* puts t in ell64[32..64] */
428  return 1;
429  }
430  /* Only reached in case the provided pubkey is invalid. */
431  memset(ell64, 0, 64);
432  return 0;
433 }
434 
438  hash->s[0] = 0xd29e1bf5ul;
439  hash->s[1] = 0xf7025f42ul;
440  hash->s[2] = 0x9b024773ul;
441  hash->s[3] = 0x094cb7d5ul;
442  hash->s[4] = 0xe59ed789ul;
443  hash->s[5] = 0x03bc9786ul;
444  hash->s[6] = 0x68335b35ul;
445  hash->s[7] = 0x4e363b53ul;
446 
447  hash->bytes = 64;
448 }
449 
450 int secp256k1_ellswift_create(const secp256k1_context *ctx, unsigned char *ell64, const unsigned char *seckey32, const unsigned char *auxrnd32) {
451  secp256k1_ge p;
452  secp256k1_fe t;
453  secp256k1_sha256 hash;
454  secp256k1_scalar seckey_scalar;
455  int ret;
456  static const unsigned char zero32[32] = {0};
457 
458  /* Sanity check inputs. */
459  VERIFY_CHECK(ctx != NULL);
460  ARG_CHECK(ell64 != NULL);
461  memset(ell64, 0, 64);
463  ARG_CHECK(seckey32 != NULL);
464 
465  /* Compute (affine) public key */
466  ret = secp256k1_ec_pubkey_create_helper(&ctx->ecmult_gen_ctx, &seckey_scalar, &p, seckey32);
467  secp256k1_declassify(ctx, &p, sizeof(p)); /* not constant time in produced pubkey */
470 
471  /* Set up hasher state. The used RNG is H(privkey || "\x00"*32 [|| auxrnd32] || cnt++),
472  * using BIP340 tagged hash with tag "secp256k1_ellswift_create". */
474  secp256k1_sha256_write(&hash, seckey32, 32);
475  secp256k1_sha256_write(&hash, zero32, sizeof(zero32));
476  secp256k1_declassify(ctx, &hash, sizeof(hash)); /* private key is hashed now */
477  if (auxrnd32) secp256k1_sha256_write(&hash, auxrnd32, 32);
478 
479  /* Compute ElligatorSwift encoding and construct output. */
480  secp256k1_ellswift_elligatorswift_var(ell64, &t, &p, &hash); /* puts u in ell64[0..32] */
481  secp256k1_fe_get_b32(ell64 + 32, &t); /* puts t in ell64[32..64] */
482 
483  secp256k1_memczero(ell64, 64, !ret);
484  secp256k1_scalar_clear(&seckey_scalar);
485 
486  return ret;
487 }
488 
489 int secp256k1_ellswift_decode(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *ell64) {
490  secp256k1_fe u, t;
491  secp256k1_ge p;
492  VERIFY_CHECK(ctx != NULL);
493  ARG_CHECK(pubkey != NULL);
494  ARG_CHECK(ell64 != NULL);
495 
496  secp256k1_fe_set_b32_mod(&u, ell64);
497  secp256k1_fe_set_b32_mod(&t, ell64 + 32);
500  secp256k1_pubkey_save(pubkey, &p);
501  return 1;
502 }
503 
504 static int ellswift_xdh_hash_function_prefix(unsigned char *output, const unsigned char *x32, const unsigned char *ell_a64, const unsigned char *ell_b64, void *data) {
505  secp256k1_sha256 sha;
506 
508  secp256k1_sha256_write(&sha, data, 64);
509  secp256k1_sha256_write(&sha, ell_a64, 64);
510  secp256k1_sha256_write(&sha, ell_b64, 64);
511  secp256k1_sha256_write(&sha, x32, 32);
512  secp256k1_sha256_finalize(&sha, output);
513 
514  return 1;
515 }
516 
520  hash->s[0] = 0x8c12d730ul;
521  hash->s[1] = 0x827bd392ul;
522  hash->s[2] = 0x9e4fb2eeul;
523  hash->s[3] = 0x207b373eul;
524  hash->s[4] = 0x2292bd7aul;
525  hash->s[5] = 0xaa5441bcul;
526  hash->s[6] = 0x15c3779ful;
527  hash->s[7] = 0xcfb52549ul;
528 
529  hash->bytes = 64;
530 }
531 
532 static int ellswift_xdh_hash_function_bip324(unsigned char* output, const unsigned char *x32, const unsigned char *ell_a64, const unsigned char *ell_b64, void *data) {
533  secp256k1_sha256 sha;
534 
535  (void)data;
536 
538  secp256k1_sha256_write(&sha, ell_a64, 64);
539  secp256k1_sha256_write(&sha, ell_b64, 64);
540  secp256k1_sha256_write(&sha, x32, 32);
541  secp256k1_sha256_finalize(&sha, output);
542 
543  return 1;
544 }
545 
548 
549 int secp256k1_ellswift_xdh(const secp256k1_context *ctx, unsigned char *output, const unsigned char *ell_a64, const unsigned char *ell_b64, const unsigned char *seckey32, int party, secp256k1_ellswift_xdh_hash_function hashfp, void *data) {
550  int ret = 0;
551  int overflow;
553  secp256k1_fe xn, xd, px, u, t;
554  unsigned char sx[32];
555  const unsigned char* theirs64;
556 
557  VERIFY_CHECK(ctx != NULL);
558  ARG_CHECK(output != NULL);
559  ARG_CHECK(ell_a64 != NULL);
560  ARG_CHECK(ell_b64 != NULL);
561  ARG_CHECK(seckey32 != NULL);
562  ARG_CHECK(hashfp != NULL);
563 
564  /* Load remote public key (as fraction). */
565  theirs64 = party ? ell_a64 : ell_b64;
566  secp256k1_fe_set_b32_mod(&u, theirs64);
567  secp256k1_fe_set_b32_mod(&t, theirs64 + 32);
568  secp256k1_ellswift_xswiftec_frac_var(&xn, &xd, &u, &t);
569 
570  /* Load private key (using one if invalid). */
571  secp256k1_scalar_set_b32(&s, seckey32, &overflow);
572  overflow = secp256k1_scalar_is_zero(&s);
574 
575  /* Compute shared X coordinate. */
576  secp256k1_ecmult_const_xonly(&px, &xn, &xd, &s, 1);
578  secp256k1_fe_get_b32(sx, &px);
579 
580  /* Invoke hasher */
581  ret = hashfp(output, sx, ell_a64, ell_b64, data);
582 
583  memset(sx, 0, 32);
584  secp256k1_fe_clear(&px);
586 
587  return !!ret & !overflow;
588 }
589 
590 #endif
int ret
unsigned int u32
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed)
static int secp256k1_ecmult_const_xonly(secp256k1_fe *r, const secp256k1_fe *n, const secp256k1_fe *d, const secp256k1_scalar *q, int known_on_curve)
Same as secp256k1_ecmult_const, but takes in an x coordinate of the base point only,...
static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context *ctx)
static void secp256k1_ellswift_swiftec_var(secp256k1_ge *p, const secp256k1_fe *u, const secp256k1_fe *t)
Decode ElligatorSwift encoding (u, t) to point P.
Definition: main_impl.h:143
const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_prefix
Definition: main_impl.h:546
int secp256k1_ellswift_create(const secp256k1_context *ctx, unsigned char *ell64, const unsigned char *seckey32, const unsigned char *auxrnd32)
Compute an ElligatorSwift public key for a secret key.
Definition: main_impl.h:450
int secp256k1_ellswift_xdh(const secp256k1_context *ctx, unsigned char *output, const unsigned char *ell_a64, const unsigned char *ell_b64, const unsigned char *seckey32, int party, secp256k1_ellswift_xdh_hash_function hashfp, void *data)
Given a private key, and ElligatorSwift public keys sent in both directions, compute a shared secret ...
Definition: main_impl.h:549
static const secp256k1_fe secp256k1_ellswift_c3
c3 = (-sqrt(-3)+1)/2 = -c1 = c2+1
Definition: main_impl.h:19
static const secp256k1_fe secp256k1_ellswift_c4
c4 = (sqrt(-3)+1)/2 = -c2 = c1+1
Definition: main_impl.h:21
static void secp256k1_ellswift_xswiftec_var(secp256k1_fe *x, const secp256k1_fe *u, const secp256k1_fe *t)
Decode ElligatorSwift encoding (u, t) to X coordinate.
Definition: main_impl.h:135
static void secp256k1_ellswift_sha256_init_create(secp256k1_sha256 *hash)
Set hash state to the BIP340 tagged hash midstate for "secp256k1_ellswift_create".
Definition: main_impl.h:436
static const secp256k1_fe secp256k1_ellswift_c2
c2 = (-sqrt(-3)-1)/2 = -(c1+1)
Definition: main_impl.h:17
static void secp256k1_ellswift_xelligatorswift_var(unsigned char *u32, secp256k1_fe *t, const secp256k1_fe *x, const secp256k1_sha256 *hasher)
Find an ElligatorSwift encoding (u, t) for X coordinate x, and random Y coordinate.
Definition: main_impl.h:333
static int ellswift_xdh_hash_function_prefix(unsigned char *output, const unsigned char *x32, const unsigned char *ell_a64, const unsigned char *ell_b64, void *data)
Definition: main_impl.h:504
const secp256k1_ellswift_xdh_hash_function secp256k1_ellswift_xdh_hash_function_bip324
Definition: main_impl.h:547
static void secp256k1_ellswift_xswiftec_frac_var(secp256k1_fe *xn, secp256k1_fe *xd, const secp256k1_fe *u, const secp256k1_fe *t)
Decode ElligatorSwift encoding (u, t) to a fraction xn/xd representing a curve X coordinate.
Definition: main_impl.h:24
static void secp256k1_ellswift_elligatorswift_var(unsigned char *u32, secp256k1_fe *t, const secp256k1_ge *p, const secp256k1_sha256 *hasher)
Find an ElligatorSwift encoding (u, t) for point P.
Definition: main_impl.h:375
static int secp256k1_ellswift_xswiftec_inv_var(secp256k1_fe *t, const secp256k1_fe *x_in, const secp256k1_fe *u_in, int c)
Definition: main_impl.h:168
static void secp256k1_ellswift_sha256_init_bip324(secp256k1_sha256 *hash)
Set hash state to the BIP340 tagged hash midstate for "bip324_ellswift_xonly_ecdh".
Definition: main_impl.h:518
static int ellswift_xdh_hash_function_bip324(unsigned char *output, const unsigned char *x32, const unsigned char *ell_a64, const unsigned char *ell_b64, void *data)
Definition: main_impl.h:532
static void secp256k1_ellswift_sha256_init_encode(secp256k1_sha256 *hash)
Set hash state to the BIP340 tagged hash midstate for "secp256k1_ellswift_encode".
Definition: main_impl.h:385
static void secp256k1_ellswift_prng(unsigned char *out32, const secp256k1_sha256 *hasher, uint32_t cnt)
Use SHA256 as a PRNG, returning SHA256(hasher || cnt).
Definition: main_impl.h:310
int secp256k1_ellswift_encode(const secp256k1_context *ctx, unsigned char *ell64, const secp256k1_pubkey *pubkey, const unsigned char *rnd32)
Construct a 64-byte ElligatorSwift encoding of a given pubkey.
Definition: main_impl.h:399
int secp256k1_ellswift_decode(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *ell64)
Decode a 64-bytes ElligatorSwift encoded public key.
Definition: main_impl.h:489
static const secp256k1_fe secp256k1_ellswift_c1
c1 = (sqrt(-3)-1)/2
Definition: main_impl.h:15
#define secp256k1_fe_negate(r, a, m)
Negate a field element.
Definition: field.h:216
#define secp256k1_fe_mul_int(r, a)
Multiply a field element with a small integer.
Definition: field.h:238
#define secp256k1_fe_normalizes_to_zero_var
Definition: field.h:82
#define secp256k1_fe_normalize_weak
Definition: field.h:79
#define secp256k1_fe_is_odd
Definition: field.h:86
#define secp256k1_fe_mul
Definition: field.h:94
static const secp256k1_fe secp256k1_fe_one
Definition: field.h:68
static int secp256k1_fe_sqrt(secp256k1_fe *SECP256K1_RESTRICT r, const secp256k1_fe *SECP256K1_RESTRICT a)
Compute a square root of a field element.
#define secp256k1_fe_add
Definition: field.h:93
#define secp256k1_fe_clear
Definition: field.h:84
#define secp256k1_fe_normalize_var
Definition: field.h:80
#define secp256k1_fe_half
Definition: field.h:102
#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0)
This expands to an initializer for a secp256k1_fe valued sum((i*32) * d_i, i=0..7) mod p.
Definition: field.h:66
#define secp256k1_fe_inv_var
Definition: field.h:100
#define secp256k1_fe_is_square_var
Definition: field.h:104
#define secp256k1_fe_set_b32_mod
Definition: field.h:88
#define secp256k1_fe_get_b32
Definition: field.h:90
#define secp256k1_fe_sqr
Definition: field.h:95
#define secp256k1_fe_normalize
Definition: field.h:78
#define secp256k1_fe_add_int
Definition: field.h:103
static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd)
Set a group element (affine) equal to the point with the given X coordinate, and given oddness for Y.
static int secp256k1_ge_x_on_curve_var(const secp256k1_fe *x)
Determine whether x is a valid X coordinate on the curve.
static int secp256k1_ge_x_frac_on_curve_var(const secp256k1_fe *xn, const secp256k1_fe *xd)
Determine whether fraction xn/xd is a valid X coordinate on the curve (xd != 0).
#define SECP256K1_B
Definition: group_impl.h:71
#define EXPECT(x, c)
Definition: util.h:26
static void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag)
If flag is true, set *r equal to *a; otherwise leave it.
static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow)
Set a scalar from a big endian byte array.
static int secp256k1_scalar_is_zero(const secp256k1_scalar *a)
Check whether a scalar equals zero.
static void secp256k1_scalar_clear(secp256k1_scalar *r)
Clear a scalar to prevent the leak of sensitive data.
static const secp256k1_scalar secp256k1_scalar_one
Definition: scalar_impl.h:27
static void secp256k1_sha256_initialize(secp256k1_sha256 *hash)
static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32)
static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t size)
#define VERIFY_CHECK(cond)
Definition: util.h:153
static SECP256K1_INLINE void secp256k1_memczero(void *s, size_t len, int flag)
Definition: util.h:207
#define ARG_CHECK(cond)
Definition: secp256k1.c:44
static int secp256k1_ec_pubkey_create_helper(const secp256k1_ecmult_gen_context *ecmult_gen_ctx, secp256k1_scalar *seckey_scalar, secp256k1_ge *p, const unsigned char *seckey)
Definition: secp256k1.c:572
static SECP256K1_INLINE void secp256k1_declassify(const secp256k1_context *ctx, const void *p, size_t len)
Definition: secp256k1.c:235
static int secp256k1_pubkey_load(const secp256k1_context *ctx, secp256k1_ge *ge, const secp256k1_pubkey *pubkey)
Definition: secp256k1.c:239
static void secp256k1_pubkey_save(secp256k1_pubkey *pubkey, secp256k1_ge *ge)
Definition: secp256k1.c:252
int(* secp256k1_ellswift_xdh_hash_function)(unsigned char *output, const unsigned char *x32, const unsigned char *ell_a64, const unsigned char *ell_b64, void *data)
A pointer to a function used by secp256k1_ellswift_xdh to hash the shared X coordinate along with the...
secp256k1_ecmult_gen_context ecmult_gen_ctx
Definition: secp256k1.c:61
This field implementation represents the value as 10 uint32_t limbs in base 2^26.
Definition: field_10x26.h:14
A group element in affine coordinates on the secp256k1 curve, or occasionally on an isomorphic curve ...
Definition: group.h:16
secp256k1_fe x
Definition: group.h:17
secp256k1_fe y
Definition: group.h:18
Opaque data structure that holds a parsed and valid public key.
Definition: secp256k1.h:74
A scalar modulo the group order of the secp256k1 curve.
Definition: scalar_4x64.h:13
uint64_t bytes
Definition: hash.h:16
uint32_t s[8]
Definition: hash.h:14