musig: mention how keyagg_cache tweak and parity relate to spec

Also rename internal_key_parity -> parity_acc because the former is
confusing.
This commit is contained in:
Jonas Nick 2022-03-15 22:26:55 +00:00
parent 57eb6b4167
commit eac0df1379
3 changed files with 24 additions and 24 deletions

View File

@ -18,8 +18,11 @@ typedef struct {
secp256k1_ge pk;
secp256k1_fe second_pk_x;
unsigned char pk_hash[32];
/* tweak is identical to value tacc[v] in the specification. */
secp256k1_scalar tweak;
int internal_key_parity;
/* parity_acc corresponds to gacc[v] in the spec. If gacc[v] is -1,
* parity_acc is 1. Otherwise, parity_acc is 0. */
int parity_acc;
} secp256k1_keyagg_cache_internal;
/* Requires that the saved point is not infinity */

View File

@ -69,7 +69,7 @@ static void secp256k1_keyagg_cache_save(secp256k1_musig_keyagg_cache *cache, sec
ptr += 32;
memcpy(ptr, cache_i->pk_hash, 32);
ptr += 32;
*ptr = cache_i->internal_key_parity;
*ptr = cache_i->parity_acc;
ptr += 1;
secp256k1_scalar_get_b32(ptr, &cache_i->tweak);
}
@ -84,7 +84,7 @@ static int secp256k1_keyagg_cache_load(const secp256k1_context* ctx, secp256k1_k
ptr += 32;
memcpy(cache_i->pk_hash, ptr, 32);
ptr += 32;
cache_i->internal_key_parity = *ptr & 1;
cache_i->parity_acc = *ptr & 1;
ptr += 1;
secp256k1_scalar_set_b32(&cache_i->tweak, ptr, NULL);
return 1;
@ -278,7 +278,7 @@ static int secp256k1_musig_pubkey_tweak_add_internal(const secp256k1_context* ct
return 0;
}
if (xonly && secp256k1_extrakeys_ge_even_y(&cache_i.pk)) {
cache_i.internal_key_parity ^= 1;
cache_i.parity_acc ^= 1;
secp256k1_scalar_negate(&cache_i.tweak, &cache_i.tweak);
}
secp256k1_scalar_add(&cache_i.tweak, &cache_i.tweak, &tweak);

View File

@ -513,21 +513,19 @@ int secp256k1_musig_partial_sign(const secp256k1_context* ctx, secp256k1_musig_p
return 0;
}
secp256k1_fe_normalize_var(&pk.y);
/* The specification requires that the secret key is multiplied by
* g*gp = g[0]*...g[v]*gp.
* Since all factors are 1 or -1, the key is negated if and only if
* (P[i] has odd y) XOR (is_xonly_t[1] and Q[0] has odd y)
* XOR (is_xonly_t[2] and Q[1] has odd y)
* XOR ... XOR (is_xonly_t[v] and Q[v-1] has odd y)
* XOR (Q[v] has odd y)
* which is equivalent to
* secp256k1_fe_is_odd(&pk.y)
* XOR cache_i.internal_key_parity
* XOR secp256k1_fe_is_odd(&cache_i.pk.y)).
* g[v]*g*gp. All factors are -1 or 1. The value g[v] is -1 iff
* secp256k1_fe_is_odd(&cache_i.pk.y)), g is is -1 iff parity_acc is 1 and
* gp is -1 if secp256k1_fe_is_odd(&pk.y). Therefore, multiplying by
* g[v]*g*gp is equivalent to negating if
* secp256k1_fe_is_odd(&cache_i.pk.y))
* XOR cache_i.parity_acc
* XOR secp256k1_fe_is_odd(&pk.y).
*/
if ((secp256k1_fe_is_odd(&pk.y)
!= secp256k1_fe_is_odd(&cache_i.pk.y))
!= cache_i.internal_key_parity) {
if ((secp256k1_fe_is_odd(&cache_i.pk.y)
!= cache_i.parity_acc)
!= secp256k1_fe_is_odd(&pk.y)) {
secp256k1_scalar_negate(&sk, &sk);
}
@ -599,14 +597,13 @@ int secp256k1_musig_partial_sig_verify(const secp256k1_context* ctx, const secp2
secp256k1_musig_keyaggcoef(&mu, &cache_i, &pkp.x);
secp256k1_scalar_mul(&e, &session_i.challenge, &mu);
/* The specification requires that the public key is multiplied by g which
* is negative if and only if fe_is_odd(&cache_i.pk.y) XOR
* internal_key_parity. Instead of multiplying g with the public key, we
* negate e which will have the same end result, since e and the public key
* are multiplied later anyway.
*/
/* The specification requires that the public key is multiplied by g[v]*g.
* All factors are -1 or 1. The value g[v] is -1 iff
* secp256k1_fe_is_odd(&cache_i.pk.y)) and g is is -1 iff parity_acc is 1.
* Therefore, multiplying by g[v]*g is equivalent to negating if
* fe_is_odd(&cache_i.pk.y) XOR parity_acc. */
if (secp256k1_fe_is_odd(&cache_i.pk.y)
!= cache_i.internal_key_parity) {
!= cache_i.parity_acc) {
secp256k1_scalar_negate(&e, &e);
}