Skip to content

Commit

Permalink
toward ed25519 full Musig2
Browse files Browse the repository at this point in the history
  • Loading branch information
renaud dubois authored and renaud dubois committed Nov 27, 2024
1 parent 5ca5058 commit f176227
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 16 deletions.
29 changes: 19 additions & 10 deletions src/libMPC/SCL_Musig2.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ export class SCL_Musig2
Get_session_values(SessionContext){

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


Expand All @@ -313,8 +313,10 @@ export class SCL_Musig2

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


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


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

//partial signature
//secnonce: 97 bytes
//secnonce: 2 nonces + kpub
//sk: 32 bytes
//input session context: 'aggnonce','pubkeys', 'tweaks', 'is_xonly','msg'
Psign(secnonce, sk, session_ctx){

let k1= int_from_bytes(secnonce.slice(0, 32));
let k2= int_from_bytes(secnonce.slice(32, 64));

let session_values= this.Get_session_values(session_ctx);// (Q, gacc, _, b, R, e)


let Q=session_values[0];
let gacc=session_values[1];
let b=session_values[3];
let R=session_values[4];
let e=session_values[5];

console.log("R=",R);


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

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

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

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

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

//todo: optional partial verif
let psig=etc.numberToBytesBE(s,32);
let psig=int_to_bytes(s,32);

return psig;
}
Expand All @@ -391,6 +394,8 @@ Psign(secnonce, sk, session_ctx){
//operations are not constant time, not required as aggregation is a public function
Partial_sig_agg(psigs, session_ctx){
let sessionV=this.Get_session_values(session_ctx);//(Q, gacc, tacc, b, R, e)


let Q=sessionV[0];//aggnonce
let tacc=sessionV[2];

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


s = (s + e * g * tacc) % this.order;
s=Buffer.from(s.toString(16), 'hex');
s=int_to_bytes(s,32);

let R=this.curve.GetX(sessionV[4]);

console.log("R=",R);
console.log("from ",sessionV[4]);
console.log("s=",s, s.length);

return Buffer.concat([R,s]);

}
Expand Down
8 changes: 5 additions & 3 deletions src/libMPC/SCL_ecc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,10 @@ export class SCL_ecc
return bytes_Point.slice(1,33);
}
if (this.curve === 'ed25519') {
bytes_Point[0]=bytes_Point[0]&1;
return bytes_Point;
let cp=Buffer.from([...bytes_Point]);

cp[0]=cp[0]&0x7f;//force parity bit to 0
return cp;
}
}

Expand Down Expand Up @@ -140,7 +142,7 @@ export class SCL_ecc
return bytePoint.slice(1,33);//x-only version for noncegen
}
if(this.curve=='ed25519') {
bytePoint[0]=bytePoint[0]&0x7f;
bytePoint[0]=bytePoint[0]&0x7f;//nullify to force parity bit to 0
return bytePoint;
}

Expand Down
3 changes: 2 additions & 1 deletion src/libMPC/common.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ export function int_to_bytes(value, byteLength){
// Pad the result to the desired byte length (if specified)
if (byteLength && bytes.length < byteLength) {
const padding = new Uint8Array(byteLength - bytes.length);
return new Uint8Array([...padding, ...bytes]);
let res= new Uint8Array([...padding, ...bytes]);
return Buffer.from(res);
} else if (byteLength && bytes.length > byteLength) {
throw new Error(`BigInt does not fit in ${byteLength} bytes.`);
}
Expand Down
4 changes: 2 additions & 2 deletions src/libMPC/test_Musig2.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ function random_fullsession(Curve){
let psigs=[p1,p2];

let res=signer.Partial_sig_agg(psigs, session_ctx);
console.log("res=", res, res.length);
console.log("Aggregated signature=", res, res.length);

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

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

// random_fullsession('ed25519');
random_fullsession('ed25519');


})();

0 comments on commit f176227

Please sign in to comment.