@@ -227,7 +227,7 @@ typedef struct {
227
227
const secp256k1_context * ctx ;
228
228
secp256k1_scalar idx ;
229
229
secp256k1_scalar idxn ;
230
- const secp256k1_pubkey * const * vss_commitment ;
230
+ const secp256k1_pubkey * vss_commitment ;
231
231
} secp256k1_frost_verify_share_ecmult_data ;
232
232
233
233
typedef struct {
@@ -245,9 +245,15 @@ typedef struct {
245
245
size_t n_pubshares ;
246
246
} secp256k1_frost_interpolate_pubkey_ecmult_data ;
247
247
248
+ typedef struct {
249
+ const secp256k1_context * ctx ;
250
+ size_t idxn ;
251
+ const secp256k1_pubkey * const * vss_commitments ;
252
+ } secp256k1_frost_vss_agg_ecmult_data ;
253
+
248
254
static int secp256k1_frost_verify_share_ecmult_callback (secp256k1_scalar * sc , secp256k1_ge * pt , size_t idx , void * data ) {
249
255
secp256k1_frost_verify_share_ecmult_data * ctx = (secp256k1_frost_verify_share_ecmult_data * ) data ;
250
- if (!secp256k1_pubkey_load (ctx -> ctx , pt , * ( ctx -> vss_commitment ) + idx )) {
256
+ if (!secp256k1_pubkey_load (ctx -> ctx , pt , & ctx -> vss_commitment [ idx ] )) {
251
257
return 0 ;
252
258
}
253
259
* sc = ctx -> idxn ;
@@ -288,8 +294,20 @@ static int secp256k1_frost_interpolate_pubkey_ecmult_callback(secp256k1_scalar *
288
294
return 1 ;
289
295
}
290
296
297
+ static int secp256k1_frost_vss_agg_pubkey_ecmult_callback (secp256k1_scalar * sc , secp256k1_ge * pt , size_t idx , void * data ) {
298
+ secp256k1_frost_vss_agg_ecmult_data * ctx = (secp256k1_frost_vss_agg_ecmult_data * ) data ;
299
+
300
+ if (!secp256k1_pubkey_load (ctx -> ctx , pt , & ctx -> vss_commitments [idx ][ctx -> idxn ])) {
301
+ return 0 ;
302
+ }
303
+
304
+ * sc = secp256k1_scalar_one ;
305
+
306
+ return 1 ;
307
+ }
308
+
291
309
/* See RFC 9591 */
292
- static int secp256k1_frost_vss_verify_internal (const secp256k1_context * ctx , size_t threshold , const unsigned char * id33 , const secp256k1_scalar * share , const secp256k1_pubkey * const * vss_commitment ) {
310
+ static int secp256k1_frost_vss_verify_internal (const secp256k1_context * ctx , size_t threshold , const unsigned char * id33 , const secp256k1_scalar * share , const secp256k1_pubkey * vss_commitment ) {
293
311
secp256k1_scalar share_neg ;
294
312
secp256k1_gej tmpj , snj ;
295
313
secp256k1_ge sng ;
@@ -319,7 +337,7 @@ static int secp256k1_frost_vss_verify_internal(const secp256k1_context* ctx, siz
319
337
return secp256k1_gej_is_infinity (& tmpj );
320
338
}
321
339
322
- int secp256k1_frost_share_verify (const secp256k1_context * ctx , size_t threshold , const unsigned char * id33 , const secp256k1_frost_share * share , const secp256k1_pubkey * const * vss_commitment ) {
340
+ int secp256k1_frost_share_verify (const secp256k1_context * ctx , size_t threshold , const unsigned char * id33 , const secp256k1_frost_share * share , const secp256k1_pubkey * vss_commitment ) {
323
341
secp256k1_scalar share_i ;
324
342
325
343
VERIFY_CHECK (ctx != NULL );
@@ -335,51 +353,73 @@ int secp256k1_frost_share_verify(const secp256k1_context* ctx, size_t threshold,
335
353
return secp256k1_frost_vss_verify_internal (ctx , threshold , id33 , & share_i , vss_commitment );
336
354
}
337
355
338
- int secp256k1_frost_compute_pubshare (const secp256k1_context * ctx , secp256k1_pubkey * pubshare , size_t threshold , const unsigned char * id33 , const secp256k1_pubkey * const * vss_commitments , size_t n_participants ) {
339
- secp256k1_gej pkj ;
356
+ int secp256k1_frost_compute_pubshare (const secp256k1_context * ctx , secp256k1_pubkey * pubshare , size_t threshold , const unsigned char * id33 , const secp256k1_pubkey * agg_vss_commitment , size_t n_participants ) {
357
+ secp256k1_gej tmpj ;
340
358
secp256k1_ge tmp ;
341
- secp256k1_frost_compute_pubshare_ecmult_data compute_pubshare_ecmult_data ;
359
+ secp256k1_frost_verify_share_ecmult_data verify_share_ecmult_data ;
342
360
343
361
VERIFY_CHECK (ctx != NULL );
362
+ ARG_CHECK (secp256k1_ecmult_gen_context_is_built (& ctx -> ecmult_gen_ctx ));
344
363
ARG_CHECK (pubshare != NULL );
345
364
memset (pubshare , 0 , sizeof (* pubshare ));
346
365
ARG_CHECK (id33 != NULL );
347
- ARG_CHECK (vss_commitments != NULL );
366
+ ARG_CHECK (agg_vss_commitment != NULL );
348
367
ARG_CHECK (n_participants > 1 );
349
368
ARG_CHECK (threshold > 1 );
350
369
351
370
if (threshold > n_participants ) {
352
371
return 0 ;
353
372
}
354
373
355
- /* Use an EC multi-multiplication to compute the following equation:
356
- * agg_share_i*G = (
357
- * idx^0*vss_commitment[0][0] + ...
358
- * + idx^(t - 1)*vss_commitment[0][t - 1]
359
- * ) + ...
360
- * + (
361
- * idx^0*vss_commitment[n - 1][0] + ...
362
- * + idx^(t - 1)*vss_commitment[n - 1][t - 1]
363
- * )*/
364
- compute_pubshare_ecmult_data .ctx = ctx ;
365
- compute_pubshare_ecmult_data .vss_commitments = vss_commitments ;
366
- compute_pubshare_ecmult_data .threshold = threshold ;
374
+ /* Use an EC multi-multiplication to verify the following equation:
375
+ * agg_share_i * G = idx^0*agg_vss_commitment[0]
376
+ * + ...
377
+ * + idx^(threshold - 1)*agg_vss_commitment[threshold - 1]*/
378
+ verify_share_ecmult_data .ctx = ctx ;
379
+ verify_share_ecmult_data .vss_commitment = agg_vss_commitment ;
367
380
/* Evaluate the public polynomial at the idx */
368
- if (!secp256k1_frost_compute_indexhash (& compute_pubshare_ecmult_data .idx , id33 )) {
381
+ if (!secp256k1_frost_compute_indexhash (& verify_share_ecmult_data .idx , id33 )) {
369
382
return 0 ;
370
383
}
371
- secp256k1_scalar_set_int (& compute_pubshare_ecmult_data .idxn , 1 );
384
+ secp256k1_scalar_set_int (& verify_share_ecmult_data .idxn , 1 );
372
385
/* TODO: add scratch */
373
- if (!secp256k1_ecmult_multi_var (& ctx -> error_callback , NULL , & pkj , NULL , secp256k1_frost_compute_pubshare_ecmult_callback , (void * ) & compute_pubshare_ecmult_data , n_participants * threshold )) {
386
+ if (!secp256k1_ecmult_multi_var (& ctx -> error_callback , NULL , & tmpj , NULL , secp256k1_frost_verify_share_ecmult_callback , (void * ) & verify_share_ecmult_data , threshold )) {
374
387
return 0 ;
375
388
}
376
- secp256k1_ge_set_gej (& tmp , & pkj );
389
+ secp256k1_ge_set_gej (& tmp , & tmpj );
377
390
secp256k1_pubkey_save (pubshare , & tmp );
378
391
379
392
return 1 ;
380
393
}
381
394
382
- int secp256k1_frost_share_agg (const secp256k1_context * ctx , secp256k1_frost_share * agg_share , const secp256k1_frost_share * const * shares , const secp256k1_pubkey * const * vss_commitments , const unsigned char * const * pok64s , size_t n_shares , size_t threshold , const unsigned char * id33 ) {
395
+ static int secp256k1_frost_vss_agg (const secp256k1_context * ctx , secp256k1_pubkey * agg_vss_commitment , const secp256k1_pubkey * const * vss_commitments , size_t n_participants , size_t threshold ) {
396
+ secp256k1_gej tmpj ;
397
+ secp256k1_ge tmp ;
398
+ secp256k1_frost_vss_agg_ecmult_data vss_agg_ecmult_data ;
399
+
400
+ VERIFY_CHECK (ctx != NULL );
401
+ ARG_CHECK (secp256k1_ecmult_gen_context_is_built (& ctx -> ecmult_gen_ctx ));
402
+ ARG_CHECK (agg_vss_commitment != NULL );
403
+ ARG_CHECK (vss_commitments != NULL );
404
+ ARG_CHECK (n_participants > 1 );
405
+ ARG_CHECK (threshold > 1 );
406
+
407
+ vss_agg_ecmult_data .ctx = ctx ;
408
+ vss_agg_ecmult_data .vss_commitments = vss_commitments ;
409
+
410
+ for (vss_agg_ecmult_data .idxn = 0 ; vss_agg_ecmult_data .idxn < threshold ; vss_agg_ecmult_data .idxn ++ ) {
411
+ /* TODO: add scratch */
412
+ if (!secp256k1_ecmult_multi_var (& ctx -> error_callback , NULL , & tmpj , NULL , secp256k1_frost_vss_agg_pubkey_ecmult_callback , (void * ) & vss_agg_ecmult_data , n_participants )) {
413
+ return 0 ;
414
+ }
415
+ secp256k1_ge_set_gej (& tmp , & tmpj );
416
+ secp256k1_pubkey_save (& agg_vss_commitment [vss_agg_ecmult_data .idxn ], & tmp );
417
+ }
418
+
419
+ return 1 ;
420
+ }
421
+
422
+ int secp256k1_frost_share_agg (const secp256k1_context * ctx , secp256k1_frost_share * agg_share , secp256k1_pubkey * agg_vss_commitment , const secp256k1_frost_share * const * shares , const secp256k1_pubkey * const * vss_commitments , const unsigned char * const * pok64s , size_t n_shares , size_t threshold , const unsigned char * id33 ) {
383
423
secp256k1_scalar acc ;
384
424
size_t i ;
385
425
int ret = 1 ;
@@ -422,10 +462,13 @@ int secp256k1_frost_share_agg(const secp256k1_context* ctx, secp256k1_frost_shar
422
462
return 0 ;
423
463
}
424
464
/* Verify share against commitments */
425
- ret &= secp256k1_frost_vss_verify_internal (ctx , threshold , id33 , & share_i , & vss_commitments [i ]);
465
+ ret &= secp256k1_frost_vss_verify_internal (ctx , threshold , id33 , & share_i , vss_commitments [i ]);
426
466
secp256k1_scalar_add (& acc , & acc , & share_i );
427
467
}
428
468
secp256k1_frost_share_save (agg_share , & acc );
469
+ if (!secp256k1_frost_vss_agg (ctx , agg_vss_commitment , vss_commitments , n_shares , threshold )) {
470
+ return 0 ;
471
+ }
429
472
430
473
return ret ;
431
474
}
0 commit comments