@@ -203,42 +203,54 @@ int secp256k1_frost_partial_sig_parse(const secp256k1_context* ctx, secp256k1_fr
203203 return 1 ;
204204}
205205
206+ /* Write optional inputs into the hash */
207+ static void secp256k1_nonce_function_frost_helper (secp256k1_sha256 * sha , unsigned int prefix_size , const unsigned char * data32 ) {
208+ /* The spec requires length prefix to be 4 bytes for `extra_in`, 1 byte
209+ * otherwise */
210+ VERIFY_CHECK (prefix_size == 4 || prefix_size == 1 );
211+ if (prefix_size == 4 ) {
212+ /* Four byte big-endian value, pad first three bytes with 0 */
213+ unsigned char zero [3 ] = {0 };
214+ secp256k1_sha256_write (sha , zero , 3 );
215+ }
216+ if (data32 != NULL ) {
217+ unsigned char len = 32 ;
218+ secp256k1_sha256_write (sha , & len , 1 );
219+ secp256k1_sha256_write (sha , data32 , 32 );
220+ } else {
221+ unsigned char len = 0 ;
222+ secp256k1_sha256_write (sha , & len , 1 );
223+ }
224+ }
225+
206226static void secp256k1_nonce_function_frost (secp256k1_scalar * k , const unsigned char * session_id , const unsigned char * msg32 , const unsigned char * key32 , const unsigned char * pk32 , const unsigned char * extra_input32 ) {
207227 secp256k1_sha256 sha ;
208- unsigned char seed [32 ];
228+ unsigned char rand [32 ];
209229 unsigned char i ;
210- enum { n_extra_in = 4 };
211- const unsigned char * extra_in [n_extra_in ];
212230
213- /* TODO: this doesn't have the same sidechannel resistance as the BIP340
214- * nonce function because the seckey feeds directly into SHA. */
231+ if (key32 != NULL ) {
232+ secp256k1_sha256_initialize_tagged (& sha , (unsigned char * )"FROST/aux" , sizeof ("FROST/aux" ) - 1 );
233+ secp256k1_sha256_write (& sha , session_id , 32 );
234+ secp256k1_sha256_finalize (& sha , rand );
235+ for (i = 0 ; i < 32 ; i ++ ) {
236+ rand [i ] ^= key32 [i ];
237+ }
238+ } else {
239+ memcpy (rand , session_id , sizeof (rand ));
240+ }
215241
216242 /* Subtract one from `sizeof` to avoid hashing the implicit null byte */
217243 secp256k1_sha256_initialize_tagged (& sha , (unsigned char * )"FROST/nonce" , sizeof ("FROST/nonce" ) - 1 );
218- secp256k1_sha256_write (& sha , session_id , 32 );
219- extra_in [0 ] = msg32 ;
220- extra_in [1 ] = key32 ;
221- extra_in [2 ] = pk32 ;
222- extra_in [3 ] = extra_input32 ;
223- for (i = 0 ; i < n_extra_in ; i ++ ) {
224- unsigned char len ;
225- if (extra_in [i ] != NULL ) {
226- len = 32 ;
227- secp256k1_sha256_write (& sha , & len , 1 );
228- secp256k1_sha256_write (& sha , extra_in [i ], 32 );
229- } else {
230- len = 0 ;
231- secp256k1_sha256_write (& sha , & len , 1 );
232- }
233- }
234- secp256k1_sha256_finalize (& sha , seed );
244+ secp256k1_sha256_write (& sha , rand , sizeof (rand ));
245+ secp256k1_nonce_function_frost_helper (& sha , 1 , pk32 );
246+ secp256k1_nonce_function_frost_helper (& sha , 1 , msg32 );
247+ secp256k1_nonce_function_frost_helper (& sha , 4 , extra_input32 );
235248
236249 for (i = 0 ; i < 2 ; i ++ ) {
237250 unsigned char buf [32 ];
238- secp256k1_sha256_initialize (& sha );
239- secp256k1_sha256_write (& sha , seed , 32 );
240- secp256k1_sha256_write (& sha , & i , sizeof (i ));
241- secp256k1_sha256_finalize (& sha , buf );
251+ secp256k1_sha256 sha_tmp = sha ;
252+ secp256k1_sha256_write (& sha_tmp , & i , 1 );
253+ secp256k1_sha256_finalize (& sha_tmp , buf );
242254 secp256k1_scalar_set_b32 (& k [i ], buf , NULL );
243255 }
244256}
0 commit comments