mirror of
https://github.com/selfxyz/self.git
synced 2026-01-10 15:18:18 -05:00
reformat file according to prettier
This commit is contained in:
@@ -1,14 +1,13 @@
|
||||
# Proof of Passport Circuits
|
||||
# Proof of Passport Circuits
|
||||
|
||||
## Requirements
|
||||
|
||||
| Requirement | Version | Installation Guide |
|
||||
|-------------|---------|--------------------|
|
||||
| nodejs | > v18 | [Install nodejs](https://nodejs.org/) |
|
||||
| circom | Latest | [Install circom](https://docs.circom.io/) |
|
||||
| Requirement | Version | Installation Guide |
|
||||
| ----------- | ------- | --------------------------------------------------- |
|
||||
| nodejs | > v18 | [Install nodejs](https://nodejs.org/) |
|
||||
| circom | Latest | [Install circom](https://docs.circom.io/) |
|
||||
| snarkjs | Latest | [Install snarkjs](https://github.com/iden3/snarkjs) |
|
||||
|
||||
|
||||
## Overview of the circuits
|
||||
|
||||
Circom circuits are located in the `circuits/` folder.
|
||||
@@ -16,6 +15,7 @@ The circuits are split into two parts: `register` and `disclose`.
|
||||
This design is close to that of [semaphore](https://semaphore.pse.dev/).
|
||||
|
||||
The `register` circuit is used for the following:
|
||||
|
||||
1. Verify the signature of the passport
|
||||
2. Verify that the public key which signed the passport is part of the registry merkle tree (a check of the merkle roots will be performed on-chain)
|
||||
3. Generate commitment = H (secret + passportData + some other data)
|
||||
@@ -27,6 +27,7 @@ The `register` will follow the `register_<hash>With<signature>.circom` naming co
|
||||
One verifier for each register circuit will be deployed on-chain, all of them committing to the same merkle tree.
|
||||
|
||||
The `disclose` circuit is used for the following:
|
||||
|
||||
1. Verify that a user knows a secret e.g., he is able to reconstruct one leaf of the merkle tree (a check of the merkle roots will be performed on-chain)
|
||||
2. Passport expiry is verified
|
||||
3. A range check is performed over the age of the user
|
||||
@@ -36,8 +37,8 @@ The `disclose` circuit is used for the following:
|
||||
Any application that wants to use Proof of Passport can actually build its own `disclose` circuit.
|
||||
|
||||
### 🚧 Under development 🚧
|
||||
Proof of Passport currently supports the following sig/hash algorithms:
|
||||
|
||||
Proof of Passport currently supports the following sig/hash algorithms:
|
||||
|
||||
- [x] sha256WithRSAEncryption
|
||||
- [x] sha1WithRSAEncryption
|
||||
@@ -48,8 +49,7 @@ Proof of Passport currently supports the following sig/hash algorithms:
|
||||
- [ ] ecdsa-with-SHA512
|
||||
- [ ] sha512WithRSAEncryption
|
||||
|
||||
> 💡 We currently have a bounty program if you implement a sig/hash setup.
|
||||
|
||||
> 💡 We currently have a bounty program if you implement a sig/hash setup.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -68,4 +68,5 @@ yarn install-circuits
|
||||
```bash
|
||||
yarn test
|
||||
```
|
||||
This will run tests with sample data generated on the fly.
|
||||
|
||||
This will run tests with sample data generated on the fly.
|
||||
|
||||
@@ -1,204 +1,199 @@
|
||||
import { assert, expect } from 'chai'
|
||||
import path from "path";
|
||||
const wasm_tester = require("circom_tester").wasm;
|
||||
import { assert, expect } from 'chai';
|
||||
import path from 'path';
|
||||
const wasm_tester = require('circom_tester').wasm;
|
||||
import { mockPassportData_sha256_rsa_65537 } from '../../../common/src/constants/mockPassportData';
|
||||
import { formatMrz, packBytes } from '../../../common/src/utils/utils';
|
||||
import { attributeToPosition, COMMITMENT_TREE_DEPTH } from "../../../common/src/constants/constants";
|
||||
import { poseidon1, poseidon2, poseidon6 } from "poseidon-lite";
|
||||
import { LeanIMT } from "@zk-kit/lean-imt";
|
||||
import {
|
||||
attributeToPosition,
|
||||
COMMITMENT_TREE_DEPTH,
|
||||
} from '../../../common/src/constants/constants';
|
||||
import { poseidon1, poseidon2, poseidon6 } from 'poseidon-lite';
|
||||
import { LeanIMT } from '@zk-kit/lean-imt';
|
||||
import { getLeaf } from '../../../common/src/utils/pubkeyTree';
|
||||
import { generateCircuitInputsDisclose } from '../../../common/src/utils/generateInputs';
|
||||
import { unpackReveal } from '../../../common/src/utils/revealBitmap';
|
||||
|
||||
describe("Disclose", function () {
|
||||
this.timeout(0);
|
||||
let inputs: any;
|
||||
let circuit: any;
|
||||
let w: any;
|
||||
let passportData = mockPassportData_sha256_rsa_65537;
|
||||
let attestation_id: string;
|
||||
let tree: any;
|
||||
const attestation_name = "E-PASSPORT";
|
||||
describe('Disclose', function () {
|
||||
this.timeout(0);
|
||||
let inputs: any;
|
||||
let circuit: any;
|
||||
let w: any;
|
||||
let passportData = mockPassportData_sha256_rsa_65537;
|
||||
let attestation_id: string;
|
||||
let tree: any;
|
||||
const attestation_name = 'E-PASSPORT';
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(path.join(__dirname, "../../circuits/disclose/disclose.circom"),
|
||||
{
|
||||
include: [
|
||||
"node_modules",
|
||||
"./node_modules/@zk-kit/binary-merkle-root.circom/src",
|
||||
"./node_modules/circomlib/circuits"
|
||||
]
|
||||
},
|
||||
);
|
||||
|
||||
const secret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
attestation_id = poseidon1([
|
||||
BigInt(Buffer.from(attestation_name).readUIntBE(0, 6))
|
||||
]).toString();
|
||||
|
||||
const majority = ["1", "8"];
|
||||
const user_identifier = "0xE6E4b6a802F2e0aeE5676f6010e0AF5C9CDd0a50";
|
||||
const bitmap = Array(90).fill("1")
|
||||
const scope = poseidon1([
|
||||
BigInt(Buffer.from("VOTEEEEE").readUIntBE(0, 6))
|
||||
]).toString();
|
||||
|
||||
// compute the commitment and insert it in the tree
|
||||
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]
|
||||
])
|
||||
tree = new LeanIMT((a, b) => poseidon2([a, b]), []);
|
||||
tree.insert(BigInt(commitment));
|
||||
|
||||
inputs = generateCircuitInputsDisclose(
|
||||
secret,
|
||||
attestation_id,
|
||||
passportData,
|
||||
tree,
|
||||
majority,
|
||||
bitmap,
|
||||
scope,
|
||||
user_identifier
|
||||
);
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(path.join(__dirname, '../../circuits/disclose/disclose.circom'), {
|
||||
include: [
|
||||
'node_modules',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
],
|
||||
});
|
||||
|
||||
it("should compile and load the circuit", async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
const secret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
attestation_id = poseidon1([BigInt(Buffer.from(attestation_name).readUIntBE(0, 6))]).toString();
|
||||
|
||||
const majority = ['1', '8'];
|
||||
const user_identifier = '0xE6E4b6a802F2e0aeE5676f6010e0AF5C9CDd0a50';
|
||||
const bitmap = Array(90).fill('1');
|
||||
const scope = poseidon1([BigInt(Buffer.from('VOTEEEEE').readUIntBE(0, 6))]).toString();
|
||||
|
||||
// compute the commitment and insert it in the tree
|
||||
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],
|
||||
]);
|
||||
tree = new LeanIMT((a, b) => poseidon2([a, b]), []);
|
||||
tree.insert(BigInt(commitment));
|
||||
|
||||
inputs = generateCircuitInputsDisclose(
|
||||
secret,
|
||||
attestation_id,
|
||||
passportData,
|
||||
tree,
|
||||
majority,
|
||||
bitmap,
|
||||
scope,
|
||||
user_identifier
|
||||
);
|
||||
});
|
||||
|
||||
it('should compile and load the circuit', async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
it('should have nullifier == poseidon(secret, scope)', async function () {
|
||||
w = await circuit.calculateWitness(inputs);
|
||||
const nullifier_js = poseidon2([inputs.secret, inputs.scope]).toString();
|
||||
const nullifier_circom = (await circuit.getOutput(w, ['nullifier'])).nullifier;
|
||||
|
||||
//console.log("nullifier_circom", nullifier_circom);
|
||||
//console.log("nullifier_js", nullifier_js);
|
||||
expect(nullifier_circom).to.equal(nullifier_js);
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with outdated passport', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
current_date: ['4', '4', '0', '5', '1', '0'], // 2044
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with different attestation_id', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
attestation_id: poseidon1([
|
||||
BigInt(Buffer.from('ANON-AADHAAR').readUIntBE(0, 6)),
|
||||
]).toString(),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
describe('MRZ selective disclosure', function () {
|
||||
const attributeCombinations = [
|
||||
['issuing_state', 'name'],
|
||||
['passport_number', 'nationality', 'date_of_birth'],
|
||||
['gender', 'expiry_date'],
|
||||
];
|
||||
|
||||
attributeCombinations.forEach((combination) => {
|
||||
it(`Disclosing ${combination.join(', ')}`, async function () {
|
||||
const attributeToReveal = Object.keys(attributeToPosition).reduce((acc, attribute) => {
|
||||
acc[attribute] = combination.includes(attribute);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const bitmap = Array(90).fill('0');
|
||||
|
||||
Object.entries(attributeToReveal).forEach(([attribute, reveal]) => {
|
||||
if (reveal) {
|
||||
const [start, end] = attributeToPosition[attribute];
|
||||
bitmap.fill('1', start, end + 1);
|
||||
}
|
||||
});
|
||||
|
||||
inputs = {
|
||||
...inputs,
|
||||
bitmap: bitmap.map(String),
|
||||
};
|
||||
|
||||
it("should have nullifier == poseidon(secret, scope)", async function () {
|
||||
w = await circuit.calculateWitness(inputs);
|
||||
const nullifier_js = poseidon2([inputs.secret, inputs.scope]).toString();
|
||||
const nullifier_circom = (await circuit.getOutput(w, ["nullifier"])).nullifier;
|
||||
|
||||
//console.log("nullifier_circom", nullifier_circom);
|
||||
//console.log("nullifier_js", nullifier_js);
|
||||
expect(nullifier_circom).to.equal(nullifier_js);
|
||||
});
|
||||
|
||||
it("should fail to calculate witness with outdated passport", async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
current_date: ["4", "4", "0", "5", "1", "0"] // 2044
|
||||
}
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail("Expected an error but none was thrown.");
|
||||
} catch (error) {
|
||||
expect(error.message).to.include("Assert Failed");
|
||||
}
|
||||
});
|
||||
|
||||
it("should fail to calculate witness with different attestation_id", async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
attestation_id: poseidon1([
|
||||
BigInt(Buffer.from("ANON-AADHAAR").readUIntBE(0, 6))
|
||||
]).toString()
|
||||
}
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail("Expected an error but none was thrown.");
|
||||
} catch (error) {
|
||||
expect(error.message).to.include("Assert Failed");
|
||||
}
|
||||
});
|
||||
|
||||
describe('MRZ selective disclosure', function () {
|
||||
const attributeCombinations = [
|
||||
['issuing_state', 'name'],
|
||||
['passport_number', 'nationality', 'date_of_birth'],
|
||||
['gender', 'expiry_date'],
|
||||
];
|
||||
|
||||
attributeCombinations.forEach(combination => {
|
||||
it(`Disclosing ${combination.join(", ")}`, async function () {
|
||||
const attributeToReveal = Object.keys(attributeToPosition).reduce((acc, attribute) => {
|
||||
acc[attribute] = combination.includes(attribute);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const bitmap = Array(90).fill('0');
|
||||
|
||||
Object.entries(attributeToReveal).forEach(([attribute, reveal]) => {
|
||||
if (reveal) {
|
||||
const [start, end] = attributeToPosition[attribute];
|
||||
bitmap.fill('1', start, end + 1);
|
||||
}
|
||||
});
|
||||
|
||||
inputs = {
|
||||
...inputs,
|
||||
bitmap: bitmap.map(String),
|
||||
}
|
||||
|
||||
w = await circuit.calculateWitness(inputs);
|
||||
|
||||
const revealedData_packed = await circuit.getOutput(w, ["revealedData_packed[3]"])
|
||||
|
||||
const reveal_unpacked = unpackReveal(revealedData_packed);
|
||||
|
||||
for (let i = 0; i < reveal_unpacked.length; i++) {
|
||||
if (bitmap[i] == '1') {
|
||||
const char = String.fromCharCode(Number(inputs.mrz[i + 5]));
|
||||
assert(reveal_unpacked[i] == char, 'Should reveal the right character');
|
||||
} else {
|
||||
assert(reveal_unpacked[i] == '\x00', 'Should not reveal');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
it("should allow disclosing majority", async function () {
|
||||
const bitmap = Array(90).fill('0');
|
||||
bitmap[88] = '1';
|
||||
bitmap[89] = '1';
|
||||
|
||||
w = await circuit.calculateWitness({
|
||||
...inputs,
|
||||
bitmap: bitmap.map(String),
|
||||
});
|
||||
|
||||
const revealedData_packed = await circuit.getOutput(w, ["revealedData_packed[3]"])
|
||||
const revealedData_packed = await circuit.getOutput(w, ['revealedData_packed[3]']);
|
||||
|
||||
const reveal_unpacked = unpackReveal(revealedData_packed);
|
||||
//console.log("reveal_unpacked", reveal_unpacked)
|
||||
|
||||
expect(reveal_unpacked[88]).to.equal("1");
|
||||
expect(reveal_unpacked[89]).to.equal("8");
|
||||
for (let i = 0; i < reveal_unpacked.length; i++) {
|
||||
if (bitmap[i] == '1') {
|
||||
const char = String.fromCharCode(Number(inputs.mrz[i + 5]));
|
||||
assert(reveal_unpacked[i] == char, 'Should reveal the right character');
|
||||
} else {
|
||||
assert(reveal_unpacked[i] == '\x00', 'Should not reveal');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow disclosing majority', async function () {
|
||||
const bitmap = Array(90).fill('0');
|
||||
bitmap[88] = '1';
|
||||
bitmap[89] = '1';
|
||||
|
||||
w = await circuit.calculateWitness({
|
||||
...inputs,
|
||||
bitmap: bitmap.map(String),
|
||||
});
|
||||
|
||||
it("shouldn't allow disclosing wrong majority", async function () {
|
||||
const bitmap = Array(90).fill('0');
|
||||
bitmap[88] = '1';
|
||||
bitmap[89] = '1';
|
||||
const revealedData_packed = await circuit.getOutput(w, ['revealedData_packed[3]']);
|
||||
|
||||
w = await circuit.calculateWitness({
|
||||
...inputs,
|
||||
majority: ["5", "0"].map(char => BigInt(char.charCodeAt(0)).toString()),
|
||||
bitmap: bitmap.map(String),
|
||||
});
|
||||
const reveal_unpacked = unpackReveal(revealedData_packed);
|
||||
//console.log("reveal_unpacked", reveal_unpacked)
|
||||
|
||||
const revealedData_packed = await circuit.getOutput(w, ["revealedData_packed[3]"])
|
||||
expect(reveal_unpacked[88]).to.equal('1');
|
||||
expect(reveal_unpacked[89]).to.equal('8');
|
||||
});
|
||||
|
||||
const reveal_unpacked = unpackReveal(revealedData_packed);
|
||||
//console.log("reveal_unpacked", reveal_unpacked)
|
||||
it("shouldn't allow disclosing wrong majority", async function () {
|
||||
const bitmap = Array(90).fill('0');
|
||||
bitmap[88] = '1';
|
||||
bitmap[89] = '1';
|
||||
|
||||
expect(reveal_unpacked[88]).to.equal("\x00");
|
||||
expect(reveal_unpacked[89]).to.equal("\x00");
|
||||
w = await circuit.calculateWitness({
|
||||
...inputs,
|
||||
majority: ['5', '0'].map((char) => BigInt(char.charCodeAt(0)).toString()),
|
||||
bitmap: bitmap.map(String),
|
||||
});
|
||||
|
||||
const revealedData_packed = await circuit.getOutput(w, ['revealedData_packed[3]']);
|
||||
|
||||
const reveal_unpacked = unpackReveal(revealedData_packed);
|
||||
//console.log("reveal_unpacked", reveal_unpacked)
|
||||
|
||||
expect(reveal_unpacked[88]).to.equal('\x00');
|
||||
expect(reveal_unpacked[89]).to.equal('\x00');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -1,57 +1,69 @@
|
||||
import { assert, expect } from 'chai'
|
||||
import fs from 'fs'
|
||||
import { assert, expect } from 'chai';
|
||||
import fs from 'fs';
|
||||
const forge = require('node-forge');
|
||||
import path from 'path';
|
||||
const wasm_tester = require("circom_tester").wasm;
|
||||
const wasm_tester = require('circom_tester').wasm;
|
||||
import { getCSCAInputs } from '../../../common/src/utils/csca';
|
||||
import { mock_dsc_sha1_rsa_2048, mock_csca_sha1_rsa_2048 } from '../../../common/src/constants/mockCertificates';
|
||||
import {
|
||||
mock_dsc_sha1_rsa_2048,
|
||||
mock_csca_sha1_rsa_2048,
|
||||
} from '../../../common/src/constants/mockCertificates';
|
||||
|
||||
describe('DSC chain certificate - SHA1 RSA', function () {
|
||||
this.timeout(0); // Disable timeout
|
||||
let circuit;
|
||||
const n_dsc = 121;
|
||||
const k_dsc = 17;
|
||||
const n_csca = 121;
|
||||
const k_csca = 17;
|
||||
const max_cert_bytes = 960;
|
||||
const dscCert = forge.pki.certificateFromPem(mock_dsc_sha1_rsa_2048);
|
||||
const cscaCert = forge.pki.certificateFromPem(mock_csca_sha1_rsa_2048);
|
||||
this.timeout(0); // Disable timeout
|
||||
let circuit;
|
||||
const n_dsc = 121;
|
||||
const k_dsc = 17;
|
||||
const n_csca = 121;
|
||||
const k_csca = 17;
|
||||
const max_cert_bytes = 960;
|
||||
const dscCert = forge.pki.certificateFromPem(mock_dsc_sha1_rsa_2048);
|
||||
const cscaCert = forge.pki.certificateFromPem(mock_csca_sha1_rsa_2048);
|
||||
|
||||
const inputs = getCSCAInputs(BigInt(0).toString(), dscCert, cscaCert, n_dsc, k_dsc, n_csca, k_csca, max_cert_bytes, true);
|
||||
const inputs = getCSCAInputs(
|
||||
BigInt(0).toString(),
|
||||
dscCert,
|
||||
cscaCert,
|
||||
n_dsc,
|
||||
k_dsc,
|
||||
n_csca,
|
||||
k_csca,
|
||||
max_cert_bytes,
|
||||
true
|
||||
);
|
||||
|
||||
before(async () => {
|
||||
const circuitPath = path.resolve(__dirname, '../../circuits/tests/dsc/dsc_sha1_rsa_2048.circom');
|
||||
circuit = await wasm_tester(
|
||||
circuitPath,
|
||||
{
|
||||
include: [
|
||||
"node_modules",
|
||||
"./node_modules/@zk-kit/binary-merkle-root.circom/src",
|
||||
"./node_modules/circomlib/circuits"
|
||||
]
|
||||
}
|
||||
);
|
||||
before(async () => {
|
||||
const circuitPath = path.resolve(
|
||||
__dirname,
|
||||
'../../circuits/tests/dsc/dsc_sha1_rsa_2048.circom'
|
||||
);
|
||||
circuit = await wasm_tester(circuitPath, {
|
||||
include: [
|
||||
'node_modules',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('verify dsc has been signed by the csca', () => {
|
||||
const tbsCertAsn1 = forge.pki.getTBSCertificate(dscCert);
|
||||
const tbsCertDer = forge.asn1.toDer(tbsCertAsn1).getBytes();
|
||||
const md = forge.md.sha1.create();
|
||||
md.update(tbsCertDer);
|
||||
const tbsHash = md.digest().getBytes();
|
||||
const signature = dscCert.signature;
|
||||
const cscaCert = forge.pki.certificateFromPem(mock_csca_sha1_rsa_2048);
|
||||
const publicKey = cscaCert.publicKey;
|
||||
const verified = publicKey.verify(tbsHash, signature);
|
||||
expect(verified).to.be.true;
|
||||
})
|
||||
it('verify dsc has been signed by the csca', () => {
|
||||
const tbsCertAsn1 = forge.pki.getTBSCertificate(dscCert);
|
||||
const tbsCertDer = forge.asn1.toDer(tbsCertAsn1).getBytes();
|
||||
const md = forge.md.sha1.create();
|
||||
md.update(tbsCertDer);
|
||||
const tbsHash = md.digest().getBytes();
|
||||
const signature = dscCert.signature;
|
||||
const cscaCert = forge.pki.certificateFromPem(mock_csca_sha1_rsa_2048);
|
||||
const publicKey = cscaCert.publicKey;
|
||||
const verified = publicKey.verify(tbsHash, signature);
|
||||
expect(verified).to.be.true;
|
||||
});
|
||||
|
||||
it('should compile and load the circuit', () => {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
})
|
||||
it('should compile and load the circuit', () => {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
it('should compute the correct output', async () => {
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
})
|
||||
|
||||
})
|
||||
it('should compute the correct output', async () => {
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,56 +1,68 @@
|
||||
import { assert, expect } from 'chai'
|
||||
import fs from 'fs'
|
||||
import { assert, expect } from 'chai';
|
||||
import fs from 'fs';
|
||||
const forge = require('node-forge');
|
||||
import path from 'path';
|
||||
const wasm_tester = require("circom_tester").wasm;
|
||||
const wasm_tester = require('circom_tester').wasm;
|
||||
import { getCSCAInputs } from '../../../common/src/utils/csca';
|
||||
import { mock_dsc_sha256_rsa_2048, mock_csca_sha256_rsa_2048 } from '../../../common/src/constants/mockCertificates';
|
||||
import {
|
||||
mock_dsc_sha256_rsa_2048,
|
||||
mock_csca_sha256_rsa_2048,
|
||||
} from '../../../common/src/constants/mockCertificates';
|
||||
|
||||
describe('DSC chain certificate - SHA256 RSA', function () {
|
||||
this.timeout(0); // Disable timeout
|
||||
let circuit;
|
||||
const n_dsc = 121;
|
||||
const k_dsc = 17;
|
||||
const n_csca = 121;
|
||||
const k_csca = 17;
|
||||
const max_cert_bytes = 960;
|
||||
const dscCert = forge.pki.certificateFromPem(mock_dsc_sha256_rsa_2048);
|
||||
const cscaCert = forge.pki.certificateFromPem(mock_csca_sha256_rsa_2048);
|
||||
this.timeout(0); // Disable timeout
|
||||
let circuit;
|
||||
const n_dsc = 121;
|
||||
const k_dsc = 17;
|
||||
const n_csca = 121;
|
||||
const k_csca = 17;
|
||||
const max_cert_bytes = 960;
|
||||
const dscCert = forge.pki.certificateFromPem(mock_dsc_sha256_rsa_2048);
|
||||
const cscaCert = forge.pki.certificateFromPem(mock_csca_sha256_rsa_2048);
|
||||
|
||||
const inputs = getCSCAInputs(BigInt(0).toString(), dscCert, cscaCert, n_dsc, k_dsc, n_csca, k_csca, max_cert_bytes, true);
|
||||
const inputs = getCSCAInputs(
|
||||
BigInt(0).toString(),
|
||||
dscCert,
|
||||
cscaCert,
|
||||
n_dsc,
|
||||
k_dsc,
|
||||
n_csca,
|
||||
k_csca,
|
||||
max_cert_bytes,
|
||||
true
|
||||
);
|
||||
|
||||
before(async () => {
|
||||
const circuitPath = path.resolve(__dirname, '../../circuits/tests/dsc/dsc_sha256_rsa_2048.circom');
|
||||
circuit = await wasm_tester(
|
||||
circuitPath,
|
||||
{
|
||||
include: [
|
||||
"node_modules",
|
||||
"./node_modules/@zk-kit/binary-merkle-root.circom/src",
|
||||
"./node_modules/circomlib/circuits"
|
||||
]
|
||||
}
|
||||
);
|
||||
before(async () => {
|
||||
const circuitPath = path.resolve(
|
||||
__dirname,
|
||||
'../../circuits/tests/dsc/dsc_sha256_rsa_2048.circom'
|
||||
);
|
||||
circuit = await wasm_tester(circuitPath, {
|
||||
include: [
|
||||
'node_modules',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('verify dsc has been signed by the csca', () => {
|
||||
const tbsCertAsn1 = forge.pki.getTBSCertificate(dscCert);
|
||||
const tbsCertDer = forge.asn1.toDer(tbsCertAsn1).getBytes();
|
||||
const md = forge.md.sha256.create();
|
||||
md.update(tbsCertDer);
|
||||
const tbsHash = md.digest().getBytes();
|
||||
const signature = dscCert.signature;
|
||||
const publicKey = cscaCert.publicKey;
|
||||
const verified = publicKey.verify(tbsHash, signature);
|
||||
expect(verified).to.be.true;
|
||||
})
|
||||
it('verify dsc has been signed by the csca', () => {
|
||||
const tbsCertAsn1 = forge.pki.getTBSCertificate(dscCert);
|
||||
const tbsCertDer = forge.asn1.toDer(tbsCertAsn1).getBytes();
|
||||
const md = forge.md.sha256.create();
|
||||
md.update(tbsCertDer);
|
||||
const tbsHash = md.digest().getBytes();
|
||||
const signature = dscCert.signature;
|
||||
const publicKey = cscaCert.publicKey;
|
||||
const verified = publicKey.verify(tbsHash, signature);
|
||||
expect(verified).to.be.true;
|
||||
});
|
||||
|
||||
it('should compile and load the circuit', () => {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
})
|
||||
it('should compile and load the circuit', () => {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
it('should compute the correct output', async () => {
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
})
|
||||
|
||||
})
|
||||
it('should compute the correct output', async () => {
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,87 +1,99 @@
|
||||
import { assert, expect } from 'chai'
|
||||
import fs from 'fs'
|
||||
import { assert, expect } from 'chai';
|
||||
import fs from 'fs';
|
||||
const forge = require('node-forge');
|
||||
import path from 'path';
|
||||
const wasm_tester = require("circom_tester").wasm;
|
||||
const wasm_tester = require('circom_tester').wasm;
|
||||
import { getCSCAInputs } from '../../../common/src/utils/csca';
|
||||
import crypto from 'crypto';
|
||||
import { mock_dsc_sha256_rsapss_2048, mock_csca_sha256_rsapss_2048 } from '../../../common/src/constants/mockCertificates';
|
||||
import {
|
||||
mock_dsc_sha256_rsapss_2048,
|
||||
mock_csca_sha256_rsapss_2048,
|
||||
} from '../../../common/src/constants/mockCertificates';
|
||||
|
||||
describe('DSC chain certificate - SHA256 RSA-PSS', function () {
|
||||
this.timeout(0); // Disable timeout
|
||||
let circuit;
|
||||
const n_dsc = 64;
|
||||
const k_dsc = 32;
|
||||
const n_csca = 64;
|
||||
const k_csca = 32;
|
||||
const max_cert_bytes = 960;
|
||||
const dscCert = forge.pki.certificateFromPem(mock_dsc_sha256_rsapss_2048);
|
||||
const cscaCert = forge.pki.certificateFromPem(mock_csca_sha256_rsapss_2048);
|
||||
this.timeout(0); // Disable timeout
|
||||
let circuit;
|
||||
const n_dsc = 64;
|
||||
const k_dsc = 32;
|
||||
const n_csca = 64;
|
||||
const k_csca = 32;
|
||||
const max_cert_bytes = 960;
|
||||
const dscCert = forge.pki.certificateFromPem(mock_dsc_sha256_rsapss_2048);
|
||||
const cscaCert = forge.pki.certificateFromPem(mock_csca_sha256_rsapss_2048);
|
||||
|
||||
const inputs = getCSCAInputs(BigInt(0).toString(), dscCert, cscaCert, n_dsc, k_dsc, n_csca, k_csca, max_cert_bytes, true);
|
||||
const inputs = getCSCAInputs(
|
||||
BigInt(0).toString(),
|
||||
dscCert,
|
||||
cscaCert,
|
||||
n_dsc,
|
||||
k_dsc,
|
||||
n_csca,
|
||||
k_csca,
|
||||
max_cert_bytes,
|
||||
true
|
||||
);
|
||||
|
||||
before(async () => {
|
||||
const circuitPath = path.resolve(__dirname, '../../circuits/tests/dsc/dsc_sha256_rsapss_2048.circom');
|
||||
circuit = await wasm_tester(
|
||||
circuitPath,
|
||||
{
|
||||
include: [
|
||||
"node_modules",
|
||||
"./node_modules/@zk-kit/binary-merkle-root.circom/src",
|
||||
"./node_modules/circomlib/circuits"
|
||||
]
|
||||
}
|
||||
);
|
||||
before(async () => {
|
||||
const circuitPath = path.resolve(
|
||||
__dirname,
|
||||
'../../circuits/tests/dsc/dsc_sha256_rsapss_2048.circom'
|
||||
);
|
||||
circuit = await wasm_tester(circuitPath, {
|
||||
include: [
|
||||
'node_modules',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
],
|
||||
});
|
||||
// TODO: Verify the certificate chain in ts too.
|
||||
// it('verify dsc has been signed by the csca using RSA-PSS', () => {
|
||||
// // Extract TBS (To Be Signed) certificate
|
||||
// const tbsCertAsn1 = forge.pki.getTBSCertificate(dscCert);
|
||||
// const tbsCertDer = forge.asn1.toDer(tbsCertAsn1).getBytes();
|
||||
});
|
||||
// TODO: Verify the certificate chain in ts too.
|
||||
// it('verify dsc has been signed by the csca using RSA-PSS', () => {
|
||||
// // Extract TBS (To Be Signed) certificate
|
||||
// const tbsCertAsn1 = forge.pki.getTBSCertificate(dscCert);
|
||||
// const tbsCertDer = forge.asn1.toDer(tbsCertAsn1).getBytes();
|
||||
|
||||
// // Create SHA-256 hash of the TBS certificate
|
||||
// const tbsHash = crypto.createHash('sha256').update(Buffer.from(tbsCertDer, 'binary')).digest();
|
||||
// // Create SHA-256 hash of the TBS certificate
|
||||
// const tbsHash = crypto.createHash('sha256').update(Buffer.from(tbsCertDer, 'binary')).digest();
|
||||
|
||||
// // Extract signature from DSC certificate
|
||||
// const signature = Buffer.from(dscCert.signature, 'binary');
|
||||
// // Extract signature from DSC certificate
|
||||
// const signature = Buffer.from(dscCert.signature, 'binary');
|
||||
|
||||
// // Get public key from CSCA certificate
|
||||
// const publicKeyPem = forge.pki.publicKeyToPem(cscaCert.publicKey);
|
||||
// const publicKey = crypto.createPublicKey(publicKeyPem);
|
||||
// // Get public key from CSCA certificate
|
||||
// const publicKeyPem = forge.pki.publicKeyToPem(cscaCert.publicKey);
|
||||
// const publicKey = crypto.createPublicKey(publicKeyPem);
|
||||
|
||||
// // Verify signature
|
||||
// const pssOptions = {
|
||||
// saltLength: 32,
|
||||
// mgf1Hash: 'sha256'
|
||||
// };
|
||||
// // Verify signature
|
||||
// const pssOptions = {
|
||||
// saltLength: 32,
|
||||
// mgf1Hash: 'sha256'
|
||||
// };
|
||||
|
||||
// try {
|
||||
// const verifier = crypto.createVerify('RSA-SHA256');
|
||||
// verifier.update(tbsHash);
|
||||
// const isValid = verifier.verify({
|
||||
// key: publicKey,
|
||||
// padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
|
||||
// saltLength: pssOptions.saltLength
|
||||
// }, signature);
|
||||
// try {
|
||||
// const verifier = crypto.createVerify('RSA-SHA256');
|
||||
// verifier.update(tbsHash);
|
||||
// const isValid = verifier.verify({
|
||||
// key: publicKey,
|
||||
// padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
|
||||
// saltLength: pssOptions.saltLength
|
||||
// }, signature);
|
||||
|
||||
// console.log('TBS Hash:', tbsHash.toString('hex'));
|
||||
// console.log('Signature:', signature.toString('hex'));
|
||||
// console.log('Public Key:', publicKeyPem);
|
||||
// console.log('Verification result:', isValid);
|
||||
// console.log('TBS Hash:', tbsHash.toString('hex'));
|
||||
// console.log('Signature:', signature.toString('hex'));
|
||||
// console.log('Public Key:', publicKeyPem);
|
||||
// console.log('Verification result:', isValid);
|
||||
|
||||
// expect(isValid).to.be.true;
|
||||
// } catch (error) {
|
||||
// console.error('Verification error:', error);
|
||||
// throw error;
|
||||
// }
|
||||
// })
|
||||
// expect(isValid).to.be.true;
|
||||
// } catch (error) {
|
||||
// console.error('Verification error:', error);
|
||||
// throw error;
|
||||
// }
|
||||
// })
|
||||
|
||||
it('should compile and load the circuit', () => {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
})
|
||||
it('should compile and load the circuit', () => {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
it('should compute the correct output', async () => {
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
})
|
||||
|
||||
})
|
||||
it('should compute the correct output', async () => {
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,124 +1,124 @@
|
||||
import { describe } from 'mocha'
|
||||
import { assert, expect } from 'chai'
|
||||
import path from "path";
|
||||
const wasm_tester = require("circom_tester").wasm;
|
||||
import { poseidon1, poseidon6 } from "poseidon-lite";
|
||||
import { mockPassportData_sha1_rsa_65537 } from "../../../common/src/constants/mockPassportData";
|
||||
import { describe } from 'mocha';
|
||||
import { assert, expect } from 'chai';
|
||||
import path from 'path';
|
||||
const wasm_tester = require('circom_tester').wasm;
|
||||
import { poseidon1, poseidon6 } from 'poseidon-lite';
|
||||
import { mockPassportData_sha1_rsa_65537 } from '../../../common/src/constants/mockPassportData';
|
||||
import { generateCircuitInputsRegister } from '../../../common/src/utils/generateInputs';
|
||||
import { getLeaf } from '../../../common/src/utils/pubkeyTree';
|
||||
import { packBytes } from '../../../common/src/utils/utils';
|
||||
|
||||
describe("Register - SHA1 RSA", function () {
|
||||
this.timeout(0);
|
||||
let inputs: any;
|
||||
let circuit: any;
|
||||
let passportData = mockPassportData_sha1_rsa_65537;
|
||||
let attestation_id: string;
|
||||
const attestation_name = "E-PASSPORT";
|
||||
const n_dsc = 121;
|
||||
const k_dsc = 17;
|
||||
describe('Register - SHA1 RSA', function () {
|
||||
this.timeout(0);
|
||||
let inputs: any;
|
||||
let circuit: any;
|
||||
let passportData = mockPassportData_sha1_rsa_65537;
|
||||
let attestation_id: string;
|
||||
const attestation_name = 'E-PASSPORT';
|
||||
const n_dsc = 121;
|
||||
const k_dsc = 17;
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, "../../circuits/register/register_sha1WithRSAEncryption_65537.circom"),
|
||||
{
|
||||
include: [
|
||||
"node_modules",
|
||||
"./node_modules/@zk-kit/binary-merkle-root.circom/src",
|
||||
"./node_modules/circomlib/circuits",
|
||||
"./node_modules/dmpierre/sha1-circom/circuits",
|
||||
]
|
||||
},
|
||||
);
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, '../../circuits/register/register_sha1WithRSAEncryption_65537.circom'),
|
||||
{
|
||||
include: [
|
||||
'node_modules',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
'./node_modules/dmpierre/sha1-circom/circuits',
|
||||
],
|
||||
}
|
||||
);
|
||||
|
||||
const secret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
const dscSecret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
const secret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
const dscSecret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
|
||||
attestation_id = poseidon1([
|
||||
BigInt(Buffer.from(attestation_name).readUIntBE(0, 6))
|
||||
]).toString();
|
||||
attestation_id = poseidon1([BigInt(Buffer.from(attestation_name).readUIntBE(0, 6))]).toString();
|
||||
|
||||
inputs = generateCircuitInputsRegister(
|
||||
secret,
|
||||
dscSecret,
|
||||
attestation_id,
|
||||
passportData,
|
||||
n_dsc,
|
||||
k_dsc
|
||||
);
|
||||
});
|
||||
inputs = generateCircuitInputsRegister(
|
||||
secret,
|
||||
dscSecret,
|
||||
attestation_id,
|
||||
passportData,
|
||||
n_dsc,
|
||||
k_dsc
|
||||
);
|
||||
});
|
||||
|
||||
it("should compile and load the circuit", async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
it('should compile and load the circuit', async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
it("should calculate the witness with correct inputs", async function () {
|
||||
const w = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(w);
|
||||
it('should calculate the witness with correct inputs', async function () {
|
||||
const w = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(w);
|
||||
|
||||
const nullifier = (await circuit.getOutput(w, ["nullifier"])).nullifier;
|
||||
console.log("\x1b[34m%s\x1b[0m", "nullifier", nullifier);
|
||||
const commitment_circom = (await circuit.getOutput(w, ["commitment"])).commitment;
|
||||
console.log("\x1b[34m%s\x1b[0m", "commitment", commitment_circom);
|
||||
const blinded_dsc_commitment = (await circuit.getOutput(w, ["blinded_dsc_commitment"])).blinded_dsc_commitment;
|
||||
console.log("\x1b[34m%s\x1b[0m", "blinded_dsc_commitment", blinded_dsc_commitment);
|
||||
const nullifier = (await circuit.getOutput(w, ['nullifier'])).nullifier;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'nullifier', nullifier);
|
||||
const commitment_circom = (await circuit.getOutput(w, ['commitment'])).commitment;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'commitment', commitment_circom);
|
||||
const blinded_dsc_commitment = (await circuit.getOutput(w, ['blinded_dsc_commitment']))
|
||||
.blinded_dsc_commitment;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'blinded_dsc_commitment', blinded_dsc_commitment);
|
||||
|
||||
const mrz_bytes = packBytes(inputs.mrz);
|
||||
const commitment_bytes = poseidon6([
|
||||
inputs.secret[0],
|
||||
attestation_id,
|
||||
getLeaf({
|
||||
signatureAlgorithm: passportData.signatureAlgorithm,
|
||||
modulus: passportData.pubKey.modulus,
|
||||
exponent: passportData.pubKey.exponent
|
||||
}),
|
||||
mrz_bytes[0],
|
||||
mrz_bytes[1],
|
||||
mrz_bytes[2]
|
||||
]);
|
||||
const commitment_js = commitment_bytes.toString();
|
||||
//console.log('commitment_js', commitment_js)
|
||||
//console.log('commitment_circom', commitment_circom)
|
||||
expect(commitment_circom).to.be.equal(commitment_js);
|
||||
});
|
||||
const mrz_bytes = packBytes(inputs.mrz);
|
||||
const commitment_bytes = poseidon6([
|
||||
inputs.secret[0],
|
||||
attestation_id,
|
||||
getLeaf({
|
||||
signatureAlgorithm: passportData.signatureAlgorithm,
|
||||
modulus: passportData.pubKey.modulus,
|
||||
exponent: passportData.pubKey.exponent,
|
||||
}),
|
||||
mrz_bytes[0],
|
||||
mrz_bytes[1],
|
||||
mrz_bytes[2],
|
||||
]);
|
||||
const commitment_js = commitment_bytes.toString();
|
||||
//console.log('commitment_js', commitment_js)
|
||||
//console.log('commitment_circom', commitment_circom)
|
||||
expect(commitment_circom).to.be.equal(commitment_js);
|
||||
});
|
||||
|
||||
it("should fail to calculate witness with invalid mrz", async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
mrz: Array(93).fill(0).map(byte => BigInt(byte).toString())
|
||||
}
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail("Expected an error but none was thrown.");
|
||||
} catch (error) {
|
||||
expect(error.message).to.include("Assert Failed");
|
||||
}
|
||||
});
|
||||
it('should fail to calculate witness with invalid mrz', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
mrz: Array(93)
|
||||
.fill(0)
|
||||
.map((byte) => BigInt(byte).toString()),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it("should fail to calculate witness with invalid econtent", async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
econtent: inputs.econtent.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
}
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail("Expected an error but none was thrown.");
|
||||
} catch (error) {
|
||||
expect(error.message).to.include("Assert Failed");
|
||||
}
|
||||
});
|
||||
it('should fail to calculate witness with invalid econtent', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
econtent: inputs.econtent.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it("should fail to calculate witness with invalid signature", async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
signature: inputs.signature.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
}
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail("Expected an error but none was thrown.");
|
||||
} catch (error) {
|
||||
expect(error.message).to.include("Assert Failed");
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
it('should fail to calculate witness with invalid signature', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
signature: inputs.signature.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,121 +1,121 @@
|
||||
import { describe } from 'mocha'
|
||||
import { assert, expect } from 'chai'
|
||||
import path from "path";
|
||||
const wasm_tester = require("circom_tester").wasm;
|
||||
import { poseidon1, poseidon6 } from "poseidon-lite";
|
||||
import { mockPassportData_sha256_rsa_65537 } from "../../../common/src/constants/mockPassportData";
|
||||
import { describe } from 'mocha';
|
||||
import { assert, expect } from 'chai';
|
||||
import path from 'path';
|
||||
const wasm_tester = require('circom_tester').wasm;
|
||||
import { poseidon1, poseidon6 } from 'poseidon-lite';
|
||||
import { mockPassportData_sha256_rsa_65537 } from '../../../common/src/constants/mockPassportData';
|
||||
import { generateCircuitInputsRegister } from '../../../common/src/utils/generateInputs';
|
||||
import { getLeaf } from '../../../common/src/utils/pubkeyTree';
|
||||
import { packBytes } from '../../../common/src/utils/utils';
|
||||
|
||||
describe("Register - SHA256 RSA", function () {
|
||||
this.timeout(0);
|
||||
let inputs: any;
|
||||
let circuit: any;
|
||||
let passportData = mockPassportData_sha256_rsa_65537;
|
||||
let attestation_id: string;
|
||||
const attestation_name = "E-PASSPORT";
|
||||
const n_dsc = 121;
|
||||
const k_dsc = 17;
|
||||
describe('Register - SHA256 RSA', function () {
|
||||
this.timeout(0);
|
||||
let inputs: any;
|
||||
let circuit: any;
|
||||
let passportData = mockPassportData_sha256_rsa_65537;
|
||||
let attestation_id: string;
|
||||
const attestation_name = 'E-PASSPORT';
|
||||
const n_dsc = 121;
|
||||
const k_dsc = 17;
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, "../../circuits/register/register_sha256WithRSAEncryption_65537.circom"),
|
||||
{
|
||||
include: [
|
||||
"node_modules",
|
||||
"./node_modules/@zk-kit/binary-merkle-root.circom/src",
|
||||
"./node_modules/circomlib/circuits"
|
||||
]
|
||||
},
|
||||
);
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, '../../circuits/register/register_sha256WithRSAEncryption_65537.circom'),
|
||||
{
|
||||
include: [
|
||||
'node_modules',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
],
|
||||
}
|
||||
);
|
||||
|
||||
const secret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
const dscSecret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
attestation_id = poseidon1([
|
||||
BigInt(Buffer.from(attestation_name).readUIntBE(0, 6))
|
||||
]).toString();
|
||||
inputs = generateCircuitInputsRegister(
|
||||
secret,
|
||||
dscSecret,
|
||||
attestation_id,
|
||||
passportData,
|
||||
n_dsc,
|
||||
k_dsc
|
||||
);
|
||||
});
|
||||
const secret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
const dscSecret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
attestation_id = poseidon1([BigInt(Buffer.from(attestation_name).readUIntBE(0, 6))]).toString();
|
||||
inputs = generateCircuitInputsRegister(
|
||||
secret,
|
||||
dscSecret,
|
||||
attestation_id,
|
||||
passportData,
|
||||
n_dsc,
|
||||
k_dsc
|
||||
);
|
||||
});
|
||||
|
||||
it("should compile and load the circuit", async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
it('should compile and load the circuit', async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
it("should calculate the witness with correct inputs", async function () {
|
||||
const w = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(w);
|
||||
it('should calculate the witness with correct inputs', async function () {
|
||||
const w = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(w);
|
||||
|
||||
const nullifier = (await circuit.getOutput(w, ["nullifier"])).nullifier;
|
||||
console.log("\x1b[34m%s\x1b[0m", "nullifier", nullifier);
|
||||
const commitment_circom = (await circuit.getOutput(w, ["commitment"])).commitment;
|
||||
console.log("\x1b[34m%s\x1b[0m", "commitment", commitment_circom);
|
||||
const blinded_dsc_commitment = (await circuit.getOutput(w, ["blinded_dsc_commitment"])).blinded_dsc_commitment;
|
||||
console.log("\x1b[34m%s\x1b[0m", "blinded_dsc_commitment", blinded_dsc_commitment);
|
||||
const nullifier = (await circuit.getOutput(w, ['nullifier'])).nullifier;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'nullifier', nullifier);
|
||||
const commitment_circom = (await circuit.getOutput(w, ['commitment'])).commitment;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'commitment', commitment_circom);
|
||||
const blinded_dsc_commitment = (await circuit.getOutput(w, ['blinded_dsc_commitment']))
|
||||
.blinded_dsc_commitment;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'blinded_dsc_commitment', blinded_dsc_commitment);
|
||||
|
||||
const mrz_bytes = packBytes(inputs.mrz);
|
||||
const commitment_bytes = poseidon6([
|
||||
inputs.secret[0],
|
||||
attestation_id,
|
||||
getLeaf({
|
||||
signatureAlgorithm: passportData.signatureAlgorithm,
|
||||
modulus: passportData.pubKey.modulus,
|
||||
exponent: passportData.pubKey.exponent
|
||||
}),
|
||||
mrz_bytes[0],
|
||||
mrz_bytes[1],
|
||||
mrz_bytes[2]
|
||||
]);
|
||||
const commitment_js = commitment_bytes.toString();
|
||||
//console.log('commitment_js', commitment_js)
|
||||
//console.log('commitment_circom', commitment_circom)
|
||||
expect(commitment_circom).to.be.equal(commitment_js);
|
||||
});
|
||||
const mrz_bytes = packBytes(inputs.mrz);
|
||||
const commitment_bytes = poseidon6([
|
||||
inputs.secret[0],
|
||||
attestation_id,
|
||||
getLeaf({
|
||||
signatureAlgorithm: passportData.signatureAlgorithm,
|
||||
modulus: passportData.pubKey.modulus,
|
||||
exponent: passportData.pubKey.exponent,
|
||||
}),
|
||||
mrz_bytes[0],
|
||||
mrz_bytes[1],
|
||||
mrz_bytes[2],
|
||||
]);
|
||||
const commitment_js = commitment_bytes.toString();
|
||||
//console.log('commitment_js', commitment_js)
|
||||
//console.log('commitment_circom', commitment_circom)
|
||||
expect(commitment_circom).to.be.equal(commitment_js);
|
||||
});
|
||||
|
||||
it("should fail to calculate witness with invalid mrz", async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
mrz: Array(93).fill(0).map(byte => BigInt(byte).toString())
|
||||
}
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail("Expected an error but none was thrown.");
|
||||
} catch (error) {
|
||||
expect(error.message).to.include("Assert Failed");
|
||||
}
|
||||
});
|
||||
it('should fail to calculate witness with invalid mrz', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
mrz: Array(93)
|
||||
.fill(0)
|
||||
.map((byte) => BigInt(byte).toString()),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it("should fail to calculate witness with invalid econtent", async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
econtent: inputs.econtent.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
}
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail("Expected an error but none was thrown.");
|
||||
} catch (error) {
|
||||
expect(error.message).to.include("Assert Failed");
|
||||
}
|
||||
});
|
||||
it('should fail to calculate witness with invalid econtent', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
econtent: inputs.econtent.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it("should fail to calculate witness with invalid signature", async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
signature: inputs.signature.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
}
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail("Expected an error but none was thrown.");
|
||||
} catch (error) {
|
||||
expect(error.message).to.include("Assert Failed");
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
it('should fail to calculate witness with invalid signature', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
signature: inputs.signature.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,126 +1,125 @@
|
||||
import { describe } from 'mocha'
|
||||
import { assert, expect } from 'chai'
|
||||
import path from "path";
|
||||
const wasm_tester = require("circom_tester").wasm;
|
||||
import { poseidon1, poseidon6 } from "poseidon-lite";
|
||||
import { mockPassportData_sha256_rsapss_65537 } from "../../../common/src/constants/mockPassportData";
|
||||
import { describe } from 'mocha';
|
||||
import { assert, expect } from 'chai';
|
||||
import path from 'path';
|
||||
const wasm_tester = require('circom_tester').wasm;
|
||||
import { poseidon1, poseidon6 } from 'poseidon-lite';
|
||||
import { mockPassportData_sha256_rsapss_65537 } from '../../../common/src/constants/mockPassportData';
|
||||
import { generateCircuitInputsRegister } from '../../../common/src/utils/generateInputs';
|
||||
import { getLeaf } from '../../../common/src/utils/pubkeyTree';
|
||||
import { packBytes } from '../../../common/src/utils/utils';
|
||||
|
||||
describe("Register - SHA256 RSASSAPSS", function () {
|
||||
this.timeout(0);
|
||||
let inputs: any;
|
||||
let circuit: any;
|
||||
let passportData = mockPassportData_sha256_rsapss_65537;
|
||||
const attestation_name = "E-PASSPORT";
|
||||
let attestation_id: string;
|
||||
const n_dsc = 64;
|
||||
const k_dsc = 32;
|
||||
describe('Register - SHA256 RSASSAPSS', function () {
|
||||
this.timeout(0);
|
||||
let inputs: any;
|
||||
let circuit: any;
|
||||
let passportData = mockPassportData_sha256_rsapss_65537;
|
||||
const attestation_name = 'E-PASSPORT';
|
||||
let attestation_id: string;
|
||||
const n_dsc = 64;
|
||||
const k_dsc = 32;
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, "../../circuits/register/register_sha256WithRSASSAPSS_65537.circom"),
|
||||
{
|
||||
include: [
|
||||
"node_modules",
|
||||
"node_modules/@zk-email/circuits/helpers/sha.circom",
|
||||
"./node_modules/@zk-kit/binary-merkle-root.circom/src",
|
||||
"./node_modules/circomlib/circuits"
|
||||
]
|
||||
},
|
||||
);
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, '../../circuits/register/register_sha256WithRSASSAPSS_65537.circom'),
|
||||
{
|
||||
include: [
|
||||
'node_modules',
|
||||
'node_modules/@zk-email/circuits/helpers/sha.circom',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
],
|
||||
}
|
||||
);
|
||||
|
||||
const secret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
const dscSecret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
attestation_id = poseidon1([
|
||||
BigInt(Buffer.from(attestation_name).readUIntBE(0, 6))
|
||||
]).toString();
|
||||
const secret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
const dscSecret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
attestation_id = poseidon1([BigInt(Buffer.from(attestation_name).readUIntBE(0, 6))]).toString();
|
||||
|
||||
inputs = generateCircuitInputsRegister(
|
||||
secret,
|
||||
dscSecret,
|
||||
attestation_id,
|
||||
passportData,
|
||||
n_dsc,
|
||||
k_dsc
|
||||
);
|
||||
inputs = generateCircuitInputsRegister(
|
||||
secret,
|
||||
dscSecret,
|
||||
attestation_id,
|
||||
passportData,
|
||||
n_dsc,
|
||||
k_dsc
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
it('should compile and load the circuit', async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
it("should compile and load the circuit", async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
it('should calculate the witness with correct inputs', async function () {
|
||||
console.time('calculateWitness');
|
||||
const w = await circuit.calculateWitness(inputs);
|
||||
console.timeEnd('calculateWitness');
|
||||
await circuit.checkConstraints(w);
|
||||
|
||||
it("should calculate the witness with correct inputs", async function () {
|
||||
console.time('calculateWitness')
|
||||
const w = await circuit.calculateWitness(inputs);
|
||||
console.timeEnd('calculateWitness')
|
||||
await circuit.checkConstraints(w);
|
||||
const nullifier = (await circuit.getOutput(w, ['nullifier'])).nullifier;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'nullifier', nullifier);
|
||||
const commitment_circom = (await circuit.getOutput(w, ['commitment'])).commitment;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'commitment', commitment_circom);
|
||||
const blinded_dsc_commitment = (await circuit.getOutput(w, ['blinded_dsc_commitment']))
|
||||
.blinded_dsc_commitment;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'blinded_dsc_commitment', blinded_dsc_commitment);
|
||||
|
||||
const nullifier = (await circuit.getOutput(w, ["nullifier"])).nullifier;
|
||||
console.log("\x1b[34m%s\x1b[0m", "nullifier", nullifier);
|
||||
const commitment_circom = (await circuit.getOutput(w, ["commitment"])).commitment;
|
||||
console.log("\x1b[34m%s\x1b[0m", "commitment", commitment_circom);
|
||||
const blinded_dsc_commitment = (await circuit.getOutput(w, ["blinded_dsc_commitment"])).blinded_dsc_commitment;
|
||||
console.log("\x1b[34m%s\x1b[0m", "blinded_dsc_commitment", blinded_dsc_commitment);
|
||||
const mrz_bytes = packBytes(inputs.mrz);
|
||||
const commitment_bytes = poseidon6([
|
||||
inputs.secret[0],
|
||||
attestation_id,
|
||||
getLeaf({
|
||||
signatureAlgorithm: passportData.signatureAlgorithm,
|
||||
modulus: passportData.pubKey.modulus,
|
||||
exponent: passportData.pubKey.exponent,
|
||||
}),
|
||||
mrz_bytes[0],
|
||||
mrz_bytes[1],
|
||||
mrz_bytes[2],
|
||||
]);
|
||||
const commitment_js = commitment_bytes.toString();
|
||||
//console.log('commitment_js', commitment_js)
|
||||
//console.log('commitment_circom', commitment_circom)
|
||||
expect(commitment_circom).to.be.equal(commitment_js);
|
||||
});
|
||||
|
||||
const mrz_bytes = packBytes(inputs.mrz);
|
||||
const commitment_bytes = poseidon6([
|
||||
inputs.secret[0],
|
||||
attestation_id,
|
||||
getLeaf({
|
||||
signatureAlgorithm: passportData.signatureAlgorithm,
|
||||
modulus: passportData.pubKey.modulus,
|
||||
exponent: passportData.pubKey.exponent
|
||||
}),
|
||||
mrz_bytes[0],
|
||||
mrz_bytes[1],
|
||||
mrz_bytes[2]
|
||||
]);
|
||||
const commitment_js = commitment_bytes.toString();
|
||||
//console.log('commitment_js', commitment_js)
|
||||
//console.log('commitment_circom', commitment_circom)
|
||||
expect(commitment_circom).to.be.equal(commitment_js);
|
||||
});
|
||||
it('should fail to calculate witness with invalid mrz', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
mrz: Array(93)
|
||||
.fill(0)
|
||||
.map((byte) => BigInt(byte).toString()),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it("should fail to calculate witness with invalid mrz", async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
mrz: Array(93).fill(0).map(byte => BigInt(byte).toString())
|
||||
}
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail("Expected an error but none was thrown.");
|
||||
} catch (error) {
|
||||
expect(error.message).to.include("Assert Failed");
|
||||
}
|
||||
});
|
||||
it('should fail to calculate witness with invalid econtent', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
econtent: inputs.econtent.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it("should fail to calculate witness with invalid econtent", async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
econtent: inputs.econtent.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
}
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail("Expected an error but none was thrown.");
|
||||
} catch (error) {
|
||||
expect(error.message).to.include("Assert Failed");
|
||||
}
|
||||
});
|
||||
|
||||
it("should fail to calculate witness with invalid signature", async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
signature: inputs.signature.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
}
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail("Expected an error but none was thrown.");
|
||||
} catch (error) {
|
||||
expect(error.message).to.include("Assert Failed");
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
it('should fail to calculate witness with invalid signature', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
signature: inputs.signature.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,154 +1,149 @@
|
||||
import path from 'path';
|
||||
import { createHash, randomBytes } from 'node:crypto';
|
||||
const wasm_tester = require("circom_tester").wasm;
|
||||
const wasm_tester = require('circom_tester').wasm;
|
||||
|
||||
describe('Mgf1_sha256 Circuit Test', function () {
|
||||
this.timeout(0); // Disable timeout
|
||||
const hashLen = 32; // SHA256 length
|
||||
this.timeout(0); // Disable timeout
|
||||
const hashLen = 32; // SHA256 length
|
||||
|
||||
const compileCircuit = async (circuitPath: string) => {
|
||||
return await wasm_tester(
|
||||
path.join(circuitPath),
|
||||
{
|
||||
include: [
|
||||
"node_modules",
|
||||
]
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function buffer2bitArray(b) {
|
||||
const res = [];
|
||||
for (let i=0; i<b.length; i++) {
|
||||
for (let j=0; j<8; j++) {
|
||||
res.push((b[i] >> (7-j) &1));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function num2Bits(n, input) {
|
||||
let out = [];
|
||||
for (let i = 0; i < n; i++) {
|
||||
out[i] = (input >> i) & 1;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
const bitArray2buffer = (a) => {
|
||||
const len = Math.floor((a.length -1 )/8)+1;
|
||||
const b = Buffer.alloc(len);
|
||||
|
||||
for (let i=0; i<a.length; i++) {
|
||||
const p = Math.floor(i/8);
|
||||
b[p] = b[p] | (Number(a[i]) << ( 7 - (i%8) ));
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
const MGF1 = (mgfSeed: Buffer, maskLen: number) => {
|
||||
const hLen = hashLen;
|
||||
if (maskLen > 0xffffffff * hLen) {
|
||||
throw new Error('mask too long');
|
||||
}
|
||||
|
||||
var T = [];
|
||||
for (var i = 0; i <= Math.ceil(maskLen / hLen) - 1; i++) {
|
||||
var C = Buffer.alloc(4);
|
||||
C.writeUInt32BE(i);
|
||||
const hash3 = createHash('sha256');
|
||||
hash3.update(Buffer.concat([mgfSeed, C]));
|
||||
T.push(hash3.digest());
|
||||
}
|
||||
return Buffer.concat(T).slice(0, maskLen);
|
||||
}
|
||||
|
||||
it('Should compile', async function () {
|
||||
await compileCircuit('circuits/tests/mgf1Sha256/Mgf1Sha256_tester.circom');
|
||||
})
|
||||
|
||||
it('Should generate correct MGF1 output - 4 Byte Seed', async function () {
|
||||
const seed = 12345678;
|
||||
const maskLen = 32;
|
||||
const seedLen = 4; // 4 bytes - set in the circuit
|
||||
|
||||
const bitArray = num2Bits(seedLen * 8, seed);
|
||||
const mgfSeed = bitArray2buffer(bitArray);
|
||||
|
||||
const expected = MGF1(mgfSeed, maskLen);
|
||||
|
||||
const circuit = await compileCircuit('circuits/tests/mgf1Sha256/Mgf1Sha256_tester.circom');
|
||||
const expected_mask_output = buffer2bitArray(expected);
|
||||
const inputs = {
|
||||
seed: seed,
|
||||
expected_mask_output,
|
||||
|
||||
};
|
||||
|
||||
const witness = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(witness);
|
||||
const compileCircuit = async (circuitPath: string) => {
|
||||
return await wasm_tester(path.join(circuitPath), {
|
||||
include: ['node_modules'],
|
||||
});
|
||||
};
|
||||
|
||||
it('Should generate correct MGF1 output - 32 Byte Seed', async function () {
|
||||
const randBytes = randomBytes(32);
|
||||
function buffer2bitArray(b) {
|
||||
const res = [];
|
||||
for (let i = 0; i < b.length; i++) {
|
||||
for (let j = 0; j < 8; j++) {
|
||||
res.push((b[i] >> (7 - j)) & 1);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
const maskLen = 32;
|
||||
const seedLen = 32; // set in circuit
|
||||
const expected = MGF1(randBytes, maskLen);
|
||||
function num2Bits(n, input) {
|
||||
let out = [];
|
||||
for (let i = 0; i < n; i++) {
|
||||
out[i] = (input >> i) & 1;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
const circuit = await compileCircuit('circuits/tests/mgf1Sha256/Mgf1Sha256_32Bytes_tester.circom');
|
||||
const expected_mask_output = buffer2bitArray(expected);
|
||||
const inputs = {
|
||||
seed: buffer2bitArray(randBytes),
|
||||
expected_mask_output,
|
||||
const bitArray2buffer = (a) => {
|
||||
const len = Math.floor((a.length - 1) / 8) + 1;
|
||||
const b = Buffer.alloc(len);
|
||||
|
||||
};
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
const p = Math.floor(i / 8);
|
||||
b[p] = b[p] | (Number(a[i]) << (7 - (i % 8)));
|
||||
}
|
||||
return b;
|
||||
};
|
||||
|
||||
const witness = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(witness);
|
||||
});
|
||||
const MGF1 = (mgfSeed: Buffer, maskLen: number) => {
|
||||
const hLen = hashLen;
|
||||
if (maskLen > 0xffffffff * hLen) {
|
||||
throw new Error('mask too long');
|
||||
}
|
||||
|
||||
it('Should generate correct MGF1 output - seedLen value > than actual seed length', async function () {
|
||||
const seed = 1234;
|
||||
const maskLen = 32;
|
||||
const seedLen = 4; //set in circuit
|
||||
var T = [];
|
||||
for (var i = 0; i <= Math.ceil(maskLen / hLen) - 1; i++) {
|
||||
var C = Buffer.alloc(4);
|
||||
C.writeUInt32BE(i);
|
||||
const hash3 = createHash('sha256');
|
||||
hash3.update(Buffer.concat([mgfSeed, C]));
|
||||
T.push(hash3.digest());
|
||||
}
|
||||
return Buffer.concat(T).slice(0, maskLen);
|
||||
};
|
||||
|
||||
const bitArray = num2Bits(seedLen * 8, seed);
|
||||
const mgfSeed = bitArray2buffer(bitArray);
|
||||
it('Should compile', async function () {
|
||||
await compileCircuit('circuits/tests/mgf1Sha256/Mgf1Sha256_tester.circom');
|
||||
});
|
||||
|
||||
const expected = MGF1(mgfSeed, maskLen);
|
||||
it('Should generate correct MGF1 output - 4 Byte Seed', async function () {
|
||||
const seed = 12345678;
|
||||
const maskLen = 32;
|
||||
const seedLen = 4; // 4 bytes - set in the circuit
|
||||
|
||||
const circuit = await compileCircuit('circuits/tests/mgf1Sha256/Mgf1Sha256_tester.circom');
|
||||
const expected_mask_output = buffer2bitArray(expected);
|
||||
const inputs = {
|
||||
seed: seed,
|
||||
expected_mask_output,
|
||||
const bitArray = num2Bits(seedLen * 8, seed);
|
||||
const mgfSeed = bitArray2buffer(bitArray);
|
||||
|
||||
};
|
||||
const expected = MGF1(mgfSeed, maskLen);
|
||||
|
||||
const witness = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(witness);
|
||||
});
|
||||
const circuit = await compileCircuit('circuits/tests/mgf1Sha256/Mgf1Sha256_tester.circom');
|
||||
const expected_mask_output = buffer2bitArray(expected);
|
||||
const inputs = {
|
||||
seed: seed,
|
||||
expected_mask_output,
|
||||
};
|
||||
|
||||
it('Should generate correct MGF1 output - maskLen == 1', async function () {
|
||||
const seed = 12345678;
|
||||
const maskLen = 1;
|
||||
const seedLen = 4;
|
||||
const witness = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(witness);
|
||||
});
|
||||
|
||||
const bitArray = num2Bits(seedLen * 8, seed);
|
||||
const mgfSeed = bitArray2buffer(bitArray);
|
||||
it('Should generate correct MGF1 output - 32 Byte Seed', async function () {
|
||||
const randBytes = randomBytes(32);
|
||||
|
||||
const expected = MGF1(mgfSeed, maskLen);
|
||||
const maskLen = 32;
|
||||
const seedLen = 32; // set in circuit
|
||||
const expected = MGF1(randBytes, maskLen);
|
||||
|
||||
const circuit = await compileCircuit('circuits/tests/mgf1Sha256/Mgf1Sha256_1ByteMask_tester.circom');
|
||||
const expected_mask_output = buffer2bitArray(expected);
|
||||
const inputs = {
|
||||
seed: seed,
|
||||
expected_mask_output,
|
||||
const circuit = await compileCircuit(
|
||||
'circuits/tests/mgf1Sha256/Mgf1Sha256_32Bytes_tester.circom'
|
||||
);
|
||||
const expected_mask_output = buffer2bitArray(expected);
|
||||
const inputs = {
|
||||
seed: buffer2bitArray(randBytes),
|
||||
expected_mask_output,
|
||||
};
|
||||
|
||||
};
|
||||
const witness = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(witness);
|
||||
});
|
||||
|
||||
const witness = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(witness);
|
||||
});
|
||||
});
|
||||
it('Should generate correct MGF1 output - seedLen value > than actual seed length', async function () {
|
||||
const seed = 1234;
|
||||
const maskLen = 32;
|
||||
const seedLen = 4; //set in circuit
|
||||
|
||||
const bitArray = num2Bits(seedLen * 8, seed);
|
||||
const mgfSeed = bitArray2buffer(bitArray);
|
||||
|
||||
const expected = MGF1(mgfSeed, maskLen);
|
||||
|
||||
const circuit = await compileCircuit('circuits/tests/mgf1Sha256/Mgf1Sha256_tester.circom');
|
||||
const expected_mask_output = buffer2bitArray(expected);
|
||||
const inputs = {
|
||||
seed: seed,
|
||||
expected_mask_output,
|
||||
};
|
||||
|
||||
const witness = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(witness);
|
||||
});
|
||||
|
||||
it('Should generate correct MGF1 output - maskLen == 1', async function () {
|
||||
const seed = 12345678;
|
||||
const maskLen = 1;
|
||||
const seedLen = 4;
|
||||
|
||||
const bitArray = num2Bits(seedLen * 8, seed);
|
||||
const mgfSeed = bitArray2buffer(bitArray);
|
||||
|
||||
const expected = MGF1(mgfSeed, maskLen);
|
||||
|
||||
const circuit = await compileCircuit(
|
||||
'circuits/tests/mgf1Sha256/Mgf1Sha256_1ByteMask_tester.circom'
|
||||
);
|
||||
const expected_mask_output = buffer2bitArray(expected);
|
||||
const inputs = {
|
||||
seed: seed,
|
||||
expected_mask_output,
|
||||
};
|
||||
|
||||
const witness = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(witness);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,179 +1,182 @@
|
||||
import chai, { expect, assert } from 'chai';
|
||||
import path from 'path';
|
||||
const wasm_tester = require("circom_tester").wasm;
|
||||
const wasm_tester = require('circom_tester').wasm;
|
||||
|
||||
describe('DateIsLessChecker Circuit Test', function () {
|
||||
this.timeout(0); // Disable timeout
|
||||
this.timeout(0); // Disable timeout
|
||||
|
||||
let circuit;
|
||||
let circuit;
|
||||
|
||||
/**
|
||||
* Test parameters
|
||||
*
|
||||
* n: number of dates to test
|
||||
* majority: age of majority
|
||||
* yearStart: start year for random current dates
|
||||
* yearEnd: end year for random current dates
|
||||
*
|
||||
* According to circuit logic, user has to be majority years and 1 day old to be major
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Test parameters
|
||||
*
|
||||
* n: number of dates to test
|
||||
* majority: age of majority
|
||||
* yearStart: start year for random current dates
|
||||
* yearEnd: end year for random current dates
|
||||
*
|
||||
* According to circuit logic, user has to be majority years and 1 day old to be major
|
||||
*
|
||||
*/
|
||||
|
||||
const n = 10;
|
||||
const majority = 18;
|
||||
const n = 10;
|
||||
const majority = 18;
|
||||
|
||||
const yearStart = 2023;
|
||||
const yearEnd = 2200;
|
||||
const maxDiff = 99; // Maximum age difference
|
||||
const minDiff = majority; // Minimum age for majority
|
||||
const yearStart = 2023;
|
||||
const yearEnd = 2200;
|
||||
const maxDiff = 99; // Maximum age difference
|
||||
const minDiff = majority; // Minimum age for majority
|
||||
|
||||
// Helper function to generate a random date within a given range
|
||||
function generateRandomDate(yearStart, yearEnd) {
|
||||
const year = Math.floor(Math.random() * (yearEnd - yearStart + 1)) + yearStart;
|
||||
const month = Math.floor(Math.random() * 12) + 1;
|
||||
const day = Math.floor(Math.random() * 28) + 1; // Simplification for month lengths
|
||||
return { year, month, day };
|
||||
}
|
||||
// Helper function to generate a random date within a given range
|
||||
function generateRandomDate(yearStart, yearEnd) {
|
||||
const year = Math.floor(Math.random() * (yearEnd - yearStart + 1)) + yearStart;
|
||||
const month = Math.floor(Math.random() * 12) + 1;
|
||||
const day = Math.floor(Math.random() * 28) + 1; // Simplification for month lengths
|
||||
return { year, month, day };
|
||||
}
|
||||
|
||||
// Generate arrays for current dates
|
||||
const currentDates = Array(n).fill(0).map(() => generateRandomDate(yearStart, yearEnd));
|
||||
// Generate arrays for current dates
|
||||
const currentDates = Array(n)
|
||||
.fill(0)
|
||||
.map(() => generateRandomDate(yearStart, yearEnd));
|
||||
|
||||
// Generate majority birthDates ensuring the age difference is at least minDiff
|
||||
const majorityBirthDates = currentDates.map(currentDate => {
|
||||
// Subtract a random number of years within the allowed age difference, plus a random number of days and months for additional variance
|
||||
const yearDiff = Math.floor(Math.random() * (maxDiff - minDiff)) + minDiff;
|
||||
const monthDiff = Math.floor(Math.random() * 12);
|
||||
const dayDiff = Math.floor(Math.random() * 28) + 1;
|
||||
return {
|
||||
year: currentDate.year - yearDiff,
|
||||
month: Math.max(1, currentDate.month - monthDiff), // Ensure month is within valid range
|
||||
day: Math.max(1, currentDate.day - dayDiff) // Ensure day is within valid range
|
||||
// Generate majority birthDates ensuring the age difference is at least minDiff
|
||||
const majorityBirthDates = currentDates.map((currentDate) => {
|
||||
// Subtract a random number of years within the allowed age difference, plus a random number of days and months for additional variance
|
||||
const yearDiff = Math.floor(Math.random() * (maxDiff - minDiff)) + minDiff;
|
||||
const monthDiff = Math.floor(Math.random() * 12);
|
||||
const dayDiff = Math.floor(Math.random() * 28) + 1;
|
||||
return {
|
||||
year: currentDate.year - yearDiff,
|
||||
month: Math.max(1, currentDate.month - monthDiff), // Ensure month is within valid range
|
||||
day: Math.max(1, currentDate.day - dayDiff), // Ensure day is within valid range
|
||||
};
|
||||
});
|
||||
|
||||
// Generate minority birthDates ensuring the age difference is less than minDiff
|
||||
const minorityBirthDates = currentDates.map((currentDate) => {
|
||||
const yearDiff = Math.floor(Math.random() * minDiff);
|
||||
const monthDiff = Math.floor(Math.random() * 12);
|
||||
const dayDiff = Math.floor(Math.random() * 28);
|
||||
return {
|
||||
year: currentDate.year - yearDiff,
|
||||
month: Math.max(1, currentDate.month - monthDiff), // Ensure month is within valid range
|
||||
day: Math.max(1, currentDate.day - dayDiff), // Ensure day is within valid range
|
||||
};
|
||||
});
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, '../../circuits/tests/utils/isOlderThan_tester.circom'),
|
||||
{
|
||||
include: ['node_modules'],
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('compile and load the circuit', async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
describe('Majority Tests', function () {
|
||||
majorityBirthDates.forEach((date, index) => {
|
||||
it(`majority check for birthdate ${genDateStr(majorityBirthDates[index])} and current date ${genDateStr(currentDates[index])} and age: ${getAgeFromDates(majorityBirthDates[index], currentDates[index])}`, async function () {
|
||||
const inputs = {
|
||||
majority: [49, 56],
|
||||
currDate: [
|
||||
Math.floor(currentDates[index].year / 10) % 10,
|
||||
currentDates[index].year % 10,
|
||||
Math.floor(currentDates[index].month / 10),
|
||||
currentDates[index].month % 10,
|
||||
Math.floor(currentDates[index].day / 10),
|
||||
currentDates[index].day % 10,
|
||||
],
|
||||
birthDateASCII: [
|
||||
Math.floor(date.year / 10) % 10,
|
||||
date.year % 10,
|
||||
Math.floor(date.month / 10),
|
||||
date.month % 10,
|
||||
Math.floor(date.day / 10),
|
||||
date.day % 10,
|
||||
].map((n) => n + 48), // Convert to ASCII for the circuit input
|
||||
};
|
||||
/*
|
||||
console.log("current date: " + JSON.stringify(currentDates[index]));
|
||||
console.log("majority birth date: " + JSON.stringify(majorityBirthDates[index]));
|
||||
console.log("yearDiff: " + (currentDates[index].year - majorityBirthDates[index].year) + " monthDiff: " + (currentDates[index].month - majorityBirthDates[index].month) + " dayDiff: " + (currentDates[index].day - majorityBirthDates[index].day));
|
||||
*/
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
const output = await circuit.getOutput(witness, ['out']);
|
||||
assert.strictEqual(output.out, '1', 'Person should be of majority age');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Generate minority birthDates ensuring the age difference is less than minDiff
|
||||
const minorityBirthDates = currentDates.map(currentDate => {
|
||||
const yearDiff = Math.floor(Math.random() * minDiff);
|
||||
const monthDiff = Math.floor(Math.random() * 12);
|
||||
const dayDiff = Math.floor(Math.random() * 28);
|
||||
return {
|
||||
year: currentDate.year - yearDiff,
|
||||
month: Math.max(1, currentDate.month - monthDiff), // Ensure month is within valid range
|
||||
day: Math.max(1, currentDate.day - dayDiff) // Ensure day is within valid range
|
||||
describe('Minority Tests', function () {
|
||||
minorityBirthDates.forEach((date, index) => {
|
||||
it(`minority check for birthdate ${genDateStr(minorityBirthDates[index])} and current date ${genDateStr(currentDates[index])} and age: ${getAgeFromDates(minorityBirthDates[index], currentDates[index])}`, async function () {
|
||||
const inputs = {
|
||||
majority: [49, 58],
|
||||
currDate: [
|
||||
Math.floor(currentDates[index].year / 10) % 10,
|
||||
currentDates[index].year % 10,
|
||||
Math.floor(currentDates[index].month / 10),
|
||||
currentDates[index].month % 10,
|
||||
Math.floor(currentDates[index].day / 10),
|
||||
currentDates[index].day % 10,
|
||||
],
|
||||
birthDateASCII: [
|
||||
Math.floor(date.year / 10) % 10,
|
||||
date.year % 10,
|
||||
Math.floor(date.month / 10),
|
||||
date.month % 10,
|
||||
Math.floor(date.day / 10),
|
||||
date.day % 10,
|
||||
].map((n) => n + 48), // Convert to ASCII for the circuit input
|
||||
};
|
||||
/*
|
||||
console.log("current date: " + JSON.stringify(currentDates[index]));
|
||||
console.log("minority birth date: " + JSON.stringify(minorityBirthDates[index]));
|
||||
console.log("yearDiff: " + (currentDates[index].year - minorityBirthDates[index].year) + " monthDiff: " + (currentDates[index].month - minorityBirthDates[index].month) + " dayDiff: " + (currentDates[index].day - minorityBirthDates[index].day));
|
||||
*/
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
const output = await circuit.getOutput(witness, ['out']);
|
||||
assert.strictEqual(output.out, '0', 'Person should not be of majority age');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, '../../circuits/tests/utils/isOlderThan_tester.circom'),
|
||||
{
|
||||
include: [
|
||||
"node_modules",
|
||||
]
|
||||
}
|
||||
);
|
||||
});
|
||||
function genDateStr(currentDate: { year: number; month: number; day: number }): string {
|
||||
// Ensure month and day are two digits by padding with '0' if necessary
|
||||
const formattedMonth = currentDate.month.toString().padStart(2, '0');
|
||||
const formattedDay = currentDate.day.toString().padStart(2, '0');
|
||||
return `${currentDate.year}${formattedMonth}${formattedDay}`;
|
||||
}
|
||||
|
||||
it("compile and load the circuit", async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
function getAgeFromDates(
|
||||
birthDate: { year: number; month: number; day: number },
|
||||
currentDate: { year: number; month: number; day: number }
|
||||
): string {
|
||||
let years = currentDate.year - birthDate.year;
|
||||
let months = currentDate.month - birthDate.month;
|
||||
let days = currentDate.day - birthDate.day;
|
||||
|
||||
describe("Majority Tests", function () {
|
||||
majorityBirthDates.forEach((date, index) => {
|
||||
it(`majority check for birthdate ${genDateStr(majorityBirthDates[index])} and current date ${genDateStr(currentDates[index])} and age: ${getAgeFromDates(majorityBirthDates[index], currentDates[index])}`, async function () {
|
||||
const inputs = {
|
||||
majority: [49, 56],
|
||||
currDate: [
|
||||
Math.floor(currentDates[index].year / 10) % 10,
|
||||
currentDates[index].year % 10,
|
||||
Math.floor(currentDates[index].month / 10),
|
||||
currentDates[index].month % 10,
|
||||
Math.floor(currentDates[index].day / 10),
|
||||
currentDates[index].day % 10
|
||||
],
|
||||
birthDateASCII: [
|
||||
Math.floor(date.year / 10) % 10,
|
||||
date.year % 10,
|
||||
Math.floor(date.month / 10),
|
||||
date.month % 10,
|
||||
Math.floor(date.day / 10),
|
||||
date.day % 10
|
||||
].map(n => n + 48) // Convert to ASCII for the circuit input
|
||||
};
|
||||
/*
|
||||
console.log("current date: " + JSON.stringify(currentDates[index]));
|
||||
console.log("majority birth date: " + JSON.stringify(majorityBirthDates[index]));
|
||||
console.log("yearDiff: " + (currentDates[index].year - majorityBirthDates[index].year) + " monthDiff: " + (currentDates[index].month - majorityBirthDates[index].month) + " dayDiff: " + (currentDates[index].day - majorityBirthDates[index].day));
|
||||
*/
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
const output = await circuit.getOutput(witness, ["out"]);
|
||||
assert.strictEqual(output.out, '1', "Person should be of majority age");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Minority Tests", function () {
|
||||
minorityBirthDates.forEach((date, index) => {
|
||||
it(`minority check for birthdate ${genDateStr(minorityBirthDates[index])} and current date ${genDateStr(currentDates[index])} and age: ${getAgeFromDates(minorityBirthDates[index], currentDates[index])}`, async function () {
|
||||
const inputs = {
|
||||
majority: [49, 58],
|
||||
currDate: [
|
||||
Math.floor(currentDates[index].year / 10) % 10,
|
||||
currentDates[index].year % 10,
|
||||
Math.floor(currentDates[index].month / 10),
|
||||
currentDates[index].month % 10,
|
||||
Math.floor(currentDates[index].day / 10),
|
||||
currentDates[index].day % 10
|
||||
],
|
||||
birthDateASCII: [
|
||||
Math.floor(date.year / 10) % 10,
|
||||
date.year % 10,
|
||||
Math.floor(date.month / 10),
|
||||
date.month % 10,
|
||||
Math.floor(date.day / 10),
|
||||
date.day % 10
|
||||
].map(n => n + 48) // Convert to ASCII for the circuit input
|
||||
};
|
||||
/*
|
||||
console.log("current date: " + JSON.stringify(currentDates[index]));
|
||||
console.log("minority birth date: " + JSON.stringify(minorityBirthDates[index]));
|
||||
console.log("yearDiff: " + (currentDates[index].year - minorityBirthDates[index].year) + " monthDiff: " + (currentDates[index].month - minorityBirthDates[index].month) + " dayDiff: " + (currentDates[index].day - minorityBirthDates[index].day));
|
||||
*/
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
const output = await circuit.getOutput(witness, ["out"]);
|
||||
assert.strictEqual(output.out, '0', "Person should not be of majority age");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function genDateStr(currentDate: { year: number; month: number; day: number }): string {
|
||||
// Ensure month and day are two digits by padding with '0' if necessary
|
||||
const formattedMonth = currentDate.month.toString().padStart(2, '0');
|
||||
const formattedDay = currentDate.day.toString().padStart(2, '0');
|
||||
return `${currentDate.year}${formattedMonth}${formattedDay}`;
|
||||
if (days < 0) {
|
||||
months -= 1;
|
||||
const lastDayOfPreviousMonth = new Date(currentDate.year, currentDate.month - 1, 0).getDate();
|
||||
days += lastDayOfPreviousMonth;
|
||||
}
|
||||
|
||||
function getAgeFromDates(birthDate: { year: number; month: number; day: number }, currentDate: { year: number; month: number; day: number }): string {
|
||||
let years = currentDate.year - birthDate.year;
|
||||
let months = currentDate.month - birthDate.month;
|
||||
let days = currentDate.day - birthDate.day;
|
||||
|
||||
if (days < 0) {
|
||||
months -= 1;
|
||||
const lastDayOfPreviousMonth = new Date(currentDate.year, currentDate.month - 1, 0).getDate();
|
||||
days += lastDayOfPreviousMonth;
|
||||
}
|
||||
|
||||
if (months < 0) {
|
||||
years -= 1;
|
||||
months += 12;
|
||||
}
|
||||
|
||||
// Add 's' at the end of year, month, and day if they are greater than 1
|
||||
const yearStr = years > 1 ? 'years' : 'year';
|
||||
const monthStr = months > 1 ? 'months' : 'month';
|
||||
const dayStr = days > 1 ? 'days' : 'day';
|
||||
|
||||
return `${years} ${yearStr}, ${months} ${monthStr}, ${days} ${dayStr}`;
|
||||
if (months < 0) {
|
||||
years -= 1;
|
||||
months += 12;
|
||||
}
|
||||
|
||||
// Add 's' at the end of year, month, and day if they are greater than 1
|
||||
const yearStr = years > 1 ? 'years' : 'year';
|
||||
const monthStr = months > 1 ? 'months' : 'month';
|
||||
const dayStr = days > 1 ? 'days' : 'day';
|
||||
|
||||
return `${years} ${yearStr}, ${months} ${monthStr}, ${days} ${dayStr}`;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,176 +1,179 @@
|
||||
import chai, { expect, assert } from 'chai';
|
||||
import path from 'path';
|
||||
const wasm_tester = require("circom_tester").wasm;
|
||||
const wasm_tester = require('circom_tester').wasm;
|
||||
|
||||
describe('DateIsLessChecker Circuit Test', function () {
|
||||
this.timeout(0); // Disable timeout
|
||||
this.timeout(0); // Disable timeout
|
||||
|
||||
let circuit;
|
||||
let circuit;
|
||||
|
||||
/**
|
||||
* Test parameters
|
||||
*
|
||||
* n: number of dates to test
|
||||
* majority: age of majority
|
||||
* yearStart: start year for random current dates
|
||||
* yearEnd: end year for random current dates
|
||||
*
|
||||
* According to circuit logic, user has to be majority years and 1 day old to be major
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* Test parameters
|
||||
*
|
||||
* n: number of dates to test
|
||||
* majority: age of majority
|
||||
* yearStart: start year for random current dates
|
||||
* yearEnd: end year for random current dates
|
||||
*
|
||||
* According to circuit logic, user has to be majority years and 1 day old to be major
|
||||
*
|
||||
*/
|
||||
|
||||
const n = 10;
|
||||
const n = 10;
|
||||
|
||||
const yearStart = 2023;
|
||||
const yearEnd = 2049;
|
||||
const maxDiff = 20; // Maximum date difference
|
||||
const minDiff = -10; // Minimum date for majority
|
||||
const yearStart = 2023;
|
||||
const yearEnd = 2049;
|
||||
const maxDiff = 20; // Maximum date difference
|
||||
const minDiff = -10; // Minimum date for majority
|
||||
|
||||
// Helper function to generate a random date within a given range
|
||||
function generateRandomDate(yearStart, yearEnd) {
|
||||
const year = Math.floor(Math.random() * (yearEnd - yearStart + 1)) + yearStart;
|
||||
const month = Math.floor(Math.random() * 12) + 1;
|
||||
const day = Math.floor(Math.random() * 28) + 1; // Simplification for month lengths
|
||||
return { year, month, day };
|
||||
}
|
||||
// Helper function to generate a random date within a given range
|
||||
function generateRandomDate(yearStart, yearEnd) {
|
||||
const year = Math.floor(Math.random() * (yearEnd - yearStart + 1)) + yearStart;
|
||||
const month = Math.floor(Math.random() * 12) + 1;
|
||||
const day = Math.floor(Math.random() * 28) + 1; // Simplification for month lengths
|
||||
return { year, month, day };
|
||||
}
|
||||
|
||||
// Generate arrays for current dates
|
||||
const currentDates = Array(n).fill(0).map(() => generateRandomDate(yearStart, yearEnd));
|
||||
// Generate arrays for current dates
|
||||
const currentDates = Array(n)
|
||||
.fill(0)
|
||||
.map(() => generateRandomDate(yearStart, yearEnd));
|
||||
|
||||
// Generate majority birthDates ensuring the age difference is at least minDiff
|
||||
const unvalidExpiryDates = currentDates.map(currentDate => {
|
||||
// Subtract a random number of years within the allowed age difference, plus a random number of days and months for additional variance
|
||||
const yearDiff = Math.floor(Math.random() * (maxDiff - 0)) + 0;
|
||||
const monthDiff = Math.floor(Math.random() * 12);
|
||||
const dayDiff = Math.floor(Math.random() * 28) + 1;
|
||||
return {
|
||||
year: currentDate.year - yearDiff,
|
||||
month: Math.max(1, currentDate.month - monthDiff), // Ensure month is within valid range
|
||||
day: Math.max(1, currentDate.day - dayDiff) // Ensure day is within valid range
|
||||
// Generate majority birthDates ensuring the age difference is at least minDiff
|
||||
const unvalidExpiryDates = currentDates.map((currentDate) => {
|
||||
// Subtract a random number of years within the allowed age difference, plus a random number of days and months for additional variance
|
||||
const yearDiff = Math.floor(Math.random() * (maxDiff - 0)) + 0;
|
||||
const monthDiff = Math.floor(Math.random() * 12);
|
||||
const dayDiff = Math.floor(Math.random() * 28) + 1;
|
||||
return {
|
||||
year: currentDate.year - yearDiff,
|
||||
month: Math.max(1, currentDate.month - monthDiff), // Ensure month is within valid range
|
||||
day: Math.max(1, currentDate.day - dayDiff), // Ensure day is within valid range
|
||||
};
|
||||
});
|
||||
|
||||
// Generate minority birthDates ensuring the age difference is less than minDiff
|
||||
const validExpiryDates = currentDates.map((currentDate) => {
|
||||
const yearDiff = Math.floor(Math.random() * -maxDiff);
|
||||
const monthDiff = Math.floor(Math.random() * 12);
|
||||
const dayDiff = Math.floor(Math.random() * 28);
|
||||
return {
|
||||
year: currentDate.year - yearDiff,
|
||||
month: Math.max(1, currentDate.month - monthDiff), // Ensure month is within valid range
|
||||
day: Math.max(1, currentDate.day - dayDiff), // Ensure day is within valid range
|
||||
};
|
||||
});
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, '../../circuits/tests/utils/isValid_tester.circom'),
|
||||
{
|
||||
include: ['node_modules'],
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('compile and load the circuit', async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
describe('Unvlaidity Tests', function () {
|
||||
unvalidExpiryDates.forEach((date, index) => {
|
||||
it(`unvalidity check for expiry date ${genDateStr(unvalidExpiryDates[index])} and current date ${genDateStr(currentDates[index])}, expired since: ${getAgeFromDates(unvalidExpiryDates[index], currentDates[index])}`, async function () {
|
||||
const inputs = {
|
||||
currDate: [
|
||||
Math.floor(currentDates[index].year / 10) % 10,
|
||||
currentDates[index].year % 10,
|
||||
Math.floor(currentDates[index].month / 10),
|
||||
currentDates[index].month % 10,
|
||||
Math.floor(currentDates[index].day / 10),
|
||||
currentDates[index].day % 10,
|
||||
],
|
||||
validityDateASCII: [
|
||||
Math.floor(date.year / 10) % 10,
|
||||
date.year % 10,
|
||||
Math.floor(date.month / 10),
|
||||
date.month % 10,
|
||||
Math.floor(date.day / 10),
|
||||
date.day % 10,
|
||||
].map((n) => n + 48), // Convert to ASCII for the circuit input
|
||||
};
|
||||
});
|
||||
|
||||
// Generate minority birthDates ensuring the age difference is less than minDiff
|
||||
const validExpiryDates = currentDates.map(currentDate => {
|
||||
const yearDiff = Math.floor(Math.random() * (- maxDiff));
|
||||
const monthDiff = Math.floor(Math.random() * 12);
|
||||
const dayDiff = Math.floor(Math.random() * 28);
|
||||
return {
|
||||
year: currentDate.year - yearDiff,
|
||||
month: Math.max(1, currentDate.month - monthDiff), // Ensure month is within valid range
|
||||
day: Math.max(1, currentDate.day - dayDiff) // Ensure day is within valid range
|
||||
};
|
||||
});
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, '../../circuits/tests/utils/isValid_tester.circom'),
|
||||
{
|
||||
include: [
|
||||
"node_modules",
|
||||
]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("compile and load the circuit", async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
describe("Unvlaidity Tests", function () {
|
||||
unvalidExpiryDates.forEach((date, index) => {
|
||||
it(`unvalidity check for expiry date ${genDateStr(unvalidExpiryDates[index])} and current date ${genDateStr(currentDates[index])}, expired since: ${getAgeFromDates(unvalidExpiryDates[index], currentDates[index])}`, async function () {
|
||||
const inputs = {
|
||||
currDate: [
|
||||
Math.floor(currentDates[index].year / 10) % 10,
|
||||
currentDates[index].year % 10,
|
||||
Math.floor(currentDates[index].month / 10),
|
||||
currentDates[index].month % 10,
|
||||
Math.floor(currentDates[index].day / 10),
|
||||
currentDates[index].day % 10
|
||||
],
|
||||
validityDateASCII: [
|
||||
Math.floor(date.year / 10) % 10,
|
||||
date.year % 10,
|
||||
Math.floor(date.month / 10),
|
||||
date.month % 10,
|
||||
Math.floor(date.day / 10),
|
||||
date.day % 10
|
||||
].map(n => n + 48) // Convert to ASCII for the circuit input
|
||||
};
|
||||
/*
|
||||
/*
|
||||
console.log("current date: " + JSON.stringify(currentDates[index]));
|
||||
console.log("majority birth date: " + JSON.stringify(majorityBirthDates[index]));
|
||||
console.log("yearDiff: " + (currentDates[index].year - majorityBirthDates[index].year) + " monthDiff: " + (currentDates[index].month - majorityBirthDates[index].month) + " dayDiff: " + (currentDates[index].day - majorityBirthDates[index].day));
|
||||
*/
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
const output = await circuit.getOutput(witness, ["out"]);
|
||||
assert.strictEqual(output.out, '0', "Passport should not be valid");
|
||||
});
|
||||
});
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
const output = await circuit.getOutput(witness, ['out']);
|
||||
assert.strictEqual(output.out, '0', 'Passport should not be valid');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Validity Tests", function () {
|
||||
validExpiryDates.forEach((date, index) => {
|
||||
it(`validity check for expiry date ${genDateStr(validExpiryDates[index])} and current date ${genDateStr(currentDates[index])} valid until: ${getAgeFromDates(currentDates[index], validExpiryDates[index])}`, async function () {
|
||||
const inputs = {
|
||||
currDate: [
|
||||
Math.floor(currentDates[index].year / 10) % 10,
|
||||
currentDates[index].year % 10,
|
||||
Math.floor(currentDates[index].month / 10),
|
||||
currentDates[index].month % 10,
|
||||
Math.floor(currentDates[index].day / 10),
|
||||
currentDates[index].day % 10
|
||||
],
|
||||
validityDateASCII: [
|
||||
Math.floor(date.year / 10) % 10,
|
||||
date.year % 10,
|
||||
Math.floor(date.month / 10),
|
||||
date.month % 10,
|
||||
Math.floor(date.day / 10),
|
||||
date.day % 10
|
||||
].map(n => n + 48) // Convert to ASCII for the circuit input
|
||||
};
|
||||
/*
|
||||
describe('Validity Tests', function () {
|
||||
validExpiryDates.forEach((date, index) => {
|
||||
it(`validity check for expiry date ${genDateStr(validExpiryDates[index])} and current date ${genDateStr(currentDates[index])} valid until: ${getAgeFromDates(currentDates[index], validExpiryDates[index])}`, async function () {
|
||||
const inputs = {
|
||||
currDate: [
|
||||
Math.floor(currentDates[index].year / 10) % 10,
|
||||
currentDates[index].year % 10,
|
||||
Math.floor(currentDates[index].month / 10),
|
||||
currentDates[index].month % 10,
|
||||
Math.floor(currentDates[index].day / 10),
|
||||
currentDates[index].day % 10,
|
||||
],
|
||||
validityDateASCII: [
|
||||
Math.floor(date.year / 10) % 10,
|
||||
date.year % 10,
|
||||
Math.floor(date.month / 10),
|
||||
date.month % 10,
|
||||
Math.floor(date.day / 10),
|
||||
date.day % 10,
|
||||
].map((n) => n + 48), // Convert to ASCII for the circuit input
|
||||
};
|
||||
/*
|
||||
console.log("current date: " + JSON.stringify(currentDates[index]));
|
||||
console.log("minority birth date: " + JSON.stringify(minorityBirthDates[index]));
|
||||
console.log("yearDiff: " + (currentDates[index].year - minorityBirthDates[index].year) + " monthDiff: " + (currentDates[index].month - minorityBirthDates[index].month) + " dayDiff: " + (currentDates[index].day - minorityBirthDates[index].day));
|
||||
*/
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
const output = await circuit.getOutput(witness, ["out"]);
|
||||
assert.strictEqual(output.out, '1', "Passport should be valid");
|
||||
});
|
||||
});
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
const output = await circuit.getOutput(witness, ['out']);
|
||||
assert.strictEqual(output.out, '1', 'Passport should be valid');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function genDateStr(currentDate: { year: number; month: number; day: number }): string {
|
||||
// Ensure month and day are two digits by padding with '0' if necessary
|
||||
const formattedMonth = currentDate.month.toString().padStart(2, '0');
|
||||
const formattedDay = currentDate.day.toString().padStart(2, '0');
|
||||
return `${currentDate.year}${formattedMonth}${formattedDay}`;
|
||||
function genDateStr(currentDate: { year: number; month: number; day: number }): string {
|
||||
// Ensure month and day are two digits by padding with '0' if necessary
|
||||
const formattedMonth = currentDate.month.toString().padStart(2, '0');
|
||||
const formattedDay = currentDate.day.toString().padStart(2, '0');
|
||||
return `${currentDate.year}${formattedMonth}${formattedDay}`;
|
||||
}
|
||||
|
||||
function getAgeFromDates(
|
||||
birthDate: { year: number; month: number; day: number },
|
||||
currentDate: { year: number; month: number; day: number }
|
||||
): string {
|
||||
let years = currentDate.year - birthDate.year;
|
||||
let months = currentDate.month - birthDate.month;
|
||||
let days = currentDate.day - birthDate.day;
|
||||
|
||||
if (days < 0) {
|
||||
months -= 1;
|
||||
const lastDayOfPreviousMonth = new Date(currentDate.year, currentDate.month - 1, 0).getDate();
|
||||
days += lastDayOfPreviousMonth;
|
||||
}
|
||||
|
||||
function getAgeFromDates(birthDate: { year: number; month: number; day: number }, currentDate: { year: number; month: number; day: number }): string {
|
||||
let years = currentDate.year - birthDate.year;
|
||||
let months = currentDate.month - birthDate.month;
|
||||
let days = currentDate.day - birthDate.day;
|
||||
|
||||
if (days < 0) {
|
||||
months -= 1;
|
||||
const lastDayOfPreviousMonth = new Date(currentDate.year, currentDate.month - 1, 0).getDate();
|
||||
days += lastDayOfPreviousMonth;
|
||||
}
|
||||
|
||||
if (months < 0) {
|
||||
years -= 1;
|
||||
months += 12;
|
||||
}
|
||||
|
||||
// Add 's' at the end of year, month, and day if they are greater than 1
|
||||
const yearStr = years > 1 ? 'years' : 'year';
|
||||
const monthStr = months > 1 ? 'months' : 'month';
|
||||
const dayStr = days > 1 ? 'days' : 'day';
|
||||
|
||||
return `${years} ${yearStr}, ${months} ${monthStr}, ${days} ${dayStr}`;
|
||||
if (months < 0) {
|
||||
years -= 1;
|
||||
months += 12;
|
||||
}
|
||||
|
||||
// Add 's' at the end of year, month, and day if they are greater than 1
|
||||
const yearStr = years > 1 ? 'years' : 'year';
|
||||
const monthStr = months > 1 ? 'months' : 'month';
|
||||
const dayStr = days > 1 ? 'days' : 'day';
|
||||
|
||||
return `${years} ${yearStr}, ${months} ${monthStr}, ${days} ${dayStr}`;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2,86 +2,104 @@ import { expect } from 'chai';
|
||||
import { X509Certificate } from 'crypto';
|
||||
import path from 'path';
|
||||
import { getCSCAInputs, getTBSHash } from '../../../common/src/utils/csca';
|
||||
const wasm_tester = require("circom_tester").wasm;
|
||||
const wasm_tester = require('circom_tester').wasm;
|
||||
import forge from 'node-forge';
|
||||
|
||||
import { mock_dsc_sha256_rsa_2048, mock_csca_sha256_rsa_2048, mock_dsc_sha1_rsa_2048, mock_csca_sha1_rsa_2048 } from '../../../common/src/constants/mockCertificates';
|
||||
import {
|
||||
mock_dsc_sha256_rsa_2048,
|
||||
mock_csca_sha256_rsa_2048,
|
||||
mock_dsc_sha1_rsa_2048,
|
||||
mock_csca_sha1_rsa_2048,
|
||||
} from '../../../common/src/constants/mockCertificates';
|
||||
|
||||
function loadCertificates(dscCertContent: string, cscaCertContent: string) {
|
||||
const dscCert = new X509Certificate(dscCertContent);
|
||||
const cscaCert = new X509Certificate(cscaCertContent);
|
||||
const dscCert_forge = forge.pki.certificateFromPem(dscCertContent);
|
||||
const cscaCert_forge = forge.pki.certificateFromPem(cscaCertContent);
|
||||
const dscCert = new X509Certificate(dscCertContent);
|
||||
const cscaCert = new X509Certificate(cscaCertContent);
|
||||
const dscCert_forge = forge.pki.certificateFromPem(dscCertContent);
|
||||
const cscaCert_forge = forge.pki.certificateFromPem(cscaCertContent);
|
||||
|
||||
return { dscCert, cscaCert, dscCert_forge, cscaCert_forge };
|
||||
return { dscCert, cscaCert, dscCert_forge, cscaCert_forge };
|
||||
}
|
||||
|
||||
describe('RSA Verifier', function () {
|
||||
this.timeout(0);
|
||||
let circuit;
|
||||
this.timeout(0);
|
||||
let circuit;
|
||||
|
||||
this.beforeAll(async () => {
|
||||
const circuitPath = path.resolve(__dirname, '../../circuits/tests/utils/rsa_verifier.circom');
|
||||
circuit = await wasm_tester(
|
||||
circuitPath,
|
||||
{
|
||||
include: [
|
||||
"node_modules",
|
||||
"./node_modules/@zk-kit/binary-merkle-root.circom/src",
|
||||
"./node_modules/circomlib/circuits"
|
||||
]
|
||||
}
|
||||
);
|
||||
this.beforeAll(async () => {
|
||||
const circuitPath = path.resolve(__dirname, '../../circuits/tests/utils/rsa_verifier.circom');
|
||||
circuit = await wasm_tester(circuitPath, {
|
||||
include: [
|
||||
'node_modules',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
],
|
||||
});
|
||||
describe('Circuit', () => {
|
||||
it('should compile and load the circuit', () => {
|
||||
expect(circuit).not.to.be.undefined;
|
||||
});
|
||||
});
|
||||
describe('Circuit', () => {
|
||||
it('should compile and load the circuit', () => {
|
||||
expect(circuit).not.to.be.undefined;
|
||||
});
|
||||
});
|
||||
|
||||
describe('SHA-256 certificates', async () => {
|
||||
const { dscCert, cscaCert, dscCert_forge, cscaCert_forge } = loadCertificates(
|
||||
mock_dsc_sha256_rsa_2048,
|
||||
mock_csca_sha256_rsa_2048
|
||||
);
|
||||
|
||||
it('should verify DSC has been signed by the CSCA', () => {
|
||||
const isVerified = dscCert.verify(cscaCert.publicKey);
|
||||
console.log(`SHA-256 DSC certificate verification result: ${isVerified}`);
|
||||
expect(isVerified).to.be.true;
|
||||
});
|
||||
|
||||
describe('SHA-256 certificates', async () => {
|
||||
const { dscCert, cscaCert, dscCert_forge, cscaCert_forge } = loadCertificates(mock_dsc_sha256_rsa_2048, mock_csca_sha256_rsa_2048);
|
||||
it('should extract and log certificate information', async () => {
|
||||
const csca_inputs = getCSCAInputs(
|
||||
'0',
|
||||
dscCert_forge,
|
||||
cscaCert_forge,
|
||||
64,
|
||||
32,
|
||||
64,
|
||||
32,
|
||||
2048,
|
||||
true
|
||||
);
|
||||
const tbsCertificateHashFormatted = getTBSHash(dscCert_forge, 'sha256');
|
||||
|
||||
it('should verify DSC has been signed by the CSCA', () => {
|
||||
const isVerified = dscCert.verify(cscaCert.publicKey);
|
||||
console.log(`SHA-256 DSC certificate verification result: ${isVerified}`);
|
||||
expect(isVerified).to.be.true;
|
||||
});
|
||||
|
||||
it('should extract and log certificate information', async () => {
|
||||
const csca_inputs = getCSCAInputs("0", dscCert_forge, cscaCert_forge, 64, 32, 64, 32, 2048, true);
|
||||
const tbsCertificateHashFormatted = getTBSHash(dscCert_forge, 'sha256');
|
||||
|
||||
const inputs = {
|
||||
"message": tbsCertificateHashFormatted,
|
||||
"signature": csca_inputs.dsc_signature,
|
||||
"modulus": csca_inputs.csca_modulus
|
||||
}
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
});
|
||||
const inputs = {
|
||||
message: tbsCertificateHashFormatted,
|
||||
signature: csca_inputs.dsc_signature,
|
||||
modulus: csca_inputs.csca_modulus,
|
||||
};
|
||||
const witness = await circuit.calculateWitness(inputs, true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('SHA-1 certificates', () => {
|
||||
const { dscCert, cscaCert, dscCert_forge, cscaCert_forge } = loadCertificates(mock_dsc_sha1_rsa_2048, mock_csca_sha1_rsa_2048);
|
||||
describe('SHA-1 certificates', () => {
|
||||
const { dscCert, cscaCert, dscCert_forge, cscaCert_forge } = loadCertificates(
|
||||
mock_dsc_sha1_rsa_2048,
|
||||
mock_csca_sha1_rsa_2048
|
||||
);
|
||||
|
||||
it('should verify DSC has been signed by the CSCA', () => {
|
||||
const isVerified = dscCert.verify(cscaCert.publicKey);
|
||||
console.log(`SHA-1 DSC certificate verification result: ${isVerified}`);
|
||||
expect(isVerified).to.be.true;
|
||||
});
|
||||
/// TODO: Use SHA1RSA verifier circuit (won't work either case because of padding)
|
||||
// it('should extract and log certificate information', async () => {
|
||||
// const csca_inputs = getCSCAInputs("0", dscCert_forge, cscaCert_forge, 64, 32, 64, 32, 2048, true);
|
||||
// const tbsCertificateHashFormatted = getTBSHash(dscCert_forge, 'sha1');
|
||||
|
||||
// const inputs = {
|
||||
// "message": tbsCertificateHashFormatted,
|
||||
// "signature": csca_inputs.dsc_signature,
|
||||
// "modulus": csca_inputs.csca_modulus
|
||||
// }
|
||||
// console.log("final inputs: ", inputs);
|
||||
// const witness = await circuit.calculateWitness(inputs, true);
|
||||
// console.log(witness);
|
||||
// });
|
||||
it('should verify DSC has been signed by the CSCA', () => {
|
||||
const isVerified = dscCert.verify(cscaCert.publicKey);
|
||||
console.log(`SHA-1 DSC certificate verification result: ${isVerified}`);
|
||||
expect(isVerified).to.be.true;
|
||||
});
|
||||
});
|
||||
/// TODO: Use SHA1RSA verifier circuit (won't work either case because of padding)
|
||||
// it('should extract and log certificate information', async () => {
|
||||
// const csca_inputs = getCSCAInputs("0", dscCert_forge, cscaCert_forge, 64, 32, 64, 32, 2048, true);
|
||||
// const tbsCertificateHashFormatted = getTBSHash(dscCert_forge, 'sha1');
|
||||
|
||||
// const inputs = {
|
||||
// "message": tbsCertificateHashFormatted,
|
||||
// "signature": csca_inputs.dsc_signature,
|
||||
// "modulus": csca_inputs.csca_modulus
|
||||
// }
|
||||
// console.log("final inputs: ", inputs);
|
||||
// const witness = await circuit.calculateWitness(inputs, true);
|
||||
// console.log(witness);
|
||||
// });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
"esModuleInterop": true,
|
||||
"target": "ES2020",
|
||||
"moduleResolution": "node",
|
||||
"module": "CommonJS",
|
||||
"module": "CommonJS"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1739,6 +1739,11 @@ prelude-ls@~1.1.2:
|
||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
||||
integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==
|
||||
|
||||
prettier@^3.3.3:
|
||||
version "3.3.3"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.3.tgz#30c54fe0be0d8d12e6ae61dbb10109ea00d53105"
|
||||
integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==
|
||||
|
||||
psl@^1.9.0:
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
|
||||
|
||||
Reference in New Issue
Block a user