Feat/verifier update scripts (#157)

This commit is contained in:
nicoshark
2025-02-19 13:51:20 +09:00
committed by GitHub
parent e13c64ba10
commit 94de78d1d4
8 changed files with 144 additions and 225 deletions

View File

@@ -24,9 +24,9 @@ CIRCUITS=(
"dsc_sha512_ecdsa_secp521r1:21:false"
# RSA circuits
"dsc_sha1_rsa_65537_4096:21:false"
"dsc_sha1_rsa_65537_4096:21:true"
"dsc_sha256_rsa_65537_4096:21:true"
"dsc_sha512_rsa_65537_4096:21:false"
"dsc_sha512_rsa_65537_4096:21:true"
# RSA-PSS circuits
"dsc_sha256_rsapss_3_32_3072:22:false"

View File

@@ -11,14 +11,14 @@ OUTPUT_DIR="build/${CIRCUIT_TYPE}"
CIRCUITS=(
"register_sha1_sha1_sha1_ecdsa_brainpoolP224r1:21:false"
"register_sha1_sha1_sha1_ecdsa_secp256r1:21:false"
"register_sha1_sha1_sha1_rsa_65537_2048:20:false"
"register_sha1_sha256_sha256_rsa_65537_4096:20:false"
"register_sha1_sha1_sha1_rsa_65537_2048:20:true"
"register_sha1_sha256_sha256_rsa_65537_4096:20:true"
"register_sha256_sha224_sha224_ecdsa_brainpoolP224r1:21:false"
"register_sha256_sha256_sha256_ecdsa_brainpoolP224r1:21:false"
"register_sha256_sha256_sha256_ecdsa_brainpoolP256r1:21:false"
"register_sha256_sha256_sha256_ecdsa_secp256r1:21:false"
"register_sha256_sha256_sha256_ecdsa_secp384r1:22:false"
"register_sha256_sha256_sha256_rsa_65537_3072:20:false"
"register_sha256_sha256_sha256_rsa_65537_3072:20:true"
"register_sha256_sha256_sha256_rsa_65537_4096:20:true"
"register_sha256_sha256_sha256_rsapss_3_32_4096:21:false"
"register_sha256_sha256_sha256_rsapss_65537_4096:21:false"

View File

@@ -1,69 +0,0 @@
import { assert } from "chai";
import { ethers } from "hardhat";
import { mockPassportData_sha256WithRSAEncryption_65537 } from "../../common/src/utils/mockPassportData";
import { groth16 } from 'snarkjs'
import { revealBitmapFromMapping } from "../../common/src/utils/revealBitmap";
import { generateCircuitInputs } from "../../common/src/utils/generateInputs";
import fs from 'fs';
async function main() {
const proofOfPassportAddress = "0xF3F619aB057E3978204Be68549f9D4a503EAa535"
const proofOfPassport = await ethers.getContractAt("OpenPassport", proofOfPassportAddress);
const passportData = mockPassportData_sha256WithRSAEncryption_65537;
const attributeToReveal = {
issuing_state: true,
name: true,
passport_number: true,
nationality: true,
date_of_birth: true,
gender: true,
expiry_date: true,
older_than: true,
}
const reveal_bitmap = revealBitmapFromMapping(attributeToReveal)
const address = "0xE6E4b6a802F2e0aeE5676f6010e0AF5C9CDd0a50";
const inputs = generateCircuitInputs(
passportData,
reveal_bitmap,
address,
18,
);
console.log('generating proof...');
const { proof, publicSignals } = await groth16.fullProve(
inputs,
"../circuits/build/proof_of_passport_js/proof_of_passport.wasm",
"../circuits/build/proof_of_passport_final.zkey"
)
console.log('proof done');
const vKey = JSON.parse(fs.readFileSync("../circuits/build/proof_of_passport_vkey.json") as unknown as string);
const verified = await groth16.verify(
vKey,
publicSignals,
proof
)
assert(verified == true, 'Should verifiable')
const cd = await groth16.exportSolidityCallData(proof, publicSignals);
const callData = JSON.parse(`[${cd}]`);
console.log('callData', callData);
const tx = await proofOfPassport.mint(...callData);
const receipt = await tx.wait();
console.log('receipt', receipt?.hash);
const tokenURI = await proofOfPassport.tokenURI(0);
console.log('tokenURI', tokenURI);
}
main()

View File

@@ -1,27 +1,14 @@
import { ethers } from "hardhat";
import { ethers } from "ethers";
import * as dotenv from "dotenv";
import * as fs from "fs";
import * as path from "path";
import { RegisterVerifierId, DscVerifierId } from "../../common/src/constants/constants";
dotenv.config();
const deployedAddresses = JSON.parse(fs.readFileSync(path.join(__dirname, "../ignition/deployments/chain-11155111/deployed_addresses.json"), "utf-8"));
const deployedAddresses = JSON.parse(fs.readFileSync(path.join(__dirname, "../ignition/deployments/chain-42220/deployed_addresses.json"), "utf-8"));
const contractAbiPath = path.join(__dirname, "../ignition/deployments/chain-11155111/artifacts");
const ProveVerifierList = [
"Verifier_prove_rsa_65537_sha1",
"Verifier_prove_rsa_65537_sha256",
"Verifier_prove_rsapss_65537_sha256",
"Verifier_prove_ecdsa_secp256r1_sha256",
"Verifier_prove_ecdsa_secp256r1_sha1",
]
const DscVerifierList = [
"Verifier_dsc_rsa_65537_sha1_4096",
"Verifier_dsc_rsa_65537_sha256_4096",
"Verifier_dsc_rsapss_65537_sha256_4096"
]
function getContractAddressByPartialName(partialName: string): string | unknown {
for (const [key, value] of Object.entries(deployedAddresses)) {
if (key.includes(partialName)) {
@@ -31,40 +18,51 @@ function getContractAddressByPartialName(partialName: string): string | unknown
return undefined;
}
function computeVerifierId(input: string): string {
return ethers.keccak256(ethers.toUtf8Bytes(input));
}
async function main() {
const verifierIds: {
proveVerifierIds: { [key: string]: string },
dscVerifierIds: { [key: string]: string }
} = {
proveVerifierIds: {},
dscVerifierIds: {}
const provider = new ethers.JsonRpcProvider(process.env.CELO_RPC_URL as string);
const wallet = new ethers.Wallet(process.env.CELO_KEY as string, provider);
const identityVerificationHubAbiFile = fs.readFileSync(path.join(__dirname, "../ignition/deployments/chain-42220/artifacts/DeployHub#IdentityVerificationHubImplV1.json"), "utf-8");
const identityVerificationHubAbi = JSON.parse(identityVerificationHubAbiFile).abi;
const identityVerificationHub = new ethers.Contract(deployedAddresses["DeployHub#IdentityVerificationHub"], identityVerificationHubAbi, wallet);
const registerVerifierKeys = Object.keys(RegisterVerifierId).filter(key => isNaN(Number(key)));
for (const key of registerVerifierKeys) {
const verifierName = `Verifier_${key}`;
const verifierAddress = getContractAddressByPartialName(verifierName);
if (!verifierAddress) {
console.log(`Skipping ${verifierName} because no deployed address was found.`);
continue;
}
console.log(`Updating for ${verifierName}`);
const verifierId = RegisterVerifierId[key as keyof typeof RegisterVerifierId];
const tx = await identityVerificationHub.updateRegisterCircuitVerifier(
verifierId,
verifierAddress
);
const receipt = await tx.wait();
console.log(`${verifierName} is updated wit this tx: ${receipt.hash}`)
}
const provider = new ethers.JsonRpcProvider(process.env.SEPOLIA_RPC_URL as string);
const wallet = new ethers.Wallet(process.env.PKEY as string, provider);
const GenericVerifierAbiFile = fs.readFileSync(path.join(__dirname, "../ignition/deployments/chain-11155111/artifacts/Deploy_Open_Passport_Verifier#GenericVerifier.json"), "utf-8");
const GenericVerifierAbi = JSON.parse(GenericVerifierAbiFile).abi;
const genericVerifier = new ethers.Contract(getContractAddressByPartialName("GenericVerifier") as string, GenericVerifierAbi, wallet);
const dscKeys = Object.keys(DscVerifierId).filter(key => isNaN(Number(key)));
for (const key of dscKeys) {
const verifierName = `Verifier_${key}`;
const verifierAddress = getContractAddressByPartialName(verifierName);
if (!verifierAddress) {
console.log(`Skipping ${verifierName} because no deployed address was found.`);
continue;
}
const verifierId = DscVerifierId[key as keyof typeof DscVerifierId];
for (let i = 0; i < ProveVerifierList.length; i++) {
// const proveVerifierAddress = getContractAddressByPartialName(ProveVerifierList[i]) as string;
const proveVerifierId = computeVerifierId(ProveVerifierList[i]);
verifierIds.proveVerifierIds[ProveVerifierList[i]] = proveVerifierId;
// await genericVerifier.updateVerifier(0, proveVerifierId, proveVerifierAddress);
const tx = await identityVerificationHub.updateDscVerifier(
verifierId,
verifierAddress
);
const receipt = await tx.wait();
console.log(`${verifierName} is updated wit this tx: ${receipt.hash}`);
}
for (let i = 0; i < DscVerifierList.length; i++) {
// const dscVerifierAddress = getContractAddressByPartialName(DscVerifierList[i]) as string;
const dscVerifierId = computeVerifierId(DscVerifierList[i]);
verifierIds.dscVerifierIds[DscVerifierList[i]] = dscVerifierId;
// await genericVerifier.updateVerifier(1, dscVerifierId, dscVerifierAddress);
}
const outputPath = path.join(__dirname, "verifierIds.json");
fs.writeFileSync(outputPath, JSON.stringify(verifierIds, null, 2), "utf-8");
}
main().catch((error) => {

View File

@@ -1,106 +0,0 @@
import { assert } from "chai";
import { ethers } from "hardhat";
import { mockPassportData_sha256WithRSAEncryption_65537 } from "../../common/src/utils/mockPassportData";
import { groth16 } from 'snarkjs'
import { revealBitmapFromMapping } from "../../common/src/utils/revealBitmap";
import { generateCircuitInputs } from "../../common/src/utils/generateInputs";
import { countryCodes } from "../../common/src/constants/constants";
import { formatRoot } from "../../common/src/utils/utils";
import fs from 'fs';
// Useful script to test formatting of tokenURI
async function main() {
const passportData = mockPassportData_sha256WithRSAEncryption_65537;
const attributeToReveal = {
issuing_state: true,
name: true,
passport_number: true,
nationality: true,
date_of_birth: true,
gender: true,
expiry_date: true,
older_than: true,
}
const reveal_bitmap = revealBitmapFromMapping(attributeToReveal)
console.log('reveal_bitmap', reveal_bitmap);
const address = "0xE6E4b6a802F2e0aeE5676f6010e0AF5C9CDd0a50";
const inputs = generateCircuitInputs(
passportData,
reveal_bitmap,
address,
18,
);
const Verifier = await ethers.getContractFactory("Groth16Verifier");
const verifier = await Verifier.deploy();
await verifier.waitForDeployment();
console.log(`Verifier deployed to ${verifier.target}`);
const Formatter = await ethers.getContractFactory("Formatter");
const formatter = await Formatter.deploy();
await formatter.waitForDeployment();
console.log(`Formatter deployed to ${formatter.target}`);
const tx = await formatter.addCountryCodes(Object.entries(countryCodes));
await tx.wait();
console.log(`Country codes added`);
const Registry = await ethers.getContractFactory("Registry");
const registry = await Registry.deploy(formatRoot(inputs.root[0]));
await registry.waitForDeployment();
console.log(`Registry deployed to ${registry.target}`);
const OpenPassport = await ethers.getContractFactory("OpenPassport");
const proofOfPassport = await OpenPassport.deploy(verifier.target, formatter.target, registry.target);
await proofOfPassport.waitForDeployment();
console.log(`OpenPassport NFT deployed to ${proofOfPassport.target}`);
console.log('generating proof...');
const { proof, publicSignals } = await groth16.fullProve(
inputs,
"../circuits/build/proof_of_passport_js/proof_of_passport.wasm",
"../circuits/build/proof_of_passport_final.zkey"
)
console.log('proof done');
const vKey = JSON.parse(fs.readFileSync("../circuits/build/proof_of_passport_vkey.json") as unknown as string);
const verified = await groth16.verify(
vKey,
publicSignals,
proof
)
assert(verified == true, 'Should verifiable')
const cd = await groth16.exportSolidityCallData(proof, publicSignals);
const callData = JSON.parse(`[${cd}]`);
console.log('callData', callData);
const mintTx = await proofOfPassport.mint(...callData);
const receipt = await mintTx.wait();
console.log('receipt', receipt?.hash);
const tokenURI = await proofOfPassport.tokenURI(0);
console.log('tokenURI', tokenURI);
const decodedTokenURI = Buffer.from(tokenURI.split(',')[1], 'base64').toString();
const parsedTokenURI = JSON.parse(decodedTokenURI)
console.log('parsedTokenURI', parsedTokenURI);
process.exit(0);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});

Binary file not shown.

View File

@@ -0,0 +1,32 @@
import { getContractInstance } from "./getContracts";
import { waitForTransactionReceipt } from "viem/actions";
export class HubContract {
protected hub: any;
protected client: any;
constructor(
chain: any,
privateKey: `0x${string}`,
rpcUrl: string
) {
const { contract, publicClient } = getContractInstance("hub", chain, privateKey, rpcUrl);
this.hub = contract;
this.client = publicClient;
}
public async sigTypeToRegisterCircuitVerifiers(
id: number
) {
const address = await this.hub.read.sigTypeToRegisterCircuitVerifiers([id]);
return address;
}
public async sigTypeToDscCircuitVerifiers(
id: number
) {
const address = await this.hub.read.sigTypeToDscCircuitVerifiers([id]);
return address
}
}

View File

@@ -1,6 +1,7 @@
import Elysia, { t } from 'elysia';
import { ProofVerifier } from '../../contracts/application/proofVerifier';
import { RegistryContract } from '../../contracts/application/registryContract';
import { HubContract } from '../application/hubContract';
import { getChain } from '../../contracts/application/chains';
import { getDscCommitmentEvents } from '../application/getEvents';
import { MerkleTreeService } from '../application/tree-reader/leanImtService';
@@ -47,7 +48,8 @@ export const ContractsController = new Elysia()
description: 'Retrieve the identity commitment root in registry contract',
},
},
).post(
)
.post(
'update-csca-root',
async ({ body, set }) => {
try {
@@ -317,6 +319,68 @@ export const ContractsController = new Elysia()
},
},
)
.get(
'sig-to-register',
async ({ query }) => {
const id = Number(query.id);
const hubContract = new HubContract(
getChain(process.env.NETWORK as string),
process.env.PRIVATE_KEY as `0x${string}`,
process.env.RPC_URL as string
);
const address = await hubContract.sigTypeToRegisterCircuitVerifiers(id);
return { status: 'success', data: address };
},
{
query: t.Object({ id: t.String() }),
response: {
200: t.Object({
status: t.String(),
data: t.String(),
}),
500: t.Object({
status: t.String(),
message: t.String(),
}),
},
detail: {
tags: ['Hub'],
summary: 'Get Register Circuit Verifier Address via Query',
description: 'Retrieve the Register Circuit Verifier address by passing id as a query parameter.',
},
}
)
.get(
'sig-to-dsc',
async ({ query }) => {
const id = Number(query.id);
const hubContract = new HubContract(
getChain(process.env.NETWORK as string),
process.env.PRIVATE_KEY as `0x${string}`,
process.env.RPC_URL as string
);
const address = await hubContract.sigTypeToDscCircuitVerifiers(id);
return { status: 'success', data: address };
},
{
query: t.Object({ id: t.String() }),
response: {
200: t.Object({
status: t.String(),
data: t.String(),
}),
500: t.Object({
status: t.String(),
message: t.String(),
}),
},
detail: {
tags: ['Hub'],
summary: 'Get DSC Circuit Verifier Address via Query',
description: 'Retrieve the DSC Circuit Verifier address by passing id as a query parameter.',
},
}
)
.post(
'verify-vc-and-disclose-proof',
async (request) => {