@@ -448,6 +448,7 @@ static int ecmult_verify_cb2(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx,
448448 if (idx == 0 ) {
449449 * pt = * data -> asset_genp ;
450450 * sc = * data -> v ;
451+ secp256k1_scalar_negate (sc , sc );
451452 return 1 ;
452453 }
453454 idx -= 1 ;
@@ -457,9 +458,31 @@ static int ecmult_verify_cb2(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx,
457458 * sc = data -> s_h [idx - data -> g_vec_len ];
458459 }
459460 * pt = data -> g_vec [idx ];
461+ secp256k1_scalar_negate (sc , sc );
460462 return 1 ;
461463}
462464
465+ typedef struct ecmult_verify_cb_data3 {
466+ const ecmult_verify_cb_data1 * cb_data1 ;
467+ const ecmult_verify_cb_data2 * cb_data2 ;
468+ size_t idx2 ;
469+ } ecmult_verify_cb_data3 ;
470+
471+ static int ecmult_verify_cb3 (secp256k1_scalar * sc , secp256k1_ge * pt , size_t idx , void * cbdata ) {
472+ ecmult_verify_cb_data3 * data = (ecmult_verify_cb_data3 * ) cbdata ;
473+ if (idx < data -> idx2 ) {
474+ if (!ecmult_verify_cb1 (sc , pt , idx , (void * )data -> cb_data1 )) {
475+ return 0 ;
476+ }
477+ } else {
478+ if (!ecmult_verify_cb2 (sc , pt , idx - data -> idx2 , (void * )data -> cb_data2 )) {
479+ return 0 ;
480+ }
481+ }
482+ return 1 ;
483+ }
484+
485+
463486/* Verify the proof. This function modifies the generators, c_vec and the challenge r. The
464487 caller should make sure to back them up if they need to be reused.
465488*/
@@ -479,7 +502,7 @@ int secp256k1_bppp_rangeproof_norm_product_verify(
479502) {
480503 secp256k1_scalar r_f , q_f , v , n , l , r_inv , h_c ;
481504 secp256k1_scalar * es , * s_g , * s_h , * r_inv_pows ;
482- secp256k1_gej res1 , res2 ;
505+ secp256k1_gej res ;
483506 size_t i = 0 , scratch_checkpoint ;
484507 int overflow ;
485508 size_t log_g_len = secp256k1_bppp_log2 (g_len ), log_h_len = secp256k1_bppp_log2 (c_vec_len );
@@ -557,35 +580,30 @@ int secp256k1_bppp_rangeproof_norm_product_verify(
557580 secp256k1_scalar_add (& v , & v , & h_c );
558581
559582 {
560- ecmult_verify_cb_data1 data ;
561- data .proof = proof ;
562- data .commit = commit ;
563- data .challenges = es ;
564-
565- if (!secp256k1_ecmult_multi_var (& ctx -> error_callback , scratch , & res1 , NULL , ecmult_verify_cb1 , & data , 2 * n_rounds + 1 )) {
583+ ecmult_verify_cb_data1 data1 ;
584+ ecmult_verify_cb_data2 data2 ;
585+ ecmult_verify_cb_data3 data3 ;
586+ data1 .proof = proof ;
587+ data1 .commit = commit ;
588+ data1 .challenges = es ;
589+ data2 .g_vec = g_vec -> gens ;
590+ data2 .g_vec_len = g_len ;
591+ data2 .s_g = s_g ;
592+ data2 .s_h = s_h ;
593+ data2 .v = & v ;
594+ data2 .asset_genp = asset_genp ;
595+ data3 .cb_data1 = & data1 ;
596+ data3 .cb_data2 = & data2 ;
597+ data3 .idx2 = 2 * n_rounds + 1 ;
598+
599+ if (!secp256k1_ecmult_multi_var (& ctx -> error_callback , scratch , & res , NULL , ecmult_verify_cb3 , & data3 , 2 * n_rounds + 1 + g_len + h_len + 1 )) {
566600 secp256k1_scratch_apply_checkpoint (& ctx -> error_callback , scratch , scratch_checkpoint );
567601 return 0 ;
568602 }
569603 }
570- {
571- ecmult_verify_cb_data2 data ;
572- data .g_vec = g_vec -> gens ;
573- data .g_vec_len = g_len ;
574- data .s_g = s_g ;
575- data .s_h = s_h ;
576- data .v = & v ;
577- data .asset_genp = asset_genp ;
578-
579- if (!secp256k1_ecmult_multi_var (& ctx -> error_callback , scratch , & res2 , NULL , ecmult_verify_cb2 , & data , g_len + h_len + 1 )) {
580- return 0 ;
581- }
582- }
583604
584605 secp256k1_scratch_apply_checkpoint (& ctx -> error_callback , scratch , scratch_checkpoint );
585606
586- /* res1 and res2 should be equal. Could not find a simpler way to compare them */
587- secp256k1_gej_neg (& res1 , & res1 );
588- secp256k1_gej_add_var (& res1 , & res1 , & res2 , NULL );
589- return secp256k1_gej_is_infinity (& res1 );
607+ return secp256k1_gej_is_infinity (& res );
590608}
591609#endif
0 commit comments