mirror of
https://github.com/selfxyz/self.git
synced 2026-04-05 03:00:53 -04:00
Use secret from keychain (#108)
This commit is contained in:
@@ -16,7 +16,7 @@ export interface CertificateData {
|
||||
| PublicKeyDetailsECDSA
|
||||
| PublicKeyDetailsRSAPSS
|
||||
| undefined;
|
||||
tbsBytes: Uint8Array | undefined;
|
||||
tbsBytes: number[] | undefined;
|
||||
tbsBytesLength: string;
|
||||
rawPem: string;
|
||||
rawTxt: string;
|
||||
|
||||
@@ -344,14 +344,8 @@ export function getCertificateFromPem(pemContent: string): Certificate {
|
||||
return new Certificate({ schema: asn1.result })
|
||||
}
|
||||
|
||||
export function getTBSBytes(pemContent: string): Uint8Array {
|
||||
const certificate = getCertificateFromPem(pemContent);
|
||||
return Uint8Array.from(
|
||||
certificate.tbsView.map((byte) => parseInt(byte.toString(16), 16))
|
||||
);
|
||||
}
|
||||
export function getTBSBytesForge(certificate: Certificate): Uint8Array {
|
||||
return Uint8Array.from(
|
||||
export function getTBSBytesForge(certificate: Certificate): number[] {
|
||||
return Array.from(
|
||||
certificate.tbsView.map((byte) => parseInt(byte.toString(16), 16))
|
||||
);
|
||||
}
|
||||
@@ -30,17 +30,16 @@ import { generateMerkleProof, generateSMTProof } from '../trees';
|
||||
import { parseCertificateSimple } from '../certificate_parsing/parseCertificateSimple';
|
||||
import { parseDscCertificateData } from '../passports/passport_parsing/parseDscCertificateData';
|
||||
|
||||
export async function generateCircuitInputsDSC(
|
||||
export function generateCircuitInputsDSC(
|
||||
dscCertificate: string,
|
||||
devMode: boolean = true
|
||||
serializedCscaTree: string[][],
|
||||
) {
|
||||
const serialized_csca_tree = (await getCSCATree(devMode) as any);
|
||||
const dscParsed = parseCertificateSimple(dscCertificate);
|
||||
const dscMetadata = parseDscCertificateData(dscParsed);
|
||||
const cscaParsed = parseCertificateSimple(dscMetadata.csca);
|
||||
|
||||
// CSCA is padded with 0s to max_csca_bytes
|
||||
const cscaTbsBytesPadded = padWithZeroes(Array.from(cscaParsed.tbsBytes), max_csca_bytes);
|
||||
const cscaTbsBytesPadded = padWithZeroes(cscaParsed.tbsBytes, max_csca_bytes);
|
||||
const dscTbsBytes = dscParsed.tbsBytes;
|
||||
|
||||
// DSC is padded using sha padding because it will be hashed in the circuit
|
||||
@@ -50,7 +49,7 @@ export async function generateCircuitInputsDSC(
|
||||
);
|
||||
|
||||
const leaf = getLeafCscaTree(cscaParsed);
|
||||
const [root, path, siblings] = getCscaTreeInclusionProof(leaf, serialized_csca_tree);
|
||||
const [root, path, siblings] = getCscaTreeInclusionProof(leaf, serializedCscaTree);
|
||||
|
||||
// Parse CSCA certificate and get its public key
|
||||
const csca_pubKey_formatted = getCertificatePubKey(
|
||||
@@ -86,16 +85,11 @@ export async function generateCircuitInputsDSC(
|
||||
};
|
||||
}
|
||||
|
||||
export async function generateCircuitInputsRegister(
|
||||
export function generateCircuitInputsRegister(
|
||||
secret: string,
|
||||
passportData: PassportData,
|
||||
devMode: boolean = false
|
||||
serializedDscTree: string,
|
||||
) {
|
||||
const serialized_dsc_tree = await getDSCTree(devMode);
|
||||
|
||||
if (!passportData.parsed) {
|
||||
throw new Error('Passport data is not parsed');
|
||||
}
|
||||
const { mrz, eContent, signedAttr } = passportData;
|
||||
const passportMetadata = passportData.passportMetadata;
|
||||
const dscParsed = passportData.dsc_parsed;
|
||||
@@ -118,23 +112,23 @@ export async function generateCircuitInputsRegister(
|
||||
}
|
||||
|
||||
const [eContentPadded, eContentLen] = pad(passportMetadata.eContentHashFunction)(
|
||||
new Uint8Array(eContent),
|
||||
eContent,
|
||||
MAX_PADDED_ECONTENT_LEN[passportMetadata.dg1HashFunction]
|
||||
);
|
||||
const [signedAttrPadded, signedAttrPaddedLen] = pad(passportMetadata.signedAttrHashFunction)(
|
||||
new Uint8Array(signedAttr),
|
||||
signedAttr,
|
||||
MAX_PADDED_SIGNED_ATTR_LEN[passportMetadata.eContentHashFunction]
|
||||
);
|
||||
|
||||
const dsc_leaf = getLeafDscTree(dscParsed, passportData.csca_parsed); // TODO: WRONG
|
||||
const [root, path, siblings, leaf_depth] = getDscTreeInclusionProof(dsc_leaf, serialized_dsc_tree);
|
||||
const [root, path, siblings, leaf_depth] = getDscTreeInclusionProof(dsc_leaf, serializedDscTree);
|
||||
const csca_tree_leaf = getLeafCscaTree(passportData.csca_parsed);
|
||||
|
||||
// Get start index of DSC pubkey based on algorithm
|
||||
const [startIndex, keyLength] = findStartPubKeyIndex(dscParsed, dscTbsBytesPadded, dscParsed.signatureAlgorithm);
|
||||
|
||||
const inputs = {
|
||||
raw_dsc: Array.from(dscTbsBytesPadded).map(x => x.toString()),
|
||||
raw_dsc: dscTbsBytesPadded.map(x => x.toString()),
|
||||
raw_dsc_actual_length: [BigInt(dscParsed.tbsBytes.length).toString()],
|
||||
dsc_pubKey_offset: startIndex,
|
||||
dsc_pubKey_actual_size: [BigInt(keyLength).toString()],
|
||||
|
||||
@@ -6,7 +6,7 @@ import { SKI_PEM, SKI_PEM_DEV } from '../constants/skiPem';
|
||||
import { splitToWords } from './bytes';
|
||||
import path from 'path';
|
||||
|
||||
export function findStartIndexEC(modulus: string, messagePadded: Uint8Array): [number, number] {
|
||||
export function findStartIndexEC(modulus: string, messagePadded: number[]): [number, number] {
|
||||
const modulusNumArray = [];
|
||||
for (let i = 0; i < modulus.length; i += 2) {
|
||||
modulusNumArray.push(parseInt(modulus.slice(i, i + 2), 16));
|
||||
@@ -38,7 +38,7 @@ export function findStartIndexEC(modulus: string, messagePadded: Uint8Array): [n
|
||||
}
|
||||
|
||||
// @returns [startIndex, length] where startIndex is the index of the first byte of the modulus in the message and length is the length of the modulus in bytes
|
||||
export function findStartIndex(modulus: string, messagePadded: Uint8Array): [number, number] {
|
||||
export function findStartIndex(modulus: string, messagePaddedNumber: number[]): [number, number] {
|
||||
const modulusNumArray = [];
|
||||
for (let i = 0; i < modulus.length; i += 2) {
|
||||
const hexPair = modulus.slice(i, i + 2);
|
||||
@@ -46,8 +46,6 @@ export function findStartIndex(modulus: string, messagePadded: Uint8Array): [num
|
||||
modulusNumArray.push(number);
|
||||
}
|
||||
|
||||
const messagePaddedNumber = Array.from(messagePadded);
|
||||
|
||||
// console.log('Modulus length:', modulusNumArray.length);
|
||||
// console.log('Message length:', messagePaddedNumber.length);
|
||||
// console.log('Modulus (hex):', modulusNumArray.map(n => n.toString(16).padStart(2, '0')).join(''));
|
||||
@@ -71,7 +69,7 @@ export function findStartIndex(modulus: string, messagePadded: Uint8Array): [num
|
||||
|
||||
export function findOIDPosition(
|
||||
oid: string,
|
||||
message: Uint8Array
|
||||
message: number[]
|
||||
): { oid_index: number; oid_length: number } {
|
||||
// Convert OID string like "1.2.840.113549" to byte array
|
||||
const oidParts = oid.split('.').map(Number);
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
import { getCurveForElliptic } from '../certificate_parsing/curves';
|
||||
import { formatAndConcatenateDataHashes, formatMrz } from './format';
|
||||
import { generateSignedAttr } from './format';
|
||||
import { initPassportDataParsing } from './passport';
|
||||
|
||||
function generateRandomBytes(length: number): number[] {
|
||||
// Generate numbers between -128 and 127 to match the existing signed byte format
|
||||
@@ -259,7 +260,7 @@ export function genMockPassportData(
|
||||
const signature = sign(privateKeyPem, dsc, hashAlgo, signedAttr);
|
||||
const signatureBytes = Array.from(signature, (byte) => (byte < 128 ? byte : byte - 256));
|
||||
|
||||
return {
|
||||
return initPassportDataParsing({
|
||||
dsc: dsc,
|
||||
mrz: mrz,
|
||||
dg2Hash: dataGroupHashes.find(([dgNum]) => dgNum === 2)?.[1] || [],
|
||||
@@ -267,9 +268,7 @@ export function genMockPassportData(
|
||||
signedAttr: signedAttr,
|
||||
encryptedDigest: signatureBytes,
|
||||
photoBase64: 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABjElEQVR42mL8//8/AyUYiBQYmIy3...',
|
||||
mockUser: true,
|
||||
parsed: false,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function sign(
|
||||
|
||||
@@ -35,7 +35,7 @@ import { findStartIndex, findStartIndexEC } from '../csca';
|
||||
import { formatInput } from '../circuits/generateInputs';
|
||||
import { getLeafDscTree } from '../trees';
|
||||
|
||||
/// @dev will brutforce passport and dsc signature — needs to be trigerred after generating mock passport data
|
||||
/// @dev will bruteforce passport and dsc signature
|
||||
export function initPassportDataParsing(passportData: PassportData) {
|
||||
const passportMetadata = parsePassportData(passportData);
|
||||
passportData.passportMetadata = passportMetadata;
|
||||
@@ -45,7 +45,6 @@ export function initPassportDataParsing(passportData: PassportData) {
|
||||
const cscaParsed = parseCertificateSimple(passportData.passportMetadata.csca);
|
||||
passportData.csca_parsed = cscaParsed;
|
||||
}
|
||||
passportData.parsed = true;
|
||||
return passportData;
|
||||
}
|
||||
|
||||
@@ -101,18 +100,9 @@ export function padWithZeroes(bytes: number[], length: number) {
|
||||
return bytes.concat(new Array(length - bytes.length).fill(0));
|
||||
}
|
||||
|
||||
function validatePassportMetadata(passportData: PassportData): void {
|
||||
if (!passportData.parsed) {
|
||||
throw new Error('Passport data is not parsed');
|
||||
}
|
||||
}
|
||||
|
||||
/// @notice Get the signature of the passport and the public key of the DSC
|
||||
/// @dev valid for only for the passport/dsc chain
|
||||
export function getPassportSignatureInfos(passportData: PassportData) {
|
||||
if (!passportData.parsed) {
|
||||
throw new Error('Passport data is not parsed');
|
||||
}
|
||||
const passportMetadata = passportData.passportMetadata;
|
||||
const signatureAlgorithmFullName = getSignatureAlgorithmFullName(
|
||||
passportData.dsc_parsed,
|
||||
@@ -257,7 +247,6 @@ export function getSignatureAlgorithmFullName(
|
||||
|
||||
/*** retrieve pubKey bytes - will be used in generateCircuitsInputsCSCA ***/
|
||||
export function getPubKeyBytes(passportData: PassportData, type: 'dsc' | 'csca'): number[] {
|
||||
validatePassportMetadata(passportData);
|
||||
if (type === 'dsc') {
|
||||
return getDscPubKeyBytes(passportData);
|
||||
} else if (type === 'csca') {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// Copied from zk-email cuz it uses crypto so can't import it here.
|
||||
|
||||
// Puts an end selector, a bunch of 0s, then the length, then fill the rest with 0s.
|
||||
export function shaPad(prehash_prepad_m: Uint8Array, maxShaBytes: number): [Uint8Array, number] {
|
||||
export function shaPad(prehash_prepad_m_array: number[], maxShaBytes: number): [number[], number] {
|
||||
let prehash_prepad_m = new Uint8Array(prehash_prepad_m_array);
|
||||
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
|
||||
@@ -18,13 +19,14 @@ export function shaPad(prehash_prepad_m: Uint8Array, maxShaBytes: number): [Uint
|
||||
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];
|
||||
return [Array.from(prehash_prepad_m), messageLen];
|
||||
}
|
||||
|
||||
export function sha384_512Pad(
|
||||
prehash_prepad_m: Uint8Array,
|
||||
prehash_prepad_m_array: number[],
|
||||
maxShaBytes: number
|
||||
): [Uint8Array, number] {
|
||||
): [number[], number] {
|
||||
let prehash_prepad_m = new Uint8Array(prehash_prepad_m_array);
|
||||
// Length in bits before padding
|
||||
let length_bits = prehash_prepad_m.length * 8;
|
||||
|
||||
@@ -57,7 +59,7 @@ export function sha384_512Pad(
|
||||
`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];
|
||||
return [Array.from(prehash_prepad_m), messageLen];
|
||||
}
|
||||
|
||||
// Helper function to convert 128-bit length to bytes
|
||||
|
||||
@@ -16,22 +16,13 @@ import { pad } from './passports/passport';
|
||||
import countries from "i18n-iso-countries";
|
||||
import en from "i18n-iso-countries/langs/en.json";
|
||||
countries.registerLocale(en);
|
||||
import serialized_csca_tree from '../../pubkeys/serialized_csca_tree.json';
|
||||
import serialized_dsc_tree from '../../pubkeys/serialized_dsc_tree.json';
|
||||
|
||||
|
||||
export async function getCSCATree(devMode: boolean): Promise<string[][]> {
|
||||
if (devMode) {
|
||||
return serialized_csca_tree;
|
||||
}
|
||||
export async function getCSCATree(): Promise<string[][]> {
|
||||
const response = await fetch(CSCA_TREE_URL);
|
||||
return await response.json().then(data => data.data ? JSON.parse(data.data) : data);
|
||||
}
|
||||
|
||||
export async function getDSCTree(devMode: boolean): Promise<string> {
|
||||
if (devMode) {
|
||||
return serialized_dsc_tree;
|
||||
}
|
||||
export async function getDSCTree(): Promise<string> {
|
||||
const response = await fetch(DSC_TREE_URL);
|
||||
return await response.json().then(data => data.data ? data.data : data);
|
||||
}
|
||||
@@ -112,6 +103,7 @@ export function getCscaTreeInclusionProof(leaf: string, _serialized_csca_tree: a
|
||||
const proof = tree.createProof(index);
|
||||
return [tree.root, proof.pathIndices.map(index => index.toString()), proof.siblings.flat().map(sibling => sibling.toString())];
|
||||
}
|
||||
|
||||
export function getCscaTreeRoot(serialized_csca_tree: any[][]) {
|
||||
let tree = new IMT(poseidon2, CSCA_TREE_DEPTH, 0, 2);
|
||||
tree.setNodes(serialized_csca_tree);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { CertificateData } from "./certificate_parsing/dataStructure";
|
||||
import { PassportMetadata } from "./passports/passport_parsing/parsePassportData";
|
||||
|
||||
export type PassportData = {
|
||||
@@ -10,11 +11,9 @@ export type PassportData = {
|
||||
signedAttr: number[];
|
||||
encryptedDigest: number[];
|
||||
photoBase64: string;
|
||||
mockUser?: boolean;
|
||||
parsed: boolean;
|
||||
passportMetadata?: PassportMetadata;
|
||||
dsc_parsed?: any;
|
||||
csca_parsed?: any;
|
||||
dsc_parsed?: CertificateData;
|
||||
csca_parsed?: CertificateData;
|
||||
};
|
||||
|
||||
// Define the signature algorithm in "algorithm_hashfunction_domainPapameter_keyLength"
|
||||
|
||||
Reference in New Issue
Block a user