mirror of
https://github.com/selfxyz/self.git
synced 2026-04-05 03:00:53 -04:00
Merge pull request #139 from ashpect/dev
Prove name is not in Ofac List
This commit is contained in:
@@ -5,6 +5,7 @@ include "@zk-email/circuits/utils/bytes.circom";
|
||||
include "../utils/isOlderThan.circom";
|
||||
include "../utils/isValid.circom";
|
||||
include "binary-merkle-root.circom";
|
||||
include "../utils/validatePassport.circom";
|
||||
|
||||
template Disclose(nLevels) {
|
||||
signal input secret;
|
||||
@@ -27,27 +28,8 @@ template Disclose(nLevels) {
|
||||
signal output nullifier; // Poseidon(secret, scope)
|
||||
signal output revealedData_packed[3];
|
||||
|
||||
// Compute the commitment
|
||||
component poseidon_hasher = Poseidon(6);
|
||||
poseidon_hasher.inputs[0] <== secret;
|
||||
poseidon_hasher.inputs[1] <== attestation_id;
|
||||
poseidon_hasher.inputs[2] <== pubkey_leaf;
|
||||
signal mrz_packed[3] <== PackBytes(93)(mrz);
|
||||
for (var i = 0; i < 3; i++) {
|
||||
poseidon_hasher.inputs[i + 3] <== mrz_packed[i];
|
||||
}
|
||||
|
||||
// Verify commitment inclusion
|
||||
signal computedRoot <== BinaryMerkleRoot(nLevels)(poseidon_hasher.out, merkletree_size, path, siblings);
|
||||
merkle_root === computedRoot;
|
||||
|
||||
// Verify validity of the passport
|
||||
component isValid = IsValid();
|
||||
isValid.currDate <== current_date;
|
||||
for (var i = 0; i < 6; i++) {
|
||||
isValid.validityDateASCII[i] <== mrz[70 + i];
|
||||
}
|
||||
1 === isValid.out;
|
||||
// Validate Passport
|
||||
ValidatePassport(nLevels)(secret, attestation_id, pubkey_leaf, mrz, merkle_root, merkletree_size, path, siblings, current_date);
|
||||
|
||||
// Disclose optional data
|
||||
component isOlderThan = IsOlderThan();
|
||||
|
||||
59
circuits/circuits/ofac/ofac_nameDob_verifier.circom
Normal file
59
circuits/circuits/ofac/ofac_nameDob_verifier.circom
Normal file
@@ -0,0 +1,59 @@
|
||||
pragma circom 2.1.5;
|
||||
|
||||
include "circomlib/circuits/poseidon.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
include "binary-merkle-root.circom";
|
||||
include "../utils/getCommonLength.circom";
|
||||
include "../utils/validatePassport.circom";
|
||||
include "../utils/smt.circom";
|
||||
|
||||
template ProveNameDobNotInOfac(nLevels) {
|
||||
signal input secret;
|
||||
signal input attestation_id;
|
||||
signal input pubkey_leaf;
|
||||
signal input mrz[93];
|
||||
signal input merkle_root;
|
||||
signal input merkletree_size;
|
||||
signal input path[nLevels];
|
||||
signal input siblings[nLevels];
|
||||
signal input current_date[6];
|
||||
|
||||
signal input closest_leaf;
|
||||
signal input smt_root;
|
||||
signal input smt_siblings[256];
|
||||
signal output proofLevel;
|
||||
|
||||
// Validate passport
|
||||
ValidatePassport(nLevels)(secret, attestation_id, pubkey_leaf, mrz, merkle_root, merkletree_size, path, siblings, current_date);
|
||||
|
||||
// Name Hash
|
||||
component poseidon_hasher[3];
|
||||
for (var j = 0; j < 3; j++) {
|
||||
poseidon_hasher[j] = Poseidon(13);
|
||||
for (var i = 0; i < 13; i++) {
|
||||
poseidon_hasher[j].inputs[i] <== mrz[10 + 13 * j + i];
|
||||
}
|
||||
}
|
||||
signal name_hash <== Poseidon(3)([poseidon_hasher[0].out, poseidon_hasher[1].out, poseidon_hasher[2].out]);
|
||||
|
||||
// Dob hash
|
||||
component pos_dob = Poseidon(6);
|
||||
for(var i = 0; i < 6; i++) {
|
||||
pos_dob.inputs[i] <== mrz[62 + i];
|
||||
}
|
||||
|
||||
// NameDob hash
|
||||
signal name_dob_hash <== Poseidon(2)([pos_dob.out, name_hash]);
|
||||
signal smtleaf_hash <== Poseidon(3)([name_dob_hash, 1,1]);
|
||||
|
||||
// SMT Verification
|
||||
signal closestleaf <== SMTVerify(256)(name_dob_hash, 1, closest_leaf, smt_root, smt_siblings);
|
||||
|
||||
signal proofType <== IsEqual()([closestleaf,smtleaf_hash]);
|
||||
proofType === 0; // Uncomment this line to make circuit handle both membership and non-membership proof and returns the type of proof (0 for non-membership, 1 for membership)
|
||||
|
||||
proofLevel <== 2;
|
||||
}
|
||||
|
||||
component main { public [ merkle_root,smt_root ] } = ProveNameDobNotInOfac(16);
|
||||
52
circuits/circuits/ofac/ofac_name_verifier.circom
Normal file
52
circuits/circuits/ofac/ofac_name_verifier.circom
Normal file
@@ -0,0 +1,52 @@
|
||||
pragma circom 2.1.5;
|
||||
|
||||
include "circomlib/circuits/poseidon.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "binary-merkle-root.circom";
|
||||
include "../utils/getCommonLength.circom";
|
||||
include "../utils/validatePassport.circom";
|
||||
include "../utils/smt.circom";
|
||||
|
||||
template ProveNameNotInOfac(nLevels) {
|
||||
signal input secret;
|
||||
signal input attestation_id;
|
||||
signal input pubkey_leaf;
|
||||
signal input mrz[93];
|
||||
signal input merkle_root;
|
||||
signal input merkletree_size;
|
||||
signal input path[nLevels];
|
||||
signal input siblings[nLevels];
|
||||
signal input current_date[6];
|
||||
|
||||
signal input closest_leaf;
|
||||
signal input smt_root;
|
||||
signal input smt_siblings[256];
|
||||
signal output proofType;
|
||||
signal output proofLevel;
|
||||
|
||||
// Validate passport
|
||||
ValidatePassport(nLevels)(secret, attestation_id, pubkey_leaf, mrz, merkle_root, merkletree_size, path, siblings, current_date);
|
||||
|
||||
// Name Hash
|
||||
component poseidon_hasher[3];
|
||||
for (var j = 0; j < 3; j++) {
|
||||
poseidon_hasher[j] = Poseidon(13);
|
||||
for (var i = 0; i < 13; i++) {
|
||||
poseidon_hasher[j].inputs[i] <== mrz[10 + 13 * j + i];
|
||||
}
|
||||
}
|
||||
|
||||
signal name_hash <== Poseidon(3)([poseidon_hasher[0].out, poseidon_hasher[1].out, poseidon_hasher[2].out]);
|
||||
signal smtleaf_hash <== Poseidon(3)([name_hash, 1,1]);
|
||||
|
||||
// SMT Verification
|
||||
signal closestleaf <== SMTVerify(256)(name_hash, 1, closest_leaf, smt_root, smt_siblings);
|
||||
|
||||
proofType <== IsEqual()([closestleaf,smtleaf_hash]);
|
||||
proofType === 0; // Uncomment this line to make circuit handle both membership and non-membership proof and returns the type of proof (0 for non-membership, 1 for membership)
|
||||
|
||||
proofLevel <== 1;
|
||||
|
||||
}
|
||||
|
||||
component main { public [ merkle_root,smt_root ] } = ProveNameNotInOfac(16);
|
||||
48
circuits/circuits/ofac/ofac_passportNo_verifier.circom
Normal file
48
circuits/circuits/ofac/ofac_passportNo_verifier.circom
Normal file
@@ -0,0 +1,48 @@
|
||||
pragma circom 2.1.5;
|
||||
|
||||
include "circomlib/circuits/poseidon.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
include "@zk-email/circuits/utils/array.circom";
|
||||
include "binary-merkle-root.circom";
|
||||
include "../utils/getCommonLength.circom";
|
||||
include "../utils/validatePassport.circom";
|
||||
include "../utils/smt.circom";
|
||||
|
||||
template ProvePassportNotInOfac(nLevels) {
|
||||
signal input secret;
|
||||
signal input attestation_id;
|
||||
signal input pubkey_leaf;
|
||||
signal input mrz[93];
|
||||
signal input merkle_root;
|
||||
signal input merkletree_size;
|
||||
signal input path[nLevels];
|
||||
signal input siblings[nLevels];
|
||||
signal input current_date[6];
|
||||
|
||||
signal input closest_leaf;
|
||||
signal input smt_root;
|
||||
signal input smt_siblings[256];
|
||||
signal output proofLevel;
|
||||
|
||||
// Validate passport
|
||||
ValidatePassport(nLevels)(secret, attestation_id, pubkey_leaf, mrz, merkle_root, merkletree_size, path, siblings, current_date);
|
||||
|
||||
// PassportNo Hash
|
||||
component poseidon_hasher = Poseidon(9);
|
||||
for (var i = 0; i < 9; i++) {
|
||||
poseidon_hasher.inputs[i] <== mrz[49 + i];
|
||||
}
|
||||
signal smtleaf_hash <== Poseidon(3)([poseidon_hasher.out, 1,1]);
|
||||
|
||||
// SMT Verification
|
||||
signal closestleaf <== SMTVerify(256)(poseidon_hasher.out, 1, closest_leaf, smt_root, smt_siblings);
|
||||
|
||||
// If leaf given = leaf calulated ; then membership proof
|
||||
signal proofType <== IsEqual()([closestleaf,smtleaf_hash]); // 1 for membership proof, 0 for non-membership proof
|
||||
proofType === 0; // Uncomment this line to make circuit handle both membership and non-membership proof (0 for non-membership, 1 for membership)
|
||||
|
||||
proofLevel <== 3;
|
||||
}
|
||||
|
||||
component main { public [ merkle_root,smt_root ] } = ProvePassportNotInOfac(16);
|
||||
67
circuits/circuits/utils/getCommonLength.circom
Normal file
67
circuits/circuits/utils/getCommonLength.circom
Normal file
@@ -0,0 +1,67 @@
|
||||
pragma circom 2.1.5;
|
||||
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
|
||||
// Computes the first n common bits of the hashes
|
||||
template CommonBitsLengthFromEnd() {
|
||||
|
||||
signal input bits1[256];
|
||||
signal input bits2[256];
|
||||
signal output out;
|
||||
|
||||
component iseq[256];
|
||||
signal pop[256];
|
||||
|
||||
pop[255] <== IsEqual()([bits1[255], bits2[255]]);
|
||||
|
||||
for (var i = 254; i >= 0; i--) {
|
||||
var temp = bits2[i] - bits1[i];
|
||||
iseq[i] = IsEqual();
|
||||
bits1[i] ==> iseq[i].in[0];
|
||||
bits2[i] ==> iseq[i].in[1];
|
||||
pop[i] <== iseq[i].out*pop[i+1];
|
||||
}
|
||||
|
||||
var added = 0;
|
||||
for(var i = 0; i<256;i++){
|
||||
added += pop[i];
|
||||
}
|
||||
|
||||
added ==> out;
|
||||
|
||||
}
|
||||
|
||||
// Computes length of an array when array is padded with 0;s from end and the last element after which padding starts is not 0, 0's might come in between.
|
||||
template SiblingsLength() {
|
||||
signal input siblings[256];
|
||||
signal output length;
|
||||
|
||||
// Siblings can be like (1,2,3,0,0,4,5,0,0...all 0 till 256[the padded 0 ones])
|
||||
// We need to get the length , i.e 7 in this case
|
||||
var foo[256];
|
||||
for(var i = 0; i<256; i++){
|
||||
foo[i] = 0;
|
||||
}
|
||||
foo[255] = siblings[255];
|
||||
for(var i = 256-2; i>=0; i--){
|
||||
foo[i] = siblings[i] + foo[i+1];
|
||||
}
|
||||
|
||||
// convert to (15,14,12,9,9,9,5,0,0,0..), this takes out the middle 0's
|
||||
var total = 0;
|
||||
signal pop[256];
|
||||
component iszero[256];
|
||||
|
||||
for(var i = 0; i<256; i++){
|
||||
iszero[i] = IsZero();
|
||||
foo[i] ==> iszero[i].in;
|
||||
pop[i] <== iszero[i].out;
|
||||
}
|
||||
|
||||
for(var i = 0; i<256; i++){
|
||||
total += pop[i];
|
||||
}
|
||||
|
||||
256-total ==> length;
|
||||
}
|
||||
46
circuits/circuits/utils/smt.circom
Normal file
46
circuits/circuits/utils/smt.circom
Normal file
@@ -0,0 +1,46 @@
|
||||
pragma circom 2.1.5;
|
||||
|
||||
include "circomlib/circuits/poseidon.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
include "@zk-email/circuits/utils/array.circom";
|
||||
include "binary-merkle-root.circom";
|
||||
include "getCommonLength.circom";
|
||||
|
||||
template SMTVerify(nLength) {
|
||||
signal input key;
|
||||
signal input value;
|
||||
signal input closest_key; // key itself if checking for inclusion
|
||||
signal input root;
|
||||
signal input siblings[nLength];
|
||||
signal output closestleaf;
|
||||
|
||||
// Calculate depth of the smt tree
|
||||
signal depth <== SiblingsLength()(siblings);
|
||||
|
||||
// Calulate the path needed
|
||||
signal path[nLength];
|
||||
signal path_in_bits_reversed[nLength] <== Num2Bits(256)(key);
|
||||
var path_in_bits[nLength];
|
||||
|
||||
for (var i = 0; i < nLength; i++) {
|
||||
path_in_bits[i] = path_in_bits_reversed[nLength-1-i];
|
||||
}
|
||||
|
||||
// Shift the path to the left by depth to make it compatible for BinaryMerkleRoot function
|
||||
component ct1 = VarShiftLeft(nLength,nLength);
|
||||
ct1.in <== path_in_bits;
|
||||
ct1.shift <== (nLength-depth);
|
||||
path <== ct1.out;
|
||||
|
||||
// Closest_key to Closest_leaf
|
||||
signal closest_hash <== Poseidon(3)([closest_key, value,1]);
|
||||
signal isClosestZero <== IsEqual()([closest_key,0]);
|
||||
signal closest <== IsEqual()([isClosestZero,0]); // Because zk-kit/smt stores a 0 leaf as itself and not as Hash(0,value,1)
|
||||
closestleaf <== closest_hash * closest;
|
||||
|
||||
// Verification
|
||||
signal computedRoot <== BinaryMerkleRoot(nLength)(closestleaf, depth, path, siblings);
|
||||
computedRoot === root;
|
||||
|
||||
}
|
||||
43
circuits/circuits/utils/validatePassport.circom
Normal file
43
circuits/circuits/utils/validatePassport.circom
Normal file
@@ -0,0 +1,43 @@
|
||||
pragma circom 2.1.5;
|
||||
|
||||
include "circomlib/circuits/poseidon.circom";
|
||||
include "@zk-email/circuits/utils/bytes.circom";
|
||||
include "isOlderThan.circom";
|
||||
include "isValid.circom";
|
||||
include "binary-merkle-root.circom";
|
||||
|
||||
template ValidatePassport(nLevels) {
|
||||
signal input secret;
|
||||
signal input attestation_id;
|
||||
signal input pubkey_leaf;
|
||||
signal input mrz[93];
|
||||
|
||||
signal input merkle_root;
|
||||
signal input merkletree_size;
|
||||
signal input path[nLevels];
|
||||
signal input siblings[nLevels];
|
||||
signal input current_date[6];
|
||||
|
||||
// Compute the commitment
|
||||
component poseidon_hasher = Poseidon(6);
|
||||
poseidon_hasher.inputs[0] <== secret;
|
||||
poseidon_hasher.inputs[1] <== attestation_id;
|
||||
poseidon_hasher.inputs[2] <== pubkey_leaf;
|
||||
signal mrz_packed[3] <== PackBytes(93)(mrz);
|
||||
for (var i = 0; i < 3; i++) {
|
||||
poseidon_hasher.inputs[i + 3] <== mrz_packed[i];
|
||||
}
|
||||
|
||||
// Verify commitment inclusion
|
||||
signal computedRoot <== BinaryMerkleRoot(nLevels)(poseidon_hasher.out, merkletree_size, path, siblings);
|
||||
merkle_root === computedRoot;
|
||||
|
||||
// Verify validity of the passport
|
||||
component isValid = IsValid();
|
||||
isValid.currDate <== current_date;
|
||||
for (var i = 0; i < 6; i++) {
|
||||
isValid.validityDateASCII[i] <== mrz[70 + i];
|
||||
}
|
||||
|
||||
1 === isValid.out;
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
"lint": "prettier --check ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@ashpect/smt": "https://github.com/ashpect/smt#main",
|
||||
"@noble/curves": "^1.4.2",
|
||||
"@types/chai-as-promised": "^7.1.6",
|
||||
"@types/node": "^20.11.19",
|
||||
|
||||
347
circuits/tests/ofac/ofac_verify.test.ts
Normal file
347
circuits/tests/ofac/ofac_verify.test.ts
Normal file
@@ -0,0 +1,347 @@
|
||||
import { expect } from 'chai';
|
||||
import path from 'path';
|
||||
const wasm_tester = require('circom_tester').wasm;
|
||||
import {
|
||||
mockPassportData_sha256_rsa_65537,
|
||||
mockPassportData2_sha256_rsa_65537,
|
||||
} from '../../../common/src/constants/mockPassportData';
|
||||
import { generateCircuitInputsOfac } from '../../../common/src/utils/generateInputs';
|
||||
import { getLeaf } from '../../../common/src/utils/pubkeyTree';
|
||||
import { SMT, ChildNodes } from '@ashpect/smt';
|
||||
import { poseidon1, poseidon2, poseidon3, poseidon6 } from 'poseidon-lite';
|
||||
import { LeanIMT } from '@zk-kit/lean-imt';
|
||||
import { formatMrz, packBytes } from '../../../common/src/utils/utils';
|
||||
import passportNojson from '../../../common/ofacdata/outputs/passportNoSMT.json';
|
||||
import nameDobjson from '../../../common/ofacdata/outputs/nameDobSMT.json';
|
||||
import namejson from '../../../common/ofacdata/outputs/nameSMT.json';
|
||||
import { PassportData } from '../../../common/src/utils/types';
|
||||
import exp from 'constants';
|
||||
|
||||
let circuit: any;
|
||||
let passportData = mockPassportData_sha256_rsa_65537; //Mock passport is ADDED in ofac list to test circuits
|
||||
let passportData2 = mockPassportData2_sha256_rsa_65537; //Mock passport is not added in ofac list to test circuits
|
||||
let tree: LeanIMT;
|
||||
const hash = (childNodes: ChildNodes) =>
|
||||
childNodes.length === 2 ? poseidon2(childNodes) : poseidon3(childNodes);
|
||||
|
||||
// Calculating common validatidy inputs for all 3 ciruits
|
||||
function getPassportInputs(passportData: PassportData) {
|
||||
const secret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
const attestation_name = 'E-PASSPORT';
|
||||
const attestation_id = poseidon1([
|
||||
BigInt(Buffer.from(attestation_name).readUIntBE(0, 6)),
|
||||
]).toString();
|
||||
|
||||
const majority = '18';
|
||||
const user_identifier = '0xE6E4b6a802F2e0aeE5676f6010e0AF5C9CDd0a50';
|
||||
const bitmap = Array(90).fill('1');
|
||||
const scope = poseidon1([BigInt(Buffer.from('VOTEEEEE').readUIntBE(0, 6))]).toString();
|
||||
|
||||
const pubkey_leaf = getLeaf({
|
||||
signatureAlgorithm: passportData.signatureAlgorithm,
|
||||
modulus: passportData.pubKey.modulus,
|
||||
exponent: passportData.pubKey.exponent,
|
||||
}).toString();
|
||||
const mrz_bytes = packBytes(formatMrz(passportData.mrz));
|
||||
const commitment = poseidon6([
|
||||
secret,
|
||||
attestation_id,
|
||||
pubkey_leaf,
|
||||
mrz_bytes[0],
|
||||
mrz_bytes[1],
|
||||
mrz_bytes[2],
|
||||
]);
|
||||
|
||||
return {
|
||||
secret: secret,
|
||||
attestation_id: attestation_id,
|
||||
passportData: passportData,
|
||||
commitment: commitment,
|
||||
majority: majority,
|
||||
bitmap: bitmap,
|
||||
scope: scope,
|
||||
user_identifier: user_identifier,
|
||||
};
|
||||
}
|
||||
const inputs = getPassportInputs(passportData);
|
||||
const mockInputs = getPassportInputs(passportData2);
|
||||
|
||||
tree = new LeanIMT((a, b) => poseidon2([a, b]), []);
|
||||
tree.insert(BigInt(inputs.commitment));
|
||||
tree.insert(BigInt(mockInputs.commitment));
|
||||
|
||||
// POSSIBLE TESTS (for each of 3 circuits) :
|
||||
// 0. Cicuits compiles and loads
|
||||
// 1. Valid proof : Correct path and corresponding closest leaf AND closest_leaf != pasport_hash ; Valid prove of non-membership
|
||||
// 2. Invalid proof : Correct path and corresponding closest leaf AND closest_leaf == pasport_hash ; Valid prove of membership ; Hence non-membership proof would fail
|
||||
// 3. Invalid proof : Correct path but wrong corresponding siblings ; fails due to calculatedRoot != smt_root
|
||||
|
||||
// Level 3 : Passport match in OfacList
|
||||
describe('start testing ofac_passportNo_verifier.circom', function () {
|
||||
this.timeout(0);
|
||||
let passno_smt = new SMT(hash, true);
|
||||
let memSmtInputs: any;
|
||||
let nonMemSmtInputs: any;
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, '../../circuits/ofac/ofac_passportNo_verifier.circom'),
|
||||
{
|
||||
include: [
|
||||
'node_modules',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
],
|
||||
}
|
||||
);
|
||||
|
||||
passno_smt.import(passportNojson);
|
||||
const proofLevel = 3;
|
||||
memSmtInputs = generateCircuitInputsOfac(
|
||||
// proof of membership
|
||||
inputs.secret,
|
||||
inputs.attestation_id,
|
||||
inputs.passportData,
|
||||
tree,
|
||||
inputs.majority,
|
||||
inputs.bitmap,
|
||||
inputs.scope,
|
||||
inputs.user_identifier,
|
||||
passno_smt,
|
||||
proofLevel
|
||||
);
|
||||
|
||||
nonMemSmtInputs = generateCircuitInputsOfac(
|
||||
// proof of non-membership
|
||||
mockInputs.secret,
|
||||
mockInputs.attestation_id,
|
||||
mockInputs.passportData,
|
||||
tree,
|
||||
mockInputs.majority,
|
||||
mockInputs.bitmap,
|
||||
mockInputs.scope,
|
||||
mockInputs.user_identifier,
|
||||
passno_smt,
|
||||
proofLevel
|
||||
);
|
||||
});
|
||||
|
||||
// Compile circuit
|
||||
it('should compile and load the circuit, level 3', async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
// Corrct siblings and closest leaf : Everything correct as a proof
|
||||
it('should pass without errors , all conditions satisfied', async function () {
|
||||
let w = await circuit.calculateWitness(nonMemSmtInputs);
|
||||
const proofLevel = await circuit.getOutput(w, ['proofLevel']);
|
||||
console.log(proofLevel);
|
||||
console.log('Everything correct, Valid proof of non-membership !!');
|
||||
});
|
||||
|
||||
// Correct siblings but membership proof : Fail at line 43 assertion
|
||||
it('should fail to calculate witness since trying to generate membership proof, level 3', async function () {
|
||||
try {
|
||||
await circuit.calculateWitness(memSmtInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
expect(error.message).to.include('line: 43');
|
||||
expect(error.message).to.not.include('SMTVerify');
|
||||
}
|
||||
});
|
||||
|
||||
// Give wrong closest leaf but correct siblings array : Fail of SMT Verification
|
||||
it('should fail to calculate witness due to wrong closest_leaf provided, level 3', async function () {
|
||||
try {
|
||||
let wrongSibInputs = nonMemSmtInputs;
|
||||
const randomNumber = Math.floor(Math.random() * Math.pow(2, 254));
|
||||
wrongSibInputs.closest_leaf = BigInt(randomNumber).toString();
|
||||
await circuit.calculateWitness(wrongSibInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
expect(error.message).to.include('SMTVerify');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Level 2 : NameDob match in OfacList
|
||||
describe('start testing ofac_nameDob_verifier.circom', function () {
|
||||
this.timeout(0);
|
||||
let namedob_smt = new SMT(hash, true);
|
||||
let memSmtInputs: any;
|
||||
let nonMemSmtInputs: any;
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, '../../circuits/ofac/ofac_nameDob_verifier.circom'),
|
||||
{
|
||||
include: [
|
||||
'node_modules',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
],
|
||||
}
|
||||
);
|
||||
|
||||
namedob_smt.import(nameDobjson);
|
||||
const proofLevel = 2;
|
||||
memSmtInputs = generateCircuitInputsOfac(
|
||||
// proof of membership
|
||||
inputs.secret,
|
||||
inputs.attestation_id,
|
||||
inputs.passportData,
|
||||
tree,
|
||||
inputs.majority,
|
||||
inputs.bitmap,
|
||||
inputs.scope,
|
||||
inputs.user_identifier,
|
||||
namedob_smt,
|
||||
proofLevel
|
||||
);
|
||||
|
||||
nonMemSmtInputs = generateCircuitInputsOfac(
|
||||
// proof of non-membership
|
||||
mockInputs.secret,
|
||||
mockInputs.attestation_id,
|
||||
mockInputs.passportData,
|
||||
tree,
|
||||
mockInputs.majority,
|
||||
mockInputs.bitmap,
|
||||
mockInputs.scope,
|
||||
mockInputs.user_identifier,
|
||||
namedob_smt,
|
||||
proofLevel
|
||||
);
|
||||
});
|
||||
|
||||
// Compile circuit
|
||||
it('should compile and load the circuit, level 2', async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
// Corrct siblings and closest leaf : Everything correct as a proof
|
||||
it('should pass without errors , all conditions satisfied', async function () {
|
||||
let w = await circuit.calculateWitness(nonMemSmtInputs);
|
||||
const proofLevel = await circuit.getOutput(w, ['proofLevel']);
|
||||
console.log(proofLevel);
|
||||
console.log('Everything correct, Valid proof of non-membership !!');
|
||||
});
|
||||
|
||||
// Correct siblings but membership proof : Fail at line 54 assertion
|
||||
it('should fail to calculate witness since trying to generate membership proof, level 2', async function () {
|
||||
try {
|
||||
await circuit.calculateWitness(memSmtInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
expect(error.message).to.include('line: 54');
|
||||
expect(error.message).to.not.include('SMTVerify');
|
||||
}
|
||||
});
|
||||
|
||||
// Give wrong closest leaf but correct siblings array
|
||||
it('should fail to calculate witness due to wrong closest_leaf provided, level 2', async function () {
|
||||
try {
|
||||
let wrongSibInputs = nonMemSmtInputs;
|
||||
const randomNumber = Math.floor(Math.random() * Math.pow(2, 254));
|
||||
wrongSibInputs.closest_leaf = BigInt(randomNumber).toString();
|
||||
await circuit.calculateWitness(wrongSibInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
expect(error.message).to.include('SMTVerify');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Level 1 : Name match in OfacList
|
||||
describe('start testing ofac_name_verifier.circom', function () {
|
||||
this.timeout(0);
|
||||
let name_smt = new SMT(hash, true);
|
||||
let memSmtInputs: any;
|
||||
let nonMemSmtInputs: any;
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, '../../circuits/ofac/ofac_name_verifier.circom'),
|
||||
{
|
||||
include: [
|
||||
'node_modules',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
],
|
||||
}
|
||||
);
|
||||
|
||||
name_smt.import(namejson);
|
||||
const proofLevel = 1;
|
||||
memSmtInputs = generateCircuitInputsOfac(
|
||||
// proof of membership
|
||||
inputs.secret,
|
||||
inputs.attestation_id,
|
||||
inputs.passportData,
|
||||
tree,
|
||||
inputs.majority,
|
||||
inputs.bitmap,
|
||||
inputs.scope,
|
||||
inputs.user_identifier,
|
||||
name_smt,
|
||||
proofLevel
|
||||
);
|
||||
|
||||
nonMemSmtInputs = generateCircuitInputsOfac(
|
||||
// proof of non-membership
|
||||
mockInputs.secret,
|
||||
mockInputs.attestation_id,
|
||||
mockInputs.passportData,
|
||||
tree,
|
||||
mockInputs.majority,
|
||||
mockInputs.bitmap,
|
||||
mockInputs.scope,
|
||||
mockInputs.user_identifier,
|
||||
name_smt,
|
||||
proofLevel
|
||||
);
|
||||
});
|
||||
|
||||
// Compile circuit
|
||||
it('should compile and load the circuit, level 1', async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
// Corrct siblings and closest leaf : Everything correct as a proof
|
||||
it('should pass without errors , all conditions satisfied', async function () {
|
||||
let w = await circuit.calculateWitness(nonMemSmtInputs);
|
||||
const proofLevel = await circuit.getOutput(w, ['proofLevel']);
|
||||
console.log(proofLevel);
|
||||
console.log('Everything correct, Valid proof of non-membership !!');
|
||||
});
|
||||
|
||||
// Correct siblings but membership proof : Fail at line 46 assertion
|
||||
it('should fail to calculate witness since trying to generate membership proof, level 1', async function () {
|
||||
try {
|
||||
await circuit.calculateWitness(memSmtInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
expect(error.message).to.include('line: 46');
|
||||
expect(error.message).to.not.include('SMTVerify');
|
||||
}
|
||||
});
|
||||
|
||||
// Give wrong closest leaf but correct siblings array
|
||||
it('should fail to calculate witness due to wrong closest_leaf provided, level 1', async function () {
|
||||
try {
|
||||
let wrongSibInputs = nonMemSmtInputs;
|
||||
const randomNumber = Math.floor(Math.random() * Math.pow(2, 254));
|
||||
wrongSibInputs.closest_leaf = BigInt(randomNumber).toString();
|
||||
await circuit.calculateWitness(wrongSibInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
expect(error.message).to.include('SMTVerify');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -2,6 +2,10 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@ashpect/smt@https://github.com/ashpect/smt#main":
|
||||
version "1.0.0"
|
||||
resolved "https://github.com/ashpect/smt#4f73fd24adb06a7f8efd6fd2d3ed58e9e2f2691a"
|
||||
|
||||
"@cspotcode/source-map-support@^0.8.0":
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
|
||||
@@ -829,11 +833,6 @@ check-types@^11.2.3:
|
||||
resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.2.3.tgz#1ffdf68faae4e941fce252840b1787b8edc93b71"
|
||||
integrity sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg==
|
||||
|
||||
child_process@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/child_process/-/child_process-1.0.2.tgz#b1f7e7fc73d25e7fd1d455adc94e143830182b5a"
|
||||
integrity sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g==
|
||||
|
||||
chokidar@3.5.3:
|
||||
version "3.5.3"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
|
||||
@@ -863,20 +862,6 @@ circom_runtime@0.1.24:
|
||||
dependencies:
|
||||
ffjavascript "0.2.60"
|
||||
|
||||
circom_tester@^0.0.19:
|
||||
version "0.0.19"
|
||||
resolved "https://registry.yarnpkg.com/circom_tester/-/circom_tester-0.0.19.tgz#e8bed494d080f8186bd0ac6571755d00ccec83bd"
|
||||
integrity sha512-SNHaBsGxcBH6XsVWfsRbRPA7NF8m8AMKJI9dtJJCFGUtOTT2+zsoIqAwi50z6XCnO4TtjyXq7AeXa1PLHqT0tw==
|
||||
dependencies:
|
||||
chai "^4.3.6"
|
||||
child_process "^1.0.2"
|
||||
ffjavascript "^0.2.56"
|
||||
fnv-plus "^1.3.1"
|
||||
r1csfile "^0.0.41"
|
||||
snarkjs "0.5.0"
|
||||
tmp-promise "^3.0.3"
|
||||
util "^0.12.4"
|
||||
|
||||
"circom_tester@github:Atomic-Buy/circom_tester#main":
|
||||
version "0.0.20"
|
||||
resolved "https://codeload.github.com/Atomic-Buy/circom_tester/tar.gz/cf7d7a60bddcffc2388f0acaf44f38bb00d6f2f6"
|
||||
@@ -988,13 +973,6 @@ diff@^4.0.1:
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
|
||||
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
||||
|
||||
"dmpierre/sha1-circom@https://github.com/dmpierre/sha1-circom/":
|
||||
version "1.0.0"
|
||||
resolved "https://github.com/dmpierre/sha1-circom/#fe18319cf72b9f3b83d0cea8f49a1f04482c125b"
|
||||
dependencies:
|
||||
circom_tester "^0.0.19"
|
||||
snarkjs "^0.5.0"
|
||||
|
||||
ejs@^3.1.6:
|
||||
version "3.1.9"
|
||||
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361"
|
||||
@@ -1156,7 +1134,7 @@ ffjavascript@0.2.60, ffjavascript@^0.2.48:
|
||||
wasmcurves "0.2.2"
|
||||
web-worker "^1.2.0"
|
||||
|
||||
ffjavascript@0.2.63, ffjavascript@^0.2.45, ffjavascript@^0.2.56, ffjavascript@^0.2.60:
|
||||
ffjavascript@0.2.63, ffjavascript@^0.2.45, ffjavascript@^0.2.60:
|
||||
version "0.2.63"
|
||||
resolved "https://registry.yarnpkg.com/ffjavascript/-/ffjavascript-0.2.63.tgz#0c1216a1f123dc9181df69e144473704d2f115eb"
|
||||
integrity sha512-dBgdsfGks58b66JnUZeZpGxdMIDQ4QsD3VYlRJyFVrKQHb2kJy4R2gufx5oetrTxXPT+aEjg0dOvOLg1N0on4A==
|
||||
@@ -1862,22 +1840,6 @@ set-function-length@^1.2.1:
|
||||
gopd "^1.0.1"
|
||||
has-property-descriptors "^1.0.1"
|
||||
|
||||
snarkjs@0.5.0, snarkjs@^0.5.0, "snarkjs@https://github.com/sampritipanda/snarkjs.git#fef81fc51d17a734637555c6edbd585ecda02d9e":
|
||||
version "0.5.0"
|
||||
resolved "https://github.com/sampritipanda/snarkjs.git#fef81fc51d17a734637555c6edbd585ecda02d9e"
|
||||
dependencies:
|
||||
"@iden3/binfileutils" "0.0.11"
|
||||
bfj "^7.0.2"
|
||||
blake2b-wasm "^2.4.0"
|
||||
circom_runtime "0.1.21"
|
||||
ejs "^3.1.6"
|
||||
fastfile "0.0.20"
|
||||
ffjavascript "0.2.56"
|
||||
js-sha3 "^0.8.0"
|
||||
localforage "^1.10.0"
|
||||
logplease "^1.2.15"
|
||||
r1csfile "0.0.41"
|
||||
|
||||
snarkjs@^0.7.0, snarkjs@^0.7.1:
|
||||
version "0.7.3"
|
||||
resolved "https://registry.yarnpkg.com/snarkjs/-/snarkjs-0.7.3.tgz#7f703d05b810235255f2d0a70d8a9b8b3ea916e5"
|
||||
@@ -1894,6 +1856,22 @@ snarkjs@^0.7.0, snarkjs@^0.7.1:
|
||||
logplease "^1.2.15"
|
||||
r1csfile "0.0.47"
|
||||
|
||||
"snarkjs@https://github.com/sampritipanda/snarkjs.git#fef81fc51d17a734637555c6edbd585ecda02d9e":
|
||||
version "0.5.0"
|
||||
resolved "https://github.com/sampritipanda/snarkjs.git#fef81fc51d17a734637555c6edbd585ecda02d9e"
|
||||
dependencies:
|
||||
"@iden3/binfileutils" "0.0.11"
|
||||
bfj "^7.0.2"
|
||||
blake2b-wasm "^2.4.0"
|
||||
circom_runtime "0.1.21"
|
||||
ejs "^3.1.6"
|
||||
fastfile "0.0.20"
|
||||
ffjavascript "0.2.56"
|
||||
js-sha3 "^0.8.0"
|
||||
localforage "^1.10.0"
|
||||
logplease "^1.2.15"
|
||||
r1csfile "0.0.41"
|
||||
|
||||
source-map-support@^0.5.6:
|
||||
version "0.5.21"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
|
||||
@@ -2076,7 +2054,7 @@ util-deprecate@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
|
||||
|
||||
util@^0.12.4, util@^0.12.5:
|
||||
util@^0.12.5:
|
||||
version "0.12.5"
|
||||
resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc"
|
||||
integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==
|
||||
|
||||
Reference in New Issue
Block a user