From 42e96c2e1f23da52cac93bb3f7f9c49e0853de93 Mon Sep 17 00:00:00 2001 From: Kobi Gurkan Date: Sat, 23 Nov 2019 21:36:06 +0200 Subject: [PATCH] makes S value in eddsa signatures be 251 bit, uses alias checks with enabled flag and adds eddsamimcsponge test --- circuits/aliascheck.circom | 3 +- circuits/eddsa.circom | 13 +-- circuits/eddsamimc.circom | 17 ++-- circuits/eddsamimcsponge.circom | 17 ++-- circuits/eddsaposeidon.circom | 15 ++-- test/circuits/eddsamimcsponge_test.circom | 3 + test/eddsamimc.js | 3 +- test/eddsamimcsponge.js | 99 +++++++++++++++++++++++ test/eddsaposeidon.js | 3 +- 9 files changed, 139 insertions(+), 34 deletions(-) create mode 100644 test/circuits/eddsamimcsponge_test.circom create mode 100644 test/eddsamimcsponge.js diff --git a/circuits/aliascheck.circom b/circuits/aliascheck.circom index 4352a0a..a5e8fb7 100644 --- a/circuits/aliascheck.circom +++ b/circuits/aliascheck.circom @@ -32,11 +32,12 @@ template AliasCheck() { template AliasCheckBabyJub() { signal input in[251]; + signal input enabled; component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040); for (var i=0; i<251; i++) in[i] ==> compConstant.in[i]; for (var i=0; i<3; i++) 0 ==> compConstant.in[251+i]; - compConstant.out === 0; + compConstant.out*enabled === 0; } diff --git a/circuits/eddsa.circom b/circuits/eddsa.circom index 1026774..93cfbe6 100644 --- a/circuits/eddsa.circom +++ b/circuits/eddsa.circom @@ -17,7 +17,7 @@ along with circom. If not, see . */ -include "compconstant.circom"; +include "aliascheck.circom"; include "pointbits.circom"; include "pedersen.circom"; include "escalarmulany.circom"; @@ -40,12 +40,15 @@ template EdDSAVerifier(n) { // Ensure S compConstant.in[i]; + for (i=0; i<251; i++) { + S[i] ==> aliasCheck.in[i]; } - compConstant.out === 0; + S[251] === 0; + S[252] === 0; + S[253] === 0; S[254] === 0; S[255] === 0; diff --git a/circuits/eddsamimc.circom b/circuits/eddsamimc.circom index aef5df5..0d5b01d 100644 --- a/circuits/eddsamimc.circom +++ b/circuits/eddsamimc.circom @@ -17,7 +17,7 @@ along with circom. If not, see . */ -include "compconstant.circom"; +include "aliascheck.circom"; include "pointbits.circom"; include "mimc.circom"; include "bitify.circom"; @@ -39,16 +39,15 @@ template EdDSAMiMCVerifier() { // Ensure S compConstant.in[i]; + for (i=0; i<251; i++) { + snum2bits.out[i] ==> aliasCheck.in[i]; } - compConstant.in[253] <== 0; - compConstant.out === 0; // Calculate the h = H(R,A, msg) @@ -104,8 +103,8 @@ template EdDSAMiMCVerifier() { 5299619240641551281634865583518297030282874472190772894086521144482721001553, 16950150798460657717958625567821834550301663161624707787222815936182638968203 ]; - component mulFix = EscalarMulFix(253, BASE8); - for (i=0; i<253; i++) { + component mulFix = EscalarMulFix(251, BASE8); + for (i=0; i<251; i++) { mulFix.e[i] <== snum2bits.out[i]; } diff --git a/circuits/eddsamimcsponge.circom b/circuits/eddsamimcsponge.circom index 93405e9..ffa22a5 100644 --- a/circuits/eddsamimcsponge.circom +++ b/circuits/eddsamimcsponge.circom @@ -17,7 +17,7 @@ along with circom. If not, see . */ -include "compconstant.circom"; +include "aliascheck.circom"; include "pointbits.circom"; include "mimcsponge.circom"; include "bitify.circom"; @@ -39,16 +39,15 @@ template EdDSAMiMCSpongeVerifier() { // Ensure S compConstant.in[i]; + for (i=0; i<251; i++) { + snum2bits.out[i] ==> aliasCheck.in[i]; } - compConstant.in[253] <== 0; - compConstant.out === 0; // Calculate the h = H(R,A, msg) @@ -104,8 +103,8 @@ template EdDSAMiMCSpongeVerifier() { 5299619240641551281634865583518297030282874472190772894086521144482721001553, 16950150798460657717958625567821834550301663161624707787222815936182638968203 ]; - component mulFix = EscalarMulFix(253, BASE8); - for (i=0; i<253; i++) { + component mulFix = EscalarMulFix(251, BASE8); + for (i=0; i<251; i++) { mulFix.e[i] <== snum2bits.out[i]; } diff --git a/circuits/eddsaposeidon.circom b/circuits/eddsaposeidon.circom index 0d9faa0..fb6c782 100644 --- a/circuits/eddsaposeidon.circom +++ b/circuits/eddsaposeidon.circom @@ -38,16 +38,15 @@ template EdDSAPoseidonVerifier() { // Ensure S compConstant.in[i]; + for (i=0; i<251; i++) { + snum2bits.out[i] ==> aliasCheck.in[i]; } - compConstant.in[253] <== 0; - compConstant.out*enabled === 0; // Calculate the h = H(R,A, msg) @@ -103,8 +102,8 @@ template EdDSAPoseidonVerifier() { 5299619240641551281634865583518297030282874472190772894086521144482721001553, 16950150798460657717958625567821834550301663161624707787222815936182638968203 ]; - component mulFix = EscalarMulFix(253, BASE8); - for (i=0; i<253; i++) { + component mulFix = EscalarMulFix(251, BASE8); + for (i=0; i<251; i++) { mulFix.e[i] <== snum2bits.out[i]; } diff --git a/test/circuits/eddsamimcsponge_test.circom b/test/circuits/eddsamimcsponge_test.circom new file mode 100644 index 0000000..ee27dc5 --- /dev/null +++ b/test/circuits/eddsamimcsponge_test.circom @@ -0,0 +1,3 @@ +include "../../circuits/eddsamimcsponge.circom"; + +component main = EdDSAMiMCSpongeVerifier(); diff --git a/test/eddsamimc.js b/test/eddsamimc.js index 76f0a4f..e5bdc9a 100644 --- a/test/eddsamimc.js +++ b/test/eddsamimc.js @@ -67,7 +67,8 @@ describe("EdDSA MiMC test", function () { M: msg}); assert(false); } catch(err) { - assert.equal(err.message, "Constraint doesn't match: 1 != 0"); + assert(err.message.indexOf("Constraint doesn't match") >= 0); + assert(err.message.indexOf("1 != 0") >= 0); } }); diff --git a/test/eddsamimcsponge.js b/test/eddsamimcsponge.js new file mode 100644 index 0000000..160e32d --- /dev/null +++ b/test/eddsamimcsponge.js @@ -0,0 +1,99 @@ +const chai = require("chai"); +const path = require("path"); +const snarkjs = require("snarkjs"); +const compiler = require("circom"); + +const eddsa = require("../src/eddsa.js"); + +const assert = chai.assert; + +const bigInt = snarkjs.bigInt; + +describe("EdDSA MiMCSponge test", function () { + let circuit; + + this.timeout(100000); + + before( async () => { + const cirDef = await compiler(path.join(__dirname, "circuits", "eddsamimcsponge_test.circom")); + + circuit = new snarkjs.Circuit(cirDef); + + console.log("NConstrains EdDSA MiMCSponge: " + circuit.nConstraints); + }); + + it("Sign a single number", async () => { + const msg = bigInt(1234); + + const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); + + const pubKey = eddsa.prv2pub(prvKey); + + const signature = eddsa.signMiMCSponge(prvKey, msg); + + assert(eddsa.verifyMiMCSponge(msg, signature, pubKey)); + + const w = circuit.calculateWitness({ + enabled: 1, + Ax: pubKey[0], + Ay: pubKey[1], + R8x: signature.R8[0], + R8y: signature.R8[1], + S: signature.S, + M: msg}); + + assert(circuit.checkWitness(w)); + }); + + it("Detect Invalid signature", async () => { + const msg = bigInt(1234); + + const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); + + const pubKey = eddsa.prv2pub(prvKey); + + + const signature = eddsa.signMiMCSponge(prvKey, msg); + + assert(eddsa.verifyMiMCSponge(msg, signature, pubKey)); + try { + const w = circuit.calculateWitness({ + enabled: 1, + Ax: pubKey[0], + Ay: pubKey[1], + R8x: signature.R8[0].add(bigInt(1)), + R8y: signature.R8[1], + S: signature.S, + M: msg}); + assert(false); + } catch(err) { + assert(err.message.indexOf("Constraint doesn't match") >= 0); + assert(err.message.indexOf("1 != 0") >= 0); + } + }); + + + it("Test a dissabled circuit with a bad signature", async () => { + const msg = bigInt(1234); + + const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); + + const pubKey = eddsa.prv2pub(prvKey); + + + const signature = eddsa.signMiMCSponge(prvKey, msg); + + assert(eddsa.verifyMiMCSponge(msg, signature, pubKey)); + + const w = circuit.calculateWitness({ + enabled: 0, + Ax: pubKey[0], + Ay: pubKey[1], + R8x: signature.R8[0].add(bigInt(1)), + R8y: signature.R8[1], + S: signature.S, + M: msg}); + + assert(circuit.checkWitness(w)); + }); +}); diff --git a/test/eddsaposeidon.js b/test/eddsaposeidon.js index 8b0e82a..b018a0d 100644 --- a/test/eddsaposeidon.js +++ b/test/eddsaposeidon.js @@ -67,7 +67,8 @@ describe("EdDSA Poseidon test", function () { M: msg}); assert(false); } catch(err) { - assert.equal(err.message, "Constraint doesn't match: 1 != 0"); + assert(err.message.indexOf("Constraint doesn't match") >= 0); + assert(err.message.indexOf("1 != 0") >= 0); } });