Skip to content

Commit f5cd168

Browse files
renaud duboisrenaud dubois
authored andcommitted
toward ed25519 full Musig2
1 parent 461cfed commit f5cd168

File tree

4 files changed

+28
-16
lines changed

4 files changed

+28
-16
lines changed

src/libMPC/SCL_Musig2.mjs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ export class SCL_Musig2
296296
Get_session_values(SessionContext){
297297

298298
let aggnonce=SessionContext[0];
299-
if(aggnonce.length!=66) return false;
299+
if(aggnonce.length!=2*this.RawBytesSize) return false;
300300
let keyagg_ctx=this.Key_agg_and_tweak(SessionContext[1], SessionContext[2], SessionContext[3] );//Q, gacc, tacc
301301

302302

@@ -313,8 +313,10 @@ export class SCL_Musig2
313313

314314
let RCompressed=this.curve.PointCompress(R);
315315

316+
316317
let e=this.TagHashChallenge('BIP0340/challenge', this.curve.GetX(RCompressed), this.curve.GetX(keyagg_ctx[0]), SessionContext[4])
317318
e=int_from_bytes(e) % this.order;
319+
318320

319321
return [keyagg_ctx[0], keyagg_ctx[1], keyagg_ctx[2], b, RCompressed, e];//(Q, gacc, tacc, b, R, e)
320322
}
@@ -333,22 +335,23 @@ Mulmod(a,b){
333335
}
334336

335337
//partial signature
336-
//secnonce: 97 bytes
338+
//secnonce: 2 nonces + kpub
337339
//sk: 32 bytes
338340
//input session context: 'aggnonce','pubkeys', 'tweaks', 'is_xonly','msg'
339341
Psign(secnonce, sk, session_ctx){
340342

341343
let k1= int_from_bytes(secnonce.slice(0, 32));
342344
let k2= int_from_bytes(secnonce.slice(32, 64));
343-
345+
344346
let session_values= this.Get_session_values(session_ctx);// (Q, gacc, _, b, R, e)
347+
348+
345349
let Q=session_values[0];
346350
let gacc=session_values[1];
347351
let b=session_values[3];
348352
let R=session_values[4];
349353
let e=session_values[5];
350-
351-
console.log("R=",R);
354+
352355

353356
//todo : test range of k1 and k2
354357
if (this.curve.Has_even_y(R)==false)
@@ -361,15 +364,15 @@ Psign(secnonce, sk, session_ctx){
361364

362365
let G= this.curve.GetBase();
363366
let P = (G.multiply(d_));//should be equal to pk
364-
let secnonce_pk=secnonce.slice(64, 64+this.RawBytesSize);//pk is part of secnonce, 33 bytes
367+
let secnonce_pk=secnonce.slice(64, 64+this.RawBytesSize);//pk is part of secnonce, 32 or 33 bytes
365368
let Q3=this.curve.PointDecompress(secnonce_pk);
366369

367370
//todo test x equality
368371
if(this.curve.EqualsX(P,Q3)==false){
369372
return false;//wrong public key
370373
}
371374

372-
let a=this.Get_session_key_agg_coeff(session_ctx[1], secnonce.slice(64, 97));
375+
let a=this.Get_session_key_agg_coeff(session_ctx[1], secnonce.slice(64, 64+this.RawBytesSize));
373376

374377
let g=BigInt('0x1') ;
375378
if(this.curve.Has_even_y(Q)==false){//this line ensures the compatibility with requirement that aggregated key is even in verification
@@ -382,7 +385,7 @@ Psign(secnonce, sk, session_ctx){
382385
s= (s+ this.Mulmod(this.Mulmod(e , a) , d))% this.order;
383386

384387
//todo: optional partial verif
385-
let psig=etc.numberToBytesBE(s,32);
388+
let psig=int_to_bytes(s,32);
386389

387390
return psig;
388391
}
@@ -391,6 +394,8 @@ Psign(secnonce, sk, session_ctx){
391394
//operations are not constant time, not required as aggregation is a public function
392395
Partial_sig_agg(psigs, session_ctx){
393396
let sessionV=this.Get_session_values(session_ctx);//(Q, gacc, tacc, b, R, e)
397+
398+
394399
let Q=sessionV[0];//aggnonce
395400
let tacc=sessionV[2];
396401

@@ -411,9 +416,13 @@ Psign(secnonce, sk, session_ctx){
411416

412417

413418
s = (s + e * g * tacc) % this.order;
414-
s=Buffer.from(s.toString(16), 'hex');
419+
s=int_to_bytes(s,32);
420+
415421
let R=this.curve.GetX(sessionV[4]);
416-
422+
console.log("R=",R);
423+
console.log("from ",sessionV[4]);
424+
console.log("s=",s, s.length);
425+
417426
return Buffer.concat([R,s]);
418427

419428
}

src/libMPC/SCL_ecc.mjs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,10 @@ export class SCL_ecc
7474
return bytes_Point.slice(1,33);
7575
}
7676
if (this.curve === 'ed25519') {
77-
bytes_Point[0]=bytes_Point[0]&1;
78-
return bytes_Point;
77+
let cp=Buffer.from([...bytes_Point]);
78+
79+
cp[0]=cp[0]&0x7f;//force parity bit to 0
80+
return cp;
7981
}
8082
}
8183

@@ -140,7 +142,7 @@ export class SCL_ecc
140142
return bytePoint.slice(1,33);//x-only version for noncegen
141143
}
142144
if(this.curve=='ed25519') {
143-
bytePoint[0]=bytePoint[0]&0x7f;
145+
bytePoint[0]=bytePoint[0]&0x7f;//nullify to force parity bit to 0
144146
return bytePoint;
145147
}
146148

src/libMPC/common.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ export function int_to_bytes(value, byteLength){
5151
// Pad the result to the desired byte length (if specified)
5252
if (byteLength && bytes.length < byteLength) {
5353
const padding = new Uint8Array(byteLength - bytes.length);
54-
return new Uint8Array([...padding, ...bytes]);
54+
let res= new Uint8Array([...padding, ...bytes]);
55+
return Buffer.from(res);
5556
} else if (byteLength && bytes.length > byteLength) {
5657
throw new Error(`BigInt does not fit in ${byteLength} bytes.`);
5758
}

src/libMPC/test_Musig2.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ function random_fullsession(Curve){
372372
let psigs=[p1,p2];
373373

374374
let res=signer.Partial_sig_agg(psigs, session_ctx);
375-
console.log("res=", res, res.length);
375+
console.log("Aggregated signature=", res, res.length);
376376

377377
console.log(" -Final Schnorr verify:");
378378

@@ -398,7 +398,7 @@ function random_fullsession(Curve){
398398
/* test full session */
399399
random_fullsession('secp256k1');
400400

401-
// random_fullsession('ed25519');
401+
random_fullsession('ed25519');
402402

403403

404404
})();

0 commit comments

Comments
 (0)