snarkjs/src/mpc_applykey.js

124 lines
3.4 KiB
JavaScript
Raw Normal View History

2020-05-15 21:30:37 +02:00
const buildTaskManager = require("./taskmanager");
/*
This function creates a new section in the fdTo file with id idSection.
It multiplies the pooints in fdFrom by first, first*inc, first*inc^2, ....
nPoint Times.
It also updates the newChallangeHasher with the new points
*/
async function applyKey(params) {
const {
fdFrom,
sections,
curve,
fdTo,
sectionId,
NPoints,
G:Gs,
first,
inc,
newChallangeHasher,
responseHasher,
returnPoints,
sectionName,
verbose
} = params;
const G = curve[Gs];
const MAX_CHUNK_SIZE = 1024;
let res = [];
const sG = G.F.n8*2;
2020-05-26 18:45:49 +02:00
const buffUv = new Uint8Array(sG);
2020-05-15 21:30:37 +02:00
const scG = G.F.n8;
2020-05-26 18:45:49 +02:00
const buffCv = new Uint8Array(scG);
2020-05-15 21:30:37 +02:00
const taskManager = await buildTaskManager(contributeThread, {
ffjavascript: "ffjavascript"
},{
curve: curve.name
});
fdFrom.pos = sections[sectionId][0].p;
await fdTo.writeULE32(sectionId); // tauG1
const pSection = fdTo.pos;
await fdTo.writeULE64(0); // Temporally set to 0 length
let t = first;
let writePointer = fdTo.pos;
let beginWritePointer = fdTo.pos;
for (let i=0; i< NPoints; i+=MAX_CHUNK_SIZE) {
if ((verbose)&&i) console.log(`${sectionName}: ` + i);
const n = Math.min(NPoints - i, MAX_CHUNK_SIZE);
const buff = await fdFrom.read(n*sG);
await taskManager.addTask({
cmd: "MUL",
G: Gs,
first: t,
inc: inc.toString(),
buff: buff.slice(),
n: n,
writePos: writePointer
}, async function(r) {
return await fdTo.write(r.buff, r.writePos);
});
t = curve.Fr.mul(t, curve.Fr.pow(inc, n));
writePointer += n*sG;
}
await taskManager.finish();
const sSize = fdTo.pos - pSection -8;
const lastPos = fdTo.pos;
await fdTo.writeULE64(sSize, pSection);
fdTo.pos = lastPos;
fdTo.pos = beginWritePointer;
for (let i=0; i<NPoints; i++) {
const buff = await fdTo.read(sG);
const P = G.fromRprLEM(buff, 0);
2020-05-26 18:45:49 +02:00
G.toRprBE(buffUv, 0, P);
2020-05-15 21:30:37 +02:00
newChallangeHasher.update(buffUv);
2020-05-26 18:45:49 +02:00
G.toRprCompressed(buffCv, 0, P);
2020-05-15 21:30:37 +02:00
responseHasher.update(buffCv);
const idx = returnPoints.indexOf(i);
if (idx>=0) res[idx] = P;
}
return res;
}
function contributeThread(ctx, task) {
if (task.cmd == "INIT") {
ctx.assert = ctx.modules.assert;
if (task.curve == "bn128") {
ctx.curve = ctx.modules.ffjavascript.bn128;
} else {
ctx.assert(false, "curve not defined");
}
return {};
} else if (task.cmd == "MUL") {
const G = ctx.curve[task.G];
const sG = G.F.n64*8*2;
2020-05-26 18:45:49 +02:00
const buffDest = new Uint8Array(sG*task.n);
2020-05-15 21:30:37 +02:00
let t = ctx.curve.Fr.e(task.first);
let inc = ctx.curve.Fr.e(task.inc);
for (let i=0; i<task.n; i++) {
const P = G.fromRprLEM(task.buff, i*sG);
const R = G.mulScalar(P, t);
G.toRprLEM(buffDest, i*sG, R); // Main thread will convert it to Montgomery
t = ctx.curve.Fr.mul(t, inc);
}
return {
buff: buffDest,
writePos: task.writePos
};
} else {
ctx.assert(false, "Op not implemented");
}
}
module.exports = applyKey;