@@ -25,19 +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 ];
36
+ secp256k1_s2c_opening s2c_opening ;
37
+ unsigned char ones [32 ];
34
38
35
39
/** setup **/
36
40
secp256k1_context * none = secp256k1_context_create (SECP256K1_CONTEXT_NONE );
37
41
secp256k1_context * sign = secp256k1_context_create (SECP256K1_CONTEXT_SIGN );
38
42
secp256k1_context * vrfy = secp256k1_context_create (SECP256K1_CONTEXT_VERIFY );
39
43
secp256k1_context * both = secp256k1_context_create (SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY );
40
44
int ecount ;
45
+ memset (ones , 0xff , 32 );
41
46
42
47
secp256k1_context_set_error_callback (none , counting_illegal_callback_fn , & ecount );
43
48
secp256k1_context_set_error_callback (sign , counting_illegal_callback_fn , & ecount );
@@ -52,24 +57,36 @@ void test_schnorrsig_api(secp256k1_scratch_space *scratch) {
52
57
secp256k1_rand256 (sk2 );
53
58
secp256k1_rand256 (sk3 );
54
59
secp256k1_rand256 (msg );
60
+ secp256k1_rand256 (s2c_data32 );
55
61
CHECK (secp256k1_ec_pubkey_create (ctx , & pk [0 ], sk1 ) == 1 );
56
62
CHECK (secp256k1_ec_pubkey_create (ctx , & pk [1 ], sk2 ) == 1 );
57
63
CHECK (secp256k1_ec_pubkey_create (ctx , & pk [2 ], sk3 ) == 1 );
58
64
59
65
/** main test body **/
60
66
ecount = 0 ;
61
- CHECK (secp256k1_schnorrsig_sign (none , & sig , msg , sk1 , NULL , NULL ) == 0 );
67
+ CHECK (secp256k1_schnorrsig_sign (none , & sig , & s2c_opening , msg , sk1 , s2c_data32 , NULL , NULL ) == 0 );
62
68
CHECK (ecount == 1 );
63
- CHECK (secp256k1_schnorrsig_sign (vrfy , & sig , msg , sk1 , NULL , NULL ) == 0 );
69
+ CHECK (secp256k1_schnorrsig_sign (vrfy , & sig , & s2c_opening , msg , sk1 , s2c_data32 , NULL , NULL ) == 0 );
64
70
CHECK (ecount == 2 );
65
- CHECK (secp256k1_schnorrsig_sign (sign , & sig , msg , sk1 , NULL , NULL ) == 1 );
71
+ CHECK (secp256k1_schnorrsig_sign (sign , & sig , & s2c_opening , msg , sk1 , s2c_data32 , NULL , NULL ) == 1 );
66
72
CHECK (ecount == 2 );
67
- CHECK (secp256k1_schnorrsig_sign (sign , NULL , msg , sk1 , NULL , NULL ) == 0 );
73
+ CHECK (secp256k1_schnorrsig_sign (sign , NULL , & s2c_opening , msg , sk1 , s2c_data32 , NULL , NULL ) == 0 );
68
74
CHECK (ecount == 3 );
69
- CHECK (secp256k1_schnorrsig_sign (sign , & sig , NULL , sk1 , NULL , NULL ) == 0 );
75
+ CHECK (secp256k1_schnorrsig_sign (sign , & sig , NULL , msg , sk1 , s2c_data32 , NULL , NULL ) == 0 );
70
76
CHECK (ecount == 4 );
71
- CHECK (secp256k1_schnorrsig_sign (sign , & sig , msg , NULL , NULL , NULL ) == 0 );
77
+ CHECK (secp256k1_schnorrsig_sign (sign , & sig , & s2c_opening , NULL , sk1 , s2c_data32 , NULL , NULL ) == 0 );
72
78
CHECK (ecount == 5 );
79
+ CHECK (secp256k1_schnorrsig_sign (sign , & sig , & s2c_opening , msg , NULL , s2c_data32 , NULL , NULL ) == 0 );
80
+ CHECK (ecount == 6 );
81
+ CHECK (secp256k1_schnorrsig_sign (sign , & sig , & s2c_opening , msg , sk1 , NULL , NULL , NULL ) == 0 );
82
+ CHECK (ecount == 7 );
83
+ /* It's okay if both s2c_opening and s2c_data32 are NULL. It's just not okay if
84
+ * only a single one of them is NULL. */
85
+ CHECK (secp256k1_schnorrsig_sign (sign , & sig , NULL , msg , sk1 , NULL , NULL , NULL ) == 1 );
86
+ CHECK (ecount == 7 );
87
+ /* s2c commitments with a different nonce function than bipschnorr are not allowed */
88
+ CHECK (secp256k1_schnorrsig_sign (sign , & sig , & s2c_opening , msg , sk1 , s2c_data32 , secp256k1_nonce_function_rfc6979 , NULL ) == 0 );
89
+ CHECK (ecount == 8 );
73
90
74
91
ecount = 0 ;
75
92
CHECK (secp256k1_schnorrsig_serialize (none , sig64 , & sig ) == 1 );
@@ -85,6 +102,36 @@ void test_schnorrsig_api(secp256k1_scratch_space *scratch) {
85
102
CHECK (secp256k1_schnorrsig_parse (none , & sig , NULL ) == 0 );
86
103
CHECK (ecount == 4 );
87
104
105
+ /* Create sign-to-contract commitment to data32 for testing verify_s2c_commit */
106
+ secp256k1_rand256 (data32 );
107
+ CHECK (secp256k1_schnorrsig_sign (sign , & sig , & s2c_opening , msg , sk1 , data32 , NULL , NULL ) == 1 );
108
+ ecount = 0 ;
109
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (none , & sig , data32 , & s2c_opening ) == 0 );
110
+ CHECK (ecount == 1 );
111
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (vrfy , & sig , data32 , & s2c_opening ) == 1 );
112
+ CHECK (ecount == 1 );
113
+ {
114
+ /* Overflowing x-coordinate in signature */
115
+ secp256k1_schnorrsig sig_tmp = sig ;
116
+ memcpy (& sig_tmp .data [0 ], ones , 32 );
117
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (vrfy , & sig_tmp , data32 , & s2c_opening ) == 0 );
118
+ }
119
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (vrfy , NULL , data32 , & s2c_opening ) == 0 );
120
+ CHECK (ecount == 2 );
121
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (vrfy , & sig , NULL , & s2c_opening ) == 0 );
122
+ CHECK (ecount == 3 );
123
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (vrfy , & sig , data32 , NULL ) == 0 );
124
+ CHECK (ecount == 4 );
125
+ {
126
+ /* Verification with uninitialized s2c_opening should fail. Actually testing
127
+ * that would be undefined behavior. Therefore we simulate it by setting the
128
+ * opening to 0. */
129
+ secp256k1_s2c_opening s2c_opening_tmp ;
130
+ memset (& s2c_opening_tmp , 0 , sizeof (s2c_opening_tmp ));
131
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (vrfy , & sig , data32 , & s2c_opening_tmp ) == 0 );
132
+ CHECK (ecount == 5 );
133
+ }
134
+
88
135
ecount = 0 ;
89
136
CHECK (secp256k1_schnorrsig_verify (none , & sig , msg , & pk [0 ]) == 0 );
90
137
CHECK (ecount == 1 );
@@ -132,7 +179,7 @@ void test_schnorrsig_bip_vectors_check_signing(const unsigned char *sk, const un
132
179
unsigned char serialized_sig [64 ];
133
180
secp256k1_pubkey pk ;
134
181
135
- CHECK (secp256k1_schnorrsig_sign (ctx , & sig , msg , sk , NULL , NULL ));
182
+ CHECK (secp256k1_schnorrsig_sign (ctx , & sig , NULL , msg , sk , NULL , NULL , NULL ));
136
183
CHECK (secp256k1_schnorrsig_serialize (ctx , serialized_sig , & sig ));
137
184
CHECK (memcmp (serialized_sig , expected_sig , 64 ) == 0 );
138
185
@@ -634,15 +681,16 @@ void test_schnorrsig_sign(void) {
634
681
secp256k1_schnorrsig sig ;
635
682
636
683
memset (sk , 23 , sizeof (sk ));
637
- CHECK (secp256k1_schnorrsig_sign (ctx , & sig , msg , sk , NULL , NULL ) == 1 );
684
+
685
+ CHECK (secp256k1_schnorrsig_sign (ctx , & sig , NULL , msg , sk , NULL , NULL , NULL ) == 1 );
638
686
639
687
/* Overflowing secret key */
640
688
memset (sk , 0xFF , sizeof (sk ));
641
- CHECK (secp256k1_schnorrsig_sign (ctx , & sig , msg , sk , NULL , NULL ) == 0 );
689
+ CHECK (secp256k1_schnorrsig_sign (ctx , & sig , NULL , msg , sk , NULL , NULL , NULL ) == 0 );
642
690
memset (sk , 23 , sizeof (sk ));
643
691
644
- CHECK (secp256k1_schnorrsig_sign (ctx , & sig , msg , sk , nonce_function_failing , NULL ) == 0 );
645
- CHECK (secp256k1_schnorrsig_sign (ctx , & sig , msg , sk , nonce_function_0 , NULL ) == 0 );
692
+ CHECK (secp256k1_schnorrsig_sign (ctx , & sig , NULL , msg , sk , NULL , nonce_function_failing , NULL ) == 0 );
693
+ CHECK (secp256k1_schnorrsig_sign (ctx , & sig , NULL , msg , sk , NULL , nonce_function_0 , NULL ) == 0 );
646
694
}
647
695
648
696
#define N_SIGS 200
@@ -664,7 +712,7 @@ void test_schnorrsig_sign_verify(secp256k1_scratch_space *scratch) {
664
712
665
713
for (i = 0 ; i < N_SIGS ; i ++ ) {
666
714
secp256k1_rand256 (msg [i ]);
667
- CHECK (secp256k1_schnorrsig_sign (ctx , & sig [i ], msg [i ], sk , NULL , NULL ));
715
+ CHECK (secp256k1_schnorrsig_sign (ctx , & sig [i ], NULL , msg [i ], sk , NULL , NULL , NULL ));
668
716
CHECK (secp256k1_schnorrsig_verify (ctx , & sig [i ], msg [i ], & pk ));
669
717
sig_arr [i ] = & sig [i ];
670
718
msg_arr [i ] = msg [i ];
@@ -706,7 +754,68 @@ void test_schnorrsig_sign_verify(secp256k1_scratch_space *scratch) {
706
754
}
707
755
#undef N_SIGS
708
756
757
+ void test_schnorrsig_s2c_commit_verify (void ) {
758
+ unsigned char data32 [32 ];
759
+ secp256k1_schnorrsig sig ;
760
+ secp256k1_s2c_opening s2c_opening ;
761
+ unsigned char msg [32 ];
762
+ unsigned char sk [32 ];
763
+ secp256k1_pubkey pk ;
764
+ unsigned char noncedata [32 ];
765
+
766
+ secp256k1_rand256 (data32 );
767
+ secp256k1_rand256 (msg );
768
+ secp256k1_rand256 (sk );
769
+ secp256k1_rand256 (noncedata );
770
+ CHECK (secp256k1_ec_pubkey_create (ctx , & pk , sk ) == 1 );
771
+
772
+ /* Create and verify correct commitment */
773
+ CHECK (secp256k1_schnorrsig_sign (ctx , & sig , & s2c_opening , msg , sk , data32 , NULL , noncedata ) == 1 );
774
+ CHECK (secp256k1_schnorrsig_verify (ctx , & sig , msg , & pk ));
775
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (ctx , & sig , data32 , & s2c_opening ) == 1 );
776
+ {
777
+ /* verify_s2c_commit fails if nonce_is_negated is wrong */
778
+ secp256k1_s2c_opening s2c_opening_tmp ;
779
+ s2c_opening_tmp = s2c_opening ;
780
+ s2c_opening_tmp .nonce_is_negated = !s2c_opening .nonce_is_negated ;
781
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (ctx , & sig , data32 , & s2c_opening_tmp ) == 0 );
782
+ }
783
+ {
784
+ /* verify_s2c_commit fails if given data does not match committed data */
785
+ unsigned char data32_tmp [32 ];
786
+ memcpy (data32_tmp , data32 , sizeof (data32_tmp ));
787
+ data32_tmp [31 ] ^= 1 ;
788
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (ctx , & sig , data32_tmp , & s2c_opening ) == 0 );
789
+ }
790
+ {
791
+ /* verify_s2c_commit fails if signature does not commit to data */
792
+ secp256k1_schnorrsig sig_tmp ;
793
+ sig_tmp = sig ;
794
+ secp256k1_rand256 (& sig_tmp .data [0 ]);
795
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (ctx , & sig_tmp , data32 , & s2c_opening ) == 0 );
796
+ }
797
+ {
798
+ /* A commitment to different data creates a different original_pubnonce
799
+ * (i.e. data is hashed into the nonce) */
800
+ secp256k1_s2c_opening s2c_opening_tmp ;
801
+ secp256k1_schnorrsig sig_tmp ;
802
+ unsigned char data32_tmp [32 ];
803
+ unsigned char serialized_nonce [33 ];
804
+ unsigned char serialized_nonce_tmp [33 ];
805
+ size_t outputlen = 33 ;
806
+ secp256k1_rand256 (data32_tmp );
807
+ CHECK (secp256k1_schnorrsig_sign (ctx , & sig_tmp , & s2c_opening_tmp , msg , sk , data32_tmp , NULL , NULL ) == 1 );
808
+ CHECK (secp256k1_schnorrsig_verify (ctx , & sig_tmp , msg , & pk ));
809
+ CHECK (secp256k1_schnorrsig_verify_s2c_commit (ctx , & sig_tmp , data32_tmp , & s2c_opening_tmp ) == 1 );
810
+ secp256k1_ec_pubkey_serialize (ctx , serialized_nonce , & outputlen , & s2c_opening .original_pubnonce , SECP256K1_EC_COMPRESSED );
811
+ secp256k1_ec_pubkey_serialize (ctx , serialized_nonce_tmp , & outputlen , & s2c_opening_tmp .original_pubnonce , SECP256K1_EC_COMPRESSED );
812
+ CHECK (outputlen == 33 );
813
+ CHECK (memcmp (serialized_nonce , serialized_nonce_tmp , outputlen ) != 0 );
814
+ }
815
+ }
816
+
709
817
void run_schnorrsig_tests (void ) {
818
+ int i ;
710
819
secp256k1_scratch_space * scratch = secp256k1_scratch_space_create (ctx , 1024 * 1024 );
711
820
712
821
test_schnorrsig_serialize ();
@@ -715,6 +824,11 @@ void run_schnorrsig_tests(void) {
715
824
test_schnorrsig_sign ();
716
825
test_schnorrsig_sign_verify (scratch );
717
826
827
+ for (i = 0 ; i < count ; i ++ ) {
828
+ /* Run multiple times to increase probability that the nonce is negated in
829
+ * a test. */
830
+ test_schnorrsig_s2c_commit_verify ();
831
+ }
718
832
secp256k1_scratch_space_destroy (ctx , scratch );
719
833
}
720
834
0 commit comments