@@ -538,56 +538,65 @@ int secp256k1_musig_partial_sign(const secp256k1_context* ctx, secp256k1_musig_p
538
538
* The following public keys arise as intermediate steps:
539
539
* - P[i] is the i-th public key with corresponding secret key x[i]
540
540
* P[i] := x[i]*G
541
- * - P_agg is the aggregate public key
542
- * P_agg := mu[0]*|P[0]| + ... + mu[n-1]*|P[n-1]|
543
- * - P_tweak[i] is the tweaked public key after the i-th tweaking operation
544
- * P_tweak[0] := P_agg
545
- * P_tweak[i] := |P_tweak[i-1]| + t[i]*G for i = 1, ..., m
541
+ * - P_agg[0] is the aggregate public key
542
+ * P_agg[0] := mu[0]*|P[0]| + ... + mu[n-1]*|P[n-1]|
543
+ * - P_agg[i] for 1 <= i <= m is the tweaked public key after the i-th
544
+ * tweaking operation. There are two types of tweaking: x-only and ordinary
545
+ * "EC" tweaking. We define a boolean predicate xonly(i) that is true if
546
+ * the i-th tweaking operation is x-only tweaking and false otherwise
547
+ * (ordinary tweaking).
548
+ * Let
549
+ * P_agg[i] := f(i, P_agg[i-1]) + t[i]*G for i = 1, ..., m
550
+ * where f(i, X) := |X| if xonly(i)
551
+ * f(i, X) := X otherwise
546
552
*
547
553
* Note that our goal is to produce a partial signature corresponding to
548
- * the final public key after m tweaking operations P_final = |P_tweak [m]|.
554
+ * the final public key after m tweaking operations P_final = |P_agg [m]|.
549
555
*
550
- * Define d[i], d_agg, and d_tweak [i] so that:
556
+ * Define d[i] for 0 <= i <= n-1 and d_agg [i] for 0 <= i <= m so that:
551
557
* - |P[i]| = d[i]*P[i]
552
- * - | P_agg| = d_agg*P_agg
553
- * - |P_tweak[i ]| = d_tweak[i]*P_tweak[i ]
558
+ * - f(i+1, P_agg[i]) = d_agg[i] *P_agg[i] for 0 <= i <= m - 1
559
+ * - |P_agg[m ]| = d_agg[m]*P_agg[m ]
554
560
*
555
- * In other words, d[i] = 1 if P[i] has even y coordinate, -1 otherwise;
556
- * similarly for d_agg and d_tweak[i].
561
+ * In other words, d[i] = 1 if P[i] has even y coordinate, -1 otherwise.
562
+ * For 0 <= i <= m-1, d_agg[i] is -1 if and only if xonly(i+1) is true and
563
+ * P_agg[i] has an odd Y coordinate.
557
564
*
558
- * The (xonly ) final public key is P_final = |P_tweak [m]|
559
- * = d_tweak [m]*P_tweak [m]
560
- * = d_tweak [m]*(|P_tweak [m-1]| + t[m]*G)
561
- * = d_tweak [m]*(d_tweak [m-1]*(|P_tweak [m-2]| + t[m-1]*G) + t[m]*G)
562
- * = d_tweak [m]*...*d_tweak[1]*| P_agg| + (d_tweak [m]*t[m]+...+*d_tweak [1]*t[1])*G.
563
- * To simplify the equation let us define
564
- * t := d_tweak [m]*t[m]+ ...+*d_tweak[1]*t[1]
565
- * d_tweak := d_tweak [m]*...*d_tweak [1].
565
+ * The (x-only ) final public key is P_final = |P_agg [m]|
566
+ * = d_agg [m]*P_agg [m]
567
+ * = d_agg [m]*(f(m, P_agg [m-1]) + t[m]*G)
568
+ * = d_agg [m]*(d_agg [m-1]*(f(m-1, P_agg [m-2]) + t[m-1]*G) + t[m]*G)
569
+ * = d_agg [m]*...*d_agg[0]* P_agg[0] + (d_agg [m]*t[m]+...+*d_agg [1]*t[1])*G.
570
+ * To simplify the equation let us define
571
+ * d_agg := d_agg [m]*...*d_agg[0].
572
+ * t := d_agg [m]*t[m]+ ...+*d_agg [1]*t[1] if m > 0, otherwise t := 0
566
573
* Then we have
567
574
* P_final - t*G
568
- * = d_tweak*|P_agg|
569
- * = d_tweak*d_agg*P_agg
570
- * = d_tweak*d_agg*(mu[0]*|P[0]| + ... + mu[n-1]*|P[n-1]|)
571
- * = d_tweak*d_agg*(d[0]*mu[0]*P[0] + ... + d[n-1]*mu[n-1]*P[n-1])
572
- * = sum((d_tweak*d_agg*d[i])*mu[i]*x[i])*G.
575
+ * = d_agg*P_agg[0]
576
+ * = d_agg*(mu[0]*|P[0]| + ... + mu[n-1]*|P[n-1]|)
577
+ * = d_agg*(d[0]*mu[0]*P[0] + ... + d[n-1]*mu[n-1]*P[n-1])
578
+ * = sum((d_agg*d[i])*mu[i]*x[i])*G.
573
579
*
574
580
* Thus whether signer i should use the negated x[i] depends on the product
575
- * d_tweak [m]*...*d_tweak [1]*d_agg*d[i]. In other words, negate if and only
581
+ * d_agg [m]*...*d_agg [1]*d_agg[0] *d[i]. In other words, negate if and only
576
582
* if the following holds:
577
- * (P[i] has odd y) XOR (P_agg has odd y)
578
- * XOR (P_tweak[1] has odd y) XOR ... XOR (P_tweak[m] has odd y)
583
+ * (P[i] has odd y) XOR (xonly(1) and P_agg[0] has odd y)
584
+ * XOR (xonly(2) and P_agg[1] has odd y)
585
+ * XOR ... XOR (xonly(m) and P_agg[m-1] has odd y)
586
+ * XOR (P_agg[m] has odd y)
579
587
*
580
588
* Let us now look at how the terms in the equation correspond to the if
581
589
* condition below for some values of m:
582
- * m = 0: P_i has odd y = secp256k1_fe_is_odd(&pk.y)
583
- * P_agg has odd y = secp256k1_fe_is_odd(&cache_i.pk.y)
590
+ * m = 0: P[i] has odd y = secp256k1_fe_is_odd(&pk.y)
591
+ * P_agg[0] has odd y = secp256k1_fe_is_odd(&cache_i.pk.y)
584
592
* cache_i.internal_key_parity = 0
585
- * m = 1: P_i has odd y = secp256k1_fe_is_odd(&pk.y)
586
- * P_agg has odd y = cache_i.internal_key_parity
587
- * P_tweak[1] has odd y = secp256k1_fe_is_odd(&cache_i.pk.y)
588
- * m = 2: P_i has odd y = secp256k1_fe_is_odd(&pk.y)
589
- * P_agg has odd y XOR P_tweak[1] has odd y = cache_i.internal_key_parity
590
- * P_tweak[2] has odd y = secp256k1_fe_is_odd(&cache_i.pk.y)
593
+ * m = 1: P[i] has odd y = secp256k1_fe_is_odd(&pk.y)
594
+ * xonly(1) and P_agg[0] has odd y = cache_i.internal_key_parity
595
+ * P_agg[1] has odd y = secp256k1_fe_is_odd(&cache_i.pk.y)
596
+ * m = 2: P[i] has odd y = secp256k1_fe_is_odd(&pk.y)
597
+ * (xonly(1) and P_agg[0] has odd y)
598
+ XOR (xonly(2) and P_agg[1] has odd y) = cache_i.internal_key_parity
599
+ * P_agg[2] has odd y = secp256k1_fe_is_odd(&cache_i.pk.y)
591
600
* etc.
592
601
*/
593
602
if ((secp256k1_fe_is_odd (& pk .y )
@@ -674,7 +683,7 @@ int secp256k1_musig_partial_sig_verify(const secp256k1_context* ctx, const secp2
674
683
/* When producing a partial signature, signer i uses a possibly
675
684
* negated secret key:
676
685
*
677
- * sk[i] = (d_tweak* d_agg*d[i])*x[i]
686
+ * sk[i] = (d_agg*d[i])*x[i]
678
687
*
679
688
* to ensure that the aggregate signature will correspond to
680
689
* an aggregate public key with even Y coordinate (see the
@@ -698,14 +707,14 @@ int secp256k1_musig_partial_sig_verify(const secp256k1_context* ctx, const secp2
698
707
* The verifier doesn't have access to sk[i]*G, but can construct
699
708
* it using the xonly public key |P[i]| as follows:
700
709
*
701
- * sk[i]*G = d_tweak* d_agg*d[i]*x[i]*G
702
- * = d_tweak* d_agg*d[i]*P[i]
703
- * = d_tweak* d_agg*|P[i]|
710
+ * sk[i]*G = d_agg*d[i]*x[i]*G
711
+ * = d_agg*d[i]*P[i]
712
+ * = d_agg*|P[i]|
704
713
*
705
- * The if condition below is true whenever d_tweak* d_agg is
706
- * negative (again, see the explanation in musig_partial_sign). In
707
- * this case, the verifier negates e which will have the same end
708
- * result as negating |P[i]|, since they are multiplied later anyway.
714
+ * The if condition below is true whenever d_agg is negative (again, see the
715
+ * explanation in musig_partial_sign). In this case, the verifier negates e
716
+ * which will have the same end result as negating |P[i]|, since they are
717
+ * multiplied later anyway.
709
718
*/
710
719
if (secp256k1_fe_is_odd (& cache_i .pk .y )
711
720
!= cache_i .internal_key_parity ) {
0 commit comments