add Proof type for simplicity and readability

This commit is contained in:
0xturboblitz
2024-05-11 22:14:20 +09:00
parent 6631cca052
commit 01384fa7fa
6 changed files with 51 additions and 34 deletions

View File

@@ -5,7 +5,7 @@ import {
DEFAULT_DOE,
AMPLITUDE_KEY
} from '@env';
import { PassportData } from '../common/src/utils/types';
import { PassportData, Proof } from '../common/src/utils/types';
import { mockPassportData_sha256WithRSAEncryption_65537 } from '../common/src/utils/mockPassportData';
import "@ethersproject/shims"
import { ethers } from "ethers";
@@ -20,8 +20,14 @@ import { prove } from './src/utils/prover';
import { useToastController } from '@tamagui/toast';
import * as amplitude from '@amplitude/analytics-react-native';
import { checkForZkey } from './src/utils/zkeyDownload';
import RNFS from 'react-native-fs';
global.Buffer = Buffer;
console.log('DEFAULT_PNUMBER', DEFAULT_PNUMBER);
const localZkeyPath = RNFS.DocumentDirectoryPath + '/proof_of_passport.zkey';
console.log('localZkeyPath', localZkeyPath);
function App(): JSX.Element {
const [passportNumber, setPassportNumber] = useState(DEFAULT_PNUMBER ?? "");
const [dateOfBirth, setDateOfBirth] = useState(DEFAULT_DOB ?? '');
@@ -31,7 +37,7 @@ function App(): JSX.Element {
const [step, setStep] = useState<number>(Steps.MRZ_SCAN);
const [generatingProof, setGeneratingProof] = useState<boolean>(false);
const [proofTime, setProofTime] = useState<number>(0);
const [proof, setProof] = useState<{ proof: string, inputs: string } | null>(null);
const [proof, setProof] = useState<Proof | null>(null);
const [mintText, setMintText] = useState<string>("");
const [majority, setMajority] = useState<number>(18);
const [zkeydownloadStatus, setDownloadStatus] = useState<"not_started" | "downloading" | "completed" | "error">("not_started");

View File

@@ -1,9 +1,10 @@
import React, { useMemo } from 'react';
import { Svg, Rect } from 'react-native-svg';
import { YStack } from 'tamagui';
import { Proof } from '../../../common/src/utils/types';
interface ProofGridProps {
proof: { proof: string; inputs: string } | null;
proof: Proof | null;
}
const ProofGrid: React.FC<ProofGridProps> = ({ proof }) => {
@@ -22,7 +23,7 @@ const ProofGrid: React.FC<ProofGridProps> = ({ proof }) => {
return { rValues: [], gValues: [], bValues: [] };
}
const parsedProof = JSON.parse(proof.proof);
const parsedProof = proof.proof;
return {
rValues: sumAndScaleDigits(parsedProof.a),
gValues: sumAndScaleDigits(parsedProof.b.flat()),

View File

@@ -12,6 +12,7 @@ import { useToastController } from '@tamagui/toast'
import { ethers } from 'ethers';
import { Platform } from 'react-native';
import { formatAttribute } from '../utils/utils';
import { Proof } from '../../../common/src/utils/types';
interface ProveScreenProps {
selectedApp: App | null;
@@ -25,7 +26,7 @@ interface ProveScreenProps {
handleMint: () => void;
step: number;
mintText: string;
proof: { proof: string, inputs: string } | null;
proof: Proof | null;
proofTime: number;
hideData: boolean;
ens: string;

View File

@@ -5,9 +5,10 @@ import contractAddresses from "../../deployments/addresses.json";
import proofOfPassportArtefact from "../../deployments/ProofOfPassport.json";
import { Steps } from './utils';
import { AWS_ENDPOINT } from '../../../common/src/constants/constants';
import { Proof } from "../../../common/src/utils/types";
interface MinterProps {
proof: { proof: string; inputs: string } | null;
proof: Proof | null;
setStep: (value: number) => void;
setMintText: (value: string) => void;
toast: any
@@ -15,7 +16,7 @@ interface MinterProps {
export const mint = async ({ proof, setStep, setMintText, toast }: MinterProps) => {
setStep(Steps.TX_MINTING);
if (!proof?.proof || !proof?.inputs) {
if (!proof?.proof || !proof?.pub_signals) {
console.log('proof or inputs is null');
return;
}
@@ -25,11 +26,8 @@ export const mint = async ({ proof, setStep, setMintText, toast }: MinterProps)
}
// Format the proof and publicInputs as calldata for the verifier contract
const p = JSON.parse(proof.proof);
const i = JSON.parse(proof.inputs);
console.log('p', p);
console.log('i', i);
const cd = groth16ExportSolidityCallData(p, i);
console.log('proof', proof);
const cd = groth16ExportSolidityCallData(proof.proof, proof.pub_signals);
const callData = JSON.parse(`[${cd}]`);
console.log('callData', callData);

View File

@@ -3,7 +3,7 @@ import { revealBitmapFromMapping } from '../../../common/src/utils/revealBitmap'
import { generateCircuitInputs } from '../../../common/src/utils/generateInputs';
import { formatProof, formatInputs } from '../../../common/src/utils/utils';
import { Steps } from './utils';
import { PassportData } from '../../../common/src/utils/types';
import { PassportData, Proof } from '../../../common/src/utils/types';
import * as amplitude from '@amplitude/analytics-react-native';
interface ProverProps {
@@ -14,7 +14,7 @@ interface ProverProps {
setStep: (value: number) => void;
setGeneratingProof: (value: boolean) => void;
setProofTime: (value: number) => void;
setProof: (value: { proof: string; inputs: string } | null) => void;
setProof: (value: Proof | null) => void;
toast: any
}
@@ -79,7 +79,7 @@ export const prove = async ({
const generateProof = async (
inputs: any,
setProofTime: (value: number) => void,
setProof: (value: { proof: string; inputs: string } | null) => void,
setProof: (proof: Proof) => void,
setGeneratingProof: (value: boolean) => void,
setStep: (value: number) => void,
) => {
@@ -97,29 +97,21 @@ const generateProof = async (
if (Platform.OS === 'android') {
const parsedResponse = parseProofAndroid(response);
const finalProof = {
proof: JSON.stringify(formatProof(parsedResponse.proof)),
inputs: JSON.stringify(formatInputs(parsedResponse.inputs)),
};
console.log('finalProof:', finalProof);
console.log('parsedResponse', parsedResponse);
setProof(finalProof);
setProof(parsedResponse);
setGeneratingProof(false);
setStep(Steps.PROOF_GENERATED);
} else {
const parsedResponse = JSON.parse(response);
console.log('parsedResponse', parsedResponse);
console.log('parsedResponse.proof:', parsedResponse.proof);
console.log('parsedResponse.inputs:', parsedResponse.inputs);
const finalProof = {
proof: JSON.stringify(parsedResponse.proof),
inputs: JSON.stringify(parsedResponse.inputs),
};
console.log('finalProof:', finalProof);
setProof(finalProof);
setProof({
proof: parsedResponse.proof,
pub_signals: parsedResponse.inputs,
});
setGeneratingProof(false);
setStep(Steps.PROOF_GENERATED);
}
@@ -128,12 +120,22 @@ const generateProof = async (
}
};
const parseProofAndroid = (response: any) => {
const match = response.match(/GenerateProofResult\(proof=\[(.*?)\], inputs=\[(.*?)\]\)/);
const parseProofAndroid = (response: string) => {
const match = response.match(/ZkProof\(proof=Proof\(pi_a=\[(.*?)\], pi_b=\[\[(.*?)\], \[(.*?)\], \[1, 0\]\], pi_c=\[(.*?)\], protocol=groth16, curve=bn128\), pub_signals=\[(.*?)\]\)/);
if (!match) throw new Error('Invalid input format');
const [, pi_a, pi_b_1, pi_b_2, pi_c, pub_signals] = match;
return {
proof: match[1].split(',').map((n: any) => (parseInt(n.trim()) + 256) % 256),
inputs: match[2].split(',').map((n: any) => (parseInt(n.trim()) + 256) % 256)
};
proof: {
a: pi_a.split(',').map((n: string) => n.trim()),
b: [
pi_b_1.split(',').map((n: string) => n.trim()),
pi_b_2.split(',').map((n: string) => n.trim()),
],
c: pi_c.split(',').map((n: string) => n.trim()),
},
pub_signals: pub_signals.split(',').map((n: string) => n.trim())
} as Proof;
};

View File

@@ -7,3 +7,12 @@ export type PassportData = {
encryptedDigest: number[];
photoBase64: string;
};
export type Proof = {
proof: {
a: [string, string],
b: [[string, string], [string, string]],
c: [string, string]
};
pub_signals: string[];
}