Closed h4sh3d closed 2 years ago
Nonce calculation is the real breaking change between 0.21.3
and 0.22.0
.
master
:
https://github.com/rust-bitcoin/rust-secp256k1/blob/master/secp256k1-sys/depend/secp256k1/src/modules/schnorrsig/main_impl.h#L52-L97
0.21.3
:
https://github.com/rust-bitcoin/rust-secp256k1/blob/secp256k1-0.21.3/secp256k1-sys/depend/secp256k1/src/modules/schnorrsig/main_impl.h#L50-L92
Especially the treatment of null
data
where data
is the aux_rand
if (data != NULL) {
// ...
} else {
/* Precomputed TaggedHash("BIP0340/aux", 0x0000...00); */
static const unsigned char ZERO_MASK[32] = {
84, 241, 105, 207, 201, 226, 229, 114,
116, 128, 68, 31, 144, 186, 37, 196,
136, 244, 97, 199, 11, 94, 165, 220,
170, 247, 175, 105, 39, 10, 165, 20
};
for (i = 0; i < 32; i++) {
masked_key[i] = key32[i] ^ ZERO_MASK[i];
}
}
Working on a patch now. It will probably be necessary to update some test vectors. This change has been introduced in rustsecp256k1_v0_5_0
.
Tests are now passing locally. I updated tree tests and added a new one.
Hey @h4sh3d thanks a lot for tracking this down. It's very important to figure out what's going on here. Is my understanding correct:
nulll
as the aux trandomness leads to hashing a bunch of zeroes now rather than nothing at all. Do we know why they made this change?If the above is the case we could consider simply dropping these tests or perhaps better just contriving the "aux" randomness so that it is 32 zeroes or whatever by using the same shim I made for the BIP340 spec tests.
[edit] this thing: https://github.com/LLFourn/secp256kfun/blob/f51990a0584affcc61fe4ddd52232d1cc7b34aac/schnorr_fun/tests/bip340.rs#L14 we could make it public with a warning no to use it unless you are just checking it has the same output as libsecp256k1.
- The BIP340 spec hasn't changed
No change in BIP340 (w.r.t. aux data) since that commit two years ago: https://github.com/bitcoin/bips/commit/cd19095fb039ee74dbb33225af21e83846e5a083
Aux definition changed from
[..] or even an empty byte array of length 0.
to
[..] or even the constant array with 32 null bytes.
- libsecp256k1 changed its API somehow so that passing in a
nulll
as the aux trandomness leads to hashing a bunch of zeroes now rather than nothing at all. Do we know why they made this change?
Yes, in that commit: https://github.com/bitcoin-core/secp256k1/commit/5324f8942dd322448fae6c9b225ecac2854fa7e2
- We found this because output of deterministic signing algorithm is now different when no aux rand is provided.
Yes
[...] just contriving the "aux" randomness so that it is 32 zeroes or whatever by using the same shim I made for the BIP340 spec tests.
I can create in the schnorr
module a deterministic nonce generator that implements BIP340 standard and use that one in tests.
EDIT: it looks like there is references here and there in docs to BIP340 and the deterministic nonce in secpfun impl. I don't know if having a second deterministic implementation is good or not.
So after thinking on this I think the right thing to do here is to leave the deterministic nonce generator as it is. Hashing stuff unnecessarily and xoring the key with a fixed value seems like a bad idea to me. So yes, please create a strict Bip340NoAux
type that implements NonceGen
hashes zeroes and xors it with the secret key. I think we can just put it in the against_c_lib.rs
so that all changes are restricted to that file.
I tried to bump secp to version
0.22
. Looks like there is breaking changes inno_aux
signature generation.I tracked the changes down to this change: https://github.com/rust-bitcoin/rust-secp256k1/commit/8294ea3f50f6de88f88b848c01eb60cab2a73241#diff-ca866735681590c6fc69b50b0a9100c0ea0c485b164e1dc508a14bf60496941b in
src/schnorr.rs
(last file in diff).Function
sign_schnorr_helper
is then used insign_schnorr_no_aux_rand
:I created a small test project to confirm that
secp256k1
introduced that change at version0.22.0
.Two signature are created for the same key (secret key
1
) and message (null array) as the failing test.It crashes and confirms what was suspected
I'll now investigate what changes are needed to update
schnorr_fun
and push a patch on this branch.EDIT: explain ongoing investigation on deterministic schnorr signature breakage