diff --git a/circuits/babyjub.circom b/circuits/babyjub.circom index a2e6b6b..c6fe41c 100644 --- a/circuits/babyjub.circom +++ b/circuits/babyjub.circom @@ -17,6 +17,9 @@ along with circom. If not, see . */ +include "bitify.circom"; +include "escalarmulfix.circom"; + template BabyAdd() { signal input x1; signal input y1; @@ -77,3 +80,27 @@ template BabyCheck() { 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]; +} diff --git a/test/babyjub.js b/test/babyjub.js index abe1b0b..f47db49 100644 --- a/test/babyjub.js +++ b/test/babyjub.js @@ -3,10 +3,12 @@ const path = require("path"); const snarkjs = require("snarkjs"); const compiler = require("circom"); -const assert = chai.assert; +const createBlakeHash = require("blake-hash"); +const eddsa = require("../src/eddsa.js"); -const bigInt = require("big-integer"); +const assert = chai.assert; +const bigInt = require("snarkjs").bigInt; describe("Baby Jub test", function () { let circuitAdd; @@ -22,6 +24,11 @@ describe("Baby Jub test", function () { const cirDefTest = await compiler(path.join(__dirname, "circuits", "babycheck_test.circom")); circuitTest = new snarkjs.Circuit(cirDefTest); 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 () => { @@ -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)); + }); + }); diff --git a/test/circuits/babypbk_test.circom b/test/circuits/babypbk_test.circom new file mode 100644 index 0000000..2583bb9 --- /dev/null +++ b/test/circuits/babypbk_test.circom @@ -0,0 +1,3 @@ +include "../../circuits/babyjub.circom"; + +component main = BabyPbk(); \ No newline at end of file