github.com/ethereum/go-ethereum@v1.16.1/crypto/secp256k1/libsecp256k1/src/modules/musig/keyagg_impl.h (about) 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. */ 31 static void secp256k1_keyagg_cache_save(secp256k1_musig_keyagg_cache *cache, const secp256k1_keyagg_cache_internal *cache_i) { 32 unsigned char *ptr = cache->data; 33 memcpy(ptr, secp256k1_musig_keyagg_cache_magic, 4); 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 46 static int secp256k1_keyagg_cache_load(const secp256k1_context* ctx, secp256k1_keyagg_cache_internal *cache_i, const secp256k1_musig_keyagg_cache *cache) { 47 const unsigned char *ptr = cache->data; 48 ARG_CHECK(secp256k1_memcmp_var(ptr, secp256k1_musig_keyagg_cache_magic, 4) == 0); 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"). */ 64 static void secp256k1_musig_keyagglist_sha256(secp256k1_sha256 *sha) { 65 secp256k1_sha256_initialize(sha); 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 83 secp256k1_musig_keyagglist_sha256(&sha); 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"). */ 99 static void secp256k1_musig_keyaggcoef_sha256(secp256k1_sha256 *sha) { 100 secp256k1_sha256_initialize(sha); 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) { 119 VERIFY_CHECK(!secp256k1_ge_is_infinity(pk)); 120 121 if (!secp256k1_ge_is_infinity(second_pk) 122 && secp256k1_ge_eq_var(pk, second_pk)) { 123 secp256k1_scalar_set_int(r, 1); 124 } else { 125 secp256k1_sha256 sha; 126 unsigned char buf[33]; 127 size_t buflen = sizeof(buf); 128 int ret; 129 secp256k1_musig_keyaggcoef_sha256(&sha); 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. */ 147 static void secp256k1_musig_keyaggcoef(secp256k1_scalar *r, const secp256k1_keyagg_cache_internal *cache_i, secp256k1_ge *pk) { 148 secp256k1_musig_keyaggcoef_internal(r, cache_i->pks_hash, pk, &cache_i->second_pk); 149 } 150 151 typedef struct { 152 const secp256k1_context *ctx; 153 /* pks_hash is the hash of the public keys */ 154 unsigned char pks_hash[32]; 155 const secp256k1_pubkey * const* pks; 156 secp256k1_ge second_pk; 157 } secp256k1_musig_pubkey_agg_ecmult_data; 158 159 /* Callback for batch EC multiplication to compute keyaggcoef_0*P0 + keyaggcoef_1*P1 + ... */ 160 static int secp256k1_musig_pubkey_agg_callback(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx, void *data) { 161 secp256k1_musig_pubkey_agg_ecmult_data *ctx = (secp256k1_musig_pubkey_agg_ecmult_data *) data; 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 171 secp256k1_musig_keyaggcoef_internal(sc, ctx->pks_hash, pt, &ctx->second_pk); 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) { 176 secp256k1_musig_pubkey_agg_ecmult_data ecmult_data; 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) { 194 secp256k1_ge pk; 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); 215 secp256k1_fe_normalize_var(&pkp.y); 216 /* The resulting public key is infinity with negligible probability */ 217 VERIFY_CHECK(!secp256k1_ge_is_infinity(&pkp)); 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) { 227 secp256k1_extrakeys_ge_even_y(&pkp); 228 secp256k1_xonly_pubkey_save(agg_pk, &pkp); 229 } 230 return 1; 231 } 232 233 int secp256k1_musig_pubkey_get(const secp256k1_context* ctx, secp256k1_pubkey *agg_pk, const secp256k1_musig_keyagg_cache *keyagg_cache) { 234 secp256k1_keyagg_cache_internal cache_i; 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) { 248 secp256k1_keyagg_cache_internal cache_i; 249 int overflow = 0; 250 secp256k1_scalar tweak; 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 */ 275 VERIFY_CHECK(!secp256k1_ge_is_infinity(&cache_i.pk)); 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