@@ -93,4 +93,146 @@ static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *ms
93
93
94
94
const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340 = nonce_function_bip340 ;
95
95
96
+ /* Initializes SHA256 with fixed midstate. This midstate was computed by applying
97
+ * SHA256 to SHA256("BIP0340/challenge")||SHA256("BIP0340/challenge"). */
98
+ static void secp256k1_schnorrsig_sha256_tagged (secp256k1_sha256 * sha ) {
99
+ secp256k1_sha256_initialize (sha );
100
+ sha -> s [0 ] = 0x9cecba11ul ;
101
+ sha -> s [1 ] = 0x23925381ul ;
102
+ sha -> s [2 ] = 0x11679112ul ;
103
+ sha -> s [3 ] = 0xd1627e0ful ;
104
+ sha -> s [4 ] = 0x97c87550ul ;
105
+ sha -> s [5 ] = 0x003cc765ul ;
106
+ sha -> s [6 ] = 0x90f61164ul ;
107
+ sha -> s [7 ] = 0x33e9b66aul ;
108
+ sha -> bytes = 64 ;
109
+ }
110
+
111
+ int secp256k1_schnorrsig_sign (const secp256k1_context * ctx , unsigned char * sig64 , const unsigned char * msg32 , const secp256k1_keypair * keypair , secp256k1_nonce_function_hardened noncefp , void * ndata ) {
112
+ secp256k1_scalar sk ;
113
+ secp256k1_scalar e ;
114
+ secp256k1_scalar k ;
115
+ secp256k1_gej rj ;
116
+ secp256k1_ge pk ;
117
+ secp256k1_ge r ;
118
+ secp256k1_sha256 sha ;
119
+ unsigned char buf [32 ] = { 0 };
120
+ unsigned char pk_buf [32 ];
121
+ unsigned char seckey [32 ];
122
+ int ret = 1 ;
123
+
124
+ VERIFY_CHECK (ctx != NULL );
125
+ ARG_CHECK (secp256k1_ecmult_gen_context_is_built (& ctx -> ecmult_gen_ctx ));
126
+ ARG_CHECK (sig64 != NULL );
127
+ ARG_CHECK (msg32 != NULL );
128
+ ARG_CHECK (keypair != NULL );
129
+
130
+ if (noncefp == NULL ) {
131
+ noncefp = secp256k1_nonce_function_bip340 ;
132
+ }
133
+
134
+ ret &= secp256k1_keypair_load (ctx , & sk , & pk , keypair );
135
+ /* Because we are signing for a x-only pubkey, the secret key is negated
136
+ * before signing if the point corresponding to the secret key does not
137
+ * have an even Y. */
138
+ if (secp256k1_fe_is_odd (& pk .y )) {
139
+ secp256k1_scalar_negate (& sk , & sk );
140
+ }
141
+
142
+ secp256k1_scalar_get_b32 (seckey , & sk );
143
+ secp256k1_fe_get_b32 (pk_buf , & pk .x );
144
+ ret &= !!noncefp (buf , msg32 , seckey , pk_buf , bip340_algo16 , ndata );
145
+ secp256k1_scalar_set_b32 (& k , buf , NULL );
146
+ ret &= !secp256k1_scalar_is_zero (& k );
147
+ secp256k1_scalar_cmov (& k , & secp256k1_scalar_one , !ret );
148
+
149
+ secp256k1_ecmult_gen (& ctx -> ecmult_gen_ctx , & rj , & k );
150
+ secp256k1_ge_set_gej (& r , & rj );
151
+
152
+ /* We declassify r to allow using it as a branch point. This is fine
153
+ * because r is not a secret. */
154
+ secp256k1_declassify (ctx , & r , sizeof (r ));
155
+ secp256k1_fe_normalize_var (& r .y );
156
+ if (secp256k1_fe_is_odd (& r .y )) {
157
+ secp256k1_scalar_negate (& k , & k );
158
+ }
159
+ secp256k1_fe_normalize_var (& r .x );
160
+ secp256k1_fe_get_b32 (& sig64 [0 ], & r .x );
161
+
162
+ /* tagged hash(r.x, pk.x, msg32) */
163
+ secp256k1_schnorrsig_sha256_tagged (& sha );
164
+ secp256k1_sha256_write (& sha , & sig64 [0 ], 32 );
165
+ secp256k1_sha256_write (& sha , pk_buf , sizeof (pk_buf ));
166
+ secp256k1_sha256_write (& sha , msg32 , 32 );
167
+ secp256k1_sha256_finalize (& sha , buf );
168
+
169
+ /* Set scalar e to the challenge hash modulo the curve order as per
170
+ * BIP340. */
171
+ secp256k1_scalar_set_b32 (& e , buf , NULL );
172
+ secp256k1_scalar_mul (& e , & e , & sk );
173
+ secp256k1_scalar_add (& e , & e , & k );
174
+ secp256k1_scalar_get_b32 (& sig64 [32 ], & e );
175
+
176
+ memczero (sig64 , 64 , !ret );
177
+ secp256k1_scalar_clear (& k );
178
+ secp256k1_scalar_clear (& sk );
179
+ memset (seckey , 0 , sizeof (seckey ));
180
+
181
+ return ret ;
182
+ }
183
+
184
+ int secp256k1_schnorrsig_verify (const secp256k1_context * ctx , const unsigned char * sig64 , const unsigned char * msg32 , const secp256k1_xonly_pubkey * pubkey ) {
185
+ secp256k1_scalar s ;
186
+ secp256k1_scalar e ;
187
+ secp256k1_gej rj ;
188
+ secp256k1_ge pk ;
189
+ secp256k1_gej pkj ;
190
+ secp256k1_fe rx ;
191
+ secp256k1_ge r ;
192
+ secp256k1_sha256 sha ;
193
+ unsigned char buf [32 ];
194
+ int overflow ;
195
+
196
+ VERIFY_CHECK (ctx != NULL );
197
+ ARG_CHECK (secp256k1_ecmult_context_is_built (& ctx -> ecmult_ctx ));
198
+ ARG_CHECK (sig64 != NULL );
199
+ ARG_CHECK (msg32 != NULL );
200
+ ARG_CHECK (pubkey != NULL );
201
+
202
+ if (!secp256k1_fe_set_b32 (& rx , & sig64 [0 ])) {
203
+ return 0 ;
204
+ }
205
+
206
+ secp256k1_scalar_set_b32 (& s , & sig64 [32 ], & overflow );
207
+ if (overflow ) {
208
+ return 0 ;
209
+ }
210
+
211
+ if (!secp256k1_xonly_pubkey_load (ctx , & pk , pubkey )) {
212
+ return 0 ;
213
+ }
214
+
215
+ secp256k1_schnorrsig_sha256_tagged (& sha );
216
+ secp256k1_sha256_write (& sha , & sig64 [0 ], 32 );
217
+ secp256k1_fe_get_b32 (buf , & pk .x );
218
+ secp256k1_sha256_write (& sha , buf , sizeof (buf ));
219
+ secp256k1_sha256_write (& sha , msg32 , 32 );
220
+ secp256k1_sha256_finalize (& sha , buf );
221
+ secp256k1_scalar_set_b32 (& e , buf , NULL );
222
+
223
+ /* Compute rj = s*G + (-e)*pkj */
224
+ secp256k1_scalar_negate (& e , & e );
225
+ secp256k1_gej_set_ge (& pkj , & pk );
226
+ secp256k1_ecmult (& ctx -> ecmult_ctx , & rj , & pkj , & e , & s );
227
+
228
+ secp256k1_ge_set_gej_var (& r , & rj );
229
+ if (secp256k1_ge_is_infinity (& r )) {
230
+ return 0 ;
231
+ }
232
+
233
+ secp256k1_fe_normalize_var (& r .y );
234
+ return !secp256k1_fe_is_odd (& r .y ) &&
235
+ secp256k1_fe_equal_var (& rx , & r .x );
236
+ }
237
+
96
238
#endif
0 commit comments