@@ -667,6 +667,7 @@ static void test_single_value_proof(uint64_t val) {
667
667
668
668
uint64_t val_out = 0 ;
669
669
size_t m_len_out = 0 ;
670
+ const int using_exact_value = secp256k1_testrand32 () & 1 ;
670
671
671
672
secp256k1_testrand256 (blind );
672
673
secp256k1_testrand256 (nonce );
@@ -685,19 +686,27 @@ static void test_single_value_proof(uint64_t val) {
685
686
secp256k1_generator_h
686
687
) == 0 );
687
688
688
- plen = sizeof (proof );
689
- CHECK (secp256k1_rangeproof_sign (
690
- ctx ,
691
- proof , & plen ,
692
- val , /* min_val */
693
- & commit , blind , nonce ,
694
- -1 , /* exp: -1 is magic value to indicate a single-value proof */
695
- 0 , /* min_bits */
696
- val , /* val */
697
- NULL , 0 ,
698
- NULL , 0 ,
699
- secp256k1_generator_h
700
- ) == 1 );
689
+ if (using_exact_value && val == 0 ) {
690
+ plen = 70 ; /* sanity-check that plen can be <73 for 0-value proofs */
691
+ } else {
692
+ plen = sizeof (proof );
693
+ }
694
+ if (using_exact_value ) {
695
+ CHECK (secp256k1_rangeproof_create_value (ctx , proof , & plen , val , blind , & commit , secp256k1_generator_h ) == 1 );
696
+ } else {
697
+ CHECK (secp256k1_rangeproof_sign (
698
+ ctx ,
699
+ proof , & plen ,
700
+ val , /* min_val */
701
+ & commit , blind , nonce ,
702
+ -1 , /* exp: -1 is magic value to indicate a single-value proof */
703
+ 0 , /* min_bits */
704
+ val , /* val */
705
+ NULL , 0 ,
706
+ NULL , 0 ,
707
+ secp256k1_generator_h
708
+ ) == 1 );
709
+ }
701
710
CHECK (plen <= secp256k1_rangeproof_max_size (ctx , val , 0 ));
702
711
703
712
/* Different proof sizes are unfortunate but is caused by `min_value` of
@@ -721,25 +730,29 @@ static void test_single_value_proof(uint64_t val) {
721
730
722
731
memset (message_out , 0 , sizeof (message_out ));
723
732
m_len_out = sizeof (message_out );
724
- CHECK (secp256k1_rangeproof_rewind (
725
- ctx ,
726
- blind_out , & val_out ,
727
- message_out , & m_len_out ,
728
- nonce ,
729
- & min_val_out , & max_val_out ,
730
- & commit ,
731
- proof , plen ,
732
- NULL , 0 ,
733
- secp256k1_generator_h
734
- ));
735
- CHECK (val_out == val );
736
- CHECK (min_val_out == val );
737
- CHECK (max_val_out == val );
738
- CHECK (m_len_out == 0 );
739
- CHECK (secp256k1_memcmp_var (blind , blind_out , 32 ) == 0 );
740
- for (m_len_out = 0 ; m_len_out < sizeof (message_out ); m_len_out ++ ) {
741
- CHECK (message_out [m_len_out ] == 0 );
733
+ /* exact-value proofs cannot be rewound */
734
+ if (!using_exact_value ) {
735
+ CHECK (secp256k1_rangeproof_rewind (
736
+ ctx ,
737
+ blind_out , & val_out ,
738
+ message_out , & m_len_out ,
739
+ nonce ,
740
+ & min_val_out , & max_val_out ,
741
+ & commit ,
742
+ proof , plen ,
743
+ NULL , 0 ,
744
+ secp256k1_generator_h
745
+ ) == 1 );
746
+ CHECK (val_out == val );
747
+ CHECK (min_val_out == val );
748
+ CHECK (max_val_out == val );
749
+ CHECK (m_len_out == 0 );
750
+ CHECK (secp256k1_memcmp_var (blind , blind_out , 32 ) == 0 );
751
+ for (m_len_out = 0 ; m_len_out < sizeof (message_out ); m_len_out ++ ) {
752
+ CHECK (message_out [m_len_out ] == 0 );
753
+ }
742
754
}
755
+ CHECK (secp256k1_rangeproof_verify_value (ctx , proof , plen , val , & commit , secp256k1_generator_h ));
743
756
}
744
757
745
758
#define MAX_N_GENS 30
@@ -1594,6 +1607,10 @@ void run_rangeproof_tests(void) {
1594
1607
test_single_value_proof (0 );
1595
1608
test_single_value_proof (12345678 );
1596
1609
test_single_value_proof (UINT64_MAX );
1610
+ for (i = 0 ; i < count / 2 ; i ++ ) {
1611
+ test_single_value_proof (secp256k1_testrand32 ());
1612
+ test_single_value_proof (((uint64_t ) secp256k1_testrand32 () << 32 ) + secp256k1_testrand32 ());
1613
+ }
1597
1614
1598
1615
test_rangeproof_fixed_vectors ();
1599
1616
test_rangeproof_fixed_vectors_reproducible ();
0 commit comments