arnaucube
arnaucube/circomlibPublic Self-hosted repository
circomlib/src/eddsa.js
src/eddsa.jsRaw
  1const createBlakeHash = require("blake-hash");
  2const bigInt = require("snarkjs").bigInt;
  3const babyJub = require("./babyjub");
  4const pedersenHash = require("./pedersenHash").hash;
  5const mimc7 = require("./mimc7");
  6
  7exports.prv2pub= prv2pub;
  8exports.sign = sign;
  9exports.signMiMC = signMiMC;
 10exports.verify = verify;
 11exports.verifyMiMC = verifyMiMC;
 12exports.packSignature = packSignature;
 13exports.unpackSignature = unpackSignature;
 14exports.pruneBuffer = pruneBuffer;
 15
 16
 17function pruneBuffer(_buff) {
 18    const buff = Buffer.from(_buff);
 19    buff[0] = buff[0] & 0xF8;
 20    buff[31] = buff[31] & 0x7F;
 21    buff[31] = buff[31] | 0x40;
 22    return buff;
 23}
 24
 25function prv2pub(prv) {
 26    const sBuff = pruneBuffer(createBlakeHash("blake512").update(prv).digest().slice(0,32));
 27    let s = bigInt.leBuff2int(sBuff);
 28    const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
 29    return A;
 30}
 31
 32function sign(prv, msg) {
 33    const h1 = createBlakeHash("blake512").update(prv).digest();
 34    const sBuff = pruneBuffer(h1.slice(0,32));
 35    const s = bigInt.leBuff2int(sBuff);
 36    const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
 37
 38    const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msg])).digest();
 39    let r = bigInt.leBuff2int(rBuff);
 40    r = r.mod(babyJub.subOrder);
 41    const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
 42    const R8p = babyJub.packPoint(R8);
 43    const Ap = babyJub.packPoint(A);
 44    const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
 45    const hm = bigInt.leBuff2int(hmBuff);
 46    const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
 47    return {
 48        R8: R8,
 49        S: S
 50    };
 51}
 52
 53function signMiMC(prv, msg) {
 54    const h1 = createBlakeHash("blake512").update(prv).digest();
 55    const sBuff = pruneBuffer(h1.slice(0,32));
 56    const s = bigInt.leBuff2int(sBuff);
 57    const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
 58
 59    const msgBuff = bigInt.leInt2Buff(msg, 32);
 60    const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
 61    let r = bigInt.leBuff2int(rBuff);
 62    r = r.mod(babyJub.subOrder);
 63    const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
 64    const hm = mimc7.multiHash([R8[0], R8[1], A[0], A[1], msg]);
 65    const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
 66    return {
 67        R8: R8,
 68        S: S
 69    };
 70}
 71
 72function verify(msg, sig, A) {
 73    // Check parameters
 74    if (typeof sig != "object") return false;
 75    if (!Array.isArray(sig.R8)) return false;
 76    if (sig.R8.length!= 2) return false;
 77    if (!babyJub.inCurve(sig.R8)) return false;
 78    if (!Array.isArray(A)) return false;
 79    if (A.length!= 2) return false;
 80    if (!babyJub.inCurve(A)) return false;
 81    if (sig.S>= babyJub.subOrder) return false;
 82
 83    const R8p = babyJub.packPoint(sig.R8);
 84    const Ap = babyJub.packPoint(A);
 85    const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
 86    const hm = bigInt.leBuff2int(hmBuff);
 87
 88    const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
 89    let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
 90    Pright = babyJub.addPoint(sig.R8, Pright);
 91
 92    if (!Pleft[0].equals(Pright[0])) return false;
 93    if (!Pleft[1].equals(Pright[1])) return false;
 94    return true;
 95}
 96
 97function verifyMiMC(msg, sig, A) {
 98    // Check parameters
 99    if (typeof sig != "object") return false;
100    if (!Array.isArray(sig.R8)) return false;
101    if (sig.R8.length!= 2) return false;
102    if (!babyJub.inCurve(sig.R8)) return false;
103    if (!Array.isArray(A)) return false;
104    if (A.length!= 2) return false;
105    if (!babyJub.inCurve(A)) return false;
106    if (sig.S>= babyJub.subOrder) return false;
107
108    const hm = mimc7.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
109
110    const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
111    let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
112    Pright = babyJub.addPoint(sig.R8, Pright);
113
114    if (!Pleft[0].equals(Pright[0])) return false;
115    if (!Pleft[1].equals(Pright[1])) return false;
116    return true;
117}
118
119function packSignature(sig) {
120    const R8p = babyJub.packPoint(sig.R8);
121    const Sp = bigInt.leInt2Buff(sig.S, 32);
122    return Buffer.concat([R8p, Sp]);
123}
124
125function unpackSignature(sigBuff) {
126    return {
127        R8: babyJub.unpackPoint(sigBuff.slice(0,32)),
128        S: bigInt.leBuff2int(sigBuff.slice(32,64))
129    };
130}
131
132