mirror of
https://github.com/selfxyz/self.git
synced 2026-04-27 03:01:15 -04:00
feat: generate inputs for ecdsa with sha1
This commit is contained in:
@@ -1,20 +1,25 @@
|
||||
import { MAX_DATAHASHES_LEN, PUBKEY_TREE_DEPTH, DEVELOPMENT_MODE } from "../constants/constants";
|
||||
import { assert, shaPad } from "./shaPad";
|
||||
import { PassportData } from "./types";
|
||||
import { MAX_DATAHASHES_LEN, PUBKEY_TREE_DEPTH, DEVELOPMENT_MODE } from '../constants/constants';
|
||||
import { assert, shaPad } from './shaPad';
|
||||
import { PassportData } from './types';
|
||||
import {
|
||||
arraysAreEqual, bytesToBigDecimal, formatMrz, hash, splitToWords,
|
||||
toUnsignedByte, getHashLen, getCurrentDateYYMMDD,
|
||||
arraysAreEqual,
|
||||
bytesToBigDecimal,
|
||||
formatMrz,
|
||||
hash,
|
||||
splitToWords,
|
||||
toUnsignedByte,
|
||||
getHashLen,
|
||||
getCurrentDateYYMMDD,
|
||||
generateMerkleProof,
|
||||
findSubarrayIndex
|
||||
} from "./utils";
|
||||
import { LeanIMT } from "@zk-kit/lean-imt";
|
||||
import { getLeaf } from "./pubkeyTree";
|
||||
import { poseidon6 } from "poseidon-lite";
|
||||
import { packBytes } from "../utils/utils";
|
||||
import { getCSCAModulusMerkleTree } from "./csca";
|
||||
import {
|
||||
mockPassportDatas,
|
||||
} from "../constants/mockPassportData";
|
||||
findSubarrayIndex,
|
||||
hexToDecimal,
|
||||
} from './utils';
|
||||
import { LeanIMT } from '@zk-kit/lean-imt';
|
||||
import { getLeaf } from './pubkeyTree';
|
||||
import { poseidon6 } from 'poseidon-lite';
|
||||
import { packBytes } from '../utils/utils';
|
||||
import { getCSCAModulusMerkleTree } from './csca';
|
||||
import { mockPassportDatas } from '../constants/mockPassportData';
|
||||
|
||||
export function generateCircuitInputsRegister(
|
||||
secret: string,
|
||||
@@ -25,21 +30,26 @@ export function generateCircuitInputsRegister(
|
||||
k_dsc: number,
|
||||
mocks: PassportData[] = mockPassportDatas
|
||||
) {
|
||||
const { mrz, signatureAlgorithm, pubKey, dataGroupHashes, eContent, encryptedDigest } = passportData;
|
||||
const { mrz, signatureAlgorithm, pubKey, dataGroupHashes, eContent, encryptedDigest } =
|
||||
passportData;
|
||||
|
||||
const tree = getCSCAModulusMerkleTree();
|
||||
|
||||
if (DEVELOPMENT_MODE) {
|
||||
for (const mockPassportData of mocks) {
|
||||
console.log('mockPassportData', mockPassportData);
|
||||
tree.insert(getLeaf(mockPassportData).toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (![
|
||||
"sha256WithRSAEncryption",
|
||||
"sha1WithRSAEncryption",
|
||||
"sha256WithRSASSAPSS"
|
||||
].includes(signatureAlgorithm)) {
|
||||
if (
|
||||
![
|
||||
'sha256WithRSAEncryption',
|
||||
'sha1WithRSAEncryption',
|
||||
'sha256WithRSASSAPSS',
|
||||
'ecdsa-with-SHA1',
|
||||
].includes(signatureAlgorithm)
|
||||
) {
|
||||
console.error(`${signatureAlgorithm} has not been implemented.`);
|
||||
throw new Error(`${signatureAlgorithm} has not been implemented.`);
|
||||
}
|
||||
@@ -48,7 +58,7 @@ export function generateCircuitInputsRegister(
|
||||
const formattedMrz = formatMrz(mrz);
|
||||
const mrzHash = hash(signatureAlgorithm, formattedMrz);
|
||||
|
||||
const dg1HashOffset = findSubarrayIndex(dataGroupHashes, mrzHash)
|
||||
const dg1HashOffset = findSubarrayIndex(dataGroupHashes, mrzHash);
|
||||
console.log('dg1HashOffset', dg1HashOffset);
|
||||
|
||||
assert(dg1HashOffset !== -1, 'MRZ hash index not found in dataGroupHashes');
|
||||
@@ -56,30 +66,31 @@ export function generateCircuitInputsRegister(
|
||||
const concatHash = hash(signatureAlgorithm, dataGroupHashes);
|
||||
|
||||
assert(
|
||||
arraysAreEqual(
|
||||
concatHash,
|
||||
eContent.slice(eContent.length - hashLen)
|
||||
),
|
||||
arraysAreEqual(concatHash, eContent.slice(eContent.length - hashLen)),
|
||||
'concatHash is not at the right place in eContent'
|
||||
);
|
||||
|
||||
// const leaf = getLeaf({
|
||||
// signatureAlgorithm: signatureAlgorithm,
|
||||
// ...pubKey,
|
||||
// }).toString();
|
||||
const leaf = getLeaf({
|
||||
signatureAlgorithm: signatureAlgorithm,
|
||||
...pubKey,
|
||||
}).toString();
|
||||
|
||||
// const index = tree.indexOf(leaf);
|
||||
// // console.log(`Index of pubkey in the registry: ${index}`);
|
||||
// if (index === -1) {
|
||||
// throw new Error("Your public key was not found in the registry");
|
||||
// }
|
||||
const index = tree.indexOf(leaf);
|
||||
// console.log(`Index of pubkey in the registry: ${index}`);
|
||||
if (index === -1) {
|
||||
throw new Error('Your public key was not found in the registry');
|
||||
}
|
||||
|
||||
// const proof = tree.createProof(index);
|
||||
// console.log("verifyProof", tree.verifyProof(proof));
|
||||
const proof = tree.createProof(index);
|
||||
console.log('verifyProof', tree.verifyProof(proof));
|
||||
|
||||
if (dataGroupHashes.length > MAX_DATAHASHES_LEN) {
|
||||
console.error(`Data hashes too long (${dataGroupHashes.length} bytes). Max length is ${MAX_DATAHASHES_LEN} bytes.`);
|
||||
throw new Error(`This length of datagroups (${dataGroupHashes.length} bytes) is currently unsupported. Please contact us so we add support!`);
|
||||
console.error(
|
||||
`Data hashes too long (${dataGroupHashes.length} bytes). Max length is ${MAX_DATAHASHES_LEN} bytes.`
|
||||
);
|
||||
throw new Error(
|
||||
`This length of datagroups (${dataGroupHashes.length} bytes) is currently unsupported. Please contact us so we add support!`
|
||||
);
|
||||
}
|
||||
|
||||
const [messagePadded, messagePaddedLen] = shaPad(
|
||||
@@ -88,25 +99,38 @@ export function generateCircuitInputsRegister(
|
||||
MAX_DATAHASHES_LEN
|
||||
);
|
||||
|
||||
let dsc_modulus: any;
|
||||
if (signatureAlgorithm === 'ecdsa-with-SHA1') {
|
||||
console.log('pubKey', pubKey);
|
||||
const curve_params = pubKey.publicKeyQ.replace(/[()]/g, '').split(',');
|
||||
let k = hexToDecimal(curve_params[0]);
|
||||
let m = hexToDecimal(curve_params[1]);
|
||||
dsc_modulus = [
|
||||
...splitToWords(BigInt(k), BigInt(n_dsc), BigInt(k_dsc)),
|
||||
...splitToWords(BigInt(m), BigInt(n_dsc), BigInt(k_dsc)),
|
||||
];
|
||||
} else {
|
||||
dsc_modulus = splitToWords(
|
||||
BigInt(passportData.pubKey.modulus as string),
|
||||
BigInt(n_dsc),
|
||||
BigInt(k_dsc)
|
||||
);
|
||||
}
|
||||
return {
|
||||
secret: [secret],
|
||||
mrz: formattedMrz.map(byte => String(byte)),
|
||||
mrz: formattedMrz.map((byte) => String(byte)),
|
||||
dg1_hash_offset: [dg1HashOffset.toString()], // uncomment when adding new circuits
|
||||
econtent: Array.from(messagePadded).map((x) => x.toString()),
|
||||
datahashes_padded_length: [messagePaddedLen.toString()],
|
||||
signed_attributes: eContent.map(toUnsignedByte).map(byte => String(byte)),
|
||||
signed_attributes: eContent.map(toUnsignedByte).map((byte) => String(byte)),
|
||||
signature: splitToWords(
|
||||
BigInt(bytesToBigDecimal(passportData.encryptedDigest)),
|
||||
BigInt(n_dsc),
|
||||
BigInt(k_dsc)
|
||||
),
|
||||
dsc_modulus: splitToWords(
|
||||
BigInt(passportData.pubKey.modulus as string),
|
||||
BigInt(n_dsc),
|
||||
BigInt(k_dsc)
|
||||
),
|
||||
dsc_modulus: dsc_modulus,
|
||||
attestation_id: [attestation_id],
|
||||
dsc_secret: [dscSecret]
|
||||
dsc_secret: [dscSecret],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -118,7 +142,7 @@ export function generateCircuitInputsDisclose(
|
||||
majority: string[],
|
||||
bitmap: string[],
|
||||
scope: string,
|
||||
user_identifier: string,
|
||||
user_identifier: string
|
||||
) {
|
||||
const pubkey_leaf = getLeaf({
|
||||
signatureAlgorithm: passportData.signatureAlgorithm,
|
||||
@@ -134,28 +158,32 @@ export function generateCircuitInputsDisclose(
|
||||
pubkey_leaf,
|
||||
mrz_bytes[0],
|
||||
mrz_bytes[1],
|
||||
mrz_bytes[2]
|
||||
mrz_bytes[2],
|
||||
]);
|
||||
|
||||
//console.log('commitment', commitment.toString());
|
||||
|
||||
const index = findIndexInTree(merkletree, commitment);
|
||||
|
||||
const { merkleProofSiblings, merkleProofIndices, depthForThisOne } = generateMerkleProof(merkletree, index, PUBKEY_TREE_DEPTH)
|
||||
const { merkleProofSiblings, merkleProofIndices, depthForThisOne } = generateMerkleProof(
|
||||
merkletree,
|
||||
index,
|
||||
PUBKEY_TREE_DEPTH
|
||||
);
|
||||
|
||||
return {
|
||||
secret: [secret],
|
||||
attestation_id: [attestation_id],
|
||||
pubkey_leaf: [pubkey_leaf.toString()],
|
||||
mrz: formattedMrz.map(byte => String(byte)),
|
||||
mrz: formattedMrz.map((byte) => String(byte)),
|
||||
merkle_root: [merkletree.root.toString()],
|
||||
merkletree_size: [BigInt(depthForThisOne).toString()],
|
||||
path: merkleProofIndices.map(index => BigInt(index).toString()),
|
||||
siblings: merkleProofSiblings.map(index => BigInt(index).toString()),
|
||||
path: merkleProofIndices.map((index) => BigInt(index).toString()),
|
||||
siblings: merkleProofSiblings.map((index) => BigInt(index).toString()),
|
||||
bitmap: bitmap,
|
||||
scope: [scope],
|
||||
current_date: getCurrentDateYYMMDD().map(datePart => BigInt(datePart).toString()),
|
||||
majority: majority.map(char => BigInt(char.charCodeAt(0)).toString()),
|
||||
current_date: getCurrentDateYYMMDD().map((datePart) => BigInt(datePart).toString()),
|
||||
majority: majority.map((char) => BigInt(char.charCodeAt(0)).toString()),
|
||||
user_identifier: [user_identifier],
|
||||
};
|
||||
}
|
||||
@@ -169,9 +197,9 @@ export function findIndexInTree(tree: LeanIMT, commitment: bigint): number {
|
||||
index = tree.indexOf(commitment.toString() as unknown as bigint);
|
||||
}
|
||||
if (index === -1) {
|
||||
throw new Error("This commitment was not found in the tree");
|
||||
throw new Error('This commitment was not found in the tree');
|
||||
} else {
|
||||
// console.log(`Index of commitment in the registry: ${index}`);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,75 +1,85 @@
|
||||
import { poseidon10, poseidon2, poseidon8 } from "poseidon-lite"
|
||||
import { SignatureAlgorithm, PUBKEY_TREE_DEPTH } from "../constants/constants";
|
||||
import { IMT } from '@zk-kit/imt'
|
||||
import { splitToWords } from "./utils";
|
||||
import { formatSigAlgNameForCircuit } from "./utils";
|
||||
import { toStandardName } from "./formatNames";
|
||||
import { poseidon10, poseidon2, poseidon5, poseidon8 } from 'poseidon-lite';
|
||||
import { SignatureAlgorithm, PUBKEY_TREE_DEPTH } from '../constants/constants';
|
||||
import { IMT } from '@zk-kit/imt';
|
||||
import { hexToDecimal, splitToWords } from './utils';
|
||||
import { formatSigAlgNameForCircuit } from './utils';
|
||||
import { toStandardName } from './formatNames';
|
||||
|
||||
export function buildPubkeyTree(pubkeys: any[]) {
|
||||
let leaves: bigint[] = []
|
||||
let leaves: bigint[] = [];
|
||||
let startTime = performance.now();
|
||||
|
||||
for (let i = 0; i < pubkeys.length; i++) {
|
||||
const pubkey = pubkeys[i]
|
||||
const pubkey = pubkeys[i];
|
||||
|
||||
if (i % 3000 === 0 && i !== 0) {
|
||||
console.log('Processing pubkey number', i, "over", pubkeys.length);
|
||||
console.log('Processing pubkey number', i, 'over', pubkeys.length);
|
||||
}
|
||||
|
||||
const leaf = getLeaf(pubkey, i)
|
||||
const leaf = getLeaf(pubkey, i);
|
||||
|
||||
if (!leaf) {
|
||||
// console.log('no leaf for this weird signature:', i, formatSigAlgNameForCircuit(pubkey.signatureAlgorithm, pubkey.exponent))
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
leaves.push(leaf)
|
||||
leaves.push(leaf);
|
||||
}
|
||||
|
||||
const tree = new IMT(poseidon2, PUBKEY_TREE_DEPTH, 0, 2, leaves)
|
||||
console.log('pubkey tree built in', performance.now() - startTime, 'ms')
|
||||
const tree = new IMT(poseidon2, PUBKEY_TREE_DEPTH, 0, 2, leaves);
|
||||
console.log('pubkey tree built in', performance.now() - startTime, 'ms');
|
||||
|
||||
return tree
|
||||
return tree;
|
||||
}
|
||||
|
||||
export function getLeaf(pubkey: any, i?: number): bigint {
|
||||
if (!pubkey?.modulus && pubkey?.pubKey?.modulus) {
|
||||
pubkey.modulus = pubkey.pubKey.modulus
|
||||
pubkey.exponent = pubkey.pubKey.exponent
|
||||
pubkey.modulus = pubkey.pubKey.modulus;
|
||||
pubkey.exponent = pubkey.pubKey.exponent;
|
||||
}
|
||||
if (!pubkey?.publicKeyQ && pubkey?.pubKey?.publicKeyQ) {
|
||||
pubkey.publicKeyQ = pubkey.pubKey.publicKeyQ
|
||||
pubkey.publicKeyQ = pubkey.pubKey.publicKeyQ;
|
||||
}
|
||||
const sigAlgFormatted = toStandardName(pubkey.signatureAlgorithm)
|
||||
const sigAlgFormattedForCircuit = formatSigAlgNameForCircuit(sigAlgFormatted, pubkey.exponent)
|
||||
|
||||
const sigAlgFormatted = toStandardName(pubkey.signatureAlgorithm);
|
||||
const sigAlgFormattedForCircuit = formatSigAlgNameForCircuit(sigAlgFormatted, pubkey.exponent);
|
||||
if (
|
||||
sigAlgFormattedForCircuit === "sha256WithRSAEncryption_65537"
|
||||
|| sigAlgFormattedForCircuit === "sha256WithRSAEncryption_3"
|
||||
|| sigAlgFormattedForCircuit === "sha1WithRSAEncryption_65537"
|
||||
|| sigAlgFormattedForCircuit === "sha256WithRSASSAPSS_65537"
|
||||
|| sigAlgFormattedForCircuit === "sha256WithRSASSAPSS_3"
|
||||
|| sigAlgFormattedForCircuit === "sha512WithRSAEncryption_65537"
|
||||
sigAlgFormattedForCircuit === 'sha256WithRSAEncryption_65537' ||
|
||||
sigAlgFormattedForCircuit === 'sha256WithRSAEncryption_3' ||
|
||||
sigAlgFormattedForCircuit === 'sha1WithRSAEncryption_65537' ||
|
||||
sigAlgFormattedForCircuit === 'sha256WithRSASSAPSS_65537' ||
|
||||
sigAlgFormattedForCircuit === 'sha256WithRSASSAPSS_3' ||
|
||||
sigAlgFormattedForCircuit === 'sha512WithRSAEncryption_65537'
|
||||
) {
|
||||
const pubkeyChunked = splitToWords(BigInt(pubkey.modulus), BigInt(230), BigInt(9));
|
||||
const leaf = poseidon10([SignatureAlgorithm[sigAlgFormattedForCircuit], ...pubkeyChunked])
|
||||
const leaf = poseidon10([SignatureAlgorithm[sigAlgFormattedForCircuit], ...pubkeyChunked]);
|
||||
try {
|
||||
|
||||
return leaf
|
||||
return leaf;
|
||||
} catch (err) {
|
||||
console.log('err', err, i, sigAlgFormattedForCircuit, pubkey)
|
||||
console.log('err', err, i, sigAlgFormattedForCircuit, pubkey);
|
||||
}
|
||||
} else if (
|
||||
sigAlgFormattedForCircuit === "ecdsa_with_SHA1"
|
||||
|| sigAlgFormattedForCircuit === "ecdsa_with_SHA224"
|
||||
|| sigAlgFormattedForCircuit === "ecdsa_with_SHA384"
|
||||
|| sigAlgFormattedForCircuit === "ecdsa_with_SHA256"
|
||||
|| sigAlgFormattedForCircuit === "ecdsa_with_SHA512"
|
||||
sigAlgFormattedForCircuit === 'ecdsa_with_SHA1' ||
|
||||
sigAlgFormattedForCircuit === 'ecdsa_with_SHA224' ||
|
||||
sigAlgFormattedForCircuit === 'ecdsa_with_SHA384' ||
|
||||
sigAlgFormattedForCircuit === 'ecdsa_with_SHA256' ||
|
||||
sigAlgFormattedForCircuit === 'ecdsa_with_SHA512'
|
||||
) {
|
||||
try {
|
||||
// this will be replaced by just X and Y or pubkey in publicKeyQ
|
||||
return poseidon8([SignatureAlgorithm[sigAlgFormattedForCircuit], pubkey.pub, pubkey.prime, pubkey.a, pubkey.b, pubkey.generator, pubkey.order, pubkey.cofactor])
|
||||
const [x, y, a, p] = pubkey.publicKeyQ.replace(/[()]/g, '').split(',');
|
||||
// ! @TODO check if this is correct
|
||||
return poseidon5([
|
||||
SignatureAlgorithm[sigAlgFormattedForCircuit],
|
||||
hexToDecimal(x), // pub.x
|
||||
hexToDecimal(y), // pub.y
|
||||
hexToDecimal(p), // prime
|
||||
hexToDecimal(a), // a
|
||||
// pubkey.b ? pubkey.b : BigInt(0), // null then 0
|
||||
// pubkey.generator ? pubkey.generator : BigInt(0), // null then 0
|
||||
// pubkey.order ? pubkey.order : BigInt(0), // null then 0
|
||||
// pubkey.cofactor ? pubkey.cofactor : BigInt(0), // null then 0
|
||||
]);
|
||||
} catch (err) {
|
||||
console.log('err', err, i, sigAlgFormattedForCircuit, pubkey)
|
||||
console.log('err', err, i, sigAlgFormattedForCircuit, pubkey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user