mirror of
https://github.com/arnaucube/circomlib.git
synced 2026-02-06 18:56:43 +01:00
Merge other basic circuits here
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
include "../../node_modules/circom/circuits/aliascheck.circom";
|
||||
include "../../circuits/aliascheck.circom";
|
||||
|
||||
component main = AliasCheck()
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
include "../../circuit/babyjub.circom";
|
||||
include "../../circuits/babyjub.circom";
|
||||
|
||||
component main = BabyAdd();
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
include "../../circuit/babyjub.circom";
|
||||
include "../../circuits/babyjub.circom";
|
||||
|
||||
component main = BabyCheck();
|
||||
|
||||
18
test/circuits/constants_test.circom
Normal file
18
test/circuits/constants_test.circom
Normal file
@@ -0,0 +1,18 @@
|
||||
include "../../circuits/sha256/constants.circom"
|
||||
|
||||
template A() {
|
||||
signal input in;
|
||||
component h0;
|
||||
h0 = K(8);
|
||||
|
||||
var lc = 0;
|
||||
var e = 1;
|
||||
for (var i=0; i<32; i++) {
|
||||
lc = lc + e*h0.out[i];
|
||||
e *= 2;
|
||||
}
|
||||
|
||||
lc === in;
|
||||
}
|
||||
|
||||
component main = A();
|
||||
@@ -1,3 +1,3 @@
|
||||
include "../../circuit/eddsa.circom";
|
||||
include "../../circuits/eddsa.circom";
|
||||
|
||||
component main = EdDSAVerifier(80);
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
include "../../circuit/montgomery.circom";
|
||||
include "../../circuits/montgomery.circom";
|
||||
|
||||
component main = Edwards2Montgomery();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
include "../../circuit/escalarmul.circom";
|
||||
include "../../circuits/escalarmul.circom";
|
||||
|
||||
|
||||
template Main() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
include "../../circuit/escalarmul.circom";
|
||||
include "../../node_modules/circom/circuits/bitify.circom";
|
||||
include "../../circuits/escalarmul.circom";
|
||||
include "../../circuits/bitify.circom";
|
||||
|
||||
|
||||
template Main() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
include "../../circuit/escalarmul.circom";
|
||||
include "../../circuits/escalarmul.circom";
|
||||
|
||||
|
||||
template Main() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
include "../../circuit/escalarmulany.circom";
|
||||
include "../../node_modules/circom/circuits/bitify.circom";
|
||||
include "../../circuits/escalarmulany.circom";
|
||||
include "../../circuits/bitify.circom";
|
||||
|
||||
template Main() {
|
||||
signal input e;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
include "../../circuit/escalarmulfix.circom";
|
||||
include "../../node_modules/circom/circuits/bitify.circom";
|
||||
include "../../circuits/escalarmulfix.circom";
|
||||
include "../../circuits/bitify.circom";
|
||||
|
||||
|
||||
template Main() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
include "../../circuit/escalarmulw4table.circom";
|
||||
include "../../circuits/escalarmulw4table.circom";
|
||||
|
||||
var base = [17777552123799933955779906779655732241715742912184938656739573121738514868268,
|
||||
2626589144620713026669568689430873010625803728049924121243784502389097019475]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
include "../../circuit/escalarmulw4table.circom";
|
||||
include "../../circuits/escalarmulw4table.circom";
|
||||
|
||||
var base = [17777552123799933955779906779655732241715742912184938656739573121738514868268,
|
||||
2626589144620713026669568689430873010625803728049924121243784502389097019475];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
include "../../circuit/escalarmulw4table.circom";
|
||||
include "../../circuits/escalarmulw4table.circom";
|
||||
|
||||
var base = [17777552123799933955779906779655732241715742912184938656739573121738514868268,
|
||||
2626589144620713026669568689430873010625803728049924121243784502389097019475]
|
||||
|
||||
4
test/circuits/isequal.circom
Normal file
4
test/circuits/isequal.circom
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
include "../../circuits/comparators.circom";
|
||||
|
||||
component main = IsEqual();
|
||||
5
test/circuits/iszero.circom
Normal file
5
test/circuits/iszero.circom
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
include "../../circuits/comparators.circom";
|
||||
|
||||
component main = IsZero();
|
||||
4
test/circuits/lessthan.circom
Normal file
4
test/circuits/lessthan.circom
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
include "../../circuits/comparators.circom";
|
||||
|
||||
component main = LessThan(32);
|
||||
3
test/circuits/mimc_test.circom
Normal file
3
test/circuits/mimc_test.circom
Normal file
@@ -0,0 +1,3 @@
|
||||
include "../../circuits/mimc.circom"
|
||||
|
||||
component main = MiMC7(91);
|
||||
@@ -1,3 +1,3 @@
|
||||
include "../../circuit/montgomery.circom";
|
||||
include "../../circuits/montgomery.circom";
|
||||
|
||||
component main = Montgomery2Edwards();
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
include "../../circuit/montgomery.circom";
|
||||
include "../../circuits/montgomery.circom";
|
||||
|
||||
component main = MontgomeryAdd();
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
include "../../circuit/montgomery.circom";
|
||||
include "../../circuits/montgomery.circom";
|
||||
|
||||
component main = MontgomeryDouble();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
include "../../circuit/mux3.circom";
|
||||
include "../../node_modules/circom/circuits/bitify.circom";
|
||||
include "../../circuits/mux3.circom";
|
||||
include "../../circuits/bitify.circom";
|
||||
|
||||
|
||||
template Constants() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
include "../../circuit/mux4.circom";
|
||||
include "../../node_modules/circom/circuits/bitify.circom";
|
||||
include "../../circuits/mux4.circom";
|
||||
include "../../circuits/bitify.circom";
|
||||
|
||||
|
||||
template Constants() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
include "../../circuit/pedersen.circom";
|
||||
include "../../node_modules/circom/circuits/bitify.circom";
|
||||
include "../../circuits/pedersen.circom";
|
||||
include "../../circuits/bitify.circom";
|
||||
|
||||
|
||||
template Main() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
include "../../circuit/pedersen_old.circom";
|
||||
include "../../node_modules/circom/circuits/bitify.circom";
|
||||
include "../../circuits/pedersen_old.circom";
|
||||
include "../../circuits/bitify.circom";
|
||||
|
||||
|
||||
template Main() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
include "../../circuit/pointbits.circom";
|
||||
include "../../circuits/pointbits.circom";
|
||||
|
||||
|
||||
template Main() {
|
||||
|
||||
15
test/circuits/sha256_2_test.circom
Normal file
15
test/circuits/sha256_2_test.circom
Normal file
@@ -0,0 +1,15 @@
|
||||
include "../../circuits/sha256/sha256_2.circom";
|
||||
|
||||
template Main() {
|
||||
signal private input a;
|
||||
signal private input b;
|
||||
signal output out;
|
||||
|
||||
component sha256_2 = Sha256_2();
|
||||
|
||||
sha256_2.a <== a;
|
||||
sha256_2.b <== b;
|
||||
out <== sha256_2.out;
|
||||
}
|
||||
|
||||
component main = Main();
|
||||
@@ -1,3 +1,3 @@
|
||||
include "../../circuit/sign.circom";
|
||||
include "../../circuits/sign.circom";
|
||||
|
||||
component main = Sign();
|
||||
|
||||
26
test/circuits/sum_test.circom
Normal file
26
test/circuits/sum_test.circom
Normal file
@@ -0,0 +1,26 @@
|
||||
include "../../circuits/bitify.circom"
|
||||
include "../../circuits/binsum.circom"
|
||||
|
||||
template A() {
|
||||
signal private input a;
|
||||
signal input b;
|
||||
signal output out;
|
||||
|
||||
component n2ba = Num2Bits(32);
|
||||
component n2bb = Num2Bits(32);
|
||||
component sum = BinSum(32,2);
|
||||
component b2n = Bits2Num(32);
|
||||
|
||||
n2ba.in <== a;
|
||||
n2bb.in <== b;
|
||||
|
||||
for (var i=0; i<32; i++) {
|
||||
sum.in[0][i] <== n2ba.out[i];
|
||||
sum.in[1][i] <== n2bb.out[i];
|
||||
b2n.in[i] <== sum.out[i];
|
||||
}
|
||||
|
||||
out <== b2n.out;
|
||||
}
|
||||
|
||||
component main = A();
|
||||
77
test/comparators.js
Normal file
77
test/comparators.js
Normal file
@@ -0,0 +1,77 @@
|
||||
const chai = require("chai");
|
||||
const path = require("path");
|
||||
const snarkjs = require("snarkjs");
|
||||
const crypto = require("crypto");
|
||||
|
||||
const compiler = require("circom");
|
||||
|
||||
const assert = chai.assert;
|
||||
|
||||
describe("Sum test", () => {
|
||||
it("Should create a iszero circuit", async() => {
|
||||
const cirDef = await compiler(path.join(__dirname, "circuits", "iszero.circom"));
|
||||
|
||||
const circuit = new snarkjs.Circuit(cirDef);
|
||||
|
||||
let witness;
|
||||
witness = circuit.calculateWitness({ "in": 111});
|
||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||
|
||||
witness = circuit.calculateWitness({ "in": 0 });
|
||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||
});
|
||||
it("Should create a isequal circuit", async() => {
|
||||
const cirDef = await compiler(path.join(__dirname, "circuits", "isequal.circom"));
|
||||
|
||||
const circuit = new snarkjs.Circuit(cirDef);
|
||||
|
||||
let witness;
|
||||
witness = circuit.calculateWitness({ "in[0]": "111", "in[1]": "222" });
|
||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||
|
||||
witness = circuit.calculateWitness({ "in[0]": "444", "in[1]": "444" });
|
||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||
});
|
||||
it("Should create a comparison", async() => {
|
||||
const cirDef = await compiler(path.join(__dirname, "circuits", "lessthan.circom"));
|
||||
|
||||
const circuit = new snarkjs.Circuit(cirDef);
|
||||
|
||||
let witness;
|
||||
witness = circuit.calculateWitness({ "in[0]": "333", "in[1]": "444" });
|
||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||
|
||||
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "1" });
|
||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||
|
||||
witness = circuit.calculateWitness({ "in[0]": "661", "in[1]": "660" });
|
||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||
|
||||
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "1" });
|
||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||
|
||||
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "444" });
|
||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
||||
|
||||
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "0" });
|
||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||
|
||||
witness = circuit.calculateWitness({ "in[0]": "555", "in[1]": "0" });
|
||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||
|
||||
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "0" });
|
||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
||||
});
|
||||
});
|
||||
@@ -5,17 +5,17 @@ const compiler = require("circom");
|
||||
|
||||
const assert = chai.assert;
|
||||
|
||||
const bigInt = require("big-integer");
|
||||
const bigInt = snarkjs.bigInt;
|
||||
|
||||
|
||||
const q=21888242871839275222246405745257275088548364400416034343698204186575808495617n
|
||||
const q=bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
function addPoint(a,b) {
|
||||
const cta = 168700n;
|
||||
const d = 168696n;
|
||||
const cta = bigInt("168700");
|
||||
const d = bigInt("168696");
|
||||
|
||||
const res = [];
|
||||
res[0] = bigInt((a[0]*b[1] + b[0]*a[1]) * bigInt(1n + d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
||||
res[1] = bigInt((a[1]*b[1] - cta*a[0]*b[0]) * bigInt(1n - d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
||||
res[0] = bigInt((a[0]*b[1] + b[0]*a[1]) * bigInt(bigInt.one + d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
||||
res[1] = bigInt((a[1]*b[1] - cta*a[0]*b[0]) * bigInt(bigInt.one - d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -38,10 +38,10 @@ describe("Exponentioation test", () => {
|
||||
|
||||
const w = circuit.calculateWitness({});
|
||||
|
||||
let g = [snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475")]
|
||||
let g = [bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||
bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475")]
|
||||
|
||||
dbl= [snarkjs.bigInt("0"), snarkjs.bigInt("1")];
|
||||
dbl= [bigInt("0"), snarkjs.bigInt("1")];
|
||||
|
||||
for (let i=0; i<16; i++) {
|
||||
const xout1 = w[circuit.getSignalIdx(`main.out[${i}][0]`)];
|
||||
|
||||
22
test/helpers/printsignal.js
Normal file
22
test/helpers/printsignal.js
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
const snarkjs = require("snarkjs");
|
||||
|
||||
const bigInt = snarkjs.bigInt;
|
||||
|
||||
module.exports = function hexBits(cir, witness, sig, nBits) {
|
||||
let v = bigInt(0);
|
||||
for (let i=nBits-1; i>=0; i--) {
|
||||
v = v.shiftLeft(1);
|
||||
const name = sig+"["+i+"]";
|
||||
const idx = cir.getSignalIdx(name);
|
||||
const vbit = bigInt(witness[idx].toString());
|
||||
if (vbit.equals(bigInt(1))) {
|
||||
v = v.add(bigInt(1));
|
||||
} else if (vbit.equals(bigInt(0))) {
|
||||
v;
|
||||
} else {
|
||||
console.log("Not Binary: "+name);
|
||||
}
|
||||
}
|
||||
return v.toString(16);
|
||||
};
|
||||
178
test/helpers/sha256.js
Normal file
178
test/helpers/sha256.js
Normal file
@@ -0,0 +1,178 @@
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
/* SHA-256 (FIPS 180-4) implementation in JavaScript (c) Chris Veness 2002-2017 */
|
||||
/* MIT Licence */
|
||||
/* www.movable-type.co.uk/scripts/sha256.html */
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
'use strict';
|
||||
|
||||
|
||||
/**
|
||||
* SHA-256 hash function reference implementation.
|
||||
*
|
||||
* This is an annotated direct implementation of FIPS 180-4, without any optimisations. It is
|
||||
* intended to aid understanding of the algorithm rather than for production use.
|
||||
*
|
||||
* While it could be used where performance is not critical, I would recommend using the ‘Web
|
||||
* Cryptography API’ (developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest) for the browser,
|
||||
* or the ‘crypto’ library (nodejs.org/api/crypto.html#crypto_class_hash) in Node.js.
|
||||
*
|
||||
* See csrc.nist.gov/groups/ST/toolkit/secure_hashing.html
|
||||
* csrc.nist.gov/groups/ST/toolkit/examples.html
|
||||
*/
|
||||
class Sha256 {
|
||||
|
||||
/**
|
||||
* Generates SHA-256 hash of string.
|
||||
*
|
||||
* @param {string} msg - (Unicode) string to be hashed.
|
||||
* @param {Object} [options]
|
||||
* @param {string} [options.msgFormat=string] - Message format: 'string' for JavaScript string
|
||||
* (gets converted to UTF-8 for hashing); 'hex-bytes' for string of hex bytes ('616263' ≡ 'abc') .
|
||||
* @param {string} [options.outFormat=hex] - Output format: 'hex' for string of contiguous
|
||||
* hex bytes; 'hex-w' for grouping hex bytes into groups of (4 byte / 8 character) words.
|
||||
* @returns {string} Hash of msg as hex character string.
|
||||
*/
|
||||
static hash(msg, options) {
|
||||
const defaults = { msgFormat: 'string', outFormat: 'hex' };
|
||||
const opt = Object.assign(defaults, options);
|
||||
|
||||
// note use throughout this routine of 'n >>> 0' to coerce Number 'n' to unsigned 32-bit integer
|
||||
|
||||
switch (opt.msgFormat) {
|
||||
default: // default is to convert string to UTF-8, as SHA only deals with byte-streams
|
||||
case 'string': msg = utf8Encode(msg); break;
|
||||
case 'hex-bytes':msg = hexBytesToString(msg); break; // mostly for running tests
|
||||
}
|
||||
|
||||
// constants [§4.2.2]
|
||||
const K = [
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ];
|
||||
|
||||
// initial hash value [§5.3.3]
|
||||
const H = [
|
||||
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ];
|
||||
|
||||
// PREPROCESSING [§6.2.1]
|
||||
|
||||
msg += String.fromCharCode(0x80); // add trailing '1' bit (+ 0's padding) to string [§5.1.1]
|
||||
|
||||
// convert string msg into 512-bit blocks (array of 16 32-bit integers) [§5.2.1]
|
||||
const l = msg.length/4 + 2; // length (in 32-bit integers) of msg + ‘1’ + appended length
|
||||
const N = Math.ceil(l/16); // number of 16-integer (512-bit) blocks required to hold 'l' ints
|
||||
const M = new Array(N); // message M is N×16 array of 32-bit integers
|
||||
|
||||
for (let i=0; i<N; i++) {
|
||||
M[i] = new Array(16);
|
||||
for (let j=0; j<16; j++) { // encode 4 chars per integer (64 per block), big-endian encoding
|
||||
M[i][j] = (msg.charCodeAt(i*64+j*4+0)<<24) | (msg.charCodeAt(i*64+j*4+1)<<16)
|
||||
| (msg.charCodeAt(i*64+j*4+2)<< 8) | (msg.charCodeAt(i*64+j*4+3)<< 0);
|
||||
} // note running off the end of msg is ok 'cos bitwise ops on NaN return 0
|
||||
}
|
||||
// add length (in bits) into final pair of 32-bit integers (big-endian) [§5.1.1]
|
||||
// note: most significant word would be (len-1)*8 >>> 32, but since JS converts
|
||||
// bitwise-op args to 32 bits, we need to simulate this by arithmetic operators
|
||||
const lenHi = ((msg.length-1)*8) / Math.pow(2, 32);
|
||||
const lenLo = ((msg.length-1)*8) >>> 0;
|
||||
M[N-1][14] = Math.floor(lenHi);
|
||||
M[N-1][15] = lenLo;
|
||||
|
||||
// HASH COMPUTATION [§6.2.2]
|
||||
|
||||
for (let i=0; i<N; i++) {
|
||||
const W = new Array(64);
|
||||
|
||||
// 1 - prepare message schedule 'W'
|
||||
for (let t=0; t<16; t++) W[t] = M[i][t];
|
||||
for (let t=16; t<64; t++) {
|
||||
W[t] = (Sha256.σ1(W[t-2]) + W[t-7] + Sha256.σ0(W[t-15]) + W[t-16]) >>> 0;
|
||||
}
|
||||
|
||||
// 2 - initialise working variables a, b, c, d, e, f, g, h with previous hash value
|
||||
let a = H[0], b = H[1], c = H[2], d = H[3], e = H[4], f = H[5], g = H[6], h = H[7];
|
||||
|
||||
// 3 - main loop (note '>>> 0' for 'addition modulo 2^32')
|
||||
for (let t=0; t<64; t++) {
|
||||
const T1 = h + Sha256.Σ1(e) + Sha256.Ch(e, f, g) + K[t] + W[t];
|
||||
const T2 = Sha256.Σ0(a) + Sha256.Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = (d + T1) >>> 0;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = (T1 + T2) >>> 0;
|
||||
}
|
||||
|
||||
// 4 - compute the new intermediate hash value (note '>>> 0' for 'addition modulo 2^32')
|
||||
H[0] = (H[0]+a) >>> 0;
|
||||
H[1] = (H[1]+b) >>> 0;
|
||||
H[2] = (H[2]+c) >>> 0;
|
||||
H[3] = (H[3]+d) >>> 0;
|
||||
H[4] = (H[4]+e) >>> 0;
|
||||
H[5] = (H[5]+f) >>> 0;
|
||||
H[6] = (H[6]+g) >>> 0;
|
||||
H[7] = (H[7]+h) >>> 0;
|
||||
}
|
||||
|
||||
// convert H0..H7 to hex strings (with leading zeros)
|
||||
for (let h=0; h<H.length; h++) H[h] = ('00000000'+H[h].toString(16)).slice(-8);
|
||||
|
||||
// concatenate H0..H7, with separator if required
|
||||
const separator = opt.outFormat=='hex-w' ? ' ' : '';
|
||||
|
||||
return H.join(separator);
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
function utf8Encode(str) {
|
||||
try {
|
||||
return new TextEncoder().encode(str, 'utf-8').reduce((prev, curr) => prev + String.fromCharCode(curr), '');
|
||||
} catch (e) { // no TextEncoder available?
|
||||
return unescape(encodeURIComponent(str)); // monsur.hossa.in/2012/07/20/utf-8-in-javascript.html
|
||||
}
|
||||
}
|
||||
|
||||
function hexBytesToString(hexStr) { // convert string of hex numbers to a string of chars (eg '616263' -> 'abc').
|
||||
const str = hexStr.replace(' ', ''); // allow space-separated groups
|
||||
return str=='' ? '' : str.match(/.{2}/g).map(byte => String.fromCharCode(parseInt(byte, 16))).join('');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Rotates right (circular right shift) value x by n positions [§3.2.4].
|
||||
* @private
|
||||
*/
|
||||
static ROTR(n, x) {
|
||||
return (x >>> n) | (x << (32-n));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Logical functions [§4.1.2].
|
||||
* @private
|
||||
*/
|
||||
static Σ0(x) { return Sha256.ROTR(2, x) ^ Sha256.ROTR(13, x) ^ Sha256.ROTR(22, x); }
|
||||
static Σ1(x) { return Sha256.ROTR(6, x) ^ Sha256.ROTR(11, x) ^ Sha256.ROTR(25, x); }
|
||||
static σ0(x) { return Sha256.ROTR(7, x) ^ Sha256.ROTR(18, x) ^ (x>>>3); }
|
||||
static σ1(x) { return Sha256.ROTR(17, x) ^ Sha256.ROTR(19, x) ^ (x>>>10); }
|
||||
static Ch(x, y, z) { return (x & y) ^ (~x & z); } // 'choice'
|
||||
static Maj(x, y, z) { return (x & y) ^ (x & z) ^ (y & z); } // 'majority'
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
if (typeof module != 'undefined' && module.exports) module.exports = Sha256; // ≡ export default Sha256
|
||||
|
||||
35
test/mimccircuit.js
Normal file
35
test/mimccircuit.js
Normal file
@@ -0,0 +1,35 @@
|
||||
const chai = require("chai");
|
||||
const path = require("path");
|
||||
const snarkjs = require("snarkjs");
|
||||
const compiler = require("circom");
|
||||
|
||||
const mimcjs = require("../src/mimc7.js");
|
||||
|
||||
const assert = chai.assert;
|
||||
|
||||
describe("MiMC Circuit test", function () {
|
||||
let circuit;
|
||||
|
||||
this.timeout(100000);
|
||||
|
||||
before( async () => {
|
||||
const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_test.circom"));
|
||||
|
||||
circuit = new snarkjs.Circuit(cirDef);
|
||||
|
||||
console.log("MiMC constraints: " + circuit.nConstraints);
|
||||
});
|
||||
|
||||
it("Should check constrain", async () => {
|
||||
const w = circuit.calculateWitness({x_in: 1, k: 2});
|
||||
|
||||
const res = w[circuit.getSignalIdx("main.out")];
|
||||
|
||||
const res2 = mimcjs.hash(1,2,91);
|
||||
|
||||
assert.equal(res.toString(), res2.toString());
|
||||
|
||||
assert(circuit.checkWitness(w));
|
||||
|
||||
});
|
||||
});
|
||||
52
test/mimccontract.js
Normal file
52
test/mimccontract.js
Normal file
@@ -0,0 +1,52 @@
|
||||
const TestRPC = require("ganache-cli");
|
||||
const Web3 = require("web3");
|
||||
const chai = require("chai");
|
||||
const mimcGenContract = require("../src/mimc_gencontract.js");
|
||||
const mimcjs = require("../src/mimc7.js");
|
||||
|
||||
|
||||
const assert = chai.assert;
|
||||
const log = (msg) => { if (process.env.MOCHA_VERBOSE) console.log(msg); };
|
||||
|
||||
const SEED = "iden3_mimc";
|
||||
|
||||
describe("MiMC Smart contract test", () => {
|
||||
let testrpc;
|
||||
let web3;
|
||||
let mimc;
|
||||
let accounts;
|
||||
|
||||
before(async () => {
|
||||
testrpc = TestRPC.server({
|
||||
ws: true,
|
||||
gasLimit: 5800000,
|
||||
total_accounts: 10,
|
||||
});
|
||||
|
||||
testrpc.listen(8546, "127.0.0.1");
|
||||
|
||||
web3 = new Web3("ws://127.0.0.1:8546");
|
||||
accounts = await web3.eth.getAccounts();
|
||||
});
|
||||
|
||||
after(async () => testrpc.close());
|
||||
|
||||
it("Should deploy the contract", async () => {
|
||||
const C = new web3.eth.Contract(mimcGenContract.abi);
|
||||
|
||||
mimc = await C.deploy({
|
||||
data: mimcGenContract.createCode(SEED, 91)
|
||||
}).send({
|
||||
gas: 1500000,
|
||||
from: accounts[0]
|
||||
});
|
||||
});
|
||||
|
||||
it("Shold calculate the mimic correctly", async () => {
|
||||
const res = await mimc.methods.MiMCpe7(1,2).call();
|
||||
const res2 = await mimcjs.hash(1,2,91);
|
||||
|
||||
assert.equal(res.toString(), res2.toString());
|
||||
});
|
||||
});
|
||||
|
||||
42
test/sha256.js
Normal file
42
test/sha256.js
Normal file
@@ -0,0 +1,42 @@
|
||||
const chai = require("chai");
|
||||
const path = require("path");
|
||||
const snarkjs = require("snarkjs");
|
||||
const crypto = require("crypto");
|
||||
|
||||
const compiler = require("circom");
|
||||
|
||||
const assert = chai.assert;
|
||||
|
||||
const sha256 = require("./helpers/sha256");
|
||||
|
||||
// const printSignal = require("./helpers/printsignal");
|
||||
|
||||
|
||||
describe("SHA256 test", () => {
|
||||
it("Should calculate a hash", async () => {
|
||||
const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_2_test.circom"));
|
||||
const circuit = new snarkjs.Circuit(cirDef);
|
||||
|
||||
console.log("Vars: "+circuit.nVars);
|
||||
console.log("Constraints: "+circuit.nConstraints);
|
||||
|
||||
const witness = circuit.calculateWitness({ "a": "1", "b": "2" });
|
||||
|
||||
const b = new Buffer.alloc(54);
|
||||
b[26] = 1;
|
||||
b[53] = 2;
|
||||
|
||||
const hash = crypto.createHash("sha256")
|
||||
.update(b)
|
||||
.digest("hex");
|
||||
const r = "0x" + hash.slice(10);
|
||||
|
||||
const hash2 = sha256.hash(b.toString("hex"), {msgFormat: "hex-bytes"});
|
||||
|
||||
assert.equal(hash, hash2);
|
||||
|
||||
assert(witness[1].equals(snarkjs.bigInt(r)));
|
||||
}).timeout(1000000);
|
||||
|
||||
|
||||
});
|
||||
35
test/sum.js
Normal file
35
test/sum.js
Normal file
@@ -0,0 +1,35 @@
|
||||
const chai = require("chai");
|
||||
const path = require("path");
|
||||
const snarkjs = require("snarkjs");
|
||||
const crypto = require("crypto");
|
||||
|
||||
const compiler = require("circom");
|
||||
|
||||
const assert = chai.assert;
|
||||
|
||||
describe("Sum test", () => {
|
||||
it("Should create a constant circuit", async () => {
|
||||
|
||||
const cirDef = await compiler(path.join(__dirname, "circuits", "constants_test.circom"));
|
||||
assert.equal(cirDef.nVars, 2);
|
||||
|
||||
const circuit = new snarkjs.Circuit(cirDef);
|
||||
|
||||
const witness = circuit.calculateWitness({ "in": "0xd807aa98" });
|
||||
|
||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||
assert(witness[1].equals(snarkjs.bigInt("0xd807aa98")));
|
||||
});
|
||||
it("Should create a sum circuit", async () => {
|
||||
|
||||
const cirDef = await compiler(path.join(__dirname, "circuits", "sum_test.circom"));
|
||||
assert.equal(cirDef.nVars, 101);
|
||||
|
||||
const circuit = new snarkjs.Circuit(cirDef);
|
||||
|
||||
const witness = circuit.calculateWitness({ "a": "111", "b": "222" });
|
||||
|
||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
||||
assert(witness[1].equals(snarkjs.bigInt("333")));
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user