mirror of
https://github.com/arnaucube/circomlib.git
synced 2026-02-07 11:16:45 +01:00
Compare commits
12 Commits
v0.0.4
...
feature/ba
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9d6e43143 | ||
|
|
8cb7b46603 | ||
|
|
7792887216 | ||
|
|
7971f0150e | ||
|
|
b3ff8b246d | ||
|
|
951e51423d | ||
|
|
9a5294dea1 | ||
|
|
2635e8d3c9 | ||
|
|
138945bfdc | ||
|
|
2f9ad59c3a | ||
|
|
4a4a30b8b8 | ||
|
|
084f5b593b |
@@ -1,14 +1,15 @@
|
|||||||
const bn128 = require("snarkjs").bn128;
|
const bn128 = require("snarkjs").bn128;
|
||||||
const bigInt = require("snarkjs").bigInt;
|
const bigInt = require("snarkjs").bigInt;
|
||||||
const createBlakeHash = require("blake-hash");
|
const createBlakeHash = require("blake-hash");
|
||||||
const assert = require("assert");
|
|
||||||
const babyJub = require("../src/babyjub");
|
const babyJub = require("../src/babyjub");
|
||||||
|
|
||||||
function getPoint(S) {
|
function getPoint(S) {
|
||||||
const F = bn128.Fr;
|
const F = bn128.Fr;
|
||||||
const h = createBlakeHash("blake256").update(S).digest();
|
const h = createBlakeHash("blake256").update(S).digest();
|
||||||
|
|
||||||
assert(h.length == 32);
|
if (h.length != 32) {
|
||||||
|
throw new Error("Invalid length")
|
||||||
|
}
|
||||||
|
|
||||||
let sign = false;
|
let sign = false;
|
||||||
if (h[31] & 0x80) {
|
if (h[31] & 0x80) {
|
||||||
@@ -52,7 +53,9 @@ function generatePoint(S) {
|
|||||||
p = getPoint(S+"_"+sidx);
|
p = getPoint(S+"_"+sidx);
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
assert(babyJub.inCurve(p), "Point not in curve");
|
if (!babyJub.inCurve(p)){
|
||||||
|
throw new Error("Point not in curve");
|
||||||
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,9 @@
|
|||||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
include "bitify.circom";
|
||||||
|
include "escalarmulfix.circom";
|
||||||
|
|
||||||
template BabyAdd() {
|
template BabyAdd() {
|
||||||
signal input x1;
|
signal input x1;
|
||||||
signal input y1;
|
signal input y1;
|
||||||
@@ -77,3 +80,27 @@ template BabyCheck() {
|
|||||||
|
|
||||||
a*x2 + y2 === 1 + d*x2*y2;
|
a*x2 + y2 === 1 + d*x2*y2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extracts the public key from private key
|
||||||
|
template BabyPbk() {
|
||||||
|
signal private input in;
|
||||||
|
signal output Ax;
|
||||||
|
signal output Ay;
|
||||||
|
|
||||||
|
var BASE8 = [
|
||||||
|
17777552123799933955779906779655732241715742912184938656739573121738514868268,
|
||||||
|
2626589144620713026669568689430873010625803728049924121243784502389097019475
|
||||||
|
];
|
||||||
|
|
||||||
|
component pvkBits = Num2Bits(253);
|
||||||
|
pvkBits.in <== in;
|
||||||
|
|
||||||
|
component mulFix = EscalarMulFix(253, BASE8);
|
||||||
|
|
||||||
|
var i;
|
||||||
|
for (i=0; i<253; i++) {
|
||||||
|
mulFix.e[i] <== pvkBits.out[i];
|
||||||
|
}
|
||||||
|
Ax <== mulFix.out[0];
|
||||||
|
Ay <== mulFix.out[1];
|
||||||
|
}
|
||||||
|
|||||||
BIN
doc/rollup_tree.monopic
Normal file
BIN
doc/rollup_tree.monopic
Normal file
Binary file not shown.
Binary file not shown.
1
index.js
1
index.js
@@ -1,3 +1,4 @@
|
|||||||
exports.smt = require("./src/smt");
|
exports.smt = require("./src/smt");
|
||||||
exports.eddsa = require("./src/eddsa");
|
exports.eddsa = require("./src/eddsa");
|
||||||
exports.mimc7 = require("./src/mimc7");
|
exports.mimc7 = require("./src/mimc7");
|
||||||
|
exports.babyJub = require("./src/babyjub");
|
||||||
|
|||||||
943
package-lock.json
generated
943
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
11
package.json
11
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "circomlib",
|
"name": "circomlib",
|
||||||
"version": "0.0.4",
|
"version": "0.0.6",
|
||||||
"description": "Basic circuits library for Circom",
|
"description": "Basic circuits library for Circom",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
@@ -25,13 +25,14 @@
|
|||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"blake-hash": "^1.1.0",
|
"blake-hash": "^1.1.0",
|
||||||
"snarkjs": "0.1.8"
|
"snarkjs": "0.1.11",
|
||||||
|
"typedarray-to-buffer": "^3.1.5",
|
||||||
|
"web3": "^1.0.0-beta.36"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"circom": "0.0.23",
|
"circom": "0.0.24",
|
||||||
"eslint-plugin-mocha": "^5.2.0",
|
"eslint-plugin-mocha": "^5.2.0",
|
||||||
"ganache-cli": "^6.2.3",
|
"ganache-cli": "^6.2.3",
|
||||||
"mocha": "^5.2.0",
|
"mocha": "^5.2.0"
|
||||||
"web3": "^1.0.0-beta.36"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,7 @@ const bigInt = require("snarkjs").bigInt;
|
|||||||
const babyJub = require("./babyjub");
|
const babyJub = require("./babyjub");
|
||||||
const pedersenHash = require("./pedersenHash").hash;
|
const pedersenHash = require("./pedersenHash").hash;
|
||||||
const mimc7 = require("./mimc7");
|
const mimc7 = require("./mimc7");
|
||||||
const crypto = require("crypto");
|
|
||||||
|
|
||||||
exports.cratePrvKey = cratePrvKey;
|
|
||||||
exports.prv2pub= prv2pub;
|
exports.prv2pub= prv2pub;
|
||||||
exports.sign = sign;
|
exports.sign = sign;
|
||||||
exports.signMiMC = signMiMC;
|
exports.signMiMC = signMiMC;
|
||||||
@@ -13,12 +11,9 @@ exports.verify = verify;
|
|||||||
exports.verifyMiMC = verifyMiMC;
|
exports.verifyMiMC = verifyMiMC;
|
||||||
exports.packSignature = packSignature;
|
exports.packSignature = packSignature;
|
||||||
exports.unpackSignature = unpackSignature;
|
exports.unpackSignature = unpackSignature;
|
||||||
|
exports.pruneBuffer = pruneBuffer;
|
||||||
|
|
||||||
|
|
||||||
function cratePrvKey() {
|
|
||||||
return crypto.randomBytes(32);
|
|
||||||
}
|
|
||||||
|
|
||||||
function pruneBuffer(_buff) {
|
function pruneBuffer(_buff) {
|
||||||
const buff = Buffer.from(_buff);
|
const buff = Buffer.from(_buff);
|
||||||
buff[0] = buff[0] & 0xF8;
|
buff[0] = buff[0] & 0xF8;
|
||||||
|
|||||||
@@ -3,8 +3,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
const Web3 = require("web3");
|
const Web3Utils = require("web3-utils");
|
||||||
const assert = require("assert");
|
|
||||||
|
|
||||||
class Contract {
|
class Contract {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -39,7 +38,7 @@ class Contract {
|
|||||||
genLoadedLength = C.code.length;
|
genLoadedLength = C.code.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Web3.utils.bytesToHex(C.code.concat(this.code));
|
return Web3Utils.bytesToHex(C.code.concat(this.code));
|
||||||
}
|
}
|
||||||
|
|
||||||
stop() { this.code.push(0x00); }
|
stop() { this.code.push(0x00); }
|
||||||
@@ -141,7 +140,9 @@ class Contract {
|
|||||||
msize() { this.code.push(0x59); }
|
msize() { this.code.push(0x59); }
|
||||||
gas() { this.code.push(0x5a); }
|
gas() { this.code.push(0x5a); }
|
||||||
label(name) {
|
label(name) {
|
||||||
assert(typeof this.labels[name] == "undefined", "Label already defined");
|
if (typeof this.labels[name] != "undefined") {
|
||||||
|
throw new Error("Label already defined");
|
||||||
|
}
|
||||||
this.labels[name] = this.code.length;
|
this.labels[name] = this.code.length;
|
||||||
this.code.push(0x5b);
|
this.code.push(0x5b);
|
||||||
|
|
||||||
@@ -149,21 +150,24 @@ class Contract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
push(data) {
|
push(data) {
|
||||||
const d = Web3.utils.hexToBytes(Web3.utils.toHex(data));
|
const d = Web3Utils.hexToBytes(Web3Utils.toHex(data));
|
||||||
assert(d.length>0);
|
if (d.length == 0 || d.length > 32) {
|
||||||
assert(d.length<=32);
|
throw new Error("Assertion failed");
|
||||||
|
}
|
||||||
this.code = this.code.concat([0x5F + d.length], d);
|
this.code = this.code.concat([0x5F + d.length], d);
|
||||||
}
|
}
|
||||||
|
|
||||||
dup(n) {
|
dup(n) {
|
||||||
assert(n>=0);
|
if (n < 0 || n >= 16) {
|
||||||
assert(n<16);
|
throw new Error("Assertion failed");
|
||||||
|
}
|
||||||
this.code.push(0x80 + n);
|
this.code.push(0x80 + n);
|
||||||
}
|
}
|
||||||
|
|
||||||
swap(n) {
|
swap(n) {
|
||||||
assert(n>=1);
|
if (n < 1 || n > 16) {
|
||||||
assert(n<=16);
|
throw new Error("Assertion failed");
|
||||||
|
}
|
||||||
this.code.push(0x8f + n);
|
this.code.push(0x8f + n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
src/mimc7.js
16
src/mimc7.js
@@ -1,6 +1,6 @@
|
|||||||
const bn128 = require("snarkjs").bn128;
|
const bn128 = require("snarkjs").bn128;
|
||||||
const bigInt = require("snarkjs").bigInt;
|
const bigInt = require("snarkjs").bigInt;
|
||||||
const Web3 = require("web3");
|
const Web3Utils = require("web3-utils");
|
||||||
const F = bn128.Fr;
|
const F = bn128.Fr;
|
||||||
|
|
||||||
const SEED = "mimc";
|
const SEED = "mimc";
|
||||||
@@ -8,8 +8,8 @@ const NROUNDS = 91;
|
|||||||
|
|
||||||
exports.getIV = (seed) => {
|
exports.getIV = (seed) => {
|
||||||
if (typeof seed === "undefined") seed = SEED;
|
if (typeof seed === "undefined") seed = SEED;
|
||||||
const c = Web3.utils.keccak256(seed+"_iv");
|
const c = Web3Utils.keccak256(seed+"_iv");
|
||||||
const cn = bigInt(Web3.utils.toBN(c).toString());
|
const cn = bigInt(Web3Utils.toBN(c).toString());
|
||||||
const iv = cn.mod(F.q);
|
const iv = cn.mod(F.q);
|
||||||
return iv;
|
return iv;
|
||||||
};
|
};
|
||||||
@@ -18,13 +18,13 @@ exports.getConstants = (seed, nRounds) => {
|
|||||||
if (typeof seed === "undefined") seed = SEED;
|
if (typeof seed === "undefined") seed = SEED;
|
||||||
if (typeof nRounds === "undefined") nRounds = NROUNDS;
|
if (typeof nRounds === "undefined") nRounds = NROUNDS;
|
||||||
const cts = new Array(nRounds);
|
const cts = new Array(nRounds);
|
||||||
let c = Web3.utils.keccak256(SEED);
|
let c = Web3Utils.keccak256(SEED);
|
||||||
for (let i=1; i<nRounds; i++) {
|
for (let i=1; i<nRounds; i++) {
|
||||||
c = Web3.utils.keccak256(c);
|
c = Web3Utils.keccak256(c);
|
||||||
|
|
||||||
const n1 = Web3.utils.toBN(c).mod(Web3.utils.toBN(F.q.toString()));
|
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.q.toString()));
|
||||||
const c2 = Web3.utils.padLeft(Web3.utils.toHex(n1), 64);
|
const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64);
|
||||||
cts[i] = bigInt(Web3.utils.toBN(c2).toString());
|
cts[i] = bigInt(Web3Utils.toBN(c2).toString());
|
||||||
}
|
}
|
||||||
cts[0] = bigInt(0);
|
cts[0] = bigInt(0);
|
||||||
return cts;
|
return cts;
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
// License: LGPL-3.0+
|
// License: LGPL-3.0+
|
||||||
//
|
//
|
||||||
|
|
||||||
const Web3 = require("web3");
|
const Web3Utils = require("web3-utils");
|
||||||
|
|
||||||
const Contract = require("./evmasm");
|
const Contract = require("./evmasm");
|
||||||
|
|
||||||
function createCode(seed, n) {
|
function createCode(seed, n) {
|
||||||
|
|
||||||
let ci = Web3.utils.keccak256(seed);
|
let ci = Web3Utils.keccak256(seed);
|
||||||
|
|
||||||
const C = new Contract();
|
const C = new Contract();
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ function createCode(seed, n) {
|
|||||||
C.mulmod(); // r=t^7 k q
|
C.mulmod(); // r=t^7 k q
|
||||||
|
|
||||||
for (let i=0; i<n-1; i++) {
|
for (let i=0; i<n-1; i++) {
|
||||||
ci = Web3.utils.keccak256(ci);
|
ci = Web3Utils.keccak256(ci);
|
||||||
C.dup(2); // q r k q
|
C.dup(2); // q r k q
|
||||||
C.dup(0); // q q r k q
|
C.dup(0); // q q r k q
|
||||||
C.dup(0); // q q q r k q
|
C.dup(0); // q q q r k q
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
const bn128 = require("snarkjs").bn128;
|
const bn128 = require("snarkjs").bn128;
|
||||||
const bigInt = require("snarkjs").bigInt;
|
const bigInt = require("snarkjs").bigInt;
|
||||||
const babyJub = require("./babyjub");
|
const babyJub = require("./babyjub");
|
||||||
const assert = require("assert");
|
|
||||||
const createBlakeHash = require("blake-hash");
|
const createBlakeHash = require("blake-hash");
|
||||||
|
|
||||||
const GENPOINT_PREFIX = "PedersenGenerator";
|
const GENPOINT_PREFIX = "PedersenGenerator";
|
||||||
@@ -73,7 +72,9 @@ function getBasePoint(pointIdx) {
|
|||||||
|
|
||||||
const p8 = babyJub.mulPointEscalar(p, 8);
|
const p8 = babyJub.mulPointEscalar(p, 8);
|
||||||
|
|
||||||
assert(babyJub.inSubgroup(p8), "Point not in curve");
|
if (!babyJub.inSubgroup(p8)) {
|
||||||
|
throw new Error("Point not in curve");
|
||||||
|
}
|
||||||
|
|
||||||
bases[pointIdx] = p8;
|
bases[pointIdx] = p8;
|
||||||
return p8;
|
return p8;
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ const path = require("path");
|
|||||||
const snarkjs = require("snarkjs");
|
const snarkjs = require("snarkjs");
|
||||||
const compiler = require("circom");
|
const compiler = require("circom");
|
||||||
|
|
||||||
|
const createBlakeHash = require("blake-hash");
|
||||||
|
const eddsa = require("../src/eddsa.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const bigInt = require("big-integer");
|
const bigInt = require("snarkjs").bigInt;
|
||||||
|
|
||||||
|
|
||||||
describe("Baby Jub test", function () {
|
describe("Baby Jub test", function () {
|
||||||
let circuitAdd;
|
let circuitAdd;
|
||||||
@@ -22,6 +24,11 @@ describe("Baby Jub test", function () {
|
|||||||
const cirDefTest = await compiler(path.join(__dirname, "circuits", "babycheck_test.circom"));
|
const cirDefTest = await compiler(path.join(__dirname, "circuits", "babycheck_test.circom"));
|
||||||
circuitTest = new snarkjs.Circuit(cirDefTest);
|
circuitTest = new snarkjs.Circuit(cirDefTest);
|
||||||
console.log("NConstrains BabyTest: " + circuitTest.nConstraints);
|
console.log("NConstrains BabyTest: " + circuitTest.nConstraints);
|
||||||
|
|
||||||
|
const cirDefPbk = await compiler(path.join(__dirname, "circuits", "babypbk_test.circom"));
|
||||||
|
circuitPbk = new snarkjs.Circuit(cirDefPbk);
|
||||||
|
console.log("NConstrains BabyPbk: " + circuitPbk.nConstraints);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should add point (0,1) and (0,1)", async () => {
|
it("Should add point (0,1) and (0,1)", async () => {
|
||||||
@@ -97,4 +104,22 @@ describe("Baby Jub test", function () {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should extract the public key from the private one", async () => {
|
||||||
|
|
||||||
|
const rawpvk = Buffer.from("0001020304050607080900010203040506070809000102030405060708090021", "hex");
|
||||||
|
const pvk = eddsa.pruneBuffer(createBlakeHash("blake512").update(rawpvk).digest().slice(0,32));
|
||||||
|
const S = bigInt.leBuff2int(pvk).shr(3);
|
||||||
|
|
||||||
|
const A = eddsa.prv2pub(rawpvk);
|
||||||
|
|
||||||
|
const input = {
|
||||||
|
in : S,
|
||||||
|
Ax : A[0],
|
||||||
|
Ay : A[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
const w = circuitPbk.calculateWitness(input);
|
||||||
|
assert(circuitPbk.checkWitness(w));
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
3
test/circuits/babypbk_test.circom
Normal file
3
test/circuits/babypbk_test.circom
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
include "../../circuits/babyjub.circom";
|
||||||
|
|
||||||
|
component main = BabyPbk();
|
||||||
@@ -2,6 +2,7 @@ const chai = require("chai");
|
|||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("snarkjs");
|
const snarkjs = require("snarkjs");
|
||||||
const compiler = require("circom");
|
const compiler = require("circom");
|
||||||
|
// const crypto = require("crypto");
|
||||||
|
|
||||||
const eddsa = require("../src/eddsa.js");
|
const eddsa = require("../src/eddsa.js");
|
||||||
const babyJub = require("../src/babyjub.js");
|
const babyJub = require("../src/babyjub.js");
|
||||||
@@ -45,7 +46,7 @@ describe("EdDSA test", function () {
|
|||||||
it("Sign a single 10 bytes from 0 to 9", async () => {
|
it("Sign a single 10 bytes from 0 to 9", async () => {
|
||||||
const msg = Buffer.from("00010203040506070809", "hex");
|
const msg = Buffer.from("00010203040506070809", "hex");
|
||||||
|
|
||||||
// const prvKey = eddsa.cratePrvKey();
|
// const prvKey = crypto.randomBytes(32);
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user