Skip to content

Commit 8a77b2c

Browse files
committed
batch: Add tests for batch_add_* APIs
This commit adds the following tests: 1. Random bitflip test for randomizer generating function 2. Random bitflip in Schnorr Signature (_batch_add_schnorrsig test) 3. NULL arg tests (for both _batch_add APIs)
1 parent d0446a8 commit 8a77b2c

File tree

6 files changed

+495
-2
lines changed

6 files changed

+495
-2
lines changed

src/modules/extrakeys/Makefile.am.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ noinst_HEADERS += src/modules/extrakeys/tests_exhaustive_impl.h
77
noinst_HEADERS += src/modules/extrakeys/main_impl.h
88
if ENABLE_MODULE_BATCH
99
noinst_HEADERS += src/modules/extrakeys/batch_add_impl.h
10+
noinst_HEADERS += src/modules/extrakeys/batch_add_tests_impl.h
1011
endif
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
#ifndef SECP256K1_MODULE_EXTRAKEYS_BATCH_ADD_TESTS_IMPL_H
2+
#define SECP256K1_MODULE_EXTRAKEYS_BATCH_ADD_TESTS_IMPL_H
3+
4+
#include "../../../include/secp256k1_extrakeys.h"
5+
#include "../../../include/secp256k1_batch.h"
6+
#include "../../../include/secp256k1_tweak_check_batch.h"
7+
8+
/* Checks that a bit flip in the n_flip-th argument (that has n_bytes many
9+
* bytes) changes the hash function */
10+
void batch_xonlypub_tweak_randomizer_gen_bitflip(secp256k1_sha256 *sha, unsigned char **args, size_t n_flip, size_t n_bytes) {
11+
unsigned char randomizers[2][32];
12+
secp256k1_sha256 sha_cpy;
13+
sha_cpy = *sha;
14+
secp256k1_batch_xonlypub_tweak_randomizer_gen(randomizers[0], &sha_cpy, args[0], args[1], args[2], args[3]);
15+
secp256k1_testrand_flip(args[n_flip], n_bytes);
16+
sha_cpy = *sha;
17+
secp256k1_batch_xonlypub_tweak_randomizer_gen(randomizers[1], &sha_cpy, args[0], args[1], args[2], args[3]);
18+
CHECK(secp256k1_memcmp_var(randomizers[0], randomizers[1], 32) != 0);
19+
}
20+
21+
void run_batch_xonlypub_tweak_randomizer_gen_tests(void) {
22+
secp256k1_sha256 sha;
23+
size_t n_checks = 20;
24+
unsigned char tweaked_pk[32];
25+
unsigned char tweaked_pk_parity;
26+
unsigned char tweak[32];
27+
unsigned char internal_pk[33];
28+
unsigned char *args[4];
29+
size_t i; /* loops through n_checks */
30+
int j; /* loops through count */
31+
32+
secp256k1_batch_sha256_tagged(&sha);
33+
34+
for (i = 0; i < n_checks; i++) {
35+
uint8_t temp_rand;
36+
37+
/* generate i-th tweak check data */
38+
secp256k1_testrand256(tweaked_pk);
39+
tweaked_pk_parity = (unsigned char) secp256k1_testrand_int(2);
40+
secp256k1_testrand256(tweak);
41+
secp256k1_testrand256(&internal_pk[1]);
42+
temp_rand = secp256k1_testrand_int(2) + 2; /* randomly choose 2 or 3 */
43+
internal_pk[0] = (unsigned char)temp_rand;
44+
45+
/* check bitflip in any argument results in generates randomizers */
46+
args[0] = tweaked_pk;
47+
args[1] = &tweaked_pk_parity;
48+
args[2] = internal_pk;
49+
args[3] = tweak;
50+
51+
for (j = 0; j < count; j++) {
52+
batch_xonlypub_tweak_randomizer_gen_bitflip(&sha, args, 0, 32);
53+
batch_xonlypub_tweak_randomizer_gen_bitflip(&sha, args, 1, 1);
54+
batch_xonlypub_tweak_randomizer_gen_bitflip(&sha, args, 2, 33);
55+
batch_xonlypub_tweak_randomizer_gen_bitflip(&sha, args, 3, 32);
56+
}
57+
58+
/* write i-th tweak check data to the sha object
59+
* this is required for generating the next randomizer */
60+
secp256k1_sha256_write(&sha, tweaked_pk, 32);
61+
secp256k1_sha256_write(&sha, &tweaked_pk_parity, 1);
62+
secp256k1_sha256_write(&sha, tweak, 32);
63+
secp256k1_sha256_write(&sha, internal_pk, 33);
64+
}
65+
66+
}
67+
68+
void test_batch_add_xonlypub_tweak_api(void) {
69+
unsigned char sk[32];
70+
secp256k1_keypair keypair;
71+
secp256k1_xonly_pubkey pk;
72+
/* xonly pubkey tweak checks data */
73+
unsigned char tweaked_pk[32];
74+
int tweaked_pk_parity;
75+
unsigned char tweak[32];
76+
secp256k1_pubkey tmp_pk;
77+
secp256k1_xonly_pubkey tmp_xonly_pk;
78+
unsigned char overflows[32];
79+
80+
/** setup **/
81+
secp256k1_context *none = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
82+
secp256k1_context *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
83+
secp256k1_context *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
84+
secp256k1_batch *batch1 = secp256k1_batch_create(none, 1, NULL);
85+
/* batch2 is used when batch_add_xonlypub_tweak is expected to fail */
86+
secp256k1_batch *batch2 = secp256k1_batch_create(none, 1, NULL);
87+
int ecount;
88+
89+
secp256k1_context_set_error_callback(none, counting_illegal_callback_fn, &ecount);
90+
secp256k1_context_set_error_callback(sign, counting_illegal_callback_fn, &ecount);
91+
secp256k1_context_set_error_callback(vrfy, counting_illegal_callback_fn, &ecount);
92+
secp256k1_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount);
93+
secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount);
94+
secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount);
95+
96+
/** generate keypair data **/
97+
secp256k1_testrand256(sk);
98+
CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
99+
CHECK(secp256k1_keypair_xonly_pub(sign, &pk, NULL, &keypair) == 1);
100+
memset(overflows, 0xFF, sizeof(overflows));
101+
102+
/** generate tweak check data (tweaked_pk, tweaked_pk_parity, tweak) **/
103+
secp256k1_testrand256(tweak);
104+
CHECK(secp256k1_xonly_pubkey_tweak_add(vrfy, &tmp_pk, &pk, tweak));
105+
CHECK(secp256k1_xonly_pubkey_from_pubkey(vrfy, &tmp_xonly_pk, &tweaked_pk_parity, &tmp_pk));
106+
CHECK(secp256k1_xonly_pubkey_serialize(vrfy, tweaked_pk, &tmp_xonly_pk));
107+
CHECK(secp256k1_xonly_pubkey_tweak_add_check(vrfy, tweaked_pk, tweaked_pk_parity, &pk, tweak));
108+
109+
CHECK(batch1 != NULL);
110+
CHECK(batch2 != NULL);
111+
112+
/** main test body **/
113+
ecount = 0;
114+
CHECK(secp256k1_batch_add_xonlypub_tweak_check(none, batch1, tweaked_pk, tweaked_pk_parity, &pk, tweak) == 1);
115+
CHECK(ecount == 0);
116+
CHECK(secp256k1_batch_verify(none, batch1) == 1);
117+
CHECK(ecount == 0);
118+
CHECK(secp256k1_batch_add_xonlypub_tweak_check(none, batch2, NULL, tweaked_pk_parity, &pk, tweak) == 0);
119+
CHECK(ecount == 1);
120+
CHECK(secp256k1_batch_add_xonlypub_tweak_check(none, batch2, tweaked_pk, tweaked_pk_parity, NULL, tweak) == 0);
121+
CHECK(ecount == 2);
122+
CHECK(secp256k1_batch_add_xonlypub_tweak_check(none, batch2, tweaked_pk, tweaked_pk_parity, &pk, NULL) == 0);
123+
CHECK(ecount == 3);
124+
CHECK(secp256k1_batch_add_xonlypub_tweak_check(none, NULL, tweaked_pk, tweaked_pk_parity, &pk, tweak) == 0);
125+
CHECK(ecount == 4);
126+
/** overflowing tweak not allowed **/
127+
CHECK(secp256k1_batch_add_xonlypub_tweak_check(none, batch2, tweaked_pk, tweaked_pk_parity, &pk, overflows) == 0);
128+
CHECK(ecount == 4);
129+
/** x-coordinate of tweaked pubkey should be less than prime order **/
130+
CHECK(secp256k1_batch_add_xonlypub_tweak_check(none, batch2, overflows, tweaked_pk_parity, &pk, tweak) == 0);
131+
CHECK(ecount == 4);
132+
133+
/** batch_verify should fail for incorrect tweak **/
134+
ecount = 0;
135+
CHECK(secp256k1_batch_usable(none, batch2));
136+
CHECK(secp256k1_batch_add_xonlypub_tweak_check(none, batch2, tweaked_pk, !tweaked_pk_parity, &pk, tweak) == 1);
137+
CHECK(ecount == 0);
138+
CHECK(secp256k1_batch_verify(none, batch2) == 0);
139+
CHECK(ecount == 0);
140+
141+
/** batch_add_ should ignore unusable batch object (i.e, batch->result = 0) **/
142+
ecount = 0;
143+
CHECK(secp256k1_batch_usable(none, batch2) == 0);
144+
CHECK(ecount == 0);
145+
CHECK(secp256k1_batch_add_xonlypub_tweak_check(none, batch2, tweaked_pk, tweaked_pk_parity, &pk, tweak) == 0);
146+
CHECK(ecount == 0);
147+
148+
ecount = 0;
149+
secp256k1_batch_destroy(none, batch1);
150+
CHECK(ecount == 0);
151+
secp256k1_batch_destroy(none, batch2);
152+
CHECK(ecount == 0);
153+
154+
secp256k1_context_destroy(none);
155+
secp256k1_context_destroy(sign);
156+
secp256k1_context_destroy(vrfy);
157+
}
158+
159+
void run_batch_add_xonlypub_tweak_tests(void) {
160+
run_batch_xonlypub_tweak_randomizer_gen_tests();
161+
test_batch_add_xonlypub_tweak_api();
162+
}
163+
164+
165+
#endif /* SECP256K1_MODULE_EXTRAKEYS_BATCH_ADD_TESTS_IMPL_H */

src/modules/schnorrsig/Makefile.am.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ noinst_HEADERS += src/modules/schnorrsig/tests_exhaustive_impl.h
88
noinst_HEADERS += src/modules/schnorrsig/bench_impl.h
99
if ENABLE_MODULE_BATCH
1010
noinst_HEADERS += src/modules/schnorrsig/batch_add_impl.h
11+
noinst_HEADERS += src/modules/schnorrsig/batch_add_tests_impl.h
1112
endif

0 commit comments

Comments
 (0)