7 #ifndef SECP256K1_MODULE_SURJECTIONPROOF_TESTS
8 #define SECP256K1_MODULE_SURJECTIONPROOF_TESTS
16 static void test_surjectionproof_api(
void) {
17 unsigned char seed[32];
26 unsigned char input_blinding_key[10][32];
27 unsigned char output_blinding_key[32];
29 size_t serialized_len;
31 size_t n_inputs =
sizeof(fixed_input_tags) /
sizeof(fixed_input_tags[0]);
36 secp256k1_rand256(seed);
46 for (i = 0; i < n_inputs; i++) {
47 secp256k1_rand256(input_blinding_key[i]);
48 secp256k1_rand256(fixed_input_tags[i].data);
51 secp256k1_rand256(output_blinding_key);
52 memcpy(&fixed_output_tag, &fixed_input_tags[0],
sizeof(fixed_input_tags[0]));
133 serialized_len =
sizeof(serialized_proof);
136 serialized_len =
sizeof(serialized_proof);
139 serialized_len =
sizeof(serialized_proof);
142 serialized_len =
sizeof(serialized_proof);
146 serialized_len =
sizeof(serialized_proof);
164 static void test_input_selection(
size_t n_inputs) {
165 unsigned char seed[32];
169 size_t try_count = n_inputs * 100;
172 const size_t max_n_inputs =
sizeof(fixed_input_tags) /
sizeof(fixed_input_tags[0]) - 1;
174 CHECK(n_inputs < max_n_inputs);
175 secp256k1_rand256(seed);
177 for (i = 0; i < n_inputs + 1; i++) {
178 secp256k1_rand256(fixed_input_tags[i].data);
191 CHECK(result < n_inputs * 10);
195 CHECK(input_index == 0);
205 CHECK(input_index == 1);
217 CHECK(input_index == 0);
226 CHECK(input_index == 0);
232 static void test_input_selection_distribution_helper(
const secp256k1_fixed_asset_tag* fixed_input_tags,
const size_t n_input_tags,
const size_t n_input_tags_to_use,
size_t *used_inputs) {
237 unsigned char seed[32];
239 for (i = 0; i < n_input_tags; i++) {
242 for(j = 0; j < 10000; j++) {
243 secp256k1_rand256(seed);
247 for (i = 0; i < n_input_tags; i++) {
258 static void test_input_selection_distribution(
void) {
260 size_t n_input_tags_to_use;
261 const size_t n_inputs = 4;
263 size_t used_inputs[4];
265 for (i = 0; i < n_inputs; i++) {
266 secp256k1_rand256(fixed_input_tags[i].data);
270 n_input_tags_to_use = 1;
271 test_input_selection_distribution_helper(fixed_input_tags, n_inputs, n_input_tags_to_use, used_inputs);
272 CHECK(used_inputs[0] == 10000);
273 CHECK(used_inputs[1] == 0);
274 CHECK(used_inputs[2] == 0);
275 CHECK(used_inputs[3] == 0);
277 n_input_tags_to_use = 2;
282 test_input_selection_distribution_helper(fixed_input_tags, n_inputs, n_input_tags_to_use, used_inputs);
283 CHECK(used_inputs[0] == 10000);
284 CHECK(used_inputs[1] > 2725 && used_inputs[1] < 3961);
285 CHECK(used_inputs[2] > 2725 && used_inputs[2] < 3961);
286 CHECK(used_inputs[3] > 2725 && used_inputs[3] < 3961);
288 n_input_tags_to_use = 3;
290 test_input_selection_distribution_helper(fixed_input_tags, n_inputs, n_input_tags_to_use, used_inputs);
291 CHECK(used_inputs[0] == 10000);
292 CHECK(used_inputs[1] > 6039 && used_inputs[1] < 7275);
293 CHECK(used_inputs[2] > 6039 && used_inputs[2] < 7275);
294 CHECK(used_inputs[3] > 6039 && used_inputs[3] < 7275);
297 n_input_tags_to_use = 1;
301 memcpy(fixed_input_tags[0].data, fixed_input_tags[1].data, 32);
302 test_input_selection_distribution_helper(fixed_input_tags, n_inputs, n_input_tags_to_use, used_inputs);
303 CHECK(used_inputs[0] > 4345 && used_inputs[0] < 5655);
304 CHECK(used_inputs[1] > 4345 && used_inputs[1] < 5655);
305 CHECK(used_inputs[2] == 0);
306 CHECK(used_inputs[3] == 0);
308 n_input_tags_to_use = 2;
313 test_input_selection_distribution_helper(fixed_input_tags, n_inputs, n_input_tags_to_use, used_inputs);
314 CHECK(used_inputs[0] > 5352 && used_inputs[0] < 6637);
315 CHECK(used_inputs[1] > 5352 && used_inputs[1] < 6637);
316 CHECK(used_inputs[2] > 3363 && used_inputs[2] < 4648);
317 CHECK(used_inputs[3] > 3363 && used_inputs[3] < 4648);
319 n_input_tags_to_use = 3;
323 test_input_selection_distribution_helper(fixed_input_tags, n_inputs, n_input_tags_to_use, used_inputs);
324 CHECK(used_inputs[0] > 6918 && used_inputs[0] < 8053);
325 CHECK(used_inputs[1] > 6918 && used_inputs[1] < 8053);
326 CHECK(used_inputs[2] > 6918 && used_inputs[2] < 8053);
327 CHECK(used_inputs[3] > 6918 && used_inputs[3] < 8053);
330 static void test_gen_verify(
size_t n_inputs,
size_t n_used) {
331 unsigned char seed[32];
338 unsigned char *input_blinding_key[1000];
339 const size_t max_n_inputs =
sizeof(fixed_input_tags) /
sizeof(fixed_input_tags[0]) - 1;
340 size_t try_count = n_inputs * 100;
347 CHECK(n_used <= n_inputs);
348 CHECK(n_inputs < max_n_inputs);
349 secp256k1_rand256(seed);
351 key_index = (((size_t) seed[0] << 8) + seed[1]) % n_inputs;
353 for (i = 0; i < n_inputs + 1; i++) {
354 input_blinding_key[i] = malloc(32);
355 secp256k1_rand256(input_blinding_key[i]);
358 secp256k1_rand256(fixed_input_tags[i].data);
360 memcpy(&fixed_input_tags[i], &fixed_input_tags[key_index],
sizeof(fixed_input_tags[i]));
372 CHECK(input_index == key_index);
374 result =
secp256k1_surjectionproof_generate(ctx, &proof, ephemeral_input_tags, n_inputs, &ephemeral_input_tags[n_inputs], input_index, input_blinding_key[input_index], input_blinding_key[n_inputs]);
382 memcpy(&serialized_proof_trailing, &serialized_proof, serialized_len);
383 serialized_proof_trailing[serialized_len] = seed[0];
396 result =
secp256k1_surjectionproof_generate(ctx, &proof, ephemeral_input_tags, n_inputs, &ephemeral_input_tags[n_inputs], input_index, input_blinding_key[input_index], input_blinding_key[n_inputs]);
404 for (i = 0; i < n_inputs + 1; i++) {
405 free(input_blinding_key[i]);
410 static void test_no_used_inputs_verify(
void) {
415 size_t n_ephemeral_input_tags = 1;
417 unsigned char blinding_key[32];
429 secp256k1_rand256(fixed_input_tag.
data);
430 secp256k1_rand256(fixed_output_tag.
data);
433 secp256k1_rand256(blinding_key);
438 secp256k1_generator_load(&output, &ephemeral_output_tag);
439 secp256k1_generator_load(&inputs[0], &ephemeral_input_tags[0]);
440 secp256k1_surjection_genmessage(proof.
data, inputs, 1, &output);
441 secp256k1_sha256_initialize(&sha256_e0);
442 secp256k1_sha256_write(&sha256_e0, proof.
data, 32);
443 secp256k1_sha256_finalize(&sha256_e0, proof.
data);
452 size_t serialized_len;
455 serialized_len = 2 + 31;
462 unsigned char serialized_proof0[] = { 0x00 };
463 unsigned char serialized_proof1[] = { 0x01, 0x00 };
464 unsigned char serialized_proof2[33] = { 0 };
476 for (i = 0; i < count; i++) {
477 test_surjectionproof_api();
480 test_input_selection(0);
481 test_input_selection(1);
482 test_input_selection(5);
483 test_input_selection(100);
486 test_input_selection_distribution();
487 test_gen_verify(10, 3);
489 test_no_used_inputs_verify();