Skip to content

Commit

Permalink
clean/refactor fix devmode
Browse files Browse the repository at this point in the history
  • Loading branch information
remicolin committed Oct 21, 2024
1 parent 4e95082 commit 73de3c0
Show file tree
Hide file tree
Showing 13 changed files with 68 additions and 114 deletions.
72 changes: 25 additions & 47 deletions app/src/screens/ProveScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { countryCodes, DEVELOPMENT_MODE, max_cert_bytes, } from '../../../common
import { bgGreen, bgGreen2, greenColorLight, separatorColor, textBlack } from '../utils/colors';
import useUserStore from '../stores/userStore';
import useNavigationStore from '../stores/navigationStore';
import { ArgumentsDisclose, DisclosureOptions, OpenPassportApp } from '../../../common/src/utils/appType';
import { DisclosureOptions, OpenPassportApp } from '../../../common/src/utils/appType';
import CustomButton from '../components/CustomButton';
import { formatProof, generateProof } from '../utils/prover';
import { generateProof } from '../utils/prover';
import io, { Socket } from 'socket.io-client';
import { getCircuitName, parseCertificate, parseDSC } from '../../../common/src/utils/certificates/handleCertificate';
import { getCircuitName, parseCertificate } from '../../../common/src/utils/certificates/handleCertificate';
import { CircuitName } from '../utils/zkeyDownload';
import { generateCircuitInputsInApp } from '../utils/generateInputsInApp';
import { buildAttestation } from '../../../common/src/utils/openPassportAttestation';
Expand Down Expand Up @@ -41,7 +41,7 @@ const ProveScreen: React.FC<ProveScreenProps> = ({ setSheetRegisterIsOpen }) =>
const [isConnecting, setIsConnecting] = useState(false);
const { signatureAlgorithm, hashFunction, authorityKeyIdentifier } = parseCertificate(passportData.dsc);
const { secret, dscSecret } = useUserStore.getState();
const circuitName = getCircuitName("prove", signatureAlgorithm, hashFunction);
const circuitName = getCircuitName(selectedApp.mode, signatureAlgorithm, hashFunction);

