mirror of
https://github.com/arnaucube/websnark.git
synced 2026-02-27 21:46:42 +01:00
Initial commit
This commit is contained in:
240
tools/buildpkey.js
Normal file
240
tools/buildpkey.js
Normal file
@@ -0,0 +1,240 @@
|
||||
const {unstringifyBigInts} = require("./stringifybigint.js");
|
||||
const fs = require("fs");
|
||||
const bigInt = require("big-integer");
|
||||
const assert = require("assert");
|
||||
|
||||
const version = require("../package").version;
|
||||
|
||||
const argv = require("yargs")
|
||||
.version(version)
|
||||
.usage(`node buildpkey.js -i "proving_key.json" -o "proving_key.bin"
|
||||
Default: circuit.json
|
||||
`)
|
||||
.alias("i", "input")
|
||||
.alias("o", "output")
|
||||
.help("h")
|
||||
.alias("h", "help")
|
||||
.epilogue(`Copyright (C) 2018 0kims association
|
||||
This program comes with ABSOLUTELY NO WARRANTY;
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; see the COPYING file in the official
|
||||
repo directory at https://github.com/iden3/circom `)
|
||||
.argv;
|
||||
|
||||
const inputName = (argv.input) ? argv.input : "proving_key.json";
|
||||
const outputName = (argv.output) ? argv.output : "proving_key.bin";
|
||||
|
||||
|
||||
const provingKey = unstringifyBigInts(JSON.parse(fs.readFileSync(inputName, "utf8")));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function writeUint32(h, val) {
|
||||
h.dataView.setUint32(h.offset, val, true);
|
||||
h.offset += 4;
|
||||
}
|
||||
|
||||
function writeUint32ToPointer(h, p, val) {
|
||||
h.dataView.setUint32(p, val, true);
|
||||
}
|
||||
|
||||
|
||||
function alloc(h, n) {
|
||||
const o = h.offset;
|
||||
h.offset += n;
|
||||
return o;
|
||||
}
|
||||
|
||||
function writeBigInt(h, bi) {
|
||||
for (let i=0; i<8; i++) {
|
||||
const v = bi.shiftRight(i*32).and(0xFFFFFFFF).toJSNumber();
|
||||
writeUint32(h, v);
|
||||
}
|
||||
}
|
||||
|
||||
function toMontgomeryQ(p) {
|
||||
const q = bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583");
|
||||
return p.times(bigInt.one.shiftLeft(256)).mod(q);
|
||||
}
|
||||
|
||||
function toMontgomeryR(p) {
|
||||
const r = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
return p.times(bigInt.one.shiftLeft(256)).mod(r);
|
||||
}
|
||||
|
||||
function writePoint(h, p) {
|
||||
writeBigInt(h, toMontgomeryQ(p[0]));
|
||||
writeBigInt(h, toMontgomeryQ(p[1]));
|
||||
}
|
||||
|
||||
function writePoint2(h, p) {
|
||||
writeBigInt(h, toMontgomeryQ(p[0][0]));
|
||||
writeBigInt(h, toMontgomeryQ(p[0][1]));
|
||||
writeBigInt(h, toMontgomeryQ(p[1][0]));
|
||||
writeBigInt(h, toMontgomeryQ(p[1][1]));
|
||||
}
|
||||
|
||||
function writeTransformedPolynomial(h, p) {
|
||||
|
||||
const keys = Object.keys(p);
|
||||
|
||||
writeUint32(h, keys.length);
|
||||
|
||||
for (let i=0; i<keys.length; i++) {
|
||||
writeUint32(h, keys[i]);
|
||||
writeBigInt(h, toMontgomeryR(p[keys[i]]));
|
||||
}
|
||||
}
|
||||
|
||||
function calculateBuffLen(provingKey) {
|
||||
function polSize(pol) {
|
||||
const l= Object.keys(pol).length;
|
||||
return 36*l + 4;
|
||||
}
|
||||
|
||||
let size = 40;
|
||||
|
||||
// alfa1, beta1, delta1
|
||||
size += 3 * (32*2);
|
||||
|
||||
// beta2, delta2
|
||||
size += 2 * (32*4);
|
||||
|
||||
for (let i=0; i<provingKey.nVars; i++) {
|
||||
size += polSize(provingKey.polsA[i]);
|
||||
size += polSize(provingKey.polsB[i]);
|
||||
}
|
||||
|
||||
size += provingKey.nVars* (32*2);
|
||||
size += provingKey.nVars* (32*2);
|
||||
size += provingKey.nVars* (32*4);
|
||||
size += (provingKey.nVars - provingKey.nPublic - 1)* (32*2);
|
||||
size += provingKey.domainSize * (32*2);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
const buffLen = calculateBuffLen(provingKey);
|
||||
|
||||
const buff = new ArrayBuffer(buffLen);
|
||||
|
||||
const h = {
|
||||
dataView: new DataView(buff),
|
||||
offset: 0
|
||||
};
|
||||
|
||||
|
||||
writeUint32(h, provingKey.nVars);
|
||||
writeUint32(h, provingKey.nPublic);
|
||||
writeUint32(h, provingKey.domainSize);
|
||||
const pPolsA = alloc(h, 4);
|
||||
const pPolsB = alloc(h, 4);
|
||||
const pPointsA = alloc(h, 4);
|
||||
const pPointsB1 = alloc(h, 4);
|
||||
const pPointsB2 = alloc(h, 4);
|
||||
const pPointsC = alloc(h, 4);
|
||||
const pPointsHExps = alloc(h, 4);
|
||||
|
||||
writePoint(h, provingKey.vk_alfa_1);
|
||||
writePoint(h, provingKey.vk_beta_1);
|
||||
writePoint(h, provingKey.vk_delta_1);
|
||||
writePoint2(h, provingKey.vk_beta_2);
|
||||
writePoint2(h, provingKey.vk_delta_2);
|
||||
|
||||
writeUint32ToPointer(h, pPolsA, h.offset);
|
||||
for (let i=0; i<provingKey.nVars; i++) {
|
||||
writeTransformedPolynomial(h, provingKey.polsA[i]);
|
||||
}
|
||||
|
||||
writeUint32ToPointer(h, pPolsB, h.offset);
|
||||
for (let i=0; i<provingKey.nVars; i++) {
|
||||
writeTransformedPolynomial(h, provingKey.polsB[i]);
|
||||
}
|
||||
|
||||
writeUint32ToPointer(h, pPointsA, h.offset);
|
||||
for (let i=0; i<provingKey.nVars; i++) {
|
||||
writePoint(h, provingKey.A[i]);
|
||||
}
|
||||
|
||||
writeUint32ToPointer(h, pPointsB1, h.offset);
|
||||
for (let i=0; i<provingKey.nVars; i++) {
|
||||
writePoint(h, provingKey.B1[i]);
|
||||
}
|
||||
|
||||
writeUint32ToPointer(h, pPointsB2, h.offset);
|
||||
for (let i=0; i<provingKey.nVars; i++) {
|
||||
writePoint2(h, provingKey.B2[i]);
|
||||
}
|
||||
|
||||
writeUint32ToPointer(h, pPointsC, h.offset);
|
||||
for (let i=provingKey.nPublic+1; i<provingKey.nVars; i++) {
|
||||
writePoint(h, provingKey.C[i]);
|
||||
}
|
||||
|
||||
writeUint32ToPointer(h, pPointsHExps, h.offset);
|
||||
for (let i=0; i<provingKey.domainSize; i++) {
|
||||
writePoint(h, provingKey.hExps[i]);
|
||||
}
|
||||
|
||||
assert.equal(h.offset, buffLen);
|
||||
|
||||
var wstream = fs.createWriteStream(outputName);
|
||||
wstream.write(Buffer.from(buff));
|
||||
wstream.end();
|
||||
|
||||
/*
|
||||
NSignals
|
||||
NPublic
|
||||
DomainSize (2 multiple)
|
||||
pPolsA
|
||||
pPolsB
|
||||
pPointsA
|
||||
pPointsB1
|
||||
pPointsB2
|
||||
pPointsC
|
||||
pPointsHExps
|
||||
Alfa1
|
||||
Beta1
|
||||
Delta1
|
||||
Beta2
|
||||
Delta2
|
||||
PolinomialA_0
|
||||
PolinomialA_1
|
||||
PolinomialA_2
|
||||
...
|
||||
PolinomialA_NVars-1
|
||||
|
||||
PolinomialB_0
|
||||
PolinomialB_1
|
||||
PolinomialB_2
|
||||
...
|
||||
PolinomialB_NVars-1
|
||||
|
||||
PointA_0
|
||||
PointA_1
|
||||
...
|
||||
PointA_NVars-1
|
||||
|
||||
PointB1_0
|
||||
PointB1_1
|
||||
...
|
||||
PointB1_NVars-1
|
||||
|
||||
PointB2_0
|
||||
PointB2_1
|
||||
...
|
||||
PointB2_NVars-1
|
||||
|
||||
PointC_nPublics+1
|
||||
PointC_nPublics+2
|
||||
...
|
||||
PointC_nPublics+NVars
|
||||
|
||||
PointHExp_0
|
||||
PointHExp_1
|
||||
...
|
||||
PointHExp_DomainSize-1
|
||||
*/
|
||||
54
tools/buildwasm.js
Normal file
54
tools/buildwasm.js
Normal file
@@ -0,0 +1,54 @@
|
||||
const bigInt = require("big-integer");
|
||||
const ModuleBuilder = require("wasmbuilder");
|
||||
const buildF1m = require("../src/build_f1m.js");
|
||||
const buildF2m = require("../src/build_f2m.js");
|
||||
const buildF1 = require("../src/build_f1.js");
|
||||
const buildCurve = require("../src/build_curve.js");
|
||||
const buildTest = require("../src/build_testg1");
|
||||
const buildFFT = require("../src/build_fft");
|
||||
const buildMultiexp = require("../src/build_multiexp");
|
||||
const buildPol = require("../src/build_pol");
|
||||
const utils = require("../src/utils");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
function buildWasm() {
|
||||
|
||||
const q = bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583");
|
||||
const r = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
|
||||
const moduleBuilder = new ModuleBuilder();
|
||||
moduleBuilder.setMemory(1000);
|
||||
buildF1m(moduleBuilder, q, "f1m");
|
||||
buildF1(moduleBuilder, r, "fr", "frm");
|
||||
buildCurve(moduleBuilder, "g1", "f1m");
|
||||
buildMultiexp(moduleBuilder, "g1", "g1", "f1m", "fr");
|
||||
buildFFT(moduleBuilder, "fft", "frm");
|
||||
buildPol(moduleBuilder, "pol", "frm");
|
||||
|
||||
const pNonResidueF2 = moduleBuilder.alloc(
|
||||
utils.bigInt2BytesLE(
|
||||
bigInt("15537367993719455909907449462855742678907882278146377936676643359958227611562"), // -1 in montgomery
|
||||
32
|
||||
)
|
||||
);
|
||||
|
||||
buildF2m(moduleBuilder, pNonResidueF2, "f2m", "f1m");
|
||||
buildCurve(moduleBuilder, "g2", "f2m");
|
||||
buildMultiexp(moduleBuilder, "g2", "g2", "f2m", "fr");
|
||||
|
||||
buildTest(moduleBuilder);
|
||||
|
||||
const code = moduleBuilder.build();
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join( __dirname, "..", "build", "groth16_wasm.js"),
|
||||
`
|
||||
exports.code = new Buffer("${Buffer.from(code).toString("base64")}", "base64");
|
||||
exports.pq = ${moduleBuilder.modules.f1m.pq};
|
||||
exports.pr = ${moduleBuilder.modules.frm.pq};
|
||||
`
|
||||
);
|
||||
}
|
||||
|
||||
buildWasm();
|
||||
76
tools/buildwitness.js
Normal file
76
tools/buildwitness.js
Normal file
@@ -0,0 +1,76 @@
|
||||
const {unstringifyBigInts} = require("./stringifybigint.js");
|
||||
const fs = require("fs");
|
||||
const assert = require("assert");
|
||||
|
||||
const version = require("../package").version;
|
||||
|
||||
const argv = require("yargs")
|
||||
.version(version)
|
||||
.usage(`node buildpkey.js -i "witness.json" -o "witness.bin"
|
||||
Default: circuit.json
|
||||
`)
|
||||
.alias("i", "input")
|
||||
.alias("o", "output")
|
||||
.help("h")
|
||||
.alias("h", "help")
|
||||
.epilogue(`Copyright (C) 2018 0kims association
|
||||
This program comes with ABSOLUTELY NO WARRANTY;
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; see the COPYING file in the official
|
||||
repo directory at https://github.com/iden3/circom `)
|
||||
.argv;
|
||||
|
||||
const inputName = (argv.input) ? argv.input : "witness.json";
|
||||
const outputName = (argv.output) ? argv.output : "witness.bin";
|
||||
|
||||
|
||||
const witness = unstringifyBigInts(JSON.parse(fs.readFileSync(inputName, "utf8")));
|
||||
|
||||
|
||||
function writeUint32(h, val) {
|
||||
h.dataView.setUint32(h.offset, val, true);
|
||||
h.offset += 4;
|
||||
}
|
||||
|
||||
|
||||
function writeBigInt(h, bi) {
|
||||
for (let i=0; i<8; i++) {
|
||||
const v = bi.shiftRight(i*32).and(0xFFFFFFFF).toJSNumber();
|
||||
writeUint32(h, v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function calculateBuffLen(witness) {
|
||||
|
||||
let size = 0;
|
||||
|
||||
// beta2, delta2
|
||||
size += witness.length * 32;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
const buffLen = calculateBuffLen(witness);
|
||||
|
||||
const buff = new ArrayBuffer(buffLen);
|
||||
|
||||
const h = {
|
||||
dataView: new DataView(buff),
|
||||
offset: 0
|
||||
};
|
||||
|
||||
|
||||
// writeUint32(h, witness.length);
|
||||
|
||||
for (let i=0; i<witness.length; i++) {
|
||||
writeBigInt(h, witness[i]);
|
||||
}
|
||||
|
||||
assert.equal(h.offset, buffLen);
|
||||
|
||||
var wstream = fs.createWriteStream(outputName);
|
||||
wstream.write(Buffer.from(buff));
|
||||
wstream.end();
|
||||
|
||||
55
tools/stringifybigint.js
Normal file
55
tools/stringifybigint.js
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright 2018 0kims association.
|
||||
|
||||
This file is part of snarkjs.
|
||||
|
||||
snarkjs is a free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
snarkjs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
snarkjs. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const bigInt = require("big-integer");
|
||||
|
||||
module.exports.stringifyBigInts = stringifyBigInts;
|
||||
module.exports.unstringifyBigInts = unstringifyBigInts;
|
||||
|
||||
function stringifyBigInts(o) {
|
||||
if ((typeof(o) == "bigint") || (o instanceof bigInt)) {
|
||||
return o.toString(10);
|
||||
} else if (Array.isArray(o)) {
|
||||
return o.map(stringifyBigInts);
|
||||
} else if (typeof o == "object") {
|
||||
const res = {};
|
||||
for (let k in o) {
|
||||
res[k] = stringifyBigInts(o[k]);
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
function unstringifyBigInts(o) {
|
||||
if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) {
|
||||
return bigInt(o);
|
||||
} else if (Array.isArray(o)) {
|
||||
return o.map(unstringifyBigInts);
|
||||
} else if (typeof o == "object") {
|
||||
const res = {};
|
||||
for (let k in o) {
|
||||
res[k] = unstringifyBigInts(o[k]);
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user