arnaucube
arnaucube/circomlibPublic Self-hosted repository
circomlib/src/eddsa.js
src/eddsa.jsRaw
  1const createBlakeHash = require("blake-hash");
  2const bigInt = require("big-integer");
  3const babyJub = require("./babyjub");
  4const utils = require("./utils");
  5const pedersenHash = require("./pedersenHash").hash;
  6const mimc7 = require("./mimc7");
  7const poseidon = require("./poseidon.js");
  8const mimcsponge = require("./mimcsponge");
  9
 10
 11exports.prv2pub= prv2pub;
 12exports.sign = sign;
 13exports.signMiMC = signMiMC;
 14exports.signPoseidon = signPoseidon;
 15exports.signMiMCSponge = signMiMCSponge;
 16exports.verify = verify;
 17exports.verifyMiMC = verifyMiMC;
 18exports.verifyPoseidon = verifyPoseidon;
 19exports.verifyMiMCSponge = verifyMiMCSponge;
 20exports.packSignature = packSignature;
 21exports.unpackSignature = unpackSignature;
 22exports.pruneBuffer = pruneBuffer;
 23
 24
 25function pruneBuffer(_buff) {
 26    const buff = Buffer.from(_buff);
 27    buff[0] = buff[0] & 0xF8;
 28    buff[31] = buff[31] & 0x7F;
 29    buff[31] = buff[31] | 0x40;
 30    return buff;
 31}
 32
 33function prv2pub(prv) {
 34    const sBuff = pruneBuffer(createBlakeHash("blake512").update(prv).digest().slice(0,32));
 35    let s = utils.leBuff2int(sBuff);
 36    const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));
 37    return A;
 38}
 39
 40function sign(prv, msg) {
 41    const h1 = createBlakeHash("blake512").update(prv).digest();
 42    const sBuff = pruneBuffer(h1.slice(0,32));
 43    const s = utils.leBuff2int(sBuff);
 44    const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));
 45
 46    const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msg])).digest();
 47    let r = utils.leBuff2int(rBuff);
 48    r = r.mod(babyJub.subOrder);
 49    const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
 50    const R8p = babyJub.packPoint(R8);
 51    const Ap = babyJub.packPoint(A);
 52    const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
 53    const hm = utils.leBuff2int(hmBuff);
 54    const S = r.add(hm.times(s)).mod(babyJub.subOrder);
 55    return {
 56        R8: R8,
 57        S: S
 58    };
 59}
 60
 61function signMiMC(prv, msg) {
 62    const h1 = createBlakeHash("blake512").update(prv).digest();
 63    const sBuff = pruneBuffer(h1.slice(0,32));
 64    const s = utils.leBuff2int(sBuff);
 65    const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));
 66
 67    const msgBuff = utils.leInt2Buff(msg, 32);
 68    const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
 69    let r = utils.leBuff2int(rBuff);
 70    r = r.mod(babyJub.subOrder);
 71    const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
 72    const hm = mimc7.multiHash([R8[0], R8[1], A[0], A[1], msg]);
 73    const S = r.add(hm.times(s)).mod(babyJub.subOrder);
 74    return {
 75        R8: R8,
 76        S: S
 77    };
 78}
 79
 80function signMiMCSponge(prv, msg) {
 81    const h1 = createBlakeHash("blake512").update(prv).digest();
 82    const sBuff = pruneBuffer(h1.slice(0,32));
 83    const s = utils.leBuff2int(sBuff);
 84    const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));
 85
 86    const msgBuff = utils.leInt2Buff(msg, 32);
 87    const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
 88    let r = utils.leBuff2int(rBuff);
 89    r = r.mod(babyJub.subOrder);
 90    const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
 91    const hm = mimcsponge.multiHash([R8[0], R8[1], A[0], A[1], msg]);
 92    const S = r.add(hm.times(s)).mod(babyJub.subOrder);
 93    return {
 94        R8: R8,
 95        S: S
 96    };
 97}
 98
 99function signPoseidon(prv, msg) {
100    const h1 = createBlakeHash("blake512").update(prv).digest();
101    const sBuff = pruneBuffer(h1.slice(0,32));
102    const s = utils.leBuff2int(sBuff);
103    const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));
104
105    const msgBuff = utils.leInt2Buff(msg, 32);
106    const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
107    let r = utils.leBuff2int(rBuff);
108    r = r.mod(babyJub.subOrder);
109    const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
110    const hash = poseidon.createHash(6, 8, 57);
111    const hm = hash([R8[0], R8[1], A[0], A[1], msg]);
112    const S = r.add(hm.times(s)).mod(babyJub.subOrder);
113    return {
114        R8: R8,
115        S: S
116    };
117}
118
119function verify(msg, sig, A) {
120    // Check parameters
121    if (typeof sig != "object") return false;
122    if (!Array.isArray(sig.R8)) return false;
123    if (sig.R8.length!= 2) return false;
124    if (!babyJub.inCurve(sig.R8)) return false;
125    if (!Array.isArray(A)) return false;
126    if (A.length!= 2) return false;
127    if (!babyJub.inCurve(A)) return false;
128    if (sig.S>= babyJub.subOrder) return false;
129
130    const R8p = babyJub.packPoint(sig.R8);
131    const Ap = babyJub.packPoint(A);
132    const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
133    const hm = utils.leBuff2int(hmBuff);
134
135    const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
136    let Pright = babyJub.mulPointEscalar(A, hm.times(bigInt("8")));
137    Pright = babyJub.addPoint(sig.R8, Pright);
138
139    if (!Pleft[0].equals(Pright[0])) return false;
140    if (!Pleft[1].equals(Pright[1])) return false;
141    return true;
142}
143
144function verifyMiMC(msg, sig, A) {
145    // Check parameters
146    if (typeof sig != "object") return false;
147    if (!Array.isArray(sig.R8)) return false;
148    if (sig.R8.length!= 2) return false;
149    if (!babyJub.inCurve(sig.R8)) return false;
150    if (!Array.isArray(A)) return false;
151    if (A.length!= 2) return false;
152    if (!babyJub.inCurve(A)) return false;
153    if (sig.S>= babyJub.subOrder) return false;
154
155    const hm = mimc7.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
156
157    const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
158    let Pright = babyJub.mulPointEscalar(A, hm.times(bigInt("8")));
159    Pright = babyJub.addPoint(sig.R8, Pright);
160
161    if (!Pleft[0].equals(Pright[0])) return false;
162    if (!Pleft[1].equals(Pright[1])) return false;
163    return true;
164}
165
166
167function verifyPoseidon(msg, sig, A) {
168    // Check parameters
169    if (typeof sig != "object") return false;
170    if (!Array.isArray(sig.R8)) return false;
171    if (sig.R8.length!= 2) return false;
172    if (!babyJub.inCurve(sig.R8)) return false;
173    if (!Array.isArray(A)) return false;
174    if (A.length!= 2) return false;
175    if (!babyJub.inCurve(A)) return false;
176    if (sig.S>= babyJub.subOrder) return false;
177
178    const hash = poseidon.createHash(6, 8, 57);
179    const hm = hash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
180
181    const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
182    let Pright = babyJub.mulPointEscalar(A, hm.times(bigInt("8")));
183    Pright = babyJub.addPoint(sig.R8, Pright);
184
185    if (!Pleft[0].equals(Pright[0])) return false;
186    if (!Pleft[1].equals(Pright[1])) return false;
187    return true;
188}
189
190function verifyMiMCSponge(msg, sig, A) {
191    // Check parameters
192    if (typeof sig != "object") return false;
193    if (!Array.isArray(sig.R8)) return false;
194    if (sig.R8.length!= 2) return false;
195    if (!babyJub.inCurve(sig.R8)) return false;
196    if (!Array.isArray(A)) return false;
197    if (A.length!= 2) return false;
198    if (!babyJub.inCurve(A)) return false;
199    if (sig.S>= babyJub.subOrder) return false;
200
201    const hm = mimcsponge.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
202
203    const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
204    let Pright = babyJub.mulPointEscalar(A, hm.times(bigInt("8")));
205    Pright = babyJub.addPoint(sig.R8, Pright);
206
207    if (!Pleft[0].equals(Pright[0])) return false;
208    if (!Pleft[1].equals(Pright[1])) return false;
209    return true;
210}
211
212function packSignature(sig) {
213    const R8p = babyJub.packPoint(sig.R8);
214    const Sp = utils.leInt2Buff(sig.S, 32);
215    return Buffer.concat([R8p, Sp]);
216}
217
218function unpackSignature(sigBuff) {
219    return {
220        R8: babyJub.unpackPoint(sigBuff.slice(0,32)),
221        S: utils.leBuff2int(sigBuff.slice(32,64))
222    };
223}
224
225