Skip to content

Commit 163508a

Browse files
committed
musig: add key aggregation spec draft
1 parent 04b189b commit 163508a

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<pre>
2+
Title: MuSig Key Aggregation
3+
Author:
4+
Status: Draft
5+
License: BSD-2-Clause
6+
Created: 2020-01-19
7+
</pre>
8+
9+
== Introduction ==
10+
11+
=== Abstract ===
12+
13+
This document describes MuSig Key Aggregation in libsecp256k1-zkp.
14+
15+
=== Copyright ===
16+
17+
This document is licensed under the 2-clause BSD license.
18+
19+
=== Motivation ===
20+
21+
== Description ==
22+
23+
=== Design ===
24+
25+
* A function for sorting public keys allows to aggregate keys independent of the (initial) order.
26+
* The MuSig coefficient is computed by hashing the key instead of key index because. Otherwise, if the pubkey list gets sorted, the signer needs to translate between key indices pre- and post-sorting.
27+
* The second unique key in the pubkey list gets the constant MuSig coefficient 1 which saves an exponentiation.
28+
29+
30+
=== Specification ===
31+
32+
The following conventions are used, with constants as defined for [https://www.secg.org/sec2-v2.pdf secp256k1]. We note that adapting this specification to other elliptic curves is not straightforward and can result in an insecure scheme<ref>Among other pitfalls, using the specification with a curve whose order is not close to the size of the range of the nonce derivation function is insecure.</ref>.
33+
* Lowercase variables represent integers or byte arrays.
34+
** The constant ''p'' refers to the field size, ''0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F''.
35+
** The constant ''n'' refers to the curve order, ''0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141''.
36+
* Uppercase variables refer to points on the curve with equation ''y<sup>2</sup> = x<sup>3</sup> + 7'' over the integers modulo ''p''.
37+
** ''is_infinite(P)'' returns whether or not ''P'' is the point at infinity.
38+
** ''x(P)'' and ''y(P)'' are integers in the range ''0..p-1'' and refer to the X and Y coordinates of a point ''P'' (assuming it is not infinity).
39+
** The constant ''G'' refers to the base point, for which ''x(G) = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798'' and ''y(G) = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8''.
40+
** Addition of points refers to the usual [https://en.wikipedia.org/wiki/Elliptic_curve#The_group_law elliptic curve group operation].
41+
** [https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication Multiplication (⋅) of an integer and a point] refers to the repeated application of the group operation.
42+
* Functions and operations:
43+
** ''||'' refers to byte array concatenation.
44+
** The function ''x[i:j]'', where ''x'' is a byte array and ''i, j &ge; 0'', returns a ''(j - i)''-byte array with a copy of the ''i''-th byte (inclusive) to the ''j''-th byte (exclusive) of ''x''.
45+
** The function ''bytes(x)'', where ''x'' is an integer, returns the 32-byte encoding of ''x'', most significant byte first.
46+
** The function ''bytes(P)'', where ''P'' is a point, returns ''bytes(x(P))''.
47+
** The function ''int(x)'', where ''x'' is a 32-byte array, returns the 256-bit unsigned integer whose most significant byte first encoding is ''x''.
48+
** The function ''has_even_y(P)'', where ''P'' is a point for which ''not is_infinite(P)'', returns ''y(P) mod 2 = 0''.
49+
** The function ''lift_x(x)'', where ''x'' is an integer in range ''0..p-1'', returns the point ''P'' for which ''x(P) = x''<ref>
50+
Given a candidate X coordinate ''x'' in the range ''0..p-1'', there exist either exactly two or exactly zero valid Y coordinates. If no valid Y coordinate exists, then ''x'' is not a valid X coordinate either, i.e., no point ''P'' exists for which ''x(P) = x''. The valid Y coordinates for a given candidate ''x'' are the square roots of ''c = x<sup>3</sup> + 7 mod p'' and they can be computed as ''y = &plusmn;c<sup>(p+1)/4</sup> mod p'' (see [https://en.wikipedia.org/wiki/Quadratic_residue#Prime_or_prime_power_modulus Quadratic residue]) if they exist, which can be checked by squaring and comparing with ''c''.</ref> and ''has_even_y(P)'', or fails if no such point exists. The function ''lift_x(x)'' is equivalent to the following pseudocode:
51+
*** Let ''c = x<sup>3</sup> + 7 mod p''.
52+
*** Let ''y = c<sup>(p+1)/4</sup> mod p''.
53+
*** Fail if ''c &ne; y<sup>2</sup> mod p''.
54+
*** Return the unique point ''P'' such that ''x(P) = x'' and ''y(P) = y'' if ''y mod 2 = 0'' or ''y(P) = p-y'' otherwise.
55+
** The function ''hash<sub>tag</sub>(x)'' where ''tag'' is a UTF-8 encoded tag name and ''x'' is a byte array returns the 32-byte hash ''SHA256(SHA256(tag) || SHA256(tag) || x)''.
56+
57+
58+
==== Key Sorting ====
59+
60+
Input:
61+
* The number ''u'' of signatures with ''0 < u < 2^32''
62+
* The public keys ''pk<sub>1..u</sub>'': ''u'' 32-byte arrays
63+
64+
The algorithm ''KeySort(pk<sub>1..u</sub>)'' is defined as:
65+
* Return ''sort(pk)''
66+
** where ''pk<sub>i</sub> < pk<sub>j</sub>'' if for the smallest ''k'' such that ''pk<sub>i</sub>[k] &ne pk<sub>j</sub>[k]'' it holds that ''pk<sub>i</sub>[k] < pk<sub>j</sub>[k]''.
67+
68+
==== Key Aggregation ====
69+
70+
Input:
71+
* The number ''u'' of signatures with ''0 < u < 2^32''
72+
* The public keys ''pk<sub>1..u</sub>'': ''u'' 32-byte arrays
73+
74+
The algorithm ''KeyAgg(pk<sub>1..u</sub>)'' is defined as:
75+
* For ''i = 1 .. u'':
76+
** Let ''a<sub>i</sub> = ComputeCoefficient(pk<sub>1..u</sub>, i)''.
77+
** Let ''P<sub>i</sub> = lift_x(int(pk<sub>i</sub>))''; fail if it fails.
78+
* Let ''S = a<sub>1</sub>⋅P<sub>1</sub> + a<sub>2</sub>⋅P<sub>1</sub> + ... + a<sub>u</sub>⋅P<sub>u</sub>''
79+
* Fail if ''is_infinite(S)''.
80+
* Return ''bytes(S)''.
81+
82+
The algorithm ''HashKeys(pk<sub>1..u</sub>)'' is defined as:
83+
* Return ''hash(pk<sub>1</sub> || pk<sub>2</sub> || ... || pk<sub>u</sub>)''
84+
85+
The algorithm ''IsSecond(pk<sub>1..u</sub>, i)'' is defined as:
86+
* For ''j = 1 .. u'':
87+
** If ''pk<sub>j</sub> &ne; pk<sub>1</sub>'':
88+
*** Return ''true'' if ''pk<sub>j</sub> = pk<sub>i</sub>'', otherwise return ''false''.
89+
* Return ''false''
90+
91+
The algorithm ''ComputeCoefficient(pk<sub>1..u</sub>, i)'' is defined as:
92+
* Let ''L = HashKeys(pk<sub>1..u</sub>)''.
93+
* Return ''int(hash<sub>MuSig coefficient</sub>(L || pk) mod n'' if ''IsSecond(pk<sub>1..u</sub>, i)'' &ne; 2, otherwise return 1.
94+
95+
== Applications ==
96+
97+
== Test Vectors and Reference Code ==
98+
99+
== Footnotes ==
100+
101+
<references />
102+
103+
== Acknowledgements ==

0 commit comments

Comments
 (0)