<pre>
  Title: MuSig Key Aggregation
  Author:
  Status: Draft
  License: BSD-2-Clause
  Created: 2020-01-19
</pre>

== Introduction ==

=== Abstract ===

This document describes MuSig Key Aggregation in libsecp256k1-zkp.

=== Copyright ===

This document is licensed under the 2-clause BSD license.

=== Motivation ===

== Description ==

=== Design ===

* The output of the ''KeyAgg'' algorithm depends on the order of the input public keys.
* It is possible to sort the public keys with the ''KeySort'' algorithm before key aggregation to ensure the same output, independent of the (initial) order.
* The KeyAgg coefficient is computed by hashing the key instead of key index. Otherwise, if the pubkey list gets sorted, the signer needs to translate between key indices pre- and post-sorting.
* The second unique key in the pubkey list given to ''KeyAgg'' (as well as any keys identical to this key) gets the constant KeyAgg coefficient 1 which saves an exponentiation (see the MuSig2* appendix in the [https://eprint.iacr.org/2020/1261 MuSig2 paper]).
* The public key inputs are serialized using x-only (32 byte) instead of compressed (33 byte) serialization. The reason for this is that as x-only keys are becoming more common, the full key may not be available.

=== Specification ===

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>.
* Lowercase variables represent integers or byte arrays.
** The constant ''p'' refers to the field size, ''0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F''.
** The constant ''n'' refers to the curve order, ''0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141''.
* Uppercase variables refer to points on the curve with equation ''y<sup>2</sup> = x<sup>3</sup> + 7'' over the integers modulo ''p''.
** ''is_infinite(P)'' returns whether or not ''P'' is the point at infinity.
** ''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).
** The constant ''G'' refers to the base point, for which ''x(G) = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798'' and ''y(G) = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8''.
** Addition of points refers to the usual [https://en.wikipedia.org/wiki/Elliptic_curve#The_group_law elliptic curve group operation].
** [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.
* Functions and operations:
** ''||'' refers to byte array concatenation.
** 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''.
** The function ''bytes(x)'', where ''x'' is an integer, returns the 32-byte encoding of ''x'', most significant byte first.
** The function ''bytes(P)'', where ''P'' is a point, returns ''bytes(x(P))''.
** The function ''has_even_y(P)'', where ''P'' is a point for which ''not is_infinite(P)'', returns ''y(P) mod 2 = 0''.
** The function ''cbytes(P)'', where ''P'' is a point, returns ''a || bytes(P)'' where ''a'' is ''2'' if ''has_even_y(P)'' and ''3'' otherwise.
** 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''.
** The function ''lift_x(x)'', where ''x'' is an integer in range ''0..2<sup>256</sup>-1'', returns the point ''P'' for which ''x(P) = x''<ref>
    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 ''x'' is greater than ''p-1'' or no such point exists. The function ''lift_x(x)'' is equivalent to the following pseudocode:
*** Fail if ''x &gt; p-1''.
*** Let ''c = x<sup>3</sup> + 7 mod p''.
*** Let ''y' = c<sup>(p+1)/4</sup> mod p''.
*** Fail if ''c &ne; y'<sup>2</sup> mod p''.
*** Let ''y = y' '' if ''y' mod 2 = 0'', otherwise let ''y = p - y' ''.
*** Return the unique point ''P'' such that ''x(P) = x'' and ''y(P) = y''.
** 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)''.


==== Key Sorting ====

Input:
* The number ''u'' of signatures with ''0 < u < 2^32''
* The public keys ''pk<sub>1..u</sub>'': ''u'' 32-byte arrays

The algorithm ''KeySort(pk<sub>1..u</sub>)'' is defined as:
* Return ''pk<sub>1..u</sub>'' sorted in lexicographical order.

==== Key Aggregation ====

Input:
* The number ''u'' of public keys with ''0 < u < 2^32''
* The public keys ''pk<sub>1..u</sub>'': ''u'' 32-byte arrays

The algorithm ''KeyAgg(pk<sub>1..u</sub>)'' is defined as:
* For ''i = 1 .. u'':
** Let ''a<sub>i</sub> = KeyAggCoeff(pk<sub>1..u</sub>, pk<sub>i</sub>)''.
** Let ''P<sub>i</sub> = lift_x(int(pk<sub>i</sub>))''; fail if it fails.
* Let ''Q = a<sub>1</sub>⋅P<sub>1</sub> + a<sub>2</sub>⋅P<sub>1</sub> + ... + a<sub>u</sub>⋅P<sub>u</sub>''
* Fail if ''is_infinite(Q)''.
* Return ''bytes(Q)''.

The algorithm ''HashKeys(pk<sub>1..u</sub>)'' is defined as:
* Return ''hash<sub>KeyAgg list</sub>(pk<sub>1</sub> || pk<sub>2</sub> || ... || pk<sub>u</sub>)''

The algorithm ''IsSecond(pk<sub>1..u</sub>, pk')'' is defined as:
* For ''j = 1 .. u'':
** If ''pk<sub>j</sub> &ne; pk<sub>1</sub>'':
*** Return ''true'' if ''pk<sub>j</sub> = pk' '', otherwise return ''false''.
* Return ''false''

The algorithm ''KeyAggCoeff(pk<sub>1..u</sub>, pk')'' is defined as:
* Let ''L = HashKeys(pk<sub>1..u</sub>)''.
* If ''IsSecond(pk<sub>1..u</sub>, pk')'':
** Return 1
* Return ''int(hash<sub>KeyAgg coefficient</sub>(L || pk')) mod n''

== Applications ==

== Test Vectors and Reference Code ==

There are some vectors in libsecp256k1's [https://github.com/ElementsProject/secp256k1-zkp/blob/master/src/modules/musig/tests_impl.h MuSig test file].
Search for the ''musig_test_vectors_keyagg'' function.

== Footnotes ==

<references />

== Acknowledgements ==
