@@ -25,20 +25,24 @@ void test_schnorrsig_api(secp256k1_scratch_space *scratch) {
25
25
unsigned char sk2 [32 ];
26
26
unsigned char sk3 [32 ];
27
27
unsigned char msg [32 ];
28
+ unsigned char data32 [32 ];
29
+ unsigned char s2c_data32 [32 ];
28
30
unsigned char sig64 [64 ];
29
31
secp256k1_pubkey pk [3 ];
30
32
secp256k1_schnorrsig sig ;
31
33
const secp256k1_schnorrsig * sigptr = & sig ;
32
34
const unsigned char * msgptr = msg ;
33
35
const secp256k1_pubkey * pkptr = & pk [0 ];
34
- int nonce_is_negated ;
36
+ secp256k1_s2c_opening s2c_opening ;
37
+ unsigned char ones [32 ];
35
38
36
39
/** setup **/
37
40
secp256k1_context * none = secp256k1_context_create (SECP256K1_CONTEXT_NONE );
38
41
secp256k1_context * sign = secp256k1_context_create (SECP256K1_CONTEXT_SIGN );
39
42
secp256k1_context * vrfy = secp256k1_context_create (SECP256K1_CONTEXT_VERIFY );
40
43
secp256k1_context * both = secp256k1_context_create (SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY );
41
44
int ecount ;
45
+ memset (ones , 0xff , 32 );
42
46
43
47
secp256k1_context_set_error_callback (none , counting_illegal_callback_fn , & ecount );
44
48
secp256k1_context_set_error_callback (sign , counting_illegal_callback_fn , & ecount );
@@ -59,20 +63,25 @@ void test_schnorrsig_api(secp256k1_scratch_space *scratch) {
59
63
60
64
/** main test body **/
61
65
ecount = 0 ;
62
- CHECK (secp256k1_schnorrsig_sign (none , & sig , & nonce_is_negated , msg , sk1 , NULL , NULL ) == 0 );
66
+ CHECK (secp256k1_schnorrsig_sign (none , & sig , & s2c_opening , msg , sk1 , s2c_data32 , NULL , NULL ) == 0 );
63
67
CHECK (ecount == 1 );
64
- CHECK (secp256k1_schnorrsig_sign (vrfy , & sig , & nonce_is_negated , msg , sk1 , NULL , NULL ) == 0 );
68
+ CHECK (secp256k1_schnorrsig_sign (vrfy , & sig , & s2c_opening , msg , sk1 , s2c_data32 , NULL , NULL ) == 0 );
65
69
CHECK (ecount == 2 );
66
- CHECK (secp256k1_schnorrsig_sign (sign , & sig , & nonce_is_negated , msg , sk1 , NULL , NULL ) == 1 );
70
+ CHECK (secp256k1_schnorrsig_sign (sign , & sig , & s2c_opening , msg , sk1 , s2c_data32 , NULL , NULL ) == 1 );
67
71
CHECK (ecount == 2 );
68
- CHECK (secp256k1_schnorrsig_sign (sign , NULL , & nonce_is_negated , msg , sk1 , NULL , NULL ) == 0 );
72
+ CHECK (secp256k1_schnorrsig_sign (sign , NULL , & s2c_opening , msg , sk1 , s2c_data32 , NULL , NULL ) == 0 );
69
73
CHECK (ecount == 3 );
70
- CHECK (secp256k1_schnorrsig_sign (sign , & sig , NULL , msg , sk1 , NULL , NULL ) == 1 );
74
+ CHECK (secp256k1_schnorrsig_sign (sign , & sig , NULL , msg , sk1 , s2c_data32 , NULL , NULL ) == 1 );
71
75
CHECK (ecount == 3 );
72
- CHECK (secp256k1_schnorrsig_sign (sign , & sig , & nonce_is_negated , NULL , sk1 , NULL , NULL ) == 0 );
76
+ CHECK (secp256k1_schnorrsig_sign (sign , & sig , & s2c_opening , NULL , sk1 , s2c_data32 , NULL , NULL ) == 0 );
73
77
CHECK (ecount == 4 );
74
- CHECK (secp256k1_schnorrsig_sign (sign , & sig , & nonce_is_negated , msg , NULL , NULL , NULL ) == 0 );
78
+ CHECK (secp256k1_schnorrsig_sign (sign , & sig , & s2c_opening , msg , NULL , s2c_data32 , NULL , NULL ) == 0 );
75
79
CHECK (ecount == 5 );
80
+ CHECK (secp256k1_schnorrsig_sign (sign , & sig , & s2c_opening , msg , sk1 , NULL , NULL , NULL ) == 1 );
81
+ CHECK (ecount == 5 );
82
+ /* s2c commitments with a different nonce function than bipschnorr are not allowed */
83
+ CHECK (secp256k1_schnorrsig_sign (sign , & sig , & s2c_opening , msg , sk1 , s2c_data32 , secp256k1_nonce_function_rfc6979 , NULL ) == 0 );
84
+ CHECK (ecount == 6 );
76
85
77
86
ecount = 0 ;
78
87
CHECK (secp256k1_schnorrsig_serialize (none , sig64 , & sig ) == 1 );
@@ -88,6 +97,33 @@ void test_schnorrsig_api(secp256k1_scratch_space *scratch) {
88
97
CHECK (secp256k1_schnorrsig_parse (none , & sig , NULL ) == 0 );
89
98
CHECK (ecount == 4 );
90
99
100
+ /* Create sign-to-contract commitment to data32 for testing verify_s2c_commit */
101
+ secp256k1_rand256 (data32 );
102
+ CHECK (secp256k1_schnorrsig_sign (sign , & sig , & s2c_opening , msg , sk1 , data32 , NULL , NULL ) == 1 );
103
+ ecount = 0 ;
104
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (none , & sig , data32 , & s2c_opening ) == 0 );
105
+ CHECK (ecount == 1 );
106
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (vrfy , & sig , data32 , & s2c_opening ) == 1 );
107
+ CHECK (ecount == 1 );
108
+ {
109
+ /* Overflowing x-coordinate in signature */
110
+ secp256k1_schnorrsig sig_tmp = sig ;
111
+ memcpy (& sig_tmp .data [0 ], ones , 32 );
112
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (vrfy , & sig_tmp , data32 , & s2c_opening ) == 0 );
113
+ }
114
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (vrfy , NULL , data32 , & s2c_opening ) == 0 );
115
+ CHECK (ecount == 2 );
116
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (vrfy , & sig , NULL , & s2c_opening ) == 0 );
117
+ CHECK (ecount == 3 );
118
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (vrfy , & sig , data32 , NULL ) == 0 );
119
+ CHECK (ecount == 4 );
120
+ {
121
+ /* Verification with uninitialized s2c_opening should fail */
122
+ secp256k1_s2c_opening s2c_opening_tmp ;
123
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (vrfy , & sig , data32 , & s2c_opening_tmp ) == 0 );
124
+ CHECK (ecount == 5 );
125
+ }
126
+
91
127
ecount = 0 ;
92
128
CHECK (secp256k1_schnorrsig_verify (none , & sig , msg , & pk [0 ]) == 0 );
93
129
CHECK (ecount == 1 );
@@ -134,10 +170,10 @@ void test_schnorrsig_bip_vectors_check_signing(const unsigned char *sk, const un
134
170
secp256k1_schnorrsig sig ;
135
171
unsigned char serialized_sig [64 ];
136
172
secp256k1_pubkey pk ;
137
- int nonce_is_negated ;
173
+ secp256k1_s2c_opening s2c_opening ;
138
174
139
- CHECK (secp256k1_schnorrsig_sign (ctx , & sig , & nonce_is_negated , msg , sk , NULL , NULL ));
140
- CHECK (nonce_is_negated == expected_nonce_is_negated );
175
+ CHECK (secp256k1_schnorrsig_sign (ctx , & sig , & s2c_opening , msg , sk , NULL , NULL , NULL ));
176
+ CHECK (s2c_opening . nonce_is_negated == expected_nonce_is_negated );
141
177
CHECK (secp256k1_schnorrsig_serialize (ctx , serialized_sig , & sig ));
142
178
CHECK (memcmp (serialized_sig , expected_sig , 64 ) == 0 );
143
179
@@ -639,15 +675,15 @@ void test_schnorrsig_sign(void) {
639
675
secp256k1_schnorrsig sig ;
640
676
641
677
memset (sk , 23 , sizeof (sk ));
642
- CHECK (secp256k1_schnorrsig_sign (ctx , & sig , NULL , msg , sk , NULL , NULL ) == 1 );
678
+ CHECK (secp256k1_schnorrsig_sign (ctx , & sig , NULL , msg , sk , NULL , NULL , NULL ) == 1 );
643
679
644
680
/* Overflowing secret key */
645
681
memset (sk , 0xFF , sizeof (sk ));
646
- CHECK (secp256k1_schnorrsig_sign (ctx , & sig , NULL , msg , sk , NULL , NULL ) == 0 );
682
+ CHECK (secp256k1_schnorrsig_sign (ctx , & sig , NULL , msg , sk , NULL , NULL , NULL ) == 0 );
647
683
memset (sk , 23 , sizeof (sk ));
648
684
649
- CHECK (secp256k1_schnorrsig_sign (ctx , & sig , NULL , msg , sk , nonce_function_failing , NULL ) == 0 );
650
- CHECK (secp256k1_schnorrsig_sign (ctx , & sig , NULL , msg , sk , nonce_function_0 , NULL ) == 0 );
685
+ CHECK (secp256k1_schnorrsig_sign (ctx , & sig , NULL , msg , sk , NULL , nonce_function_failing , NULL ) == 0 );
686
+ CHECK (secp256k1_schnorrsig_sign (ctx , & sig , NULL , msg , sk , NULL , nonce_function_0 , NULL ) == 0 );
651
687
}
652
688
653
689
#define N_SIGS 200
@@ -669,7 +705,7 @@ void test_schnorrsig_sign_verify(secp256k1_scratch_space *scratch) {
669
705
670
706
for (i = 0 ; i < N_SIGS ; i ++ ) {
671
707
secp256k1_rand256 (msg [i ]);
672
- CHECK (secp256k1_schnorrsig_sign (ctx , & sig [i ], NULL , msg [i ], sk , NULL , NULL ));
708
+ CHECK (secp256k1_schnorrsig_sign (ctx , & sig [i ], NULL , msg [i ], sk , NULL , NULL , NULL ));
673
709
CHECK (secp256k1_schnorrsig_verify (ctx , & sig [i ], msg [i ], & pk ));
674
710
sig_arr [i ] = & sig [i ];
675
711
msg_arr [i ] = msg [i ];
@@ -711,15 +747,80 @@ void test_schnorrsig_sign_verify(secp256k1_scratch_space *scratch) {
711
747
}
712
748
#undef N_SIGS
713
749
750
+ void test_schnorrsig_s2c_commit_verify (void ) {
751
+ unsigned char data32 [32 ];
752
+ secp256k1_schnorrsig sig ;
753
+ secp256k1_s2c_opening s2c_opening ;
754
+ unsigned char msg [32 ];
755
+ unsigned char sk [32 ];
756
+ secp256k1_pubkey pk ;
757
+ unsigned char noncedata [32 ];
758
+
759
+ secp256k1_rand256 (data32 );
760
+ secp256k1_rand256 (msg );
761
+ secp256k1_rand256 (sk );
762
+ secp256k1_rand256 (noncedata );
763
+ CHECK (secp256k1_ec_pubkey_create (ctx , & pk , sk ) == 1 );
764
+
765
+ /* Create and verify correct commitment */
766
+ CHECK (secp256k1_schnorrsig_sign (ctx , & sig , & s2c_opening , msg , sk , data32 , NULL , noncedata ) == 1 );
767
+ CHECK (secp256k1_schnorrsig_verify (ctx , & sig , msg , & pk ));
768
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (ctx , & sig , data32 , & s2c_opening ) == 1 );
769
+ {
770
+ /* verify_s2c_commit fails if nonce_is_negated is wrong */
771
+ secp256k1_s2c_opening s2c_opening_tmp ;
772
+ s2c_opening_tmp = s2c_opening ;
773
+ s2c_opening_tmp .nonce_is_negated = !s2c_opening .nonce_is_negated ;
774
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (ctx , & sig , data32 , & s2c_opening_tmp ) == 0 );
775
+ }
776
+ {
777
+ /* verify_s2c_commit fails if given data does not match committed data */
778
+ unsigned char data32_tmp [32 ];
779
+ memcpy (data32_tmp , data32 , sizeof (data32_tmp ));
780
+ data32_tmp [31 ] ^= 1 ;
781
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (ctx , & sig , data32_tmp , & s2c_opening ) == 0 );
782
+ }
783
+ {
784
+ /* verify_s2c_commit fails if signature does not commit to data */
785
+ secp256k1_schnorrsig sig_tmp ;
786
+ sig_tmp = sig ;
787
+ secp256k1_rand256 (& sig_tmp .data [0 ]);
788
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (ctx , & sig_tmp , data32 , & s2c_opening ) == 0 );
789
+ }
790
+ {
791
+ /* A commitment to different data creates a different original_pubnonce
792
+ * (i.e. data is hashed into the nonce) */
793
+ secp256k1_s2c_opening s2c_opening_tmp ;
794
+ secp256k1_schnorrsig sig_tmp ;
795
+ unsigned char data32_tmp [32 ];
796
+ unsigned char serialized_nonce [33 ];
797
+ unsigned char serialized_nonce_tmp [33 ];
798
+ size_t outputlen = 33 ;
799
+ secp256k1_rand256 (data32_tmp );
800
+ CHECK (secp256k1_schnorrsig_sign (ctx , & sig_tmp , & s2c_opening_tmp , msg , sk , data32_tmp , NULL , NULL ) == 1 );
801
+ CHECK (secp256k1_schnorrsig_verify (ctx , & sig_tmp , msg , & pk ));
802
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (ctx , & sig_tmp , data32_tmp , & s2c_opening_tmp ) == 1 );
803
+ secp256k1_ec_pubkey_serialize (ctx , serialized_nonce , & outputlen , & s2c_opening .original_pubnonce , SECP256K1_EC_COMPRESSED );
804
+ secp256k1_ec_pubkey_serialize (ctx , serialized_nonce_tmp , & outputlen , & s2c_opening_tmp .original_pubnonce , SECP256K1_EC_COMPRESSED );
805
+ CHECK (outputlen == 33 );
806
+ CHECK (memcmp (serialized_nonce , serialized_nonce_tmp , outputlen ) != 0 );
807
+ }
808
+ }
809
+
714
810
void run_schnorrsig_tests (void ) {
811
+ int i ;
715
812
secp256k1_scratch_space * scratch = secp256k1_scratch_space_create (ctx , 1024 * 1024 );
716
813
717
814
test_schnorrsig_serialize ();
718
815
test_schnorrsig_api (scratch );
719
816
test_schnorrsig_bip_vectors (scratch );
720
817
test_schnorrsig_sign ();
721
818
test_schnorrsig_sign_verify (scratch );
722
-
819
+ for (i = 0 ; i < count ; i ++ ) {
820
+ /* Run multiple times to increase probability that the nonce is negated in
821
+ * a test. */
822
+ test_schnorrsig_s2c_commit_verify ();
823
+ }
723
824
secp256k1_scratch_space_destroy (scratch );
724
825
}
725
826
0 commit comments