1
I'm trying to understand the signing function secp256k1_ecdsa_sig_sign(), and I'm curious about the nonce usage here.
static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar *sigr, secp256k1_scalar *sigs, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid) {
unsigned char b[32];
secp256k1_gej rp;
secp256k1_ge r;
secp256k1_scalar n;
int overflow = 0;
secp256k1_ecmult_gen(ctx, &rp, nonce);
secp256k1_ge_set_gej(&r, &rp);
secp256k1_fe_normalize(&r.x);
secp256k1_fe_normalize(&r.y);
secp256k1_fe_get_b32(b, &r.x);
secp256k1_scalar_set_b32(sigr, b, &overflow);
/* These two conditions should be checked before calling */
VERIFY_CHECK(!secp256k1_scalar_is_zero(sigr));
VERIFY_CHECK(overflow == 0);
if (recid) {
/* The overflow condition is cryptographically unreachable as hitting it requires finding the discrete log
* of some P where P.x >= order, and only 1 in about 2^127 points meet this criteria.
*/
*recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0);
}
secp256k1_scalar_mul(&n, sigr, seckey);
secp256k1_scalar_add(&n, &n, message);
secp256k1_scalar_inverse(sigs, nonce);
secp256k1_scalar_mul(sigs, sigs, &n);
secp256k1_scalar_clear(&n);
secp256k1_gej_clear(&rp);
secp256k1_ge_clear(&r);
if (secp256k1_scalar_is_zero(sigs)) {
return 0;
}
if (secp256k1_scalar_is_high(sigs)) {
secp256k1_scalar_negate(sigs, sigs);
if (recid) {
*recid ^= 1;
}
}
return 1;
}
I'm familiar with the standard ECDSA, but what exactly is being done with the nonce here and why?
Thanks!
Can you be more specific than "what is being done with the nonce"? Do you mean how to create the nonce? Or what requirements are on it? Or something on a specific line that doesn't match your expectations? – Pieter Wuille – 2019-01-28T18:32:10.867
@PieterWuille Sorry for the ambiguity, I'm new to the BTC libraries. I had assumed that the nonce was just used to generate the hash being signed, but it looks like the nonce is also used to calculate the final S value in the signature after the hash has been found. I don't recall the formal definition of EC signing addressing how to use a nonce in signing, so I suppose my question is how is the nonce used to manipulate the R,S signature values during signing? Thanks! – svan – 2019-01-28T18:52:48.050
1That's just ECDSA. The nonce is the randomness for the signature, and has nothing to do with the message being signed. An ECDSA signature is a pair (r,s) where r is the X coordinate of kG, and s = (m+r*x)/k (where k=nonce, m=message hash, x=private key, G=curve generator). – Pieter Wuille – 2019-01-28T18:54:18.907
@PieterWuille Alright great that makes more sense, thanks for the quick answer. – svan – 2019-01-28T18:59:10.490