Skip to content

Commit 851c038

Browse files
committed
tests: impl bitflip test for schnorrsig randomizer gen
- refactor `secp256k1_batch_add_schnorrsig_randomizer` to support testing - `randomizer_gen` -> generates a 32-byte array randomizer - `randomizer_set` -> converts the 32-byte array to secp256k1_scalar - impl bitflip test for `secp256k1_batch_add_schnorrsig_randomizer_gen`
1 parent f793514 commit 851c038

File tree

2 files changed

+87
-13
lines changed

2 files changed

+87
-13
lines changed

src/modules/batch/tests_impl.h

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@
55

66
#define MAX_TERMS 10
77

8+
/*
9+
todo: separate tests of batch_add_* from (create, destroy, verify)
10+
since, compiling libsecp with batch module and without
11+
schnorrsig, won't compile add functions. So, can't use them in tests
12+
*/
813

914
/* Tests for the equality of two sha256 structs. This function only produces a
1015
* correct result if an integer multiple of 64 many bytes have been written
1116
* into the hash functions. */
12-
void batch_test_sha256_eq(const secp256k1_sha256 *sha1, const secp256k1_sha256 *sha2) {
17+
void test_batch_sha256_eq(const secp256k1_sha256 *sha1, const secp256k1_sha256 *sha2) {
1318
/* Is buffer fully consumed? */
1419
CHECK((sha1->bytes & 0x3F) == 0);
1520

@@ -26,7 +31,66 @@ void test_batch_sha256_tagged(void) {
2631

2732
secp256k1_sha256_initialize_tagged(&sha, (unsigned char *) tag, sizeof(tag));
2833
secp256k1_batch_sha256_tagged(&sha_optimized);
29-
batch_test_sha256_eq(&sha, &sha_optimized);
34+
test_batch_sha256_eq(&sha, &sha_optimized);
35+
}
36+
37+
/* Checks that a bit flip in the n_flip-th argument (that has n_bytes many
38+
* bytes) changes the hash function */
39+
void batch_schnorrsig_randomizer_gen_bitflip(secp256k1_sha256 *sha, unsigned char **args, size_t n_flip, size_t n_bytes, size_t msglen) {
40+
unsigned char randomizers[2][32];
41+
secp256k1_sha256 sha_cpy;
42+
sha_cpy = *sha;
43+
CHECK(secp256k1_batch_schnorrsig_randomizer_gen(randomizers[0], &sha_cpy, args[0], args[1], msglen, args[2]) == 1);
44+
secp256k1_testrand_flip(args[n_flip], n_bytes);
45+
sha_cpy = *sha;
46+
CHECK(secp256k1_batch_schnorrsig_randomizer_gen(randomizers[1], &sha_cpy, args[0], args[1], msglen, args[2]) == 1);
47+
CHECK(secp256k1_memcmp_var(randomizers[0], randomizers[1], 32) != 0);
48+
}
49+
50+
/*todo: make n_sigs var global macro? then, wouldn't it affects n_sigs api tests?*/
51+
void run_batch_schnorrsig_randomizer_gen_tests(void) {
52+
secp256k1_sha256 sha;
53+
size_t n_sigs = 20;
54+
unsigned char msg[32];
55+
size_t msglen = sizeof(msg);
56+
unsigned char sig[64];
57+
unsigned char compressed_pk[33];
58+
unsigned char *args[3];
59+
uint8_t rand;
60+
size_t i; /* loops through n_sigs */
61+
int j; /* loops through count */
62+
63+
secp256k1_batch_sha256_tagged(&sha);
64+
65+
for (i = 0; i < n_sigs; i++) {
66+
/* generate i-th schnorrsig verify data */
67+
secp256k1_testrand256(msg);
68+
secp256k1_testrand256(&sig[0]);
69+
secp256k1_testrand256(&sig[32]);
70+
secp256k1_testrand256(&compressed_pk[1]);
71+
rand = secp256k1_testrand_int(2) + 2; /* randomly choose 2 or 3 */
72+
compressed_pk[0] = (unsigned char)rand;
73+
74+
/* check that bitflip in an argument results in different nonces */
75+
args[0] = sig;
76+
args[1] = msg;
77+
args[2] = compressed_pk;
78+
79+
for (j = 0; j < count; j++) {
80+
batch_schnorrsig_randomizer_gen_bitflip(&sha, args, 0, 64, msglen);
81+
batch_schnorrsig_randomizer_gen_bitflip(&sha, args, 1, 32, msglen);
82+
batch_schnorrsig_randomizer_gen_bitflip(&sha, args, 2, 33, msglen);
83+
}
84+
85+
/* write i-th schnorrsig verify data to the sha object
86+
* this is required for generating the next randomizer */
87+
secp256k1_sha256_write(&sha, sig, 64);
88+
secp256k1_sha256_write(&sha, msg, msglen);
89+
secp256k1_sha256_write(&sha, compressed_pk, 33);
90+
91+
}
92+
93+
/* todo: msglen difference test?? */
3094
}
3195

3296
void test_batch_api(void) {
@@ -113,6 +177,7 @@ void test_batch_api(void) {
113177
void run_batch_tests(void) {
114178
test_batch_api();
115179
test_batch_sha256_tagged();
180+
run_batch_schnorrsig_randomizer_gen_tests();
116181
}
117182

118183
#endif /* SECP256K1_MODULE_BATCH_TESTS_H */

src/modules/schnorrsig/batch_add_impl.h

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,26 @@
55
#include "src/hash.h"
66
#include "src/modules/batch/main_impl.h"
77

8-
static int secp256k1_batch_schnorrsig_randomizer(const secp256k1_context *ctx, secp256k1_batch *batch, secp256k1_scalar *r, const unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_xonly_pubkey *pubkey) {
8+
static int secp256k1_batch_schnorrsig_randomizer_gen(unsigned char *randomizer32, secp256k1_sha256 *sha256, const unsigned char *sig64, const unsigned char *msg, size_t msglen, const unsigned char *compressed_pk33) {
99
secp256k1_sha256 sha256_cpy;
10+
11+
/* add schnorrsig data to sha256 object */
12+
secp256k1_sha256_write(sha256, sig64, 64);
13+
secp256k1_sha256_write(sha256, msg, msglen);
14+
secp256k1_sha256_write(sha256, compressed_pk33, 33);
15+
16+
/* generate randomizer */
17+
sha256_cpy = *sha256;
18+
secp256k1_sha256_finalize(&sha256_cpy, randomizer32);
19+
20+
return 1;
21+
}
22+
23+
static int secp256k1_batch_schnorrsig_randomizer_set(const secp256k1_context *ctx, secp256k1_batch *batch, secp256k1_scalar *r, const unsigned char *sig64, const unsigned char *msg, size_t msglen, const secp256k1_xonly_pubkey *pubkey) {
24+
int overflow;
1025
unsigned char randomizer[32];
1126
unsigned char buf[33];
1227
size_t buflen = sizeof(buf);
13-
int overflow;
1428

1529
/* We use compressed serialization here. If we would use
1630
* xonly_pubkey serialization and a user would wrongly memcpy
@@ -20,14 +34,9 @@ static int secp256k1_batch_schnorrsig_randomizer(const secp256k1_context *ctx, s
2034
return 0;
2135
}
2236

23-
/* add schnorrsig data to sha256 object */
24-
secp256k1_sha256_write(&batch->sha256, sig64, 64);
25-
secp256k1_sha256_write(&batch->sha256, msg, msglen);
26-
secp256k1_sha256_write(&batch->sha256, buf, buflen);
27-
28-
/* generate randomizer */
29-
sha256_cpy = batch->sha256;
30-
secp256k1_sha256_finalize(&sha256_cpy, randomizer);
37+
if(!secp256k1_batch_schnorrsig_randomizer_gen(randomizer, &batch->sha256, sig64, msg, msglen, buf)) {
38+
return 0;
39+
}
3140
secp256k1_scalar_set_b32(r, randomizer, &overflow);
3241
VERIFY_CHECK(overflow == 0);
3342

@@ -112,7 +121,7 @@ int secp256k1_batch_add_schnorrsig(const secp256k1_context* ctx, secp256k1_batch
112121
secp256k1_schnorrsig_challenge(&e, &sig64[0], msg, msglen, buf);
113122

114123
/* Compute ai */
115-
if (!secp256k1_batch_schnorrsig_randomizer(ctx, batch, &ai, sig64, msg, msglen, pubkey)) {
124+
if (!secp256k1_batch_schnorrsig_randomizer_set(ctx, batch, &ai, sig64, msg, msglen, pubkey)) {
116125
return 0;
117126
}
118127

0 commit comments

Comments
 (0)