Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Schnorr is not compatible with BIP340 #1365

Closed
paulmillr opened this issue Jun 28, 2023 · 5 comments
Closed

Schnorr is not compatible with BIP340 #1365

paulmillr opened this issue Jun 28, 2023 · 5 comments

Comments

@paulmillr
Copy link
Contributor

I believe this has been mentioned in comment #757 (comment), but nevertheless decided to open an issue for visibility.

BIP340 https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#default-signing clearly says auxRand should always be used even if it's all-zero. It also provides exact algorithm to calculate nonce from it.

Right now, libsecp256k1, when auxRand was not passed, uses its own nonce generation algorithm.

It would be good to make the library follow specification.

@sipa
Copy link
Contributor

sipa commented Jun 28, 2023

I don't think that's the case? Passing auxrand == NULL should behave identically as passing a pointer to 32 0x00 bytes. This is even tested explicitly:

/* NULL aux_rand argument is allowed, and identical to passing all zero aux_rand. */
memset(aux_rand, 0, 32);
CHECK(nonce_function_bip340(nonce_z, msg, msglen, key, pk, algo, algolen, &aux_rand) == 1);
CHECK(nonce_function_bip340(nonce, msg, msglen, key, pk, algo, algolen, NULL) == 1);
CHECK(secp256k1_memcmp_var(nonce_z, nonce, 32) == 0);

@paulmillr
Copy link
Contributor Author

@landabaso do your tests say otherwise?

@sipa
Copy link
Contributor

sipa commented Jun 28, 2023

I see the linked issue now. I think there is some confusion.

  • noble-curves, if no auxrand is specified, generates 32 random bytes and uses those.
  • libsecp256k1, if no auxrand is specified, acts as if 32 0x00 bytes are passed.

Both are BIP340 compliant (emphasis mine):

If randomness is not available at all at signing time, a simple counter wide enough to not repeat in practice (e.g., 64 bits or wider) and padded with null bytes to a 32 byte-array can be used, or even the constant array with 32 null bytes. Using any non-repeating value increases protection against fault injection attacks. Using unpredictable randomness additionally increases protection against other side-channel attacks, and is recommended whenever available.

Using random nonces is recommended and obviously better, but libsecp256k1 has no access to high-quality randomness; it's up to the caller to provide it.

@paulmillr
Copy link
Contributor Author

Thanks for clarifying this! Your behavior is perfectly fine. The topicstarter just wanted to replicate libsecp behavior, so I guess we can point to use 32 0x00 bytes and be done.

@real-or-random
Copy link
Contributor

I was about to say that this should be documented, but it turns out that it is documented:

* aux_rand32: 32 bytes of fresh randomness. While recommended to provide
* this, it is only supplemental to security and can be NULL. A
* NULL argument is treated the same as an all-zero one. See
* BIP-340 "Default Signing" for a full explanation of this
* argument and for guidance if randomness is expensive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants