@@ -432,6 +432,55 @@ static int secp256k1_bulletproofs_eq65_cb(secp256k1_scalar *sc, secp256k1_ge *pt
432
432
return 1 ;
433
433
}
434
434
435
+ /** Equation (67) is the sum of these 2 scalar-point multiplications, minus mu*G, plus a
436
+ * somewhat complicatied inner product computation.. */
437
+ typedef struct {
438
+ const secp256k1_bulletproofs_generators * gens ;
439
+ const unsigned char * proof ;
440
+ const secp256k1_ge * ap ;
441
+ const secp256k1_ge * sp ;
442
+ secp256k1_scalar x ;
443
+ secp256k1_scalar z ;
444
+ secp256k1_scalar z_sq_2i ;
445
+ secp256k1_scalar y_inv ;
446
+ secp256k1_scalar y_neg_i ;
447
+ } secp256k1_bulletproofs_eq67_data ;
448
+
449
+ static int secp256k1_bulletproofs_eq67_cb (secp256k1_scalar * sc , secp256k1_ge * pt , size_t idx , void * data ) {
450
+ secp256k1_bulletproofs_eq67_data * ctx = (secp256k1_bulletproofs_eq67_data * ) data ;
451
+ secp256k1_scalar lr_i ;
452
+ int overflow ;
453
+
454
+ switch (idx ) {
455
+ case 0 : /* A */
456
+ * pt = * ctx -> ap ;
457
+ secp256k1_scalar_set_int (sc , 1 );
458
+ return 1 ;
459
+ case 1 : /* xS */
460
+ * pt = * ctx -> sp ;
461
+ * sc = ctx -> x ;
462
+ return 1 ;
463
+ }
464
+
465
+ * pt = ctx -> gens -> gens [idx - 2 ];
466
+ secp256k1_scalar_set_b32 (& lr_i , & ctx -> proof [194 + 32 * (idx - 2 )], & overflow );
467
+ VERIFY_CHECK (overflow == 0 ); /* checked in main_impl.h */
468
+ /* (-z - l_i) G_i */
469
+ if (idx % 2 == 0 ) {
470
+ secp256k1_scalar_add (sc , & ctx -> z , & lr_i );
471
+ secp256k1_scalar_negate (sc , sc );
472
+ /* (z + (2^i*z^2 - r)/y^i) H_i */
473
+ } else {
474
+ secp256k1_scalar_negate (sc , & lr_i );
475
+ secp256k1_scalar_add (sc , sc , & ctx -> z_sq_2i );
476
+ secp256k1_scalar_mul (sc , sc , & ctx -> y_neg_i );
477
+ secp256k1_scalar_add (sc , sc , & ctx -> z );
478
+
479
+ secp256k1_scalar_mul (& ctx -> y_neg_i , & ctx -> y_neg_i , & ctx -> y_inv );
480
+ secp256k1_scalar_add (& ctx -> z_sq_2i , & ctx -> z_sq_2i , & ctx -> z_sq_2i );
481
+ }
482
+ return 1 ;
483
+ }
435
484
436
485
static int secp256k1_bulletproofs_rangeproof_uncompressed_verify_impl (
437
486
const secp256k1_context * ctx ,
@@ -442,6 +491,8 @@ static int secp256k1_bulletproofs_rangeproof_uncompressed_verify_impl(
442
491
const uint64_t min_value ,
443
492
const secp256k1_ge * commitp ,
444
493
const secp256k1_ge * asset_genp ,
494
+ const secp256k1_ge * ap ,
495
+ const secp256k1_ge * sp ,
445
496
const secp256k1_ge * t1p ,
446
497
const secp256k1_ge * t2p ,
447
498
const secp256k1_bulletproofs_generators * gens ,
@@ -528,8 +579,32 @@ static int secp256k1_bulletproofs_rangeproof_uncompressed_verify_impl(
528
579
if (!secp256k1_ecmult_multi_var (& ctx -> error_callback , scratch , & res_j , & neg_tau_x , secp256k1_bulletproofs_eq65_cb , (void * ) & eq65 , 4 )) {
529
580
return 0 ;
530
581
}
531
- return secp256k1_gej_is_infinity (& res_j );
582
+ if (!secp256k1_gej_is_infinity (& res_j )) {
583
+ return 0 ;
584
+ }
532
585
}
586
+ /* Then (66-67) */
587
+ {
588
+ secp256k1_gej res_j ;
589
+ secp256k1_bulletproofs_eq67_data eq67 ;
590
+ eq67 .gens = gens ;
591
+ eq67 .proof = proof ;
592
+ eq67 .ap = ap ;
593
+ eq67 .sp = sp ;
594
+ eq67 .x = x ;
595
+ eq67 .z = z ;
596
+ secp256k1_scalar_sqr (& eq67 .z_sq_2i , & z );
597
+ secp256k1_scalar_inverse_var (& eq67 .y_inv , & y );
598
+ secp256k1_scalar_set_int (& eq67 .y_neg_i , 1 );
599
+
600
+ if (!secp256k1_ecmult_multi_var (& ctx -> error_callback , scratch , & res_j , & neg_mu , secp256k1_bulletproofs_eq67_cb , (void * ) & eq67 , 2 + 2 * n_bits )) {
601
+ return 0 ;
602
+ }
603
+ if (!secp256k1_gej_is_infinity (& res_j )) {
604
+ return 0 ;
605
+ }
606
+ }
607
+ return 1 ;
533
608
}
534
609
535
610
#endif
0 commit comments