mirror of
https://github.com/arnaucube/circomlib.git
synced 2026-02-07 11:16:45 +01:00
Compare commits
21 Commits
v0.0.5
...
feature/sy
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74a7e71c33 | ||
|
|
d7f7243239 | ||
|
|
ba2fc931af | ||
|
|
b6aa6e5c51 | ||
|
|
536268709a | ||
|
|
5b1b2f76ca | ||
|
|
0f87cc7cae | ||
|
|
58f758d5ad | ||
|
|
7792887216 | ||
|
|
7971f0150e | ||
|
|
b3ff8b246d | ||
|
|
951e51423d | ||
|
|
9a5294dea1 | ||
|
|
2635e8d3c9 | ||
|
|
138945bfdc | ||
|
|
2f9ad59c3a | ||
|
|
5b7abbc4ec | ||
|
|
480d64987a | ||
|
|
b34c4228d9 | ||
|
|
130e3906fb | ||
|
|
49244ea6b7 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -60,6 +60,9 @@ typings/
|
|||||||
# next.js build output
|
# next.js build output
|
||||||
.next
|
.next
|
||||||
|
|
||||||
|
# Visual code configuration
|
||||||
|
.vscode
|
||||||
|
|
||||||
tmp
|
tmp
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ template EdDSAMiMCVerifier() {
|
|||||||
hash.in[2] <== Ax;
|
hash.in[2] <== Ax;
|
||||||
hash.in[3] <== Ay;
|
hash.in[3] <== Ay;
|
||||||
hash.in[4] <== M;
|
hash.in[4] <== M;
|
||||||
|
hash.k <== 0;
|
||||||
|
|
||||||
component h2bits = Num2Bits_strict();
|
component h2bits = Num2Bits_strict();
|
||||||
h2bits.in <== hash.out;
|
h2bits.in <== hash.out;
|
||||||
|
|||||||
@@ -137,18 +137,19 @@ template MiMC7(nrounds) {
|
|||||||
|
|
||||||
template MultiMiMC7(nInputs, nRounds) {
|
template MultiMiMC7(nInputs, nRounds) {
|
||||||
signal input in[nInputs];
|
signal input in[nInputs];
|
||||||
|
signal input k;
|
||||||
signal output out;
|
signal output out;
|
||||||
|
signal r[nInputs +1];
|
||||||
|
|
||||||
component mims[nInputs];
|
component mims[nInputs];
|
||||||
|
|
||||||
|
r[0] <== k;
|
||||||
for (var i=0; i<nInputs; i++) {
|
for (var i=0; i<nInputs; i++) {
|
||||||
mims[i] = MiMC7(nRounds);
|
mims[i] = MiMC7(nRounds);
|
||||||
if (i==0) {
|
mims[i].x_in <== in[i];
|
||||||
mims[i].x_in <== 15021630795539610737508582392395901278341266317943626182700664337106830745361;
|
mims[i].k <== r[i];
|
||||||
} else {
|
r[i+1] <== r[i] + in[i] + mims[i].out;
|
||||||
mims[i].x_in <== mims[i-1].out;
|
|
||||||
}
|
|
||||||
mims[i].k <== in[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out <== mims[nInputs-1].out;
|
out <== r[nInputs];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,19 +29,12 @@ template SMTHash1() {
|
|||||||
signal input value;
|
signal input value;
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
component h1 = MiMC7(91); // Constant
|
component h = MultiMiMC7(2, 91); // Constant
|
||||||
h1.x_in <== 15021630795539610737508582392395901278341266317943626182700664337106830745361;
|
h.in[0] <== key;
|
||||||
h1.k <== 1;
|
h.in[1] <== value;
|
||||||
|
h.k <== 1;
|
||||||
|
|
||||||
component h2 = MiMC7(91);
|
out <== h.out;
|
||||||
h2.x_in <== h1.out;
|
|
||||||
h2.k <== key;
|
|
||||||
|
|
||||||
component h3 = MiMC7(91);
|
|
||||||
h3.x_in <== h2.out;
|
|
||||||
h3.k <== value;
|
|
||||||
|
|
||||||
out <== h3.out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -55,13 +48,10 @@ template SMTHash2() {
|
|||||||
signal input R;
|
signal input R;
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
component h1 = MiMC7(91);
|
component h = MultiMiMC7(2, 91); // Constant
|
||||||
h1.x_in <== 15021630795539610737508582392395901278341266317943626182700664337106830745361;
|
h.in[0] <== L;
|
||||||
h1.k <== L;
|
h.in[1] <== R;
|
||||||
|
h.k <== 0;
|
||||||
|
|
||||||
component h2 = MiMC7(91);
|
out <== h.out;
|
||||||
h2.x_in <== h1.out;
|
|
||||||
h2.k <== R;
|
|
||||||
|
|
||||||
out <== h2.out;
|
|
||||||
}
|
}
|
||||||
|
|||||||
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");
|
||||||
|
|||||||
873
package-lock.json
generated
873
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "circomlib",
|
"name": "circomlib",
|
||||||
"version": "0.0.5",
|
"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,7 +25,7 @@
|
|||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"blake-hash": "^1.1.0",
|
"blake-hash": "^1.1.0",
|
||||||
"snarkjs": "0.1.9",
|
"snarkjs": "0.1.11",
|
||||||
"web3": "^1.0.0-beta.36"
|
"web3": "^1.0.0-beta.36"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
37
src/mimc7.js
37
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;
|
||||||
@@ -44,10 +44,21 @@ exports.hash = (_x_in, _k) =>{
|
|||||||
return F.affine(F.add(r, k));
|
return F.affine(F.add(r, k));
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.multiHash = (arr) => {
|
exports.multiHash = (arr, key) => {
|
||||||
let r = exports.getIV();
|
let r;
|
||||||
for (let i=0; i<arr.length; i++) {
|
if (typeof(key) === "undefined") {
|
||||||
r = exports.hash(r, bigInt(arr[i]));
|
r = F.zero;
|
||||||
|
} else {
|
||||||
|
r = key;
|
||||||
}
|
}
|
||||||
return r;
|
for (let i=0; i<arr.length; i++) {
|
||||||
|
r = F.add(
|
||||||
|
F.add(
|
||||||
|
r,
|
||||||
|
arr[i]
|
||||||
|
),
|
||||||
|
exports.hash(bigInt(arr[i]), r)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return F.affine(r);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
32
src/smt.js
32
src/smt.js
@@ -46,8 +46,8 @@ class SMT {
|
|||||||
const ins = [];
|
const ins = [];
|
||||||
const dels = [];
|
const dels = [];
|
||||||
|
|
||||||
let rtOld = mimc7.multiHash([1, key, resFind.foundValue]);
|
let rtOld = mimc7.multiHash([key, resFind.foundValue], bigInt.one);
|
||||||
let rtNew = mimc7.multiHash([1, key, newValue]);
|
let rtNew = mimc7.multiHash([key, newValue], bigInt.one);
|
||||||
ins.push([rtNew, [1, key, newValue ]]);
|
ins.push([rtNew, [1, key, newValue ]]);
|
||||||
dels.push(rtOld);
|
dels.push(rtOld);
|
||||||
|
|
||||||
@@ -59,11 +59,11 @@ class SMT {
|
|||||||
oldNode = [sibling, rtOld];
|
oldNode = [sibling, rtOld];
|
||||||
newNode = [sibling, rtNew];
|
newNode = [sibling, rtNew];
|
||||||
} else {
|
} else {
|
||||||
oldNode = [rtOld, sibling, ];
|
oldNode = [rtOld, sibling];
|
||||||
newNode = [rtNew, sibling, ];
|
newNode = [rtNew, sibling];
|
||||||
}
|
}
|
||||||
rtOld = mimc7.multiHash(oldNode);
|
rtOld = mimc7.multiHash(oldNode, bigInt.zero);
|
||||||
rtNew = mimc7.multiHash(newNode);
|
rtNew = mimc7.multiHash(newNode, bigInt.zero);
|
||||||
dels.push(rtOld);
|
dels.push(rtOld);
|
||||||
ins.push([rtNew, newNode]);
|
ins.push([rtNew, newNode]);
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,7 @@ class SMT {
|
|||||||
|
|
||||||
const dels = [];
|
const dels = [];
|
||||||
const ins = [];
|
const ins = [];
|
||||||
let rtOld = mimc7.multiHash([1, key, resFind.foundValue]);
|
let rtOld = mimc7.multiHash([key, resFind.foundValue], bigInt.one);
|
||||||
let rtNew;
|
let rtNew;
|
||||||
dels.push(rtOld);
|
dels.push(rtOld);
|
||||||
|
|
||||||
@@ -130,9 +130,9 @@ class SMT {
|
|||||||
}
|
}
|
||||||
const oldSibling = resFind.siblings[level];
|
const oldSibling = resFind.siblings[level];
|
||||||
if (keyBits[level]) {
|
if (keyBits[level]) {
|
||||||
rtOld = mimc7.multiHash([oldSibling, rtOld]);
|
rtOld = mimc7.multiHash([oldSibling, rtOld], bigInt.zero);
|
||||||
} else {
|
} else {
|
||||||
rtOld = mimc7.multiHash([rtOld, oldSibling]);
|
rtOld = mimc7.multiHash([rtOld, oldSibling], bigInt.zero);
|
||||||
}
|
}
|
||||||
dels.push(rtOld);
|
dels.push(rtOld);
|
||||||
if (!newSibling.isZero()) {
|
if (!newSibling.isZero()) {
|
||||||
@@ -147,7 +147,7 @@ class SMT {
|
|||||||
} else {
|
} else {
|
||||||
newNode = [rtNew, newSibling];
|
newNode = [rtNew, newSibling];
|
||||||
}
|
}
|
||||||
rtNew = mimc7.multiHash(newNode);
|
rtNew = mimc7.multiHash(newNode, bigInt.zero);
|
||||||
ins.push([rtNew, newNode]);
|
ins.push([rtNew, newNode]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,7 +185,7 @@ class SMT {
|
|||||||
for (let i= res.siblings.length; oldKeyits[i] == newKeyBits[i]; i++) {
|
for (let i= res.siblings.length; oldKeyits[i] == newKeyBits[i]; i++) {
|
||||||
res.siblings.push(bigInt.zero);
|
res.siblings.push(bigInt.zero);
|
||||||
}
|
}
|
||||||
rtOld = mimc7.multiHash([1, resFind.notFoundKey, resFind.notFoundValue]);
|
rtOld = mimc7.multiHash([resFind.notFoundKey, resFind.notFoundValue], bigInt.one);
|
||||||
res.siblings.push(rtOld);
|
res.siblings.push(rtOld);
|
||||||
addedOne = true;
|
addedOne = true;
|
||||||
mixed = false;
|
mixed = false;
|
||||||
@@ -197,7 +197,7 @@ class SMT {
|
|||||||
const inserts = [];
|
const inserts = [];
|
||||||
const dels = [];
|
const dels = [];
|
||||||
|
|
||||||
let rt = mimc7.multiHash([1, key, value]);
|
let rt = mimc7.multiHash([key, value], bigInt.one);
|
||||||
inserts.push([rt,[1, key, value]] );
|
inserts.push([rt,[1, key, value]] );
|
||||||
|
|
||||||
for (let i=res.siblings.length-1; i>=0; i--) {
|
for (let i=res.siblings.length-1; i>=0; i--) {
|
||||||
@@ -207,9 +207,9 @@ class SMT {
|
|||||||
if (mixed) {
|
if (mixed) {
|
||||||
const oldSibling = resFind.siblings[i];
|
const oldSibling = resFind.siblings[i];
|
||||||
if (newKeyBits[i]) {
|
if (newKeyBits[i]) {
|
||||||
rtOld = mimc7.multiHash([oldSibling, rtOld]);
|
rtOld = mimc7.multiHash([oldSibling, rtOld], bigInt.zero);
|
||||||
} else {
|
} else {
|
||||||
rtOld = mimc7.multiHash([rtOld, oldSibling]);
|
rtOld = mimc7.multiHash([rtOld, oldSibling], bigInt.zero);
|
||||||
}
|
}
|
||||||
dels.push(rtOld);
|
dels.push(rtOld);
|
||||||
}
|
}
|
||||||
@@ -217,10 +217,10 @@ class SMT {
|
|||||||
|
|
||||||
let newRt;
|
let newRt;
|
||||||
if (newKeyBits[i]) {
|
if (newKeyBits[i]) {
|
||||||
newRt = mimc7.multiHash([res.siblings[i], rt]);
|
newRt = mimc7.multiHash([res.siblings[i], rt], bigInt.zero);
|
||||||
inserts.push([newRt,[res.siblings[i], rt]] );
|
inserts.push([newRt,[res.siblings[i], rt]] );
|
||||||
} else {
|
} else {
|
||||||
newRt = mimc7.multiHash([rt, res.siblings[i]]);
|
newRt = mimc7.multiHash([rt, res.siblings[i]], bigInt.zero);
|
||||||
inserts.push([newRt,[rt, res.siblings[i]]] );
|
inserts.push([newRt,[rt, res.siblings[i]]] );
|
||||||
}
|
}
|
||||||
rt = newRt;
|
rt = newRt;
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const assert = chai.assert;
|
|||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
describe("EdDSA test", function () {
|
describe("EdDSA MiMC test", function () {
|
||||||
let circuit;
|
let circuit;
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|||||||
51
test/mimctestvectors.js
Normal file
51
test/mimctestvectors.js
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
const chai = require("chai");
|
||||||
|
const snarkjs = require("snarkjs");
|
||||||
|
const mimcjs = require("../src/mimc7.js");
|
||||||
|
const expect = chai.expect;
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
|
function bytesToHex(buff) {
|
||||||
|
return `0x${buff.toString("hex")}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bigIntToBuffer(number) {
|
||||||
|
const buff = Buffer.alloc(32);
|
||||||
|
let pos = buff.length - 1;
|
||||||
|
while (!number.isZero()) {
|
||||||
|
buff[pos] = number.and(255);
|
||||||
|
number = number.shiftRight(8);
|
||||||
|
pos -= 1;
|
||||||
|
}
|
||||||
|
return buff;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("[mimc hash] Javascript test", function () {
|
||||||
|
|
||||||
|
this.timeout(100000);
|
||||||
|
before( async () => {
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Mimc7 hash with 1 entry", () => {
|
||||||
|
const entries = [bigInt(12)];
|
||||||
|
const hash = mimcjs.multiHash(entries);
|
||||||
|
const hashHex = bytesToHex(bigIntToBuffer(hash));
|
||||||
|
expect(hashHex).to.be.equal("0x237c92644dbddb86d8a259e0e923aaab65a93f1ec5758b8799988894ac0958fd");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Mimc7 hash with 2 entries", () => {
|
||||||
|
const entries = [bigInt(12), bigInt(45), bigInt(78), bigInt(41)];
|
||||||
|
const hi = mimcjs.multiHash(entries.slice(2));
|
||||||
|
const hiHex = bytesToHex(bigIntToBuffer(hi));
|
||||||
|
expect(hiHex).to.be.equal("0x067f3202335ea256ae6e6aadcd2d5f7f4b06a00b2d1e0de903980d5ab552dc70");
|
||||||
|
const hv = mimcjs.multiHash(entries.slice(0, 2));
|
||||||
|
const hvHex = bytesToHex(bigIntToBuffer(hv));
|
||||||
|
expect(hvHex).to.be.equal("0x15ff7fe9793346a17c3150804bcb36d161c8662b110c50f55ccb7113948d8879");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Mimc7 hash with 4 entries", () => {
|
||||||
|
const entries = [bigInt(12), bigInt(45), bigInt(78), bigInt(41)];
|
||||||
|
const hash = mimcjs.multiHash(entries);
|
||||||
|
const hashHex = bytesToHex(bigIntToBuffer(hash));
|
||||||
|
expect(hashHex).to.be.equal("0x284bc1f34f335933a23a433b6ff3ee179d682cd5e5e2fcdd2d964afa85104beb");
|
||||||
|
});
|
||||||
|
});
|
||||||
147
test/smttestvectors.js
Normal file
147
test/smttestvectors.js
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
const chai = require("chai");
|
||||||
|
const snarkjs = require("snarkjs");
|
||||||
|
|
||||||
|
const smt = require("../src/smt.js");
|
||||||
|
const mimcjs = require("../src/mimc7.js");
|
||||||
|
|
||||||
|
const expect = chai.expect;
|
||||||
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
|
function bytesToHex(buff) {
|
||||||
|
return `0x${buff.toString("hex")}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bigIntToBuffer(number) {
|
||||||
|
const buff = Buffer.alloc(32);
|
||||||
|
let pos = buff.length - 1;
|
||||||
|
while (!number.isZero()) {
|
||||||
|
buff[pos] = number.and(255);
|
||||||
|
number = number.shiftRight(8);
|
||||||
|
pos -= 1;
|
||||||
|
}
|
||||||
|
return buff;
|
||||||
|
}
|
||||||
|
|
||||||
|
function newEntry(arr) {
|
||||||
|
return {
|
||||||
|
hi: mimcjs.multiHash(arr.slice(2)),
|
||||||
|
hv: mimcjs.multiHash(arr.slice(0, 2)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("[sparse-merkle-tree] Javascript test", function () {
|
||||||
|
|
||||||
|
this.timeout(100000);
|
||||||
|
before( async () => {
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Add one claim", async () => {
|
||||||
|
const claim = [bigInt(12), bigInt(45), bigInt(78), bigInt(41)];
|
||||||
|
const entries = newEntry(claim);
|
||||||
|
const tree = await smt.newMemEmptyTrie();
|
||||||
|
const key1 = entries.hi;
|
||||||
|
const value1 = entries.hv;
|
||||||
|
|
||||||
|
await tree.insert(key1,value1);
|
||||||
|
const root = tree.root;
|
||||||
|
const rootBuff = bigIntToBuffer(root);
|
||||||
|
expect(bytesToHex(rootBuff)).to.be.equal("0x2bf39430aa2482fc1e2f170179c8cab126b0f55f71edc8d333f4c80cb4e798f5");
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
it("Add two claims", async () => {
|
||||||
|
const firstClaim = [bigInt(12), bigInt(45), bigInt(78), bigInt(41)];
|
||||||
|
const firstEntries = newEntry(firstClaim);
|
||||||
|
const secondClaim = [bigInt(33), bigInt(44), bigInt(55), bigInt(66)];
|
||||||
|
const secondEntries = newEntry(secondClaim);
|
||||||
|
const tree = await smt.newMemEmptyTrie();
|
||||||
|
const key1 = firstEntries.hi;
|
||||||
|
const value1 = firstEntries.hv;
|
||||||
|
const key2 = secondEntries.hi;
|
||||||
|
const value2 = secondEntries.hv;
|
||||||
|
|
||||||
|
await tree.insert(key1,value1);
|
||||||
|
await tree.insert(key2,value2);
|
||||||
|
const root = tree.root;
|
||||||
|
const rootBuff = bigIntToBuffer(root);
|
||||||
|
expect(bytesToHex(rootBuff)).to.be.equal("0x1fb755a3677f8fd6c47b5462b69778ef6383c31d2d498b765e953f8cacaa6744");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Add claims in different orders", async () => {
|
||||||
|
const tree1 = await smt.newMemEmptyTrie();
|
||||||
|
for (let i = 0; i < 16; i++) {
|
||||||
|
const claim = [bigInt(0), bigInt(i), bigInt(0), bigInt(i)];
|
||||||
|
const entries = newEntry(claim);
|
||||||
|
await tree1.insert(entries.hi, entries.hv);
|
||||||
|
}
|
||||||
|
const tree2 = await smt.newMemEmptyTrie();
|
||||||
|
for (let i = 0; i < 16; i++) {
|
||||||
|
const claim = [bigInt(0), bigInt(i), bigInt(0), bigInt(i)];
|
||||||
|
const entries = newEntry(claim);
|
||||||
|
await tree2.insert(entries.hi, entries.hv);
|
||||||
|
}
|
||||||
|
const root1 = bigIntToBuffer(tree1.root);
|
||||||
|
const root2 = bigIntToBuffer(tree2.root);
|
||||||
|
expect(bytesToHex(root1)).to.be.equal(bytesToHex(root2));
|
||||||
|
expect(bytesToHex(root1)).to.be.equal("0x173fd27f6622526dfb21c4d8d83e3c95adba5d8f46a397113e4e80e629c6de76");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Insert 3 elements in different order into different trees", async () => {
|
||||||
|
const claim1 = [bigInt(33), bigInt(44), bigInt(55), bigInt(66)];
|
||||||
|
const entries1 = newEntry(claim1);
|
||||||
|
const claim2 = [bigInt(1111), bigInt(2222), bigInt(3333), bigInt(4444)];
|
||||||
|
const entries2 = newEntry(claim2);
|
||||||
|
const claim3 = [bigInt(5555), bigInt(6666), bigInt(7777), bigInt(8888)];
|
||||||
|
const entries3 = newEntry(claim3);
|
||||||
|
|
||||||
|
const tree1 = await smt.newMemEmptyTrie();
|
||||||
|
const tree2 = await smt.newMemEmptyTrie();
|
||||||
|
const tree3 = await smt.newMemEmptyTrie();
|
||||||
|
const tree4 = await smt.newMemEmptyTrie();
|
||||||
|
const tree5 = await smt.newMemEmptyTrie();
|
||||||
|
const tree6 = await smt.newMemEmptyTrie();
|
||||||
|
|
||||||
|
await tree1.insert(entries1.hi,entries1.hv);
|
||||||
|
await tree1.insert(entries2.hi,entries2.hv);
|
||||||
|
await tree1.insert(entries3.hi,entries3.hv);
|
||||||
|
|
||||||
|
await tree2.insert(entries1.hi,entries1.hv);
|
||||||
|
await tree2.insert(entries3.hi,entries3.hv);
|
||||||
|
await tree2.insert(entries2.hi,entries2.hv);
|
||||||
|
|
||||||
|
await tree3.insert(entries2.hi,entries2.hv);
|
||||||
|
await tree3.insert(entries1.hi,entries1.hv);
|
||||||
|
await tree3.insert(entries3.hi,entries3.hv);
|
||||||
|
|
||||||
|
await tree4.insert(entries2.hi,entries2.hv);
|
||||||
|
await tree4.insert(entries3.hi,entries3.hv);
|
||||||
|
await tree4.insert(entries1.hi,entries1.hv);
|
||||||
|
|
||||||
|
await tree5.insert(entries3.hi,entries3.hv);
|
||||||
|
await tree5.insert(entries1.hi,entries1.hv);
|
||||||
|
await tree5.insert(entries2.hi,entries2.hv);
|
||||||
|
|
||||||
|
await tree6.insert(entries3.hi,entries3.hv);
|
||||||
|
await tree6.insert(entries2.hi,entries2.hv);
|
||||||
|
await tree6.insert(entries1.hi,entries1.hv);
|
||||||
|
|
||||||
|
const root1 = bigIntToBuffer(tree1.root);
|
||||||
|
const root2 = bigIntToBuffer(tree2.root);
|
||||||
|
const root3 = bigIntToBuffer(tree3.root);
|
||||||
|
const root4 = bigIntToBuffer(tree4.root);
|
||||||
|
const root5 = bigIntToBuffer(tree5.root);
|
||||||
|
const root6 = bigIntToBuffer(tree6.root);
|
||||||
|
|
||||||
|
expect(bytesToHex(root1)).to.be.equal(bytesToHex(root2));
|
||||||
|
expect(bytesToHex(root2)).to.be.equal(bytesToHex(root3));
|
||||||
|
expect(bytesToHex(root3)).to.be.equal(bytesToHex(root4));
|
||||||
|
expect(bytesToHex(root4)).to.be.equal(bytesToHex(root5));
|
||||||
|
expect(bytesToHex(root5)).to.be.equal(bytesToHex(root6));
|
||||||
|
|
||||||
|
expect(bytesToHex(root1)).to.be.equal("0x27990ef22656f49f010b2b48b2418c46f2bc93e4afb2e3377a1eb09f129e9802");
|
||||||
|
});
|
||||||
|
<<<<<<< HEAD
|
||||||
|
*/
|
||||||
|
=======
|
||||||
|
>>>>>>> 5b7abbc4ec56447e5e2baa31e3b4ce3a0c0617a8
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user