add common sdk (#537)

* add common sdk

* remove sdk backend api

* remove registry

* regenerate sha256 rsa dsc each time

* download ski-pem dynamically on staging, refactor initpassportDataParsing

* add state machine for button on prove screen, improve ux on splash screen

* fetch ski-pem in production

* fix linter issues

* fix prove screen button bugs

* update podfile.lock and yarn.lock

* run linter in circuits repo

* bump build

* bump version for sentry debugging

* bump ios to version 118

---------

Co-authored-by: Justin Hernandez <transphorm@gmail.com>
This commit is contained in:
turnoffthiscomputer
2025-05-07 05:45:21 -04:00
committed by GitHub
parent 5163761a52
commit cc169061bd
213 changed files with 5413 additions and 144545 deletions

View File

@@ -1,15 +1,15 @@
import { expect } from "chai";
import { deploySystemFixtures } from "../utils/deployment";
import { DeployedActors } from "../utils/types";
import { ethers } from "hardhat";
import { RegisterVerifierId, DscVerifierId, CIRCUIT_CONSTANTS } from "../../../common/src/constants/constants";
import { ATTESTATION_ID } from "../utils/constants";
import { generateRegisterProof, generateDscProof } from "../utils/generateProof";
import { generateRandomFieldElement } from "../utils/utils";
import { TransactionReceipt, ZeroAddress } from "ethers";
import serialized_dsc_tree from '../utils/pubkeys/serialized_dsc_tree.json';
import { LeanIMT } from "@openpassport/zk-kit-lean-imt";
import {poseidon2} from "poseidon-lite";
import { expect } from "chai";
import { TransactionReceipt, ZeroAddress } from "ethers";
import { ethers } from "hardhat";
import { poseidon2 } from "poseidon-lite";
import { CIRCUIT_CONSTANTS, DscVerifierId, RegisterVerifierId } from "../../../common/src/constants/constants";
import { ATTESTATION_ID } from "../utils/constants";
import { deploySystemFixtures } from "../utils/deployment";
import { generateDscProof, generateRegisterProof } from "../utils/generateProof";
import serialized_dsc_tree from '../utils/pubkeys/serialized_dsc_tree.json';
import { DeployedActors } from "../utils/types";
import { generateRandomFieldElement } from "../utils/utils";
describe("Commitment Registration Tests", function () {
this.timeout(0);
@@ -26,7 +26,7 @@ describe("Commitment Registration Tests", function () {
deployedActors = await deploySystemFixtures();
registerSecret = generateRandomFieldElement();
baseDscProof = await generateDscProof(
deployedActors.mockPassport.dsc,
deployedActors.mockPassport,
);
baseRegisterProof = await generateRegisterProof(
registerSecret,
@@ -50,7 +50,7 @@ describe("Commitment Registration Tests", function () {
describe("Initialization", () => {
it("should have consistent addresses between registry and hub", async () => {
const {hub, registry} = deployedActors;
expect(await registry.hub()).to.equal(hub.target);
expect(await hub.registry()).to.equal(registry.target);
});
@@ -263,25 +263,25 @@ describe("Commitment Registration Tests", function () {
it("should register passport commitment successfully", async () => {
const {hub, registry, mockPassport} = deployedActors;
const registerProof = await generateRegisterProof(
registerSecret,
mockPassport
);
const previousRoot = await registry.getIdentityCommitmentMerkleRoot();
const hashFunction = (a: bigint, b: bigint) => poseidon2([a, b]);
const imt = new LeanIMT<bigint>(hashFunction);
await imt.insert(BigInt(registerProof.pubSignals[CIRCUIT_CONSTANTS.REGISTER_COMMITMENT_INDEX]));
const tx = await hub.registerPassportCommitment(
RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096,
registerProof
);
const receipt = await tx.wait() as TransactionReceipt;
const blockTimestamp = (await ethers.provider.getBlock(receipt.blockNumber))!.timestamp;
const currentRoot = await registry.getIdentityCommitmentMerkleRoot();
const size = await registry.getIdentityCommitmentMerkleTreeSize();
const rootTimestamp = await registry.rootTimestamps(currentRoot);
@@ -290,7 +290,7 @@ describe("Commitment Registration Tests", function () {
ATTESTATION_ID.E_PASSPORT,
registerProof.pubSignals[CIRCUIT_CONSTANTS.REGISTER_NULLIFIER_INDEX]
);
const event = receipt?.logs.find(
log => log.topics[0] === registry.interface.getEvent("CommitmentRegistered").topicHash
);
@@ -299,14 +299,14 @@ describe("Commitment Registration Tests", function () {
event.data,
event.topics
) : null;
expect(eventArgs?.attestationId).to.equal(ATTESTATION_ID.E_PASSPORT);
expect(eventArgs?.nullifier).to.equal(registerProof.pubSignals[CIRCUIT_CONSTANTS.REGISTER_NULLIFIER_INDEX]);
expect(eventArgs?.commitment).to.equal(registerProof.pubSignals[CIRCUIT_CONSTANTS.REGISTER_COMMITMENT_INDEX]);
expect(eventArgs?.timestamp).to.equal(blockTimestamp);
expect(eventArgs?.imtRoot).to.equal(currentRoot);
expect(eventArgs?.imtIndex).to.equal(0);
expect(currentRoot).to.not.equal(previousRoot);
expect(currentRoot).to.be.equal(imt.root);
expect(size).to.equal(1);
@@ -317,9 +317,9 @@ describe("Commitment Registration Tests", function () {
it("should fail when verifier is not set", async () => {
const {hub} = deployedActors;
registerProof.a[0] = generateRandomFieldElement();
await expect(
hub.registerPassportCommitment(
RegisterVerifierId.register_sha256_sha256_sha256_rsa_3_4096,
@@ -344,9 +344,9 @@ describe("Commitment Registration Tests", function () {
it("should fail when register proof verification fails", async () => {
const {hub} = deployedActors;
registerProof.a[0] = generateRandomFieldElement();
await expect(
hub.registerPassportCommitment(
RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096,
@@ -357,17 +357,17 @@ describe("Commitment Registration Tests", function () {
it("should fail when nullifier is already used", async () => {
const {hub, registry, mockPassport} = deployedActors;
const registerProof = await generateRegisterProof(
registerSecret,
mockPassport
);
await hub.registerPassportCommitment(
RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096,
registerProof
);
await expect(
hub.registerPassportCommitment(
RegisterVerifierId.register_sha256_sha256_sha256_rsa_65537_4096,
@@ -444,4 +444,4 @@ describe("Commitment Registration Tests", function () {
});
});
});
});

View File

@@ -1,19 +1,19 @@
import { expect } from "chai";
import { deploySystemFixtures } from "../utils/deployment";
import { DeployedActors } from "../utils/types";
import { ethers } from "hardhat";
import { RegisterVerifierId, DscVerifierId, CIRCUIT_CONSTANTS } from "../../../common/src/constants/constants";
import { ATTESTATION_ID } from "../utils/constants";
import { generateRegisterProof, generateDscProof, generateVcAndDiscloseProof } from "../utils/generateProof";
import { generateRandomFieldElement, splitHexFromBack } from "../utils/utils";
import { BigNumberish, TransactionReceipt, ZeroAddress } from "ethers";
import serialized_dsc_tree from '../utils/pubkeys/serialized_dsc_tree.json';
import { LeanIMT } from "@openpassport/zk-kit-lean-imt";
import {poseidon2} from "poseidon-lite";
import { castFromScope } from "../../../common/src/utils/circuits/uuid";
import BalanceTree from "../utils/example/balance-tree";
import { expect } from "chai";
import { BigNumberish, TransactionReceipt } from "ethers";
import { ethers } from "hardhat";
import { poseidon2 } from "poseidon-lite";
import { CIRCUIT_CONSTANTS, DscVerifierId, RegisterVerifierId } from "../../../common/src/constants/constants";
import { formatCountriesList, reverseBytes } from "../../../common/src/utils/circuits/formatInputs";
import { castFromScope } from "../../../common/src/utils/circuits/uuid";
import { ATTESTATION_ID } from "../utils/constants";
import { deploySystemFixtures } from "../utils/deployment";
import BalanceTree from "../utils/example/balance-tree";
import { Formatter } from "../utils/formatter";
import { generateDscProof, generateRegisterProof, generateVcAndDiscloseProof } from "../utils/generateProof";
import serialized_dsc_tree from '../utils/pubkeys/serialized_dsc_tree.json';
import { DeployedActors } from "../utils/types";
import { generateRandomFieldElement, splitHexFromBack } from "../utils/utils";
describe("End to End Tests", function () {
this.timeout(0);
@@ -40,12 +40,12 @@ describe("End to End Tests", function () {
const dscKeys = JSON.parse(serialized_dsc_tree);
let registerDscTx;
const dscProof = await generateDscProof(
mockPassport.dsc,
mockPassport,
);
const registerSecret = generateRandomFieldElement();
for (let i = 0; i < dscKeys[0].length; i++) {
if (BigInt(dscKeys[0][i]) == dscProof.pubSignals[CIRCUIT_CONSTANTS.DSC_TREE_LEAF_INDEX]) {
const previousRoot = await registry.getDscKeyCommitmentMerkleRoot();
const previousRoot = await registry.getDscKeyCommitmentMerkleRoot();
const previousSize = await registry.getDscKeyCommitmentTreeSize();
registerDscTx = await hub.registerDscKeyCommitment(
DscVerifierId.dsc_sha256_rsa_65537_4096,
@@ -204,8 +204,8 @@ describe("End to End Tests", function () {
await airdrop.connect(owner).openClaim();
const merkleProof = tree.getProof(0, await user1.getAddress(), BigInt(1000000000000000000));
const claimTx = await airdrop.connect(user1).claim(
0,
BigInt(1000000000000000000),
0,
BigInt(1000000000000000000),
merkleProof
);
const claimReceipt = await claimTx.wait() as TransactionReceipt;
@@ -248,4 +248,4 @@ describe("End to End Tests", function () {
expect(readableData[7]).to.equal(20n);
expect(readableData[8]).to.equal(1n);
});
});
});

View File

@@ -1,20 +1,20 @@
import { ethers } from "hardhat";
import { Signer } from "ethers";
import { getSMTs } from "./generateProof";
import { PassportData } from "../../../common/src/utils/types";
import { genMockPassportData } from "../../../common/src/utils/passports/genMockPassportData";
import { RegisterVerifierId, DscVerifierId } from "../../../common/src/constants/constants";
import { ethers } from "hardhat";
import { DscVerifierId, RegisterVerifierId } from "../../../common/src/constants/constants";
import { genAndInitMockPassportData } from "../../../common/src/utils/passports/genMockPassportData";
import { getCscaTreeRoot } from "../../../common/src/utils/trees";
import { PassportData } from "../../../common/src/utils/types";
import { getSMTs } from "./generateProof";
import serialized_csca_tree from "./pubkeys/serialized_csca_tree.json";
import {
DeployedActors,
VcAndDiscloseVerifier,
RegisterVerifier,
DscVerifier,
IdentityVerificationHub,
IdentityVerificationHubImplV1,
IdentityRegistry,
IdentityRegistryImplV1,
IdentityVerificationHub,
IdentityVerificationHubImplV1,
RegisterVerifier,
VcAndDiscloseVerifier,
} from "./types";
// Verifier artifacts
@@ -46,7 +46,7 @@ export async function deploySystemFixtures(): Promise<DeployedActors> {
await ethers.provider.send("hardhat_setBalance", [await user1.getAddress(), newBalance]);
await ethers.provider.send("hardhat_setBalance", [await user2.getAddress(), newBalance]);
mockPassport = genMockPassportData(
mockPassport = genAndInitMockPassportData(
"sha256",
"sha256",
"rsa_sha256_65537_4096",
@@ -176,4 +176,4 @@ export async function deploySystemFixtures(): Promise<DeployedActors> {
user2: user2,
mockPassport: mockPassport
};
}
}

View File

@@ -3,24 +3,24 @@ const YELLOW = '\x1b[33m';
const GREEN = '\x1b[32m';
const RESET = '\x1b[0m';
import type {
PublicSignals,
Groth16Proof,
import { LeanIMT } from "@openpassport/zk-kit-lean-imt";
import { ChildNodes, SMT } from "@openpassport/zk-kit-smt";
import fs from "fs";
import path from "path";
import { poseidon2, poseidon3 } from "poseidon-lite";
import type {
CircuitSignals,
Groth16Proof,
PublicSignals,
} from "snarkjs";
import { groth16 } from "snarkjs";
import fs from "fs";
import { SMT, ChildNodes } from "@openpassport/zk-kit-smt";
import { poseidon2, poseidon3 } from "poseidon-lite";
import { LeanIMT } from "@openpassport/zk-kit-lean-imt";
import path from "path";
import { RegisterCircuitProof, DscCircuitProof, CircuitArtifacts, VcAndDiscloseProof } from "./types";
import { PassportData } from "../../../common/src/utils/types";
import { CircuitArtifacts, DscCircuitProof, RegisterCircuitProof, VcAndDiscloseProof } from "./types";
import {BigNumberish} from "ethers";
import {
generateCircuitInputsRegister,
import { BigNumberish } from "ethers";
import {
generateCircuitInputsDSC,
generateCircuitInputsRegister,
generateCircuitInputsVCandDisclose
} from "../../../common/src/utils/circuits/generateInputs";
import serialized_csca_tree from './pubkeys/serialized_csca_tree.json';
@@ -63,7 +63,7 @@ export async function generateRegisterProof(
// Generate the proof
const startTime = performance.now();
const registerProof: {
proof: Groth16Proof,
publicSignals: PublicSignals
@@ -72,7 +72,7 @@ export async function generateRegisterProof(
registerCircuits["register_sha256_sha256_sha256_rsa_65537_4096"].wasm,
registerCircuits["register_sha256_sha256_sha256_rsa_65537_4096"].zkey
);
const endTime = performance.now();
console.log(GREEN, `groth16.fullProve execution time: ${((endTime - startTime) / 1000).toFixed(2)} seconds`, RESET);
@@ -92,12 +92,12 @@ export async function generateRegisterProof(
}
export async function generateDscProof(
dscCertificate: string,
passportData: PassportData,
): Promise<DscCircuitProof> {
console.log(CYAN, "=== Start generateDscProof ===", RESET);
const dscCircuitInputs: CircuitSignals = await generateCircuitInputsDSC(
dscCertificate,
passportData,
serialized_csca_tree
);
@@ -151,7 +151,7 @@ export async function generateVcAndDiscloseRawProof(
nameAndDob_smt = smts.nameAndDob_smt;
nameAndYob_smt = smts.nameAndYob_smt;
}
const vcAndDiscloseCircuitInputs: CircuitSignals = generateCircuitInputsVCandDisclose(
secret,
attestationId,
@@ -233,10 +233,10 @@ export async function generateVcAndDiscloseProof(
export function parseSolidityCalldata<T>(rawCallData: string, _type: T): T {
const parsed = JSON.parse("[" + rawCallData + "]");
return {
a: parsed[0].map((x: string) => x.replace(/"/g, '')) as [BigNumberish, BigNumberish],
b: parsed[1].map((arr: string[]) =>
b: parsed[1].map((arr: string[]) =>
arr.map((x: string) => x.replace(/"/g, ''))
) as [[BigNumberish, BigNumberish], [BigNumberish, BigNumberish]],
c: parsed[2].map((x: string) => x.replace(/"/g, '')) as [BigNumberish, BigNumberish],
@@ -245,7 +245,7 @@ export function parseSolidityCalldata<T>(rawCallData: string, _type: T): T {
}
export function getSMTs() {
export function getSMTs() {
const passportNo_smt = importSMTFromJsonFile("../common/ofacdata/outputs/passportNoAndNationalitySMT.json") as SMT;
const nameAndDob_smt = importSMTFromJsonFile("../common/ofacdata/outputs/nameAndDobSMT.json") as SMT;
const nameAndYob_smt = importSMTFromJsonFile("../common/ofacdata/outputs/nameAndYobSMT.json") as SMT;
@@ -260,16 +260,16 @@ export function getSMTs() {
function importSMTFromJsonFile(filePath?: string): SMT | null {
try {
const jsonString = fs.readFileSync(path.resolve(process.cwd(), filePath as string), 'utf8');
const data = JSON.parse(jsonString);
const hash2 = (childNodes: ChildNodes) => (childNodes.length === 2 ? poseidon2(childNodes) : poseidon3(childNodes));
const smt = new SMT(hash2, true);
smt.import(data);
return smt;
} catch (error) {
console.error('Failed to import SMT from JSON file:', error);
return null;
}
}
}