const waitForSocketConnection = (socket: Socket): Promise<void> => {
return new Promise((resolve) => {
Expand Down Expand Up @@ -88,7 +88,7 @@ const ProveScreen: React.FC<ProveScreenProps> = ({ setSheetRegisterIsOpen }) =>
console.log("result", result);
if (JSON.parse(result).valid) {
toast.show("✅", {
message: "Proof verified",
message: "Identity verified",
customData: {
type: "success",
},
Expand All @@ -98,7 +98,7 @@ const ProveScreen: React.FC<ProveScreenProps> = ({ setSheetRegisterIsOpen }) =>
}, 700);
} else {
toast.show("❌", {
message: "Wrong proof",
message: "Verification failed",
customData: {
type: "info",
},
Expand Down Expand Up @@ -142,28 +142,16 @@ const ProveScreen: React.FC<ProveScreenProps> = ({ setSheetRegisterIsOpen }) =>

socket.emit('proof_generation_start', { sessionId: selectedApp.sessionId });

console.log("selectedApp.mode", selectedApp.mode);
const inputs = await generateCircuitInputsInApp(passportData, selectedApp);
let attestation;
let proof;
let dscProof;

switch (selectedApp.mode) {
case 'vc_and_disclose':
const inputs_disclose = await generateCircuitInputsInApp(passportData, selectedApp);
const proof_disclose = await generateProof('vc_and_disclose', inputs_disclose);
const formattedProof_disclose = formatProof(proof_disclose);
console.log(formattedProof_disclose);
const attestation_disclose = buildAttestation({
userIdType: selectedApp.userIdType,
mode: selectedApp.mode,
proof: formattedProof_disclose.proof,
publicSignals: formattedProof_disclose.publicSignals,
signatureAlgorithm: signatureAlgorithm,
hashFunction: hashFunction,
});
socket.emit('proof_generated', { sessionId: selectedApp.sessionId, proof: attestation_disclose });
break;
case 'prove_onchain':
case 'register':
const inputs = await generateCircuitInputsInApp(passportData, selectedApp);
const cscaInputs = generateCircuitInputsDSC(dscSecret as string, passportData.dsc, max_cert_bytes, true);
const [modalResponse, proof] = await Promise.all([
const cscaInputs = generateCircuitInputsDSC(dscSecret as string, passportData.dsc, max_cert_bytes, selectedApp.devMode);
[dscProof, proof] = await Promise.all([
sendCSCARequest(
cscaInputs
),
Expand All @@ -172,17 +160,12 @@ const ProveScreen: React.FC<ProveScreenProps> = ({ setSheetRegisterIsOpen }) =>
inputs,
)
]);
const dscProof = JSON.parse(JSON.stringify(modalResponse));
const cscaPem = getCSCAFromSKI(authorityKeyIdentifier, DEVELOPMENT_MODE);
if (!cscaPem) {
throw new Error(`CSCA not found, devMode: ${DEVELOPMENT_MODE}, authorityKeyIdentifier: ${authorityKeyIdentifier}`);
}
const { signatureAlgorithm: signatureAlgorithmDsc } = parseCertificate(cscaPem);
const formattedProof = formatProof(proof);
const attestation = buildAttestation({
attestation = buildAttestation({
mode: selectedApp.mode,
proof: formattedProof.proof,
publicSignals: formattedProof.publicSignals,
proof: proof.proof,
publicSignals: proof.publicSignals,
signatureAlgorithm: signatureAlgorithm,
hashFunction: hashFunction,
userIdType: selectedApp.userIdType,
Expand All @@ -191,30 +174,25 @@ const ProveScreen: React.FC<ProveScreenProps> = ({ setSheetRegisterIsOpen }) =>
signatureAlgorithmDsc: signatureAlgorithmDsc,
hashFunctionDsc: hashFunction,
});
console.log("\x1b[90mattestation\x1b[0m", attestation);
socket.emit('proof_generated', { sessionId: selectedApp.sessionId, proof: attestation });
break;
case 'prove_offchain':
const inputs_prove = await generateCircuitInputsInApp(passportData, selectedApp);
const proof_prove = await generateProof(
default:
proof = await generateProof(
circuitName,
inputs_prove,
);
const formattedProof_prove = formatProof(proof_prove);
const attestation_prove = buildAttestation({
inputs,
)
attestation = buildAttestation({
userIdType: selectedApp.userIdType,
mode: selectedApp.mode,
proof: formattedProof_prove.proof,
publicSignals: formattedProof_prove.publicSignals,
proof: proof.proof,
publicSignals: proof.publicSignals,
signatureAlgorithm: signatureAlgorithm,
hashFunction: hashFunction,
dsc: passportData.dsc,
});
console.log("\x1b[90mattestation\x1b[0m", attestation_prove);

socket.emit('proof_generated', { sessionId: selectedApp.sessionId, proof: attestation_prove });
break;
}
console.log("\x1b[90mattestation\x1b[0m", attestation);
socket.emit('proof_generated', { sessionId: selectedApp.sessionId, proof: attestation });

} catch (error) {
toast.show("Error", {
Expand Down
6 changes: 3 additions & 3 deletions app/src/utils/prover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ export const generateProof = async (
if (Platform.OS === 'android') {
const parsedResponse = parseProofAndroid(response);
console.log('parsedResponse', parsedResponse);
return parsedResponse
return formatProof(parsedResponse)
} else {
const parsedResponse = JSON.parse(response);
console.log('parsedResponse', parsedResponse);

return {
return formatProof({
proof: parsedResponse.proof,
pub_signals: parsedResponse.inputs,
}
})
}
} catch (err: any) {
console.log('err', err);
Expand Down
2 changes: 2 additions & 0 deletions common/src/constants/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,12 @@ export const ECDSA_K_LENGTH_FACTOR = 2;
// possible values because of sha1 constaints: 192,320,384, 448, 576, 640

export const circuitNameFromMode = {
prove: 'prove',
prove_onchain: 'prove',
prove_offchain: 'prove',
register: 'prove',
vc_and_disclose: 'vc_and_disclose',
dsc: 'dsc',
}

export enum SignatureAlgorithmIndex {
Expand Down
1 change: 1 addition & 0 deletions common/src/utils/appType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface OpenPassportAppPartial {
sessionId: string;
userId: string;
userIdType: UserIdType;
devMode: boolean;
}

export interface OpenPassportApp extends OpenPassportAppPartial {
Expand Down
14 changes: 10 additions & 4 deletions common/src/utils/certificates/handleCertificate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import elliptic from 'elliptic';
import { parseRsaPublicKey, parseRsaPssPublicKey, parseECParameters } from './publicKeyDetails';
import { PublicKeyDetailsRSAPSS } from './dataStructure';
import { getNamedCurve } from './curves';
import { circuitNameFromMode } from '../../constants/constants';
import { Mode } from '../appType';

if (typeof global.Buffer === 'undefined') {
global.Buffer = require('buffer').Buffer;
Expand Down Expand Up @@ -48,12 +50,16 @@ export function parseCertificate(pem: string) {

}

export const getCircuitName = (circuitType: string, signatureAlgorithm: string, hashFunction: string) => {
if (signatureAlgorithm === 'ecdsa') {
return circuitType + "_" + signatureAlgorithm + "_secp256r1_" + hashFunction;
export const getCircuitName = (circuitMode: Mode, signatureAlgorithm: string, hashFunction: string) => {
const circuit = circuitNameFromMode[circuitMode];
if (circuit == 'vc_and_disclose') {
return 'vc_and_disclose';
}
else if (signatureAlgorithm === 'ecdsa') {
return circuit + "_" + signatureAlgorithm + "_secp256r1_" + hashFunction;
}
else {
return circuitType + "_" + signatureAlgorithm + "_65537_" + hashFunction;
return circuit + "_" + signatureAlgorithm + "_65537_" + hashFunction;
}
}

Expand Down
27 changes: 11 additions & 16 deletions common/src/utils/csca.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { sha1Pad, sha256Pad } from "./shaPad";
import { shaPad } from "./shaPad";
import * as forge from "node-forge";
import { bytesToBigDecimal, extractRSFromSignature, getNAndK, getNAndKCSCA, hexToDecimal, splitToWords } from "./utils";
import { CSCA_TREE_DEPTH, MODAL_SERVER_ADDRESS } from "../constants/constants";
Expand All @@ -9,13 +9,16 @@ import axios from "axios";
import { parseCertificate } from "./certificates/handleCertificate";
import { getLeafCSCA } from "./pubkeyTree";
import { SKI_PEM, SKI_PEM_DEV } from "../constants/skiPem";

export function findStartIndex(modulus: string, messagePadded: Uint8Array): number {
console.log('messagePadded', messagePadded);
const modulusNumArray = [];
for (let i = 0; i < modulus.length; i += 2) {
const hexPair = modulus.slice(i, i + 2);
const number = parseInt(hexPair, 16);
modulusNumArray.push(number);
}
console.log('modulusNumArray', modulusNumArray);
const messagePaddedNumber = [];
for (let i = 0; i < messagePadded.length; i += 1) {
const number = Number(messagePadded[i]);
Expand All @@ -26,17 +29,18 @@ export function findStartIndex(modulus: string, messagePadded: Uint8Array): numb
if (modulusNumArray[0] === messagePaddedNumber[i]) {
for (let j = 0; j < modulusNumArray.length; j++) {
if (modulusNumArray[j] !== messagePaddedNumber[i + j]) {
//console.log("NO MODULUS FOUND IN CERTIFICATE");
break;
}
else if (j === modulusNumArray.length - 1) {
//console.log("MODULUS FOUND IN CERTIFICATE");
startIndex = i;
}
}
break;
}
}
if (startIndex === -1) {
throw new Error('DSC Pubkey not found in CSCA certificate');
}
return startIndex;
}

Expand All @@ -52,18 +56,7 @@ export function generateCircuitInputsDSC(dscSecret: string, dscCertificate: any,
const { signatureAlgorithm, hashFunction, publicKeyDetails, x, y, modulus, curve, exponent, bits, subjectKeyIdentifier, authorityKeyIdentifier } = parseCertificate(dscCertificate);
let dsc_message_padded;
let dsc_messagePaddedLen;
switch (hashFunction) {
case 'sha1':
[dsc_message_padded, dsc_messagePaddedLen] = sha1Pad(dscTbsCertUint8Array, max_cert_bytes);
break;
case 'sha256':
[dsc_message_padded, dsc_messagePaddedLen] = sha256Pad(dscTbsCertUint8Array, max_cert_bytes);
break;
default:
console.log("Signature algorithm not recognized", signatureAlgorithm);
[dsc_message_padded, dsc_messagePaddedLen] = sha256Pad(dscTbsCertUint8Array, max_cert_bytes);
break;
}
[dsc_message_padded, dsc_messagePaddedLen] = shaPad(dscTbsCertUint8Array, max_cert_bytes);

const { n, k } = getNAndK(signatureAlgorithm);
// Extract the signature from the DSC certificate
Expand All @@ -78,6 +71,7 @@ export function generateCircuitInputsDSC(dscSecret: string, dscCertificate: any,
const dsc_messagePaddedLen_formatted = BigInt(dsc_messagePaddedLen).toString()

const cscaPem = getCSCAFromSKI(authorityKeyIdentifier, devMode);
console.log('cscaPem', cscaPem);

const { x: csca_x, y: csca_y, modulus: csca_modulus, signature_algorithm: csca_signature_algorithm } = parseCertificate(cscaPem);
const { n: n_csca, k: k_csca } = getNAndKCSCA(csca_signature_algorithm);
Expand Down Expand Up @@ -139,12 +133,13 @@ export function generateCircuitInputsDSC(dscSecret: string, dscCertificate: any,

}

export function getCSCAFromSKI(ski: string, devMode: boolean): string | null {
export function getCSCAFromSKI(ski: string, devMode: boolean): string {
const cscaPemPROD = (SKI_PEM as any)[ski];
const cscaPemDEV = (SKI_PEM_DEV as any)[ski];
const cscaPem = devMode ? cscaPemDEV || cscaPemPROD : cscaPemPROD;
if (!cscaPem) {
console.log('\x1b[31m%s\x1b[0m', `CSCA with SKI ${ski} not found`, 'devMode: ', devMode);
throw new Error(`CSCA not found, authorityKeyIdentifier: ${ski}, areMockPassportsAllowed: ${devMode},`);
}
return cscaPem;
}
Expand Down
2 changes: 0 additions & 2 deletions common/src/utils/generateInputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,10 @@ export function generateCircuitInputsProve(
}

const [eContentPadded, eContentLen] = shaPad(
signatureAlgorithm,
new Uint8Array(eContent),
MAX_PADDED_ECONTENT_LEN[signatureAlgorithmFullName]
);
const [signedAttrPadded, signedAttrPaddedLen] = shaPad(
signatureAlgorithm,
new Uint8Array(signedAttr),
MAX_PADDED_SIGNED_ATTR_LEN[signatureAlgorithmFullName]
);
Expand Down
32 changes: 1 addition & 31 deletions common/src/utils/shaPad.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,7 @@
// Copied from zk-email cuz it uses crypto so can't import it here.

export function shaPad(signatureAlgorithm: string, prehash_prepad_m: Uint8Array, maxShaBytes: number): [Uint8Array, number] {
if (signatureAlgorithm == 'sha1WithRSAEncryption') {
return sha1Pad(prehash_prepad_m, maxShaBytes);
} else {
return sha256Pad(prehash_prepad_m, maxShaBytes);
}
}

// Puts an end selector, a bunch of 0s, then the length, then fill the rest with 0s.
export function sha1Pad(prehash_prepad_m: Uint8Array, maxShaBytes: number): [Uint8Array, number] {
let length_bits = prehash_prepad_m.length * 8; // bytes to bits
let length_in_bytes = int64toBytes(length_bits);
prehash_prepad_m = mergeUInt8Arrays(prehash_prepad_m, int8toBytes(2 ** 7)); // Add the 1 on the end, length 505
while ((prehash_prepad_m.length * 8 + length_in_bytes.length * 8) % 512 !== 0) {
prehash_prepad_m = mergeUInt8Arrays(prehash_prepad_m, int8toBytes(0));
}
prehash_prepad_m = mergeUInt8Arrays(prehash_prepad_m, length_in_bytes);
assert((prehash_prepad_m.length * 8) % 512 === 0, "Padding did not complete properly!");
let messageLen = prehash_prepad_m.length;
while (prehash_prepad_m.length < maxShaBytes) {
prehash_prepad_m = mergeUInt8Arrays(prehash_prepad_m, int64toBytes(0));
}
assert(
prehash_prepad_m.length === maxShaBytes,
`Padding to max length did not complete properly! Your padded message is ${prehash_prepad_m.length} long but max is ${maxShaBytes}!`
);
return [prehash_prepad_m, messageLen];
}


// Puts an end selector, a bunch of 0s, then the length, then fill the rest with 0s.
export function sha256Pad(prehash_prepad_m: Uint8Array, maxShaBytes: number): [Uint8Array, number] {
export function shaPad(prehash_prepad_m: Uint8Array, maxShaBytes: number): [Uint8Array, number] {
let length_bits = prehash_prepad_m.length * 8; // bytes to bits
let length_in_bytes = int64toBytes(length_bits);
prehash_prepad_m = mergeUInt8Arrays(prehash_prepad_m, int8toBytes(2 ** 7)); // Add the 1 on the end, length 505
Expand Down
3 changes: 1 addition & 2 deletions sdk/src/AttestationVerifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,7 @@ export class AttestationVerifier {
signatureAlgorithm: string,
hashFunction: string
): Promise<void> {
const circuitName = circuitNameFromMode[mode];
const vkey = getVkeyFromArtifacts(circuitName, signatureAlgorithm, hashFunction);
const vkey = getVkeyFromArtifacts(mode, signatureAlgorithm, hashFunction);
const isVerified = await groth16.verify(vkey, publicSignals, proof as any);
this.verifyAttribute('proof', isVerified.toString(), 'true');
}
Expand Down
1 change: 1 addition & 0 deletions sdk/src/OpenPassportVerifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export class OpenPassportVerifier extends AttestationVerifier {
sessionId: sessionId,
userId: userId,
userIdType: userIdType,
devMode: this.devMode,
};

let openPassportArguments: ArgumentsProveOffChain | ArgumentsRegister;
Expand Down
5 changes: 2 additions & 3 deletions sdk/tests/web-app/src/app/disclose/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,15 @@ export default function Prove() {
.setCommitmentMerkleTreeUrl(COMMITMENT_TREE_TRACKER_URL)
.excludeCountries('Albania')
.setMinimumAge(20)
.enableOFACCheck()
.setNationality('Germany');
.enableOFACCheck();
return (
<div className="h-screen w-full bg-white flex flex-col items-center justify-center gap-4">
<OpenPassportQRcode
appName="Mock App"
userId={userId}
userIdType={'uuid'}
openPassportVerifier={openPassportVerifierDisclose}
onSuccess={(attestation) => {}}
onSuccess={(attestation) => { }}
/>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion sdk/tests/web-app/src/app/register/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default function Prove() {
const openPassportVerifier = new OpenPassportVerifier(
'register',
scope
).setCommitmentMerkleTreeUrl(COMMITMENT_TREE_TRACKER_URL);
).setCommitmentMerkleTreeUrl(COMMITMENT_TREE_TRACKER_URL).allowMockPassports();
return (
<div className="h-screen w-full bg-white flex flex-col items-center justify-center gap-4">
<OpenPassportQRcode
Expand Down
Loading

0 comments on commit 73de3c0

Please sign in to comment.