Bitcoin Core  29.1.0
P2P Digital Currency
keyagg_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_MUSIG_KEYAGG_IMPL_H
7 #define SECP256K1_MODULE_MUSIG_KEYAGG_IMPL_H
8 
9 #include <string.h>
10 
11 #include "keyagg.h"
12 #include "../../eckey.h"
13 #include "../../ecmult.h"
14 #include "../../field.h"
15 #include "../../group.h"
16 #include "../../hash.h"
17 #include "../../util.h"
18 
19 static const unsigned char secp256k1_musig_keyagg_cache_magic[4] = { 0xf4, 0xad, 0xbb, 0xdf };
20 
21 /* A keyagg cache consists of
22  * - 4 byte magic set during initialization to allow detecting an uninitialized
23  * object.
24  * - 64 byte aggregate (and potentially tweaked) public key
25  * - 64 byte "second" public key (set to the point at infinity if not present)
26  * - 32 byte hash of all public keys
27  * - 1 byte the parity of the internal key (if tweaked, otherwise 0)
28  * - 32 byte tweak
29  */
30 /* Requires that cache_i->pk is not infinity. */
32  unsigned char *ptr = cache->data;
34  ptr += 4;
35  secp256k1_ge_to_bytes(ptr, &cache_i->pk);
36  ptr += 64;
37  secp256k1_ge_to_bytes_ext(ptr, &cache_i->second_pk);
38  ptr += 64;
39  memcpy(ptr, cache_i->pks_hash, 32);
40  ptr += 32;
41  *ptr = cache_i->parity_acc;
42  ptr += 1;
43  secp256k1_scalar_get_b32(ptr, &cache_i->tweak);
44 }
45 
47  const unsigned char *ptr = cache->data;
49  ptr += 4;
50  secp256k1_ge_from_bytes(&cache_i->pk, ptr);
51  ptr += 64;
52  secp256k1_ge_from_bytes_ext(&cache_i->second_pk, ptr);
53  ptr += 64;
54  memcpy(cache_i->pks_hash, ptr, 32);
55  ptr += 32;
56  cache_i->parity_acc = *ptr & 1;
57  ptr += 1;
58  secp256k1_scalar_set_b32(&cache_i->tweak, ptr, NULL);
59  return 1;
60 }
61 
62 /* Initializes SHA256 with fixed midstate. This midstate was computed by applying
63  * SHA256 to SHA256("KeyAgg list")||SHA256("KeyAgg list"). */
66 
67  sha->s[0] = 0xb399d5e0ul;
68  sha->s[1] = 0xc8fff302ul;
69  sha->s[2] = 0x6badac71ul;
70  sha->s[3] = 0x07c5b7f1ul;
71  sha->s[4] = 0x9701e2eful;
72  sha->s[5] = 0x2a72ecf8ul;
73  sha->s[6] = 0x201a4c7bul;
74  sha->s[7] = 0xab148a38ul;
75  sha->bytes = 64;
76 }
77 
78 /* Computes pks_hash = tagged_hash(pk[0], ..., pk[np-1]) */
79 static int secp256k1_musig_compute_pks_hash(const secp256k1_context *ctx, unsigned char *pks_hash, const secp256k1_pubkey * const* pks, size_t np) {
80  secp256k1_sha256 sha;
81  size_t i;
82 
84  for (i = 0; i < np; i++) {
85  unsigned char ser[33];
86  size_t ser_len = sizeof(ser);
87  if (!secp256k1_ec_pubkey_serialize(ctx, ser, &ser_len, pks[i], SECP256K1_EC_COMPRESSED)) {
88  return 0;
89  }
90  VERIFY_CHECK(ser_len == sizeof(ser));
91  secp256k1_sha256_write(&sha, ser, sizeof(ser));
92  }
93  secp256k1_sha256_finalize(&sha, pks_hash);
94  return 1;
95 }
96 
97 /* Initializes SHA256 with fixed midstate. This midstate was computed by applying
98  * SHA256 to SHA256("KeyAgg coefficient")||SHA256("KeyAgg coefficient"). */
101 
102  sha->s[0] = 0x6ef02c5aul;
103  sha->s[1] = 0x06a480deul;
104  sha->s[2] = 0x1f298665ul;
105  sha->s[3] = 0x1d1134f2ul;
106  sha->s[4] = 0x56a0b063ul;
107  sha->s[5] = 0x52da4147ul;
108  sha->s[6] = 0xf280d9d4ul;
109  sha->s[7] = 0x4484be15ul;
110  sha->bytes = 64;
111 }
112 
113 /* Compute KeyAgg coefficient which is constant 1 for the second pubkey and
114  * otherwise tagged_hash(pks_hash, pk) where pks_hash is the hash of public keys.
115  * second_pk is the point at infinity in case there is no second_pk. Assumes
116  * that pk is not the point at infinity and that the Y-coordinates of pk and
117  * second_pk are normalized. */
118 static void secp256k1_musig_keyaggcoef_internal(secp256k1_scalar *r, const unsigned char *pks_hash, secp256k1_ge *pk, const secp256k1_ge *second_pk) {
120 
121  if (!secp256k1_ge_is_infinity(second_pk)
122  && secp256k1_ge_eq_var(pk, second_pk)) {
124  } else {
125  secp256k1_sha256 sha;
126  unsigned char buf[33];
127  size_t buflen = sizeof(buf);
128  int ret;
130  secp256k1_sha256_write(&sha, pks_hash, 32);
131  ret = secp256k1_eckey_pubkey_serialize(pk, buf, &buflen, 1);
132 #ifdef VERIFY
133  /* Serialization does not fail since the pk is not the point at infinity
134  * (according to this function's precondition). */
135  VERIFY_CHECK(ret && buflen == sizeof(buf));
136 #else
137  (void) ret;
138 #endif
139  secp256k1_sha256_write(&sha, buf, sizeof(buf));
140  secp256k1_sha256_finalize(&sha, buf);
141  secp256k1_scalar_set_b32(r, buf, NULL);
142  }
143 }
144 
145 /* Assumes that pk is not the point at infinity and that the Y-coordinates of pk
146  * and cache_i->second_pk are normalized. */
148  secp256k1_musig_keyaggcoef_internal(r, cache_i->pks_hash, pk, &cache_i->second_pk);
149 }
150 
151 typedef struct {
153  /* pks_hash is the hash of the public keys */
154  unsigned char pks_hash[32];
155  const secp256k1_pubkey * const* pks;
158 
159 /* Callback for batch EC multiplication to compute keyaggcoef_0*P0 + keyaggcoef_1*P1 + ... */
162  int ret;
163  ret = secp256k1_pubkey_load(ctx->ctx, pt, ctx->pks[idx]);
164 #ifdef VERIFY
165  /* pubkey_load can't fail because the same pks have already been loaded in
166  * `musig_compute_pks_hash` (and we test this). */
167  VERIFY_CHECK(ret);
168 #else
169  (void) ret;
170 #endif
172  return 1;
173 }
174 
175 int secp256k1_musig_pubkey_agg(const secp256k1_context* ctx, secp256k1_xonly_pubkey *agg_pk, secp256k1_musig_keyagg_cache *keyagg_cache, const secp256k1_pubkey * const* pubkeys, size_t n_pubkeys) {
177  secp256k1_gej pkj;
178  secp256k1_ge pkp;
179  size_t i;
180 
181  VERIFY_CHECK(ctx != NULL);
182  if (agg_pk != NULL) {
183  memset(agg_pk, 0, sizeof(*agg_pk));
184  }
185  ARG_CHECK(pubkeys != NULL);
186  ARG_CHECK(n_pubkeys > 0);
187 
188  ecmult_data.ctx = ctx;
189  ecmult_data.pks = pubkeys;
190 
191  secp256k1_ge_set_infinity(&ecmult_data.second_pk);
192  for (i = 1; i < n_pubkeys; i++) {
193  if (secp256k1_memcmp_var(pubkeys[0], pubkeys[i], sizeof(*pubkeys[0])) != 0) {
195  if (!secp256k1_pubkey_load(ctx, &pk, pubkeys[i])) {
196  return 0;
197  }
198  ecmult_data.second_pk = pk;
199  break;
200  }
201  }
202 
203  if (!secp256k1_musig_compute_pks_hash(ctx, ecmult_data.pks_hash, pubkeys, n_pubkeys)) {
204  return 0;
205  }
206  /* TODO: actually use optimized ecmult_multi algorithms by providing a
207  * scratch space */
208  if (!secp256k1_ecmult_multi_var(&ctx->error_callback, NULL, &pkj, NULL, secp256k1_musig_pubkey_agg_callback, (void *) &ecmult_data, n_pubkeys)) {
209  /* In order to reach this line with the current implementation of
210  * ecmult_multi_var one would need to provide a callback that can
211  * fail. */
212  return 0;
213  }
214  secp256k1_ge_set_gej(&pkp, &pkj);
216  /* The resulting public key is infinity with negligible probability */
218  if (keyagg_cache != NULL) {
219  secp256k1_keyagg_cache_internal cache_i = { 0 };
220  cache_i.pk = pkp;
221  cache_i.second_pk = ecmult_data.second_pk;
222  memcpy(cache_i.pks_hash, ecmult_data.pks_hash, sizeof(cache_i.pks_hash));
223  secp256k1_keyagg_cache_save(keyagg_cache, &cache_i);
224  }
225 
226  if (agg_pk != NULL) {
228  secp256k1_xonly_pubkey_save(agg_pk, &pkp);
229  }
230  return 1;
231 }
232 
235  VERIFY_CHECK(ctx != NULL);
236  ARG_CHECK(agg_pk != NULL);
237  memset(agg_pk, 0, sizeof(*agg_pk));
238  ARG_CHECK(keyagg_cache != NULL);
239 
240  if (!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) {
241  return 0;
242  }
243  secp256k1_pubkey_save(agg_pk, &cache_i.pk);
244  return 1;
245 }
246 
247 static int secp256k1_musig_pubkey_tweak_add_internal(const secp256k1_context* ctx, secp256k1_pubkey *output_pubkey, secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *tweak32, int xonly) {
249  int overflow = 0;
251 
252  VERIFY_CHECK(ctx != NULL);
253  if (output_pubkey != NULL) {
254  memset(output_pubkey, 0, sizeof(*output_pubkey));
255  }
256  ARG_CHECK(keyagg_cache != NULL);
257  ARG_CHECK(tweak32 != NULL);
258 
259  if (!secp256k1_keyagg_cache_load(ctx, &cache_i, keyagg_cache)) {
260  return 0;
261  }
262  secp256k1_scalar_set_b32(&tweak, tweak32, &overflow);
263  if (overflow) {
264  return 0;
265  }
266  if (xonly && secp256k1_extrakeys_ge_even_y(&cache_i.pk)) {
267  cache_i.parity_acc ^= 1;
268  secp256k1_scalar_negate(&cache_i.tweak, &cache_i.tweak);
269  }
270  secp256k1_scalar_add(&cache_i.tweak, &cache_i.tweak, &tweak);
271  if (!secp256k1_eckey_pubkey_tweak_add(&cache_i.pk, &tweak)) {
272  return 0;
273  }
274  /* eckey_pubkey_tweak_add fails if cache_i.pk is infinity */
276  secp256k1_keyagg_cache_save(keyagg_cache, &cache_i);
277  if (output_pubkey != NULL) {
278  secp256k1_pubkey_save(output_pubkey, &cache_i.pk);
279  }
280  return 1;
281 }
282 
283 int secp256k1_musig_pubkey_ec_tweak_add(const secp256k1_context* ctx, secp256k1_pubkey *output_pubkey, secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *tweak32) {
284  return secp256k1_musig_pubkey_tweak_add_internal(ctx, output_pubkey, keyagg_cache, tweak32, 0);
285 }
286 
287 int secp256k1_musig_pubkey_xonly_tweak_add(const secp256k1_context* ctx, secp256k1_pubkey *output_pubkey, secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *tweak32) {
288  return secp256k1_musig_pubkey_tweak_add_internal(ctx, output_pubkey, keyagg_cache, tweak32, 1);
289 }
290 
291 #endif
static int secp256k1_ge_is_infinity(const secp256k1_ge *a)
Check whether a group element is the point at infinity.
#define VERIFY_CHECK(cond)
Definition: util.h:159
static const unsigned char secp256k1_musig_keyagg_cache_magic[4]
Definition: keyagg_impl.h:19
This module implements BIP 327 "MuSig2 for BIP340-compatible Multi-Signatures" (https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki) v1.0.0.
int ret
static int secp256k1_ge_eq_var(const secp256k1_ge *a, const secp256k1_ge *b)
Check two group elements (affine) for equality in variable time.
static void secp256k1_keyagg_cache_save(secp256k1_musig_keyagg_cache *cache, const secp256k1_keyagg_cache_internal *cache_i)
Definition: keyagg_impl.h:31
static void secp256k1_musig_keyaggcoef_internal(secp256k1_scalar *r, const unsigned char *pks_hash, secp256k1_ge *pk, const secp256k1_ge *second_pk)
Definition: keyagg_impl.h:118
static void secp256k1_musig_keyagglist_sha256(secp256k1_sha256 *sha)
Definition: keyagg_impl.h:64
static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge *key, const secp256k1_scalar *tweak)
int secp256k1_musig_pubkey_get(const secp256k1_context *ctx, secp256k1_pubkey *agg_pk, const secp256k1_musig_keyagg_cache *keyagg_cache)
Obtain the aggregate public key from a keyagg_cache.
Definition: keyagg_impl.h:233
static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a)
Compute the complement of a scalar (modulo the group order).
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed)
static void secp256k1_pubkey_save(secp256k1_pubkey *pubkey, secp256k1_ge *ge)
Definition: secp256k1.c:246
static void secp256k1_musig_keyaggcoef_sha256(secp256k1_sha256 *sha)
Definition: keyagg_impl.h:99
SECP256K1_API int secp256k1_ec_pubkey_serialize(const secp256k1_context *ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey *pubkey, unsigned int flags) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Serialize a pubkey object into a serialized byte sequence.
Definition: secp256k1.c:268
memcpy(result.begin(), stream.data(), stream.size())
static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow)
Set a scalar from a big endian byte array.
A group element of the secp256k1 curve, in jacobian coordinates.
Definition: group.h:28
static int secp256k1_extrakeys_ge_even_y(secp256k1_ge *r)
Keeps a group element as is if it has an even Y and otherwise negates it.
Definition: main_impl.h:88
static int tweak(const secp256k1_context *ctx, secp256k1_xonly_pubkey *agg_pk, secp256k1_musig_keyagg_cache *cache)
Definition: musig.c:63
static void secp256k1_ge_to_bytes_ext(unsigned char *data, const secp256k1_ge *ge)
Convert a group element (that is allowed to be infinity) to a 64-byte array.
static int secp256k1_musig_pubkey_tweak_add_internal(const secp256k1_context *ctx, secp256k1_pubkey *output_pubkey, secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *tweak32, int xonly)
Definition: keyagg_impl.h:247
#define SECP256K1_EC_COMPRESSED
Flag to pass to secp256k1_ec_pubkey_serialize.
Definition: secp256k1.h:212
static void secp256k1_ge_set_infinity(secp256k1_ge *r)
Set a group element (affine) equal to the point at infinity.
const secp256k1_context * ctx
Definition: keyagg_impl.h:152
int secp256k1_musig_pubkey_xonly_tweak_add(const secp256k1_context *ctx, secp256k1_pubkey *output_pubkey, secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *tweak32)
Apply x-only tweaking to a public key in a given keyagg_cache by adding the generator multiplied with...
Definition: keyagg_impl.h:287
Opaque data structure that holds a parsed and valid "x-only" public key.
uint32_t s[8]
Definition: hash.h:14
int secp256k1_musig_pubkey_agg(const secp256k1_context *ctx, secp256k1_xonly_pubkey *agg_pk, secp256k1_musig_keyagg_cache *keyagg_cache, const secp256k1_pubkey *const *pubkeys, size_t n_pubkeys)
Computes an aggregate public key and uses it to initialize a keyagg_cache.
Definition: keyagg_impl.h:175
#define ARG_CHECK(cond)
Definition: secp256k1.c:45
static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a)
Set a group element equal to another which is given in jacobian coordinates.
int secp256k1_musig_pubkey_ec_tweak_add(const secp256k1_context *ctx, secp256k1_pubkey *output_pubkey, secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *tweak32)
Apply plain "EC" tweaking to a public key in a given keyagg_cache by adding the generator multiplied ...
Definition: keyagg_impl.h:283
static int secp256k1_ecmult_multi_var(const secp256k1_callback *error_callback, secp256k1_scratch *scratch, secp256k1_gej *r, const secp256k1_scalar *inp_g_sc, secp256k1_ecmult_multi_callback cb, void *cbdata, size_t n)
Multi-multiply: R = inp_g_sc * G + sum_i ni * Ai.
A group element in affine coordinates on the secp256k1 curve, or occasionally on an isomorphic curve ...
Definition: group.h:16
static SECP256K1_INLINE void secp256k1_xonly_pubkey_save(secp256k1_xonly_pubkey *pubkey, secp256k1_ge *ge)
Definition: main_impl.h:18
secp256k1_scalar tweak
Definition: keyagg.h:22
static int secp256k1_musig_compute_pks_hash(const secp256k1_context *ctx, unsigned char *pks_hash, const secp256k1_pubkey *const *pks, size_t np)
Definition: keyagg_impl.h:79
A scalar modulo the group order of the secp256k1 curve.
Definition: scalar_4x64.h:13
uint64_t bytes
Definition: hash.h:16
static void secp256k1_ge_from_bytes_ext(secp256k1_ge *ge, const unsigned char *data)
Convert a 64-byte array into a group element.
unsigned char pks_hash[32]
Definition: keyagg.h:20
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar *a)
Convert a scalar to a byte array.
static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t size)
static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b)
Add two scalars together (modulo the group order).
static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v)
Set a scalar to an unsigned integer.
static int secp256k1_musig_pubkey_agg_callback(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data)
Definition: keyagg_impl.h:160
static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n)
Semantics like memcmp.
Definition: util.h:255
#define secp256k1_fe_normalize_var
Definition: field.h:80
const secp256k1_pubkey *const * pks
Definition: keyagg_impl.h:155
static int secp256k1_keyagg_cache_load(const secp256k1_context *ctx, secp256k1_keyagg_cache_internal *cache_i, const secp256k1_musig_keyagg_cache *cache)
Definition: keyagg_impl.h:46
static int secp256k1_pubkey_load(const secp256k1_context *ctx, secp256k1_ge *ge, const secp256k1_pubkey *pubkey)
Definition: secp256k1.c:240
secp256k1_callback error_callback
Definition: secp256k1.c:64
static void secp256k1_sha256_initialize(secp256k1_sha256 *hash)
secp256k1_fe y
Definition: group.h:18
static void secp256k1_ge_to_bytes(unsigned char *buf, const secp256k1_ge *a)
Convert a group element that is not infinity to a 64-byte array.
static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32)
static void secp256k1_ge_from_bytes(secp256k1_ge *r, const unsigned char *buf)
Convert a 64-byte array into group element.
static void secp256k1_musig_keyaggcoef(secp256k1_scalar *r, const secp256k1_keyagg_cache_internal *cache_i, secp256k1_ge *pk)
Definition: keyagg_impl.h:147
Opaque data structure that holds a parsed and valid public key.
Definition: secp256k1.h:61