@@ -655,6 +655,7 @@ static void test_single_value_proof(uint64_t val) {
655
655
uint64_t max_val_out = 0 ;
656
656
uint64_t val_out = 0 ;
657
657
size_t m_len_out = 0 ;
658
+ const int using_exact_value = secp256k1_testrand32 () & 1 ;
658
659
659
660
secp256k1_testrand256 (blind );
660
661
secp256k1_testrand256 (nonce );
@@ -673,19 +674,27 @@ static void test_single_value_proof(uint64_t val) {
673
674
secp256k1_generator_h
674
675
) == 0 );
675
676
676
- plen = sizeof (proof );
677
- CHECK (secp256k1_rangeproof_sign (
678
- ctx ,
679
- proof , & plen ,
680
- val , /* min_val */
681
- & commit , blind , nonce ,
682
- -1 , /* exp: -1 is magic value to indicate a single-value proof */
683
- 0 , /* min_bits */
684
- val , /* val */
685
- NULL , 0 ,
686
- NULL , 0 ,
687
- secp256k1_generator_h
688
- ) == 1 );
677
+ if (using_exact_value && val == 0 ) {
678
+ plen = 70 ; /* sanity-check that plen can be <73 for 0-value proofs */
679
+ } else {
680
+ plen = sizeof (proof );
681
+ }
682
+ if (using_exact_value ) {
683
+ CHECK (secp256k1_rangeproof_create_value (ctx , proof , & plen , val , blind , & commit , secp256k1_generator_h ) == 1 );
684
+ } else {
685
+ CHECK (secp256k1_rangeproof_sign (
686
+ ctx ,
687
+ proof , & plen ,
688
+ val , /* min_val */
689
+ & commit , blind , nonce ,
690
+ -1 , /* exp: -1 is magic value to indicate a single-value proof */
691
+ 0 , /* min_bits */
692
+ val , /* val */
693
+ NULL , 0 ,
694
+ NULL , 0 ,
695
+ secp256k1_generator_h
696
+ ) == 1 );
697
+ }
689
698
690
699
/* Different proof sizes are unfortunate but is caused by `min_value` of
691
700
* zero being special-cased and encoded more efficiently. */
@@ -708,25 +717,29 @@ static void test_single_value_proof(uint64_t val) {
708
717
709
718
memset (message_out , 0 , sizeof (message_out ));
710
719
m_len_out = sizeof (message_out );
711
- CHECK (secp256k1_rangeproof_rewind (
712
- ctx ,
713
- blind_out , & val_out ,
714
- message_out , & m_len_out ,
715
- nonce ,
716
- & min_val_out , & max_val_out ,
717
- & commit ,
718
- proof , plen ,
719
- NULL , 0 ,
720
- secp256k1_generator_h
721
- ) == 1 );
722
- CHECK (val_out == val );
723
- CHECK (min_val_out == val );
724
- CHECK (max_val_out == val );
725
- CHECK (m_len_out == 0 );
726
- CHECK (secp256k1_memcmp_var (blind , blind_out , 32 ) == 0 );
727
- for (m_len_out = 0 ; m_len_out < sizeof (message_out ); m_len_out ++ ) {
728
- CHECK (message_out [m_len_out ] == 0 );
720
+ /* exact-value proofs cannot be rewound */
721
+ if (!using_exact_value ) {
722
+ CHECK (secp256k1_rangeproof_rewind (
723
+ ctx ,
724
+ blind_out , & val_out ,
725
+ message_out , & m_len_out ,
726
+ nonce ,
727
+ & min_val_out , & max_val_out ,
728
+ & commit ,
729
+ proof , plen ,
730
+ NULL , 0 ,
731
+ secp256k1_generator_h
732
+ ) == 1 );
733
+ CHECK (val_out == val );
734
+ CHECK (min_val_out == val );
735
+ CHECK (max_val_out == val );
736
+ CHECK (m_len_out == 0 );
737
+ CHECK (secp256k1_memcmp_var (blind , blind_out , 32 ) == 0 );
738
+ for (m_len_out = 0 ; m_len_out < sizeof (message_out ); m_len_out ++ ) {
739
+ CHECK (message_out [m_len_out ] == 0 );
740
+ }
729
741
}
742
+ CHECK (secp256k1_rangeproof_verify_value (ctx , proof , plen , val , & commit , secp256k1_generator_h ));
730
743
}
731
744
732
745
#define MAX_N_GENS 30
@@ -1045,8 +1058,10 @@ void run_rangeproof_tests(void) {
1045
1058
test_single_value_proof (0 );
1046
1059
test_single_value_proof (12345678 );
1047
1060
test_single_value_proof (UINT64_MAX );
1048
- test_single_value_proof (secp256k1_testrand32 ());
1049
- test_single_value_proof (((uint64_t ) secp256k1_testrand32 () << 32 ) + secp256k1_testrand32 ());
1061
+ for (i = 0 ; i < count / 2 ; i ++ ) {
1062
+ test_single_value_proof (secp256k1_testrand32 ());
1063
+ test_single_value_proof (((uint64_t ) secp256k1_testrand32 () << 32 ) + secp256k1_testrand32 ());
1064
+ }
1050
1065
1051
1066
test_rangeproof_fixed_vectors ();
1052
1067
test_pedersen_commitment_fixed_vector ();
0 commit comments