* Run secp256k1_ecmult_multi_var with num points and a scratch space restricted to * 1 <= i <= num points. */
| 5292 | * 1 <= i <= num points. |
| 5293 | */ |
| 5294 | static void test_ecmult_multi_batching(void) { |
| 5295 | static const int n_points = 2*ECMULT_PIPPENGER_THRESHOLD; |
| 5296 | secp256k1_scalar scG; |
| 5297 | secp256k1_scalar *sc = (secp256k1_scalar *)checked_malloc(&CTX->error_callback, sizeof(secp256k1_scalar) * n_points); |
| 5298 | secp256k1_ge *pt = (secp256k1_ge *)checked_malloc(&CTX->error_callback, sizeof(secp256k1_ge) * n_points); |
| 5299 | secp256k1_gej r; |
| 5300 | secp256k1_gej r2; |
| 5301 | ecmult_multi_data data; |
| 5302 | int i; |
| 5303 | secp256k1_scratch *scratch; |
| 5304 | |
| 5305 | secp256k1_gej_set_infinity(&r2); |
| 5306 | |
| 5307 | /* Get random scalars and group elements and compute result */ |
| 5308 | random_scalar_order(&scG); |
| 5309 | secp256k1_ecmult(&r2, &r2, &secp256k1_scalar_zero, &scG); |
| 5310 | for(i = 0; i < n_points; i++) { |
| 5311 | secp256k1_ge ptg; |
| 5312 | secp256k1_gej ptgj; |
| 5313 | random_group_element_test(&ptg); |
| 5314 | secp256k1_gej_set_ge(&ptgj, &ptg); |
| 5315 | pt[i] = ptg; |
| 5316 | random_scalar_order(&sc[i]); |
| 5317 | secp256k1_ecmult(&ptgj, &ptgj, &sc[i], NULL); |
| 5318 | secp256k1_gej_add_var(&r2, &r2, &ptgj, NULL); |
| 5319 | } |
| 5320 | data.sc = sc; |
| 5321 | data.pt = pt; |
| 5322 | secp256k1_gej_neg(&r2, &r2); |
| 5323 | |
| 5324 | /* Test with empty scratch space. It should compute the correct result using |
| 5325 | * ecmult_mult_simple algorithm which doesn't require a scratch space. */ |
| 5326 | scratch = secp256k1_scratch_create(&CTX->error_callback, 0); |
| 5327 | CHECK(secp256k1_ecmult_multi_var(&CTX->error_callback, scratch, &r, &scG, ecmult_multi_callback, &data, n_points)); |
| 5328 | secp256k1_gej_add_var(&r, &r, &r2, NULL); |
| 5329 | CHECK(secp256k1_gej_is_infinity(&r)); |
| 5330 | secp256k1_scratch_destroy(&CTX->error_callback, scratch); |
| 5331 | |
| 5332 | /* Test with space for 1 point in pippenger. That's not enough because |
| 5333 | * ecmult_multi selects strauss which requires more memory. It should |
| 5334 | * therefore select the simple algorithm. */ |
| 5335 | scratch = secp256k1_scratch_create(&CTX->error_callback, secp256k1_pippenger_scratch_size(1, 1) + PIPPENGER_SCRATCH_OBJECTS*ALIGNMENT); |
| 5336 | CHECK(secp256k1_ecmult_multi_var(&CTX->error_callback, scratch, &r, &scG, ecmult_multi_callback, &data, n_points)); |
| 5337 | secp256k1_gej_add_var(&r, &r, &r2, NULL); |
| 5338 | CHECK(secp256k1_gej_is_infinity(&r)); |
| 5339 | secp256k1_scratch_destroy(&CTX->error_callback, scratch); |
| 5340 | |
| 5341 | for(i = 1; i <= n_points; i++) { |
| 5342 | if (i > ECMULT_PIPPENGER_THRESHOLD) { |
| 5343 | int bucket_window = secp256k1_pippenger_bucket_window(i); |
| 5344 | size_t scratch_size = secp256k1_pippenger_scratch_size(i, bucket_window); |
| 5345 | scratch = secp256k1_scratch_create(&CTX->error_callback, scratch_size + PIPPENGER_SCRATCH_OBJECTS*ALIGNMENT); |
| 5346 | } else { |
| 5347 | size_t scratch_size = secp256k1_strauss_scratch_size(i); |
| 5348 | scratch = secp256k1_scratch_create(&CTX->error_callback, scratch_size + STRAUSS_SCRATCH_OBJECTS*ALIGNMENT); |
| 5349 | } |
| 5350 | CHECK(secp256k1_ecmult_multi_var(&CTX->error_callback, scratch, &r, &scG, ecmult_multi_callback, &data, n_points)); |
| 5351 | secp256k1_gej_add_var(&r, &r, &r2, NULL); |
no test coverage detected