Bitcoin Core 32.99.0
P2P Digital Currency
Loading...
Searching...
No Matches
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
19static 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;
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;
44}
45
47 const unsigned char *ptr = cache->data;
49 ptr += 4;
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;
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"). */
65 static const uint32_t midstate[8] = {
66 0xb399d5e0ul, 0xc8fff302ul, 0x6badac71ul, 0x07c5b7f1ul,
67 0x9701e2eful, 0x2a72ecf8ul, 0x201a4c7bul, 0xab148a38ul
68 };
70}
71
72/* Computes pks_hash = tagged_hash(pk[0], ..., pk[np-1]) */
73static int secp256k1_musig_compute_pks_hash(const secp256k1_context *ctx, unsigned char *pks_hash, const secp256k1_pubkey * const* pks, size_t np) {
75 size_t i;
76
78 for (i = 0; i < np; i++) {
79 unsigned char ser[33];
80 size_t ser_len = sizeof(ser);
82 return 0;
83 }
84 VERIFY_CHECK(ser_len == sizeof(ser));
85 secp256k1_sha256_write(&ctx->hash_ctx, &sha, ser, sizeof(ser));
86 }
87 secp256k1_sha256_finalize(&ctx->hash_ctx, &sha, pks_hash);
88 return 1;
89}
90
91/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
92 * SHA256 to SHA256("KeyAgg coefficient")||SHA256("KeyAgg coefficient"). */
94 static const uint32_t midstate[8] = {
95 0x6ef02c5aul, 0x06a480deul, 0x1f298665ul, 0x1d1134f2ul,
96 0x56a0b063ul, 0x52da4147ul, 0xf280d9d4ul, 0x4484be15ul
97 };
99}
100
101/* Compute KeyAgg coefficient which is constant 1 for the second pubkey and
102 * otherwise tagged_hash(pks_hash, pk) where pks_hash is the hash of public keys.
103 * second_pk is the point at infinity in case there is no second_pk. Assumes
104 * that pk is not the point at infinity and that the Y-coordinates of pk and
105 * second_pk are normalized. */
106static void secp256k1_musig_keyaggcoef_internal(const secp256k1_hash_ctx *hash_ctx, secp256k1_scalar *r, const unsigned char *pks_hash, secp256k1_ge *pk, const secp256k1_ge *second_pk) {
108
109 if (!secp256k1_ge_is_infinity(second_pk)
110 && secp256k1_ge_eq_var(pk, second_pk)) {
112 } else {
114 unsigned char buf[33];
116 secp256k1_sha256_write(hash_ctx, &sha, pks_hash, 32);
117 /* Serialization does not fail since the pk is not the point at infinity
118 * (according to this function's precondition). */
120 secp256k1_sha256_write(hash_ctx, &sha, buf, sizeof(buf));
121 secp256k1_sha256_finalize(hash_ctx, &sha, buf);
123 }
124}
125
126/* Assumes that pk is not the point at infinity and that the Y-coordinates of pk
127 * and cache_i->second_pk are normalized. */
131
132typedef struct {
134 /* pks_hash is the hash of the public keys */
135 unsigned char pks_hash[32];
136 const secp256k1_pubkey * const* pks;
139
140/* Callback for batch EC multiplication to compute keyaggcoef_0*P0 + keyaggcoef_1*P1 + ... */
143 int ret;
144 ret = secp256k1_pubkey_load(ctx->ctx, pt, ctx->pks[idx]);
145#ifdef VERIFY
146 /* pubkey_load can't fail because the same pks have already been loaded in
147 * `musig_compute_pks_hash` (and we test this). */
149#else
150 (void) ret;
151#endif
153 return 1;
154}
155
160 size_t i;
161
162 VERIFY_CHECK(ctx != NULL);
163 if (agg_pk != NULL) {
164 memset(agg_pk, 0, sizeof(*agg_pk));
165 }
166 ARG_CHECK(pubkeys != NULL);
167 ARG_CHECK(n_pubkeys > 0);
168 for (i = 0; i < n_pubkeys; i++) {
169 ARG_CHECK(pubkeys[i] != NULL);
170 }
171
172 ecmult_data.ctx = ctx;
173 ecmult_data.pks = pubkeys;
174
176 for (i = 1; i < n_pubkeys; i++) {
177 if (secp256k1_memcmp_var(pubkeys[0], pubkeys[i], sizeof(*pubkeys[0])) != 0) {
178 secp256k1_ge pk;
179 if (!secp256k1_pubkey_load(ctx, &pk, pubkeys[i])) {
180 return 0;
181 }
182 ecmult_data.second_pk = pk;
183 break;
184 }
185 }
186
187 if (!secp256k1_musig_compute_pks_hash(ctx, ecmult_data.pks_hash, pubkeys, n_pubkeys)) {
188 return 0;
189 }
190 /* TODO: actually use optimized ecmult_multi algorithms by providing a
191 * scratch space */
193 /* In order to reach this line with the current implementation of
194 * ecmult_multi_var one would need to provide a callback that can
195 * fail. */
196 return 0;
197 }
200 /* The resulting public key is infinity with negligible probability */
202 if (keyagg_cache != NULL) {
204 cache_i.pk = pkp;
205 cache_i.second_pk = ecmult_data.second_pk;
206 memcpy(cache_i.pks_hash, ecmult_data.pks_hash, sizeof(cache_i.pks_hash));
208 }
209
210 if (agg_pk != NULL) {
213 }
214 return 1;
215}
216
230
233 int overflow = 0;
235
236 VERIFY_CHECK(ctx != NULL);
237 if (output_pubkey != NULL) {
238 memset(output_pubkey, 0, sizeof(*output_pubkey));
239 }
242
244 return 0;
245 }
247 if (overflow) {
248 return 0;
249 }
251 cache_i.parity_acc ^= 1;
253 }
254 secp256k1_scalar_add(&cache_i.tweak, &cache_i.tweak, &tweak);
256 return 0;
257 }
258 /* eckey_pubkey_tweak_add fails if cache_i.pk is infinity */
261 if (output_pubkey != NULL) {
263 }
264 return 1;
265}
266
270
274
275#endif
int ret
static const PrecomputedData data
Precomputed COutPoint and CCoins values.
static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge *key, const secp256k1_scalar *tweak)
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.
static SECP256K1_INLINE void secp256k1_xonly_pubkey_save(secp256k1_xonly_pubkey *pubkey, secp256k1_ge *ge)
Definition main_impl.h:18
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:95
#define secp256k1_fe_normalize_var
Definition field.h:80
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_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 void secp256k1_ge_serialize33(secp256k1_ge *elem, unsigned char *pub33)
Serialize a group element (that is not allowed to be infinity) to a compressed public key (33 bytes).
static void secp256k1_ge_from_bytes_ext(secp256k1_ge *ge, const unsigned char *data)
Convert a 64-byte array into a group element.
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.
static int secp256k1_ge_is_infinity(const secp256k1_ge *a)
Check whether a group element is the point at infinity.
static void secp256k1_ge_set_infinity(secp256k1_ge *r)
Set a group element (affine) equal to the point at infinity.
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_ge_from_bytes(secp256k1_ge *r, const unsigned char *buf)
Convert a 64-byte array into group element.
static void secp256k1_musig_keyaggcoef(const secp256k1_hash_ctx *hash_ctx, secp256k1_scalar *r, const secp256k1_keyagg_cache_internal *cache_i, secp256k1_ge *pk)
static int secp256k1_musig_pubkey_agg_callback(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data)
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 void secp256k1_musig_keyaggcoef_sha256(secp256k1_sha256 *sha)
Definition keyagg_impl.h:93
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)
static void secp256k1_musig_keyagglist_sha256(secp256k1_sha256 *sha)
Definition keyagg_impl.h:64
static const unsigned char secp256k1_musig_keyagg_cache_magic[4]
Definition keyagg_impl.h:19
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(const secp256k1_hash_ctx *hash_ctx, secp256k1_scalar *r, const unsigned char *pks_hash, secp256k1_ge *pk, const secp256k1_ge *second_pk)
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...
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:73
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 ...
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.
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.
static int tweak(const secp256k1_context *ctx, secp256k1_xonly_pubkey *agg_pk, secp256k1_musig_keyagg_cache *cache)
Definition musig.c:64
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 void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v)
Set a scalar to an unsigned integer.
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar *a)
Convert a scalar to a byte array.
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_negate(secp256k1_scalar *r, const secp256k1_scalar *a)
Compute the complement of a scalar (modulo the group order).
static void secp256k1_sha256_finalize(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *hash, unsigned char *out32)
static void secp256k1_sha256_initialize_midstate(secp256k1_sha256 *hash, uint64_t bytes, const uint32_t state[8])
static void secp256k1_sha256_write(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *hash, const unsigned char *data, size_t size)
static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n)
Semantics like memcmp.
Definition util.h:281
#define VERIFY_CHECK(cond)
Definition util.h:169
#define ARG_CHECK(cond)
Definition secp256k1.c:45
static int secp256k1_pubkey_load(const secp256k1_context *ctx, secp256k1_ge *ge, const secp256k1_pubkey *pubkey)
Definition secp256k1.c:254
static void secp256k1_pubkey_save(secp256k1_pubkey *pubkey, secp256k1_ge *ge)
Definition secp256k1.c:260
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:282
#define SECP256K1_EC_COMPRESSED
Flag to pass to secp256k1_ec_pubkey_serialize.
Definition secp256k1.h:216
secp256k1_callback error_callback
Definition secp256k1.c:65
secp256k1_hash_ctx hash_ctx
Definition secp256k1.c:63
A group element in affine coordinates on the secp256k1 curve, or occasionally on an isomorphic curve ...
Definition group.h:16
A group element of the secp256k1 curve, in jacobian coordinates.
Definition group.h:28
This module implements BIP 327 "MuSig2 for BIP340-compatible Multi-Signatures" (https://github....
const secp256k1_pubkey *const * pks
const secp256k1_context * ctx
Opaque data structure that holds a parsed and valid public key.
Definition secp256k1.h:62
A scalar modulo the group order of the secp256k1 curve.
Definition scalar_4x64.h:13
Opaque data structure that holds a parsed and valid "x-only" public key.
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.
Definition time.h:82