Code Freeze Fall 2021: Schnorr signatures
The code is templated in such a way that the primes and are defined relative to the group G1
, which is unfortunate, since is chosen as a fixed, definite value in our specs. An alternative would be to have the templates in schnorr.tcc refer to F_nat
and F_em
(for 'native' and 'emulated') or something like this. The easier and probably better alternative for now is to just rename our primes in the Yellow Paper as and .
For Aztec's current uses cases, G1
is a cyclic subgroup of an elliptic curve defined over a field (implemented as a class Fq
), and Fr
(aka field_t
) is the a field of size equal to the size of G1
, so Fr
is the field acting on G1
by scalar multiplication.
Role:
Yellow paper only mentions them here: The Blake2s hash is utilized for computing nullifiers and for generating pseudorandom challenges, when verifying Schnorr signatures and when recursively verifying Plonk proofs.
They are used by the account circuit and the join-split circuit.
Data types
crypto::schnorr::signature
is a pair of two 256-bit integers represented as length-32 std::array
's of uint32_t
's.
crypto::schnorr::signature_b
is a pair of the same type.
wnaf_record<C>
is a vector of bool_t<C>
's along with a skew.
signature_bits<C>
is four field_t
's, representing a signature by splitting component into two.
Formulas
Elliptic curve addition
We restrict in this code to working with curves described by Weierstrass equations of the form defined over a with prime. Consider two non-identity points , . If , then , so the two points are equal or one is the inverse of the other. If , then one has with . In the case of Grumpkin, the equation splits over , there are indeed distinct pairs of points satisfying this relation (for an example of how we handle this elsewhere in the code base, see https://github.com/AztecProtocol/aztec2-internal/issues/437).
Suppose . Then with
where if and if .
Algorithms
Let be a generator of .
HMAC
We the HMAC algorithm as Pseudo-Random Function (PRF) to generate a randomly distributed Schnorr signature nonce in a deterministic way. HMAC is the Hash-based Message Authentication Code specification as defined in RFC4231.
The HMAC algorithm: Given a message , and a PRF key , the value is computed as
where:
- is a hash function modeling a random oracle, whose block size is 64 bytes
- is a block-sized key derived from .
- If is larger than the block size, we first hash it using and set
- Otherwise,
- In both cases, is right-padded with 0s up to the 64 byte block size.
- is a 64-byte string, consisting of repeated bytes valued
0x5c
- is a 64-byte string, consisting of repeated bytes valued
0x36
- denotes concatenation
- denotes bitwise exclusive or
- is a 32-byte string
In order to derive a secret nonce , we need to expand in order to derive a 512 bit integer
Modeling as a uniformly sampled integer, taking ensures that the statistical distance between the distribution of and the uniform distribution over is negligible.
Sign
We use signatures with compression as described in Section 19.2.3 of [BS], in the sense that the signature contains the hash, meaning that the signature contains a hash and a field element, rather than a group element and a field element.
The algorithm: Given a message , an account produces the signature
where:
- .
- is the signer's secret nonce.
- , is a commitment to the signer's nonce .
- is the Fiat-Shamir response.
- is the affine representation of the signer's public key
- is a function interpreting a binary string as an integer and applying the modular reduction by .
- is a collisian-resistant pedersen hash function.
- is a hash function modeling a random oracle, which is instantiated with BLAKE2s.
The purpose of is to include the public key in the parameter whilst ensuring the input to is no more than 64 bytes.
Verify
Given , purported to be the signature of a messages by an account with respect to a random oracle hash function , compute
- ;
- .
The signature is verified if and only if , where the comparison is done bit-wise.
Imprecise rationale: The verification equation is where both sides of the equation are represented as an array of 256 bits. VERIFIER has seen that SIGNER can produce a preimage for a given which is outside of SIGNER's control by chosing a particular value of . The difficulty of this assumption is documented, in the case where is the units group of a finite field, in Schnorr's original paper [Sch] (cf especially pages 10-11).
Variable base multiplication
scalar presented as bit_array
scalar presented as a wnaf_record
, provided along with a current_accumulator
Code Paths
verify_signature
- There is an aborted state reached if and have the same x-coordinate.
- Normal signature verification path.
variable_base_mul(pub_key, current_accumulator, wnaf)
- This function is only called inside of
variable_base_mul(pub_key, low_bits, high_bits)
. There is aninit
predicate given by: "current_accumulator
andpub_key
have the same x-coordinate". This is intended as a stand-in for the more general check that these two points are equal. This condition distinguishes between two modes in which the function is used in the implementation of the functionvariable_base_mul(pub_key, low_bits, high_bits)
: on the second call, the conditioninit
is espected to be false, so that the results of the first call, recorded incurrent_accumulator
, are incorporated in the output. - There is branching depending on whether on the parity of the scalar represented by
wnaf
.
variable_base_mul(pub_key, low_bits, high_bits)
- There is an aborted state that is reached when either of the field elements is zero.
convert_signature(scontext, signature)
There is no branching here.
convert_message(context, message_string)
This function has not been investigated since I propose it be removed. It is not used or tested.
convert_field_into_wnaf(context, limb)
- When accumulating a
field_t
element using the proposed wnaf representaiton, there is branching at each bit position depending on the 32nd digit of the currentuint64_t
elementwnaf_entries[i+1]
.
Security Notes
Usage of HMAC for deterministic signatures
There are two main reasons why one may want deterministic signatures.
In some instances, the entropy provided by the system may be insufficient to guarantee uniform k
, and using HMAC
with a proper cryptographic hash function should therefore ensure this property.
By deriving it from the secret key, it also ensures that k
remains private to the signer.
Nowadays, and especially with the types of devices we would be creating signatures, we can assume that the system's randomness source is strong enough for creating signatures.
There are different ways of achieving this property, such as RFC 6979, or as defined by the EdDSA specification.
Our approach is closer to RFC 6979, though we do not use rejection sampling and instead generate a 512-bit value and apply modular reduction by .
This ensures that the statistical difference between the distribution of k
and the uniform distribution over is negligible.
Note that any leakage of the value of k
may be catastrophic, especially in ECDSA.
Unfortunately, by using the secret key for signing and as input to HMAC
, the original security proof of the signature scheme no longer applies.
We would need to derive two independent signing and PRF keys from one 256-bit secret seed.
Signature malleability
Given a valid signature , it is possible to generate another valid signature , where but (take to be congruent to modulo ). The solution would be to check that , but this would incurr an additional range check within the circuit which we avoid for efficiency reasons.
In our context, signatures are used within the account
and join_split
circuits to link the public inputs to the user's spending key
It is essentially a proof of knowledge of the private spending key, parametrized over the public inputs.
The circuits ensures that the user is able to create a valid signature for the specific transaction.
The signatures themselves are private inputs to the circuit and are not therefore not revealed, used in other places, or checked for uniqueness.
The user is already able to create two different proofs for the same set of public inputs since proofs are never unique due to the ZK property.
It is impossible to distinguish between proofs where:
- the signature was created honestly using a deterministic nonce
- the signature was created honestly using a random nonce
- the signature's value was modified, given an original honestly generated signature.
Since malleability is only possible given an original valid signature signature, the user must have already approved the transaction. Therefore, we can also accept the modified signature.
Missing component in Pedersen hash
As mentioned, we use the collision-resistant Pedersen hash to compress and when computing the Fiat-Shamir challenge .
For efficiency reasons, we do not pass the coordinate of into the Pedersen hash. This optimization only incurs a loss of 1 bit of security, because there are only two valid values of given the coordinate of .
Biased sampling of Fiat-Shamir challenge
When we interpret as a field element by reducing the corresponding integer modulo , the resulting field element is slightly biased in favor of "smaller" field elements, since . Fixing this issue would require a technique similar to the method we use to derive without bias. Unfortunately, this would require many more gates inside the circuit verification algorithm (additional hash computation and modular reduction of a 512 bit integer).
We are no longer in the random oracle model since the distribution of the challenge is not uniform. We are looking into alternative proofs to guarantee correctness.
Domain separation
We do not use domain separation when generating the Fiat-Shamir challenge with BLAKE2s. Other components using the same hash function as random oracle should be careful that this could not lead to collisions when similar inputs are being processed.
We also note that we do not hash the group generator into the hash function.
References
WNAF representation: https://github.com/bitcoin-core/secp256k1/blob/master/src/ecmult_impl.h, circa line 151
NOTE: the original NAF paper Morain, Olivos, "Speeding up the computations...", 1990 has a sign error in displayed equation (7). This is not present in our variable_base_mul
function.
[BS20] Boneh, D., Shoup, V "A Graduate Course in Applied Cryptography" Version 0.5, January 2020.
[Sch] Schnorr, C. "Efficient Identification and Signatures for Smart Cards", 1990.