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 Jan 28 at 18:32
  • @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 Jan 28 at 18:52
  • 1
    That'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 Jan 28 at 18:54
  • @PieterWuille Alright great that makes more sense, thanks for the quick answer. – svan Jan 28 at 18:59
1

Answered by Pieter Wuille in comments:

That'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).

0

The nonce that is used in the secp256k1 function is a random private key that is generated in order to generate the final signature. To sign a message 'm' you lock that message with your private key and that generates a unique signature. The signature has two components (R,S).

The first step is calculating R using a random number (say k). This random number is generated with the help of nonce. The next step is calculating the public key using this random number using the same generator point as that of bitcoin. That means P = k*G. The x coordinate of P is then R.

Let us say that your original private key that was used to sign the signature is dA. Then the S component of the signature is:

S = (k^(-1))(hash(m) + dA*R) ----- where k is your nonce

The signature field in the bitcoin transaction has both R and S. You take this component and calculate the value of the equation

S^(-1)*hash(m)*G + S^(-1)*R*Qa ----- where Qa is the public key of your private key qA

If the x-coordinate of that equation is equal to R, then the signature is valid. So without revealing the private key you can verify the authenticity of the transaction through a digital signature from your private key. The reason nonce is used is because you need to create two unknowns so that people cannot reverse engineer the private key from the public key.

This nonce has to be random everytime you sign a transaction. If you use the same nonce, then the attacker will have two equations and only two unknowns which can be reverse engineered.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.