Skip to content

Commit

Permalink
Merge pull request #13 from hyperledger-labs/proving-keys
Browse files Browse the repository at this point in the history
zeto-js should make no assumptions about environment variables
  • Loading branch information
awrichar committed Jul 12, 2024
2 parents 80a17a9 + d3fc8c1 commit ebfa06b
Show file tree
Hide file tree
Showing 23 changed files with 162 additions and 94 deletions.
1 change: 1 addition & 0 deletions solidity/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 39 additions & 0 deletions solidity/test/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright © 2024 Kaleido, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { readFileSync } from "fs";
import * as path from "path";

function provingKeysRoot() {
const PROVING_KEYS_ROOT = process.env.PROVING_KEYS_ROOT;
if (!PROVING_KEYS_ROOT) {
throw new Error("PROVING_KEYS_ROOT env var is not set");
}
return PROVING_KEYS_ROOT;
}

export function loadProvingKeys(type: string) {
const provingKeyFile = path.join(provingKeysRoot(), `${type}.zkey`);
const verificationKey = JSON.parse(
new TextDecoder().decode(
readFileSync(path.join(provingKeysRoot(), `${type}-vkey.json`))
)
);
return {
provingKeyFile,
verificationKey,
};
}
9 changes: 4 additions & 5 deletions solidity/test/zeto_anon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
import { ethers, ignition } from 'hardhat';
import { Signer, BigNumberish, AddressLike, ContractTransactionReceipt, ZeroAddress } from 'ethers';
import { expect } from 'chai';
import { loadCircuits, encodeProof, Poseidon } from "zeto-js";
import { loadCircuit, encodeProof, Poseidon } from "zeto-js";
import { groth16 } from 'snarkjs';
import { formatPrivKeyForBabyJub, stringifyBigInts } from 'maci-crypto';
import { User, UTXO, newUser, newUTXO, doMint, parseUTXOEvents } from './lib/utils';

import RegistryModule from '../ignition/modules/registry';
import zetoModule from '../ignition/modules/zeto_anon';
import { loadProvingKeys } from './utils';

const ZERO_PUBKEY = [0, 0];
const poseidonHash = Poseidon.poseidon4;
Expand Down Expand Up @@ -57,9 +57,8 @@ describe("Zeto based fungible token with anonymity without encryption or nullifi
const tx3 = await registry.connect(deployer).register(Charlie.ethAddress, Charlie.babyJubPublicKey as [BigNumberish, BigNumberish]);
await tx3.wait();

const result = await loadCircuits('anon');
circuit = result.circuit;
provingKey = result.provingKeyFile;
circuit = await loadCircuit('anon');
({ provingKeyFile: provingKey } = loadProvingKeys('anon'));
});

