Merge pull request #293 from zk-passport/feat/nullifier

new nullifier logic
This commit is contained in:
turnoffthiscomputer
2025-01-08 17:47:40 +01:00
committed by GitHub
3 changed files with 42 additions and 8 deletions

View File

@@ -58,7 +58,7 @@ template OPENPASSPORT_PROVE(DG_HASH_ALGO, ECONTENT_HASH_ALGO, signatureAlgorithm
isWrongSelectorMode === 0;
// verify passport signature
PassportVerifier(DG_HASH_ALGO, ECONTENT_HASH_ALGO, signatureAlgorithm, n, k, MAX_ECONTENT_PADDED_LEN, MAX_SIGNED_ATTR_PADDED_LEN)(dg1,dg1_hash_offset, dg2_hash, eContent,eContent_padded_length, signed_attr, signed_attr_padded_length, signed_attr_econtent_hash_offset, pubKey, signature);
signal signedAttrShaBytes[HASH_LEN_BYTES] <== PassportVerifier(DG_HASH_ALGO, ECONTENT_HASH_ALGO, signatureAlgorithm, n, k, MAX_ECONTENT_PADDED_LEN, MAX_SIGNED_ATTR_PADDED_LEN)(dg1,dg1_hash_offset, dg2_hash, eContent,eContent_padded_length, signed_attr, signed_attr_padded_length, signed_attr_econtent_hash_offset, pubKey, signature);
// verify passport is not expired
component isValid = IsValid();
isValid.currDate <== current_date;
@@ -67,9 +67,10 @@ template OPENPASSPORT_PROVE(DG_HASH_ALGO, ECONTENT_HASH_ALGO, signatureAlgorithm
}
// nulifier
signal signatureHashed <== CustomHasher(kScaled)(signature);
component passportDataHashed = CustomHasher(HASH_LEN_BYTES);
passportDataHashed.in <== signedAttrShaBytes;
component poseidon_hasher = PoseidonHash(2);
poseidon_hasher.in[0] <== signatureHashed;
poseidon_hasher.in[0] <== passportDataHashed.out;
poseidon_hasher.in[1] <== scope;
signal output nullifier <== poseidon_hasher.out;

View File

@@ -81,5 +81,17 @@ template PassportVerifier(DG_HASH_ALGO, ECONTENT_HASH_ALGO, signatureAlgorithm,
signal signedAttrSha[SIGNED_ATTR_HASH_ALGO] <== ShaBytesDynamic(SIGNED_ATTR_HASH_ALGO, MAX_SIGNED_ATTR_LEN)(signed_attr, signed_attr_padded_length);
SignatureVerifier(signatureAlgorithm, n, k)(signedAttrSha, pubKey, signature);
signal output signedAttrShaBytes[SIGNED_ATTR_HASH_ALGO_BYTES];
component signedAttrShaBytesComp[SIGNED_ATTR_HASH_ALGO_BYTES];
for (var i = 0; i < SIGNED_ATTR_HASH_ALGO_BYTES; i++) {
signedAttrShaBytesComp[i] = Bits2Num(8);
for (var j = 0; j < 8; j++) {
signedAttrShaBytesComp[i].in[7 - j] <== signedAttrSha[i * 8 + j];
}
signedAttrShaBytes[i] <== signedAttrShaBytesComp[i].out;
}
}

View File

@@ -1,5 +1,5 @@
import { describe } from 'mocha';
import { expect } from 'chai';
import { assert, expect } from 'chai';
import path from 'path';
import { wasm as wasm_tester } from 'circom_tester';
import { generateCircuitInputsProve } from '../../common/src/utils/generateInputs';
@@ -10,6 +10,8 @@ import { poseidon2 } from 'poseidon-lite';
import { SMT } from '@openpassport/zk-kit-smt';
import namejson from '../../common/ofacdata/outputs/nameSMT.json';
import { getCircuitNameFromPassportData } from '../../common/src/utils/circuitsName';
import { customHasher } from '../../common/src/utils/pubkeyTree';
import { hash } from '../../common/src/utils/utils';
const sigAlgs = [
{
@@ -19,6 +21,7 @@ const sigAlgs = [
hashFunction: 'sha256',
domainParameter: '3',
keyLength: '3072',
checkNullifier: true,
},
{
dgHashAlgo: 'sha256',
@@ -62,6 +65,7 @@ const fullSigAlgs = [
hashFunction: 'sha1',
domainParameter: '65537',
keyLength: '2048',
checkNullifier: true,
},
{
dgHashAlgo: 'sha256',
@@ -229,7 +233,15 @@ const testSuite = process.env.FULL_TEST_SUITE === 'true' ? fullSigAlgs : sigAlgs
// const testSuite = fullSigAlgs;
testSuite.forEach(
({ dgHashAlgo, eContentHashAlgo, sigAlg, hashFunction, domainParameter, keyLength }) => {
({
dgHashAlgo,
eContentHashAlgo,
sigAlg,
hashFunction,
domainParameter,
keyLength,
checkNullifier,
}) => {
describe(`Prove - ${dgHashAlgo.toUpperCase()} ${eContentHashAlgo.toUpperCase()} ${hashFunction.toUpperCase()} ${sigAlg.toUpperCase()} ${domainParameter} ${keyLength}`, function () {
this.timeout(0);
let circuit: any;
@@ -293,13 +305,22 @@ testSuite.forEach(
it('should calculate the witness with correct inputs', async function () {
const w = await circuit.calculateWitness(inputs);
await circuit.checkConstraints(w);
// circuits.getOutput takes way too long for ecdsa
if (true) {
console.log('skipping printing outputs to console for ecdsa');
if (!checkNullifier) {
return;
}
const passportDataHash = customHasher(
hash(
hashFunction,
inputs.signed_attr.slice(0, inputs.signed_attr.lastIndexOf('128')).map((x) => +x)
).map((x) => (x & 0xff).toString())
);
const expectedNullifier = poseidon2([passportDataHash, inputs.scope[0]]).toString();
const nullifier = (await circuit.getOutput(w, ['nullifier'])).nullifier;
assert(expectedNullifier == nullifier);
console.log('\x1b[34m%s\x1b[0m', 'nullifier', nullifier);
const commitment = (await circuit.getOutput(w, ['commitment'])).commitment;
console.log('\x1b[34m%s\x1b[0m', 'commitment', commitment);