mirror of
https://github.com/semaphore-protocol/semaphore.git
synced 2026-01-10 15:18:41 -05:00
tests
This commit is contained in:
81
integration-test/semaphore-proof-test.js
Normal file
81
integration-test/semaphore-proof-test.js
Normal file
@@ -0,0 +1,81 @@
|
||||
const { expect, before } = require("chai");
|
||||
const {ethers } = require('hardhat');
|
||||
const { poseidon_gencontract: poseidonGenContract } = require("circomlibjs");
|
||||
const { Semaphore, generateMerkleProof, genExternalNullifier, genSignalHash } = require("@libsem/protocols");
|
||||
const { ZkIdentity } = require("@libsem/identity");
|
||||
|
||||
const deployPoseidonTx = (x) => {
|
||||
return ethers.getContractFactory(
|
||||
poseidonGenContract.generateABI(x),
|
||||
poseidonGenContract.createCode(x)
|
||||
)
|
||||
}
|
||||
let semaphore;
|
||||
let defaultExternalNullifier;
|
||||
const identityCommitments = [];
|
||||
const ZERO_VALUE = BigInt(ethers.utils.solidityKeccak256(['bytes'], [ethers.utils.toUtf8Bytes('Semaphore')]))
|
||||
|
||||
|
||||
before("*", async () => {
|
||||
defaultExternalNullifier = genExternalNullifier("voting_1");
|
||||
newExternalNullifier = genExternalNullifier('voting-2');
|
||||
|
||||
const PoseidonT3 = await deployPoseidonTx(2);
|
||||
const poseidonT3 = await PoseidonT3.deploy();
|
||||
await poseidonT3.deployed();
|
||||
|
||||
const PoseidonT6 = await deployPoseidonTx(5);
|
||||
const poseidonT6 = await PoseidonT6.deploy();
|
||||
await poseidonT6.deployed();
|
||||
|
||||
const Semaphore = await ethers.getContractFactory("Semaphore", {
|
||||
libraries: {
|
||||
PoseidonT3: poseidonT3.address,
|
||||
PoseidonT6: poseidonT6.address,
|
||||
}
|
||||
});
|
||||
semaphore = await Semaphore.deploy(20, defaultExternalNullifier);
|
||||
await semaphore.deployed();
|
||||
|
||||
const leafIndex = 3
|
||||
|
||||
for (let i = 0; i < leafIndex; i++) {
|
||||
const tmpIdentity = new ZkIdentity();
|
||||
const tmpCommitment = tmpIdentity.genIdentityCommitment();
|
||||
identityCommitments.push(tmpCommitment)
|
||||
}
|
||||
})
|
||||
|
||||
describe("Semaphore contract", () => {
|
||||
it("Should generate full semaphore proof", async () => {
|
||||
const identity = new ZkIdentity();
|
||||
const identityCommitment = identity.genIdentityCommitment();
|
||||
|
||||
await semaphore.insertIdentity(identityCommitment);
|
||||
|
||||
const signal = "0x111";
|
||||
const nullifierHash = Semaphore.genNullifierHash(externalNullifier, identity.getNullifier(), 20)
|
||||
|
||||
const commitments = Object.assign([], identityCommitments)
|
||||
commitments.push(identityCommitment)
|
||||
|
||||
const merkleProof = generateMerkleProof(20, ZERO_VALUE, 5, commitments, identityCommitment)
|
||||
const witness = Semaphore.genWitness(identity.getIdentity(), merkleProof, externalNullifier, signal)
|
||||
|
||||
const publicSignals = [
|
||||
merkleProof.root,
|
||||
nullifierHash,
|
||||
genSignalHash(signal),
|
||||
externalNullifier
|
||||
]
|
||||
|
||||
const vkeyPath = path.join("./zkeyFiles", "semaphore", "verification_key.json")
|
||||
const vKey = JSON.parse(fs.readFileSync(vkeyPath, "utf-8"))
|
||||
|
||||
const wasmFilePath = path.join("./zkeyFiles", "semaphore", "semaphore.wasm")
|
||||
const finalZkeyPath = path.join("./zkeyFiles", "semaphore", "semaphore_final.zkey")
|
||||
|
||||
const fullProof = await Semaphore.genProof(witness, wasmFilePath, finalZkeyPath)
|
||||
const res = await Semaphore.verifyProof(vKey, { proof: fullProof.proof, publicSignals })
|
||||
})
|
||||
})
|
||||
3279
package-lock.json
generated
3279
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
15
package.json
15
package.json
@@ -3,11 +3,13 @@
|
||||
"version": "2.0.0",
|
||||
"description": "Solidity contracts, zk-SNARK circuits, and test scripts for the Semaphore zero-knowledge signalling gadget. This version uses the Poseidon hash and does not use EdDSA signatures.",
|
||||
"scripts": {
|
||||
"test": "npx hardhat test",
|
||||
"compile": "npx hardhat compile",
|
||||
"compile:circuits": "scripts/build-circuits.sh <<< $'random text'",
|
||||
"compile:contracts": "npx hardhat compile",
|
||||
"develop": "npx hardhat node",
|
||||
"deploy": "npx hardhat deploy --tags complete",
|
||||
"deployPoseidon": "npx hardhat deploy --tags Poseidon"
|
||||
"deploy:poseidon": "npx hardhat deploy --tags Poseidon",
|
||||
"test": "npx hardhat test",
|
||||
"test:integration": "npm run compile:circuits && node integration-test semaphore-proof-test.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,21 +23,24 @@
|
||||
},
|
||||
"homepage": "https://github.com/appliedzkp/semaphore.git#readme",
|
||||
"dependencies": {
|
||||
"@libsem/identity": "^1.0.8",
|
||||
"@libsem/protocols": "^1.0.9",
|
||||
"circomlib": "^0.5.3",
|
||||
"hardhat-deploy": "^0.9.4",
|
||||
"hardhat-deploy-ethers": "^0.3.0-beta.11",
|
||||
"web3": "^1.5.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@libsem/identity": "^1.0.14",
|
||||
"@libsem/protocols": "^1.0.14",
|
||||
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
||||
"@nomiclabs/hardhat-waffle": "^2.0.1",
|
||||
"chai": "^4.3.4",
|
||||
"chai-ethers": "^0.0.1",
|
||||
"circomlibjs": "^0.0.8",
|
||||
"ethereum-waffle": "^3.4.0",
|
||||
"ethers": "^5.4.6",
|
||||
"hardhat": "^2.6.1",
|
||||
"http-server": "^13.0.1",
|
||||
"mocha": "^9.1.3",
|
||||
"snarkjs": "^0.4.7",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "^4.4.2"
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
cd "$(dirname "$0")"
|
||||
mkdir -p ../build
|
||||
cd ../build
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
mkdir -p ../build
|
||||
mkdir -p ../zkeyFiles
|
||||
|
||||
npx circom ../circuits/semaphore.circom --r1cs --wasm --sym
|
||||
cd ../build
|
||||
|
||||
if [ -f ./powersOfTau28_hez_final_16.ptau ]; then
|
||||
echo "powersOfTau28_hez_final_16.ptau already exists. Skipping."
|
||||
@@ -14,6 +12,8 @@ else
|
||||
wget https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_16.ptau
|
||||
fi
|
||||
|
||||
npx circom ../circuits/semaphore.circom --r1cs --wasm --sym
|
||||
|
||||
npx snarkjs zkey new semaphore.r1cs powersOfTau28_hez_final_16.ptau semaphore_0000.zkey
|
||||
|
||||
npx snarkjs zkey contribute semaphore_0000.zkey semaphore_final.zkey
|
||||
|
||||
84
test/external-nullifier-test.js
Normal file
84
test/external-nullifier-test.js
Normal file
@@ -0,0 +1,84 @@
|
||||
const { expect } = require("chai");
|
||||
const { ethers } = require('hardhat');
|
||||
const { poseidon_gencontract: poseidonGenContract } = require("circomlibjs");
|
||||
const { genExternalNullifier } = require("@libsem/protocols");
|
||||
|
||||
|
||||
const deployPoseidonTx = (x) => {
|
||||
return ethers.getContractFactory(
|
||||
poseidonGenContract.generateABI(x),
|
||||
poseidonGenContract.createCode(x)
|
||||
)
|
||||
}
|
||||
let semaphore;
|
||||
let defaultExternalNullifier;
|
||||
let newExternalNullifier;
|
||||
|
||||
|
||||
before("*", async () => {
|
||||
defaultExternalNullifier = genExternalNullifier("voting_1");
|
||||
newExternalNullifier = genExternalNullifier('voting-2');
|
||||
|
||||
const PoseidonT3 = await deployPoseidonTx(2);
|
||||
const poseidonT3 = await PoseidonT3.deploy();
|
||||
await poseidonT3.deployed();
|
||||
|
||||
const PoseidonT6 = await deployPoseidonTx(5);
|
||||
const poseidonT6 = await PoseidonT6.deploy();
|
||||
await poseidonT6.deployed();
|
||||
|
||||
const Semaphore = await ethers.getContractFactory("Semaphore", {
|
||||
libraries: {
|
||||
PoseidonT3: poseidonT3.address,
|
||||
PoseidonT6: poseidonT6.address,
|
||||
}
|
||||
});
|
||||
semaphore = await Semaphore.deploy(20, defaultExternalNullifier);
|
||||
await semaphore.deployed();
|
||||
})
|
||||
|
||||
describe("Semaphore contract", () => {
|
||||
it("Default nullifier should be active", async () => {
|
||||
const isActive = await semaphore.isExternalNullifierActive(defaultExternalNullifier);
|
||||
expect(isActive).to.be.true;
|
||||
});
|
||||
it("ExternalNullifier should be active after add", async () => {
|
||||
await semaphore.addExternalNullifier(newExternalNullifier);
|
||||
const isActive = await semaphore.isExternalNullifierActive(newExternalNullifier);
|
||||
expect(isActive).to.be.true;
|
||||
});
|
||||
it("ExternalNullifier should not be active after deactivation", async () => {
|
||||
await semaphore.deactivateExternalNullifier(newExternalNullifier);
|
||||
const isActive = await semaphore.isExternalNullifierActive(newExternalNullifier);
|
||||
expect(isActive).to.be.false;
|
||||
});
|
||||
it("ExternalNullifier should be active after reactivation", async () => {
|
||||
await semaphore.reactivateExternalNullifier(newExternalNullifier);
|
||||
const isActive = await semaphore.isExternalNullifierActive(newExternalNullifier);
|
||||
expect(isActive).to.be.true;
|
||||
});
|
||||
it("Non owner should not be able to add nullifier", async () => {
|
||||
const [_, addr1] = await ethers.getSigners();
|
||||
|
||||
const newNullifier = genExternalNullifier('voting-3');
|
||||
await expect(semaphore.connect(addr1).addExternalNullifier(newNullifier))
|
||||
.to.be.revertedWith('Ownable: caller is not the owner');
|
||||
})
|
||||
it("Non owner should be able to add nullifier after setPermissioning", async () => {
|
||||
const [_, addr1] = await ethers.getSigners();
|
||||
|
||||
await semaphore.setPermissioning(true);
|
||||
const newNullifier = genExternalNullifier('voting-3');
|
||||
await semaphore.addExternalNullifier(newNullifier);
|
||||
const isActive = await semaphore.isExternalNullifierActive(newNullifier);
|
||||
expect(isActive).to.be.true;
|
||||
})
|
||||
it("Should fail to add already existing nullifier", async () => {
|
||||
await expect(semaphore.addExternalNullifier(newExternalNullifier))
|
||||
.to.be.revertedWith('Semaphore: external nullifier already set');
|
||||
})
|
||||
it("Should return newExternalNullifier as next nullifier", async () => {
|
||||
const nextNullifier = await semaphore.getNextExternalNullifier(defaultExternalNullifier);
|
||||
expect(nextNullifier).to.be.equal(newExternalNullifier);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user