it("mint to Alice and transfer UTXOs honestly to Bob should succeed", async function () {
Expand Down
8 changes: 4 additions & 4 deletions solidity/test/zeto_anon_enc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
import { ethers, ignition } from 'hardhat';
import { ContractTransactionReceipt, Signer, BigNumberish, AddressLike } from 'ethers';
import { expect } from 'chai';
import { loadCircuits, poseidonDecrypt, encodeProof, Poseidon } from "zeto-js";
import { loadCircuit, poseidonDecrypt, encodeProof, Poseidon } from "zeto-js";
import { groth16 } from 'snarkjs';
import { genRandomSalt, formatPrivKeyForBabyJub, genEcdhSharedKey, stringifyBigInts } from 'maci-crypto';
import RegistryModule from '../ignition/modules/registry';
import zetoModule from '../ignition/modules/zeto_anon_enc';
import { User, UTXO, newUser, newUTXO, doMint, ZERO_UTXO, parseUTXOEvents } from './lib/utils';
import { loadProvingKeys } from './utils';

const poseidonHash = Poseidon.poseidon4;

Expand Down Expand Up @@ -56,9 +57,8 @@ describe("Zeto based fungible token with anonymity and encryption", function ()
const tx3 = await registry.connect(deployer).register(Charlie.ethAddress, Charlie.babyJubPublicKey as [BigNumberish, BigNumberish]);
await tx3.wait();

const result = await loadCircuits('anon_enc');
circuit = result.circuit;
provingKey = result.provingKeyFile;
circuit = await loadCircuit('anon_enc');
({ provingKeyFile: provingKey } = loadProvingKeys('anon_enc'));
});

it("mint to Alice and transfer UTXOs honestly to Bob should succeed", async function () {
Expand Down
10 changes: 5 additions & 5 deletions solidity/test/zeto_anon_enc_nullifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@
// limitations under the License.

import { ethers, ignition } from 'hardhat';
import { ContractTransactionReceipt, Signer, BigNumberish, AddressLike } from 'ethers';
import { ContractTransactionReceipt, Signer, BigNumberish } from 'ethers';
import { expect } from 'chai';
import { loadCircuits, poseidonDecrypt, encodeProof } from "zeto-js";
import { loadCircuit, poseidonDecrypt, encodeProof } from "zeto-js";
import { groth16 } from 'snarkjs';
import { genRandomSalt, genEcdhSharedKey, stringifyBigInts } from 'maci-crypto';
import { Merkletree, InMemoryDB, str2Bytes } from '@iden3/js-merkletree';
import RegistryModule from '../ignition/modules/registry';
import zetoModule from '../ignition/modules/zeto_anon_enc_nullifier';
import { UTXO, User, newUser, newUTXO, newNullifier, doMint, ZERO_UTXO, parseUTXOEvents } from './lib/utils';
import { loadProvingKeys } from './utils';

describe("Zeto based fungible token with anonymity using nullifiers and encryption", function () {
let deployer: Signer;
Expand Down Expand Up @@ -56,9 +57,8 @@ describe("Zeto based fungible token with anonymity using nullifiers and encrypti
const tx3 = await registry.connect(deployer).register(Charlie.ethAddress, Charlie.babyJubPublicKey as [BigNumberish, BigNumberish]);
await tx3.wait();

const result = await loadCircuits('anon_enc_nullifier');
circuit = result.circuit;
provingKey = result.provingKeyFile;
circuit = await loadCircuit('anon_enc_nullifier');
({ provingKeyFile: provingKey } = loadProvingKeys('anon_enc_nullifier'));

const storage1 = new InMemoryDB(str2Bytes(""))
smtAlice = new Merkletree(storage1, true, 64);
Expand Down
8 changes: 4 additions & 4 deletions solidity/test/zeto_anon_nullifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
import { ethers, ignition } from 'hardhat';
import { ContractTransactionReceipt, Signer, BigNumberish, AddressLike } from 'ethers';
import { expect } from 'chai';
import { loadCircuits, Poseidon, encodeProof } from "zeto-js";
import { loadCircuit, Poseidon, encodeProof } from "zeto-js";
import { groth16 } from 'snarkjs';
import { Merkletree, InMemoryDB, str2Bytes } from '@iden3/js-merkletree';
import RegistryModule from '../ignition/modules/registry';
import zetoModule from '../ignition/modules/zeto_anon_nullifier';
import { UTXO, User, newUser, newUTXO, newNullifier, doMint, ZERO_UTXO, parseUTXOEvents } from './lib/utils';
import { loadProvingKeys } from './utils';

describe("Zeto based fungible token with anonymity using nullifiers without encryption", function () {
let deployer: Signer;
Expand Down Expand Up @@ -55,9 +56,8 @@ describe("Zeto based fungible token with anonymity using nullifiers without encr
const tx3 = await registry.connect(deployer).register(Charlie.ethAddress, Charlie.babyJubPublicKey as [BigNumberish, BigNumberish]);
await tx3.wait();

const result = await loadCircuits('anon_nullifier');
circuit = result.circuit;
provingKey = result.provingKeyFile;
circuit = await loadCircuit('anon_nullifier');
({ provingKeyFile: provingKey } = loadProvingKeys('anon_nullifier'));

const storage1 = new InMemoryDB(str2Bytes(""))
smtAlice = new Merkletree(storage1, true, 64);
Expand Down
9 changes: 4 additions & 5 deletions solidity/test/zeto_nf_anon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
import { ethers, ignition } from 'hardhat';
import { Signer, BigNumberish, AddressLike } from 'ethers';
import { expect } from 'chai';
import { loadCircuits, hashTokenUri, encodeProof } from "zeto-js";
import { loadCircuit, hashTokenUri, encodeProof } from "zeto-js";
import { groth16 } from 'snarkjs';
import { formatPrivKeyForBabyJub, stringifyBigInts } from 'maci-crypto';
import { User, UTXO, newUser, newAssetUTXO, doMint } from './lib/utils';

import RegistryModule from '../ignition/modules/registry';
import zetoModule from '../ignition/modules/zeto_nf_anon';
import { loadProvingKeys } from './utils';

describe("Zeto based non-fungible token with anonymity without encryption or nullifiers", function () {
let deployer: Signer;
Expand Down Expand Up @@ -52,9 +52,8 @@ describe("Zeto based non-fungible token with anonymity without encryption or nul
const tx3 = await registry.connect(deployer).register(Charlie.ethAddress, Charlie.babyJubPublicKey as [BigNumberish, BigNumberish]);
await tx3.wait();

const result = await loadCircuits('nf_anon');
circuit = result.circuit;
provingKey = result.provingKeyFile;
circuit = await loadCircuit('nf_anon');
({ provingKeyFile: provingKey } = loadProvingKeys('nf_anon'));
});

it("mint to Alice and transfer UTXOs honestly to Bob should succeed", async function () {
Expand Down
8 changes: 4 additions & 4 deletions solidity/test/zeto_nf_anon_nullifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
import { ethers, ignition } from 'hardhat';
import { ContractTransactionReceipt, Signer, BigNumberish, AddressLike } from 'ethers';
import { expect } from 'chai';
import { loadCircuits, Poseidon, encodeProof, hashTokenUri } from "zeto-js";
import { loadCircuit, Poseidon, encodeProof, hashTokenUri } from "zeto-js";
import { groth16 } from 'snarkjs';
import { Merkletree, InMemoryDB, str2Bytes } from '@iden3/js-merkletree';
import RegistryModule from '../ignition/modules/registry';
import zetoModule from '../ignition/modules/zeto_nf_anon_nullifier';
import { UTXO, User, newUser, newAssetUTXO, newAssetNullifier, doMint, parseUTXOEvents } from './lib/utils';
import { loadProvingKeys } from './utils';

describe("Zeto based non-fungible token with anonymity using nullifiers without encryption", function () {
let deployer: Signer;
Expand Down Expand Up @@ -52,9 +53,8 @@ describe("Zeto based non-fungible token with anonymity using nullifiers without
const tx3 = await registry.connect(deployer).register(Charlie.ethAddress, Charlie.babyJubPublicKey as [BigNumberish, BigNumberish]);
await tx3.wait();

const result = await loadCircuits('nf_anon_nullifier');
circuit = result.circuit;
provingKey = result.provingKeyFile;
circuit = await loadCircuit('nf_anon_nullifier');
({ provingKeyFile: provingKey } = loadProvingKeys('nf_anon_nullifier'));

const storage1 = new InMemoryDB(str2Bytes(""))
smtAlice = new Merkletree(storage1, true, 64);
Expand Down
12 changes: 7 additions & 5 deletions solidity/test/zkDvP.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@
// limitations under the License.

import { ethers, ignition } from 'hardhat';
import { Signer, BigNumberish, AddressLike, encodeBytes32String, ZeroAddress, ZeroHash } from 'ethers';
import { Signer, BigNumberish, encodeBytes32String, ZeroHash } from 'ethers';
import { expect } from 'chai';
import { loadCircuits, getProofHash } from "zeto-js";
import { loadCircuit, getProofHash } from "zeto-js";
import RegistryModule from '../ignition/modules/registry';
import zetoAnonModule from '../ignition/modules/zeto_anon';
import zetoNFAnonModule from '../ignition/modules/zeto_nf_anon';
import zkDvPModule from '../ignition/modules/zkDvP';
import zetoAnonTests from './zeto_anon';
import zetoNFAnonTests from './zeto_nf_anon';

import { UTXO, User, newUser, newUTXO, doMint, newAssetUTXO, ZERO_UTXO, parseUTXOEvents } from './lib/utils';
import { loadProvingKeys } from './utils';

describe("DvP flows between fungible and non-fungible tokens based on Zeto with anonymity without encryption or nullifiers", function () {
// users interacting with each other in the DvP transactions
Expand Down Expand Up @@ -182,7 +182,8 @@ describe("DvP flows between fungible and non-fungible tokens based on Zeto with
const utxo2 = newUTXO(100, Bob);

// 1.2 Alice generates the proof for the trade proposal
const { circuit: circuit1, provingKeyFile: provingKey1 } = await loadCircuits('anon');
const circuit1 = await loadCircuit('anon');
const { provingKeyFile: provingKey1 } = loadProvingKeys('anon');
const proof1 = await zetoAnonTests.prepareProof(circuit1, provingKey1, Alice, [_utxo1, ZERO_UTXO], [utxo2, ZERO_UTXO], [Bob, {}]);
const hash1 = getProofHash(proof1.encodedProof);

Expand All @@ -197,7 +198,8 @@ describe("DvP flows between fungible and non-fungible tokens based on Zeto with
const utxo4 = newAssetUTXO(202, "http://ipfs.io/file-hash-1", Alice);

// 2.2 Bob generates the proof for accepting the trade
const { circuit: circuit2, provingKeyFile: provingKey2 } = await loadCircuits('nf_anon');
const circuit2 = await loadCircuit('nf_anon');
const { provingKeyFile: provingKey2 } = loadProvingKeys('nf_anon');
const proof2 = await zetoNFAnonTests.prepareProof(circuit2, provingKey2, Bob, utxo3, utxo4, Alice);
const hash2 = getProofHash(proof2.encodedProof);

Expand Down
4 changes: 2 additions & 2 deletions zkp/Makefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
excluded_circuits := circuits/check-nullifiers.circom
circuits := $(filter-out $(excluded_circuits),$(wildcard circuits/*.circom))
circuits := $(wildcard circuits/*.circom)
keys := $(patsubst circuits/%.circom,proving-keys/%-vkey.json,$(circuits))
ptau_files := $(addsuffix .ptau,$(addprefix ptau/powersOfTau28_hez_final_,11 12 13 14 15 16))

ptau_size__anon := 12
ptau_size__anon_enc := 13
ptau_size__anon_nullifier := 16
ptau_size__anon_enc_nullifier := 16
ptau_size__check_nullifiers := 11
ptau_size__nf_anon := 11
ptau_size__nf_anon_nullifier := 15

Expand Down
File renamed without changes.
37 changes: 17 additions & 20 deletions zkp/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,30 @@
// See the License for the specific language governing permissions and
// limitations under the License.

const path = require('path');
const { readFileSync } = require('fs');
const Poseidon = require('poseidon-lite');
const { newSalt, poseidonDecrypt, encodeProof, getProofHash, hashTokenUri } = require('./lib/util.js');
const path = require("path");
const { readFileSync } = require("fs");
const Poseidon = require("poseidon-lite");
const {
newSalt,
poseidonDecrypt,
encodeProof,
getProofHash,
hashTokenUri,
} = require("./lib/util.js");

async function loadCircuits(type) {
function loadCircuit(type) {
if (!type) {
type = '3';
throw new Error('The circuit name must be provided');
}
const WitnessCalculator = require(`./lib/${type}_js/witness_calculator.js`);
const buffer = readFileSync(path.join(__dirname, `./lib/${type}_js/${type}.wasm`));
const circuit = await WitnessCalculator(buffer);
const PROVING_KEYS_ROOT = process.env.PROVING_KEYS_ROOT;
if (!PROVING_KEYS_ROOT) {
throw new Error('PROVING_KEYS_ROOT env var is not set');
}
const provingKeyFile = path.join(PROVING_KEYS_ROOT, `${type}.zkey`);
const verificationKey = JSON.parse(new TextDecoder().decode(readFileSync(path.join(PROVING_KEYS_ROOT, `${type}-vkey.json`))));
return {
circuit,
provingKeyFile,
verificationKey,
};
const buffer = readFileSync(
path.join(__dirname, `./lib/${type}_js/${type}.wasm`)
);
return WitnessCalculator(buffer);
}

module.exports = {
loadCircuits,
loadCircuit,
Poseidon,
newSalt,
hashTokenUri,
Expand Down
9 changes: 4 additions & 5 deletions zkp/js/test/anon.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
const { expect } = require('chai');
const { groth16 } = require('snarkjs');
const { genKeypair, formatPrivKeyForBabyJub, stringifyBigInts } = require('maci-crypto');
const { Poseidon, newSalt, loadCircuits } = require('../index.js');
const { Poseidon, newSalt, loadCircuit } = require('../index.js');
const { loadProvingKeys } = require('./utils.js');

const ZERO_PUBKEY = [0, 0];
const poseidonHash = Poseidon.poseidon4;
Expand All @@ -29,10 +30,8 @@ describe('main circuit tests for Zeto fungible tokens with anonymity without enc
const receiver = {};

before(async () => {
const result = await loadCircuits('anon');
circuit = result.circuit;
provingKeyFile = result.provingKeyFile;
verificationKey = result.verificationKey;
circuit = await loadCircuit('anon');
({ provingKeyFile, verificationKey } = loadProvingKeys('anon'));

let keypair = genKeypair();
sender.privKey = keypair.privKey;
Expand Down
9 changes: 4 additions & 5 deletions zkp/js/test/anon_enc.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
const { expect } = require('chai');
const { groth16 } = require('snarkjs');
const { genRandomSalt, genKeypair, genEcdhSharedKey, formatPrivKeyForBabyJub, stringifyBigInts } = require('maci-crypto');
const { Poseidon, newSalt, poseidonDecrypt, loadCircuits } = require('../index.js');
const { Poseidon, newSalt, poseidonDecrypt, loadCircuit } = require('../index.js');
const { loadProvingKeys } = require('./utils.js');

const ZERO_PUBKEY = [0, 0];
const poseidonHash = Poseidon.poseidon4;
Expand All @@ -29,10 +30,8 @@ describe('main circuit tests for Zeto fungible tokens with anonymity with encryp
const receiver = {};

before(async () => {
const result = await loadCircuits('anon_enc');
circuit = result.circuit;
provingKeyFile = result.provingKeyFile;
verificationKey = result.verificationKey;
circuit = await loadCircuit('anon_enc');
({ provingKeyFile, verificationKey } = loadProvingKeys('anon_enc'));

let keypair = genKeypair();
sender.privKey = keypair.privKey;
Expand Down
10 changes: 4 additions & 6 deletions zkp/js/test/anon_enc_nullifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ const { expect } = require('chai');
const { groth16 } = require('snarkjs');
const { genRandomSalt, genKeypair, genEcdhSharedKey, formatPrivKeyForBabyJub, stringifyBigInts } = require('maci-crypto');
const { Merkletree, InMemoryDB, str2Bytes, ZERO_HASH } = require('@iden3/js-merkletree');

const { Poseidon, newSalt, poseidonDecrypt, loadCircuits } = require('../index.js');
const { Poseidon, newSalt, poseidonDecrypt, loadCircuit } = require('../index.js');
const { loadProvingKeys } = require('./utils.js');

const SMT_HEIGHT = 64;
const poseidonHash = Poseidon.poseidon4;
Expand All @@ -33,10 +33,8 @@ describe('main circuit tests for Zeto fungible tokens with encryption and anonym
let senderPrivateKey;

before(async () => {
const result = await loadCircuits('anon_enc_nullifier');
circuit = result.circuit;
provingKeyFile = result.provingKeyFile;
verificationKey = result.verificationKey;
circuit = await loadCircuit('anon_enc_nullifier');
({ provingKeyFile, verificationKey } = loadProvingKeys('anon_enc_nullifier'));

let keypair = genKeypair();
Alice.privKey = keypair.privKey;
Expand Down
Loading

0 comments on commit ebfa06b

Please sign in to comment.