mirror of
https://github.com/selfxyz/self.git
synced 2026-01-10 15:18:18 -05:00
New OFAC updates (#47)
Co-authored-by: nicoshark <i.am.nicoshark@gmail.com>
This commit is contained in:
1
common/ofacdata/outputs/nameAndDobSMT.json
Normal file
1
common/ofacdata/outputs/nameAndDobSMT.json
Normal file
File diff suppressed because one or more lines are too long
1
common/ofacdata/outputs/nameAndYobSMT.json
Normal file
1
common/ofacdata/outputs/nameAndYobSMT.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
common/ofacdata/outputs/passportNoAndNationalitySMT.json
Normal file
1
common/ofacdata/outputs/passportNoAndNationalitySMT.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -22,6 +22,7 @@
|
||||
"country-iso-3-to-2": "^1.1.1",
|
||||
"elliptic": "^6.5.5",
|
||||
"fs": "^0.0.1-security",
|
||||
"i18n-iso-countries": "^7.13.0",
|
||||
"js-sha1": "^0.7.0",
|
||||
"js-sha256": "^0.11.0",
|
||||
"js-sha512": "^0.9.0",
|
||||
|
||||
@@ -30,6 +30,8 @@ export const saltLengths = [64, 48, 32];
|
||||
|
||||
export const MAX_FORBIDDEN_COUNTRIES_LIST_LENGTH = 10;
|
||||
|
||||
export const OFAC_TREE_LEVELS = 64;
|
||||
|
||||
export const MAX_PADDED_ECONTENT_LEN: Partial<Record<(typeof hashAlgos)[number], number>> = {
|
||||
sha1: 384,
|
||||
sha224: 512,
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
// Constant Values in OneTimeSBT.sol
|
||||
export const ATTRIBUTE_ISSUING_STATE_INDEX = 0;
|
||||
export const ATTRIBUTE_NAME_INDEX = 1;
|
||||
export const ATTRIBUTE_PASSPORT_NUMBER_INDEX = 2;
|
||||
export const ATTRIBUTE_NATIONALITY_INDEX = 3;
|
||||
export const ATTRIBUTE_DATE_OF_BIRTH_INDEX = 4;
|
||||
export const ATTRIBUTE_GENDER_INDEX = 5;
|
||||
export const ATTRIBUTE_EXPIRY_DATE_INDEX = 6;
|
||||
export const ATTRIBUTE_OLDER_THAN_INDEX = 7;
|
||||
|
||||
export const PROVE_RSA_NULLIFIER_INDEX = 0;
|
||||
export const PROVE_RSA_REVEALED_DATA_PACKED_INDEX = 1;
|
||||
export const PROVE_RSA_OLDER_THAN_INDEX = 4;
|
||||
export const PROVE_RSA_PUBKEY_DISCLOSED_INDEX = 6;
|
||||
export const PROVE_RSA_FORBIDDEN_COUNTRIES_LIST_PACKED_DISCLOSED_INDEX = 38;
|
||||
export const PROVE_RSA_OFAC_RESULT_INDEX = 40;
|
||||
export const PROVE_RSA_COMMITMENT_INDEX = 41;
|
||||
export const PROVE_RSA_BLINDED_DSC_COMMITMENT_INDEX = 42;
|
||||
export const PROVE_RSA_CURRENT_DATE_INDEX = 43;
|
||||
export const PROVE_RSA_USER_IDENTIFIER_INDEX = 49;
|
||||
export const PROVE_RSA_SCOPE_INDEX = 50;
|
||||
|
||||
export const DSC_BLINDED_DSC_COMMITMENT_INDEX = 0;
|
||||
export const DSC_MERKLE_ROOT_INDEX = 1;
|
||||
|
||||
// Enum in VerifiersManager.sol
|
||||
export const VERIFICATION_TYPE_ENUM_PROVE = 0;
|
||||
export const VERIFICATION_TYPE_ENUM_DSC = 1;
|
||||
@@ -45,7 +45,7 @@ export function unpackReveal(revealedData_packed: string | string[]): string[] {
|
||||
? revealedData_packed
|
||||
: [revealedData_packed];
|
||||
|
||||
const bytesCount = [31, 31, 29]; // nb of bytes in each of the first three field elements
|
||||
const bytesCount = [31, 31, 31]; // nb of bytes in each of the first three field elements
|
||||
const bytesArray = packedArray.flatMap((element: string, index: number) => {
|
||||
const bytes = bytesCount[index] || 31; // Use 31 as default if index is out of range
|
||||
const elementBigInt = BigInt(element);
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
} from '../../constants/constants';
|
||||
import { PassportData } from '../types';
|
||||
import { LeanIMT } from '@openpassport/zk-kit-lean-imt';
|
||||
import { getCountryLeaf, getNameLeaf, getNameDobLeaf, getPassportNumberLeaf, getLeafCscaTree, getLeaf, getLeafDscTree } from '../trees';
|
||||
import { getCountryLeaf, getNameDobLeaf, getPassportNumberAndNationalityLeaf, getLeafCscaTree, getLeaf, getLeafDscTree, getNameYobLeaf } from '../trees';
|
||||
import { SMT } from '@openpassport/zk-kit-smt';
|
||||
import {
|
||||
extractSignatureFromDSC,
|
||||
@@ -167,7 +167,9 @@ export function generateCircuitInputsVCandDisclose(
|
||||
selector_older_than: string | number,
|
||||
merkletree: LeanIMT,
|
||||
majority: string,
|
||||
name_smt: SMT,
|
||||
passportNo_smt: SMT,
|
||||
nameAndDob_smt: SMT,
|
||||
nameAndYob_smt: SMT,
|
||||
selector_ofac: string | number,
|
||||
forbidden_countries_list: string[],
|
||||
user_identifier: string
|
||||
@@ -199,13 +201,28 @@ export function generateCircuitInputsVCandDisclose(
|
||||
const formattedMajority = majority.length === 1 ? `0${majority}` : majority;
|
||||
const majority_ascii = formattedMajority.split('').map((char) => char.charCodeAt(0));
|
||||
|
||||
// SMT - OFAC
|
||||
const name_leaf = getNameLeaf(formattedMrz.slice(10, 49)); // [6-44] + 5 shift
|
||||
// SMT - OFAC
|
||||
const passportNo_leaf = getPassportNumberAndNationalityLeaf(formattedMrz.slice(49, 58), formattedMrz.slice(59, 62));
|
||||
const namedob_leaf = getNameDobLeaf(formattedMrz.slice(10, 49), formattedMrz.slice(62, 68)); // [57-62] + 5 shift
|
||||
const name_leaf = getNameYobLeaf(formattedMrz.slice(10, 49), formattedMrz.slice(62, 64));
|
||||
|
||||
const {
|
||||
root: smt_root,
|
||||
closestleaf: smt_leaf_key,
|
||||
siblings: smt_siblings,
|
||||
} = generateSMTProof(name_smt, name_leaf);
|
||||
root: passportNo_smt_root,
|
||||
closestleaf: passportNo_smt_leaf_key,
|
||||
siblings: passportNo_smt_siblings,
|
||||
} = generateSMTProof(passportNo_smt, passportNo_leaf);
|
||||
|
||||
const {
|
||||
root: nameAndDob_smt_root,
|
||||
closestleaf: nameAndDob_smt_leaf_key,
|
||||
siblings: nameAndDob_smt_siblings,
|
||||
} = generateSMTProof(nameAndDob_smt, namedob_leaf);
|
||||
|
||||
const {
|
||||
root: nameAndYob_smt_root,
|
||||
closestleaf: nameAndYob_smt_leaf_key,
|
||||
siblings: nameAndYob_smt_siblings,
|
||||
} = generateSMTProof(nameAndYob_smt, name_leaf);
|
||||
|
||||
return {
|
||||
secret: formatInput(secret),
|
||||
@@ -223,9 +240,15 @@ export function generateCircuitInputsVCandDisclose(
|
||||
current_date: formatInput(getCurrentDateYYMMDD()),
|
||||
majority: formatInput(majority_ascii),
|
||||
user_identifier: formatInput(castFromUUID(user_identifier)),
|
||||
smt_root: formatInput(smt_root),
|
||||
smt_leaf_key: formatInput(smt_leaf_key),
|
||||
smt_siblings: formatInput(smt_siblings),
|
||||
ofac_passportno_smt_root: formatInput(passportNo_smt_root),
|
||||
ofac_passportno_smt_leaf_key: formatInput(passportNo_smt_leaf_key),
|
||||
ofac_passportno_smt_siblings: formatInput(passportNo_smt_siblings),
|
||||
ofac_namedob_smt_root: formatInput(nameAndDob_smt_root),
|
||||
ofac_namedob_smt_leaf_key: formatInput(nameAndDob_smt_leaf_key),
|
||||
ofac_namedob_smt_siblings: formatInput(nameAndDob_smt_siblings),
|
||||
ofac_nameyob_smt_root: formatInput(nameAndYob_smt_root),
|
||||
ofac_nameyob_smt_leaf_key: formatInput(nameAndYob_smt_leaf_key),
|
||||
ofac_nameyob_smt_siblings: formatInput(nameAndYob_smt_siblings),
|
||||
selector_ofac: formatInput(selector_ofac),
|
||||
forbidden_countries_list: formatInput(formatCountriesList(forbidden_countries_list)),
|
||||
};
|
||||
@@ -237,9 +260,11 @@ export function generateCircuitInputsOfac(
|
||||
proofLevel: number
|
||||
) {
|
||||
const mrz_bytes = formatMrz(passportData.mrz);
|
||||
const passport_leaf = getPassportNumberLeaf(mrz_bytes.slice(49, 58));
|
||||
console.log('mrz_bytes', mrz_bytes);
|
||||
console.log('mrz_bytes.slice(59, 62)', mrz_bytes.slice(59, 62).map((byte) => String.fromCharCode(byte)));
|
||||
const passport_leaf = getPassportNumberAndNationalityLeaf(mrz_bytes.slice(49, 58), mrz_bytes.slice(59, 62));
|
||||
const namedob_leaf = getNameDobLeaf(mrz_bytes.slice(10, 49), mrz_bytes.slice(62, 68)); // [57-62] + 5 shift
|
||||
const name_leaf = getNameLeaf(mrz_bytes.slice(10, 49)); // [6-44] + 5 shift
|
||||
const name_leaf = getNameYobLeaf(mrz_bytes.slice(10, 49), mrz_bytes.slice(62, 64));
|
||||
|
||||
let root, closestleaf, siblings;
|
||||
if (proofLevel == 3) {
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
import {
|
||||
PROVE_RSA_NULLIFIER_INDEX,
|
||||
PROVE_RSA_REVEALED_DATA_PACKED_INDEX,
|
||||
PROVE_RSA_OLDER_THAN_INDEX,
|
||||
PROVE_RSA_PUBKEY_DISCLOSED_INDEX,
|
||||
PROVE_RSA_FORBIDDEN_COUNTRIES_LIST_PACKED_DISCLOSED_INDEX,
|
||||
PROVE_RSA_OFAC_RESULT_INDEX,
|
||||
PROVE_RSA_COMMITMENT_INDEX,
|
||||
PROVE_RSA_BLINDED_DSC_COMMITMENT_INDEX,
|
||||
PROVE_RSA_CURRENT_DATE_INDEX,
|
||||
PROVE_RSA_USER_IDENTIFIER_INDEX,
|
||||
PROVE_RSA_SCOPE_INDEX,
|
||||
DSC_BLINDED_DSC_COMMITMENT_INDEX,
|
||||
} from '../../../constants/contractConstants';
|
||||
import { Proof } from '../../types';
|
||||
|
||||
export function generateMockRSAProveVerifierInputs({
|
||||
nullifier = '1',
|
||||
revealedData_packed = ['2', '3', '4'],
|
||||
older_than = ['49', '56'],
|
||||
pubkey_disclosed = [
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
'0',
|
||||
],
|
||||
forbidden_contries_list_packed_disclose = ['8', '9'],
|
||||
ofac_result = '10',
|
||||
commitment = '11',
|
||||
blinded_dsc_commitment = '12',
|
||||
current_date = new Date(),
|
||||
user_identifier = '13',
|
||||
scope = '14',
|
||||
}: {
|
||||
nullifier?: string;
|
||||
revealedData_packed?: string[];
|
||||
older_than?: string[];
|
||||
pubkey_disclosed?: string[];
|
||||
forbidden_contries_list_packed_disclose?: string[];
|
||||
ofac_result?: string;
|
||||
commitment?: string;
|
||||
blinded_dsc_commitment?: string;
|
||||
current_date?: Date;
|
||||
user_identifier?: string;
|
||||
scope?: string;
|
||||
}): Proof {
|
||||
let pub_signals: string[] = [];
|
||||
|
||||
pub_signals[PROVE_RSA_NULLIFIER_INDEX] = nullifier;
|
||||
pub_signals.splice(PROVE_RSA_REVEALED_DATA_PACKED_INDEX, 0, ...revealedData_packed);
|
||||
pub_signals.splice(PROVE_RSA_OLDER_THAN_INDEX, 0, ...older_than);
|
||||
pub_signals.splice(PROVE_RSA_PUBKEY_DISCLOSED_INDEX, 0, ...pubkey_disclosed);
|
||||
pub_signals.splice(
|
||||
PROVE_RSA_FORBIDDEN_COUNTRIES_LIST_PACKED_DISCLOSED_INDEX,
|
||||
0,
|
||||
...forbidden_contries_list_packed_disclose
|
||||
);
|
||||
pub_signals[PROVE_RSA_OFAC_RESULT_INDEX] = ofac_result;
|
||||
pub_signals[PROVE_RSA_COMMITMENT_INDEX] = commitment;
|
||||
pub_signals[PROVE_RSA_BLINDED_DSC_COMMITMENT_INDEX] = blinded_dsc_commitment;
|
||||
pub_signals.splice(PROVE_RSA_CURRENT_DATE_INDEX, 0, ...getDateNum(current_date));
|
||||
pub_signals[PROVE_RSA_USER_IDENTIFIER_INDEX] = user_identifier;
|
||||
pub_signals[PROVE_RSA_SCOPE_INDEX] = scope;
|
||||
|
||||
let proof: Proof = {
|
||||
proof: {
|
||||
a: ['1', '1'],
|
||||
b: [
|
||||
['1', '2'],
|
||||
['3', '4'],
|
||||
],
|
||||
c: ['5', '6'],
|
||||
},
|
||||
pub_signals: pub_signals,
|
||||
};
|
||||
return proof;
|
||||
}
|
||||
|
||||
export function generateMockDSCVerifierInputs({
|
||||
blinded_dsc_commitment = '12',
|
||||
}: {
|
||||
blinded_dsc_commitment?: string;
|
||||
}): Proof {
|
||||
let pub_signals: string[] = [];
|
||||
|
||||
pub_signals[DSC_BLINDED_DSC_COMMITMENT_INDEX] = blinded_dsc_commitment;
|
||||
|
||||
let proof: Proof = {
|
||||
proof: {
|
||||
a: ['1', '1'],
|
||||
b: [
|
||||
['1', '2'],
|
||||
['3', '4'],
|
||||
],
|
||||
c: ['5', '6'],
|
||||
},
|
||||
pub_signals: pub_signals,
|
||||
};
|
||||
return proof;
|
||||
}
|
||||
|
||||
function getDateNum(date: Date = new Date()): string[] {
|
||||
const year = date.getUTCFullYear() % 100;
|
||||
const month = date.getUTCMonth() + 1;
|
||||
const day = date.getUTCDate();
|
||||
|
||||
const dateNum = [
|
||||
Math.floor(year / 10),
|
||||
year % 10,
|
||||
Math.floor(month / 10),
|
||||
month % 10,
|
||||
Math.floor(day / 10),
|
||||
day % 10,
|
||||
];
|
||||
|
||||
return dateNum.map((num) => num.toString());
|
||||
}
|
||||
|
||||
export function convertProofTypeIntoInput(proof: Proof) {
|
||||
return {
|
||||
a: proof.proof.a,
|
||||
b: proof.proof.b,
|
||||
c: proof.proof.c,
|
||||
pubSignals: proof.pub_signals,
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { poseidon9, poseidon3, poseidon2, poseidon6, poseidon13 } from 'poseidon-lite';
|
||||
import { poseidon9, poseidon3, poseidon2, poseidon6, poseidon13, poseidon12 } from 'poseidon-lite';
|
||||
import { ChildNodes, SMT } from '@openpassport/zk-kit-smt';
|
||||
import { stringToAsciiBigIntArray } from './circuits/uuid';
|
||||
import { LeanIMT } from '@openpassport/zk-kit-lean-imt';
|
||||
@@ -8,12 +8,15 @@ import {
|
||||
import { packBytesAndPoseidon } from './hash';
|
||||
import { DscCertificateMetaData, parseDscCertificateData } from './passports/passport_parsing/parseDscCertificateData';
|
||||
import { parseCertificateSimple } from './certificate_parsing/parseCertificateSimple';
|
||||
import { CSCA_TREE_DEPTH, DSC_TREE_DEPTH, max_csca_bytes } from '../constants/constants';
|
||||
import { CSCA_TREE_DEPTH, DSC_TREE_DEPTH, max_csca_bytes, OFAC_TREE_LEVELS } from '../constants/constants';
|
||||
import { max_dsc_bytes } from '../constants/constants';
|
||||
import serialized_csca_tree from '../../pubkeys/serialized_csca_tree.json';
|
||||
import serialized_dsc_tree from '../../pubkeys/serialized_dsc_tree.json';
|
||||
import { IMT } from '@openpassport/zk-kit-imt';
|
||||
import { pad } from './passports/passport';
|
||||
import countries from "i18n-iso-countries";
|
||||
import en from "i18n-iso-countries/langs/en.json";
|
||||
countries.registerLocale(en);
|
||||
|
||||
export async function fetchTreeFromUrl(url: string): Promise<LeanIMT> {
|
||||
const response = await fetch(url);
|
||||
@@ -75,6 +78,7 @@ export function getTreeInclusionProof(leaf: string, type: 'csca' | 'dsc') {
|
||||
throw new Error('Invalid tree type');
|
||||
}
|
||||
}
|
||||
|
||||
function getDscTreeInclusionProof(leaf: string): [string, number[], bigint[], number] {
|
||||
const hashFunction = (a: any, b: any) => poseidon2([a, b]);
|
||||
const tree = LeanIMT.import(hashFunction, serialized_dsc_tree);
|
||||
@@ -96,14 +100,13 @@ function getCscaTreeInclusionProof(leaf: string) {
|
||||
const proof = tree.createProof(index);
|
||||
return [tree.root, proof.pathIndices.map(index => index.toString()), proof.siblings.flat().map(sibling => sibling.toString())];
|
||||
}
|
||||
|
||||
export function getCscaTreeRoot() {
|
||||
let tree = new IMT(poseidon2, CSCA_TREE_DEPTH, 0, 2);
|
||||
tree.setNodes(serialized_csca_tree);
|
||||
return tree.root;
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function formatRoot(root: string): string {
|
||||
let rootHex = BigInt(root).toString(16);
|
||||
return rootHex.length % 2 === 0 ? '0x' + rootHex : '0x0' + rootHex;
|
||||
@@ -130,7 +133,7 @@ export function generateSMTProof(smt: SMT, leaf: bigint) {
|
||||
|
||||
// PATH, SIBLINGS manipulation as per binary tree in the circuit
|
||||
siblings.reverse();
|
||||
while (siblings.length < 256) siblings.push(BigInt(0));
|
||||
while (siblings.length < OFAC_TREE_LEVELS) siblings.push(BigInt(0));
|
||||
|
||||
// ----- Useful for debugging hence leaving as comments -----
|
||||
// const binary = entry[0].toString(2)
|
||||
@@ -178,13 +181,10 @@ export function generateMerkleProof(imt: LeanIMT, _index: number, maxleaf_depth:
|
||||
return { siblings, path, leaf_depth };
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// SMT trees for 3 levels :
|
||||
// 1. Passport tree : level 3 (Absolute Match)
|
||||
// 2. Names and dob combo tree : level 2 (High Probability Match)
|
||||
// 3. Names tree : level 1 (Partial Match)
|
||||
// SMT trees for 3 levels of matching :
|
||||
// 1. Passport Number and Nationality tree : level 3 (Absolute Match)
|
||||
// 2. Name and date of birth combo tree : level 2 (High Probability Match)
|
||||
// 3. Name and year of birth combo tree : level 1 (Partial Match)
|
||||
export function buildSMT(field: any[], treetype: string): [number, number, SMT] {
|
||||
let count = 0;
|
||||
let startTime = performance.now();
|
||||
@@ -201,12 +201,12 @@ export function buildSMT(field: any[], treetype: string): [number, number, SMT]
|
||||
}
|
||||
|
||||
let leaf = BigInt(0);
|
||||
if (treetype == 'passport') {
|
||||
leaf = processPassport(entry.Pass_No, i);
|
||||
} else if (treetype == 'name_dob') {
|
||||
leaf = processNameDob(entry, i);
|
||||
} else if (treetype == 'name') {
|
||||
leaf = processName(entry.First_Name, entry.Last_Name, i);
|
||||
if (treetype == 'passport_no_and_nationality') {
|
||||
leaf = processPassportNoAndNationality(entry.Pass_No, entry.Pass_Country, i);
|
||||
} else if (treetype == 'name_and_dob') {
|
||||
leaf = processNameAndDob(entry, i);
|
||||
} else if (treetype == 'name_and_yob') {
|
||||
leaf = processNameAndYob(entry, i);
|
||||
} else if (treetype == 'country') {
|
||||
const keys = Object.keys(entry);
|
||||
leaf = processCountry(keys[0], entry[keys[0]], i);
|
||||
@@ -226,24 +226,60 @@ export function buildSMT(field: any[], treetype: string): [number, number, SMT]
|
||||
return [count, performance.now() - startTime, tree];
|
||||
}
|
||||
|
||||
function processPassport(passno: string, index: number): bigint {
|
||||
function processPassportNoAndNationality(passno: string, nationality: string, index: number): bigint {
|
||||
if (passno.length > 9) {
|
||||
console.log('passport length is greater than 9:', index, passno);
|
||||
console.log('passport number length is greater than 9:', index, passno);
|
||||
} else if (passno.length < 9) {
|
||||
while (passno.length != 9) {
|
||||
passno += '<';
|
||||
}
|
||||
}
|
||||
|
||||
const leaf = getPassportNumberLeaf(stringToAsciiBigIntArray(passno));
|
||||
const countryCode = getCountryCode(nationality);
|
||||
if (!countryCode) {
|
||||
console.log('Error getting country code', index, nationality);
|
||||
return BigInt(0);
|
||||
}
|
||||
console.log('nationality and countryCode', nationality, countryCode);
|
||||
|
||||
const leaf = getPassportNumberAndNationalityLeaf(
|
||||
stringToAsciiBigIntArray(passno),
|
||||
stringToAsciiBigIntArray(countryCode),
|
||||
index
|
||||
);
|
||||
if (!leaf) {
|
||||
console.log('Error creating leaf value', index, passno);
|
||||
console.log('Error creating leaf value', index, passno, nationality);
|
||||
return BigInt(0);
|
||||
}
|
||||
return leaf;
|
||||
}
|
||||
|
||||
function processNameDob(entry: any, i: number): bigint {
|
||||
// this is a temporary workaround for some of the country name,
|
||||
// will be removed once we parse the OFAC list better, starting from the XML file.
|
||||
const normalizeCountryName = (country: string): string => {
|
||||
const mapping: Record<string, string> = {
|
||||
"palestinian": "Palestine",
|
||||
"korea, north": "North Korea",
|
||||
"korea, south": "Korea, Republic of",
|
||||
"united kingdom": "United Kingdom",
|
||||
"syria": "Syrian Arab Republic",
|
||||
"burma": "Myanmar",
|
||||
"cabo verde": "Cape Verde",
|
||||
"congo, democratic republic of the": "Democratic Republic of the Congo",
|
||||
"macau": "Macao",
|
||||
};
|
||||
return mapping[country.toLowerCase()] || country;
|
||||
};
|
||||
|
||||
const getCountryCode = (countryName: string): string | undefined => {
|
||||
return countries.getAlpha3Code(normalizeCountryName(countryName), "en");
|
||||
};
|
||||
|
||||
function generateSmallKey(input: bigint): bigint {
|
||||
return input % (BigInt(1) << BigInt(OFAC_TREE_LEVELS));
|
||||
}
|
||||
|
||||
function processNameAndDob(entry: any, i: number): bigint {
|
||||
const firstName = entry.First_Name;
|
||||
const lastName = entry.Last_Name;
|
||||
const day = entry.day;
|
||||
@@ -255,8 +291,30 @@ function processNameDob(entry: any, i: number): bigint {
|
||||
}
|
||||
const nameHash = processName(firstName, lastName, i);
|
||||
const dobHash = processDob(day, month, year, i);
|
||||
const leaf = poseidon2([dobHash, nameHash]);
|
||||
return leaf;
|
||||
return generateSmallKey(poseidon2([dobHash, nameHash]));
|
||||
}
|
||||
|
||||
function processNameAndYob(entry: any, i: number): bigint {
|
||||
const firstName = entry.First_Name;
|
||||
const lastName = entry.Last_Name;
|
||||
const year = entry.year;
|
||||
if (year == null) {
|
||||
console.log('year is null', i, entry);
|
||||
return BigInt(0);
|
||||
}
|
||||
const nameHash = processName(firstName, lastName, i);
|
||||
const yearHash = processYear(year, i);
|
||||
return generateSmallKey(poseidon2([yearHash, nameHash]));
|
||||
}
|
||||
|
||||
function processYear(year: string, i: number): bigint {
|
||||
year = year.slice(-2);
|
||||
const yearArr = stringToAsciiBigIntArray(year);
|
||||
return getYearLeaf(yearArr);
|
||||
}
|
||||
|
||||
function getYearLeaf(yearArr: (bigint | number)[]): bigint {
|
||||
return poseidon2(yearArr);
|
||||
}
|
||||
|
||||
function processName(firstName: string, lastName: string, i: number): bigint {
|
||||
@@ -337,13 +395,18 @@ export function getCountryLeaf(
|
||||
}
|
||||
}
|
||||
|
||||
export function getPassportNumberLeaf(passport: (bigint | number)[], i?: number): bigint {
|
||||
export function getPassportNumberAndNationalityLeaf(passport: (bigint | number)[], nationality: (bigint | number)[], i?: number): bigint {
|
||||
if (passport.length !== 9) {
|
||||
console.log('parsed passport length is not 9:', i, passport);
|
||||
return;
|
||||
}
|
||||
if (nationality.length !== 3) {
|
||||
console.log('parsed nationality length is not 3:', i, nationality);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
return poseidon9(passport);
|
||||
const fullHash = poseidon12(passport.concat(nationality));
|
||||
return generateSmallKey(fullHash);
|
||||
} catch (err) {
|
||||
console.log('err : passport', err, i, passport);
|
||||
}
|
||||
@@ -354,7 +417,15 @@ export function getNameDobLeaf(
|
||||
dobMrz: (bigint | number)[],
|
||||
i?: number
|
||||
): bigint {
|
||||
return poseidon2([getDobLeaf(dobMrz), getNameLeaf(nameMrz)]);
|
||||
return generateSmallKey(poseidon2([getDobLeaf(dobMrz), getNameLeaf(nameMrz)]));
|
||||
}
|
||||
|
||||
export function getNameYobLeaf(
|
||||
nameMrz: (bigint | number)[],
|
||||
yobMrz: (bigint | number)[],
|
||||
i?: number
|
||||
): bigint {
|
||||
return generateSmallKey(poseidon2([getYearLeaf(yobMrz), getNameLeaf(nameMrz)]));
|
||||
}
|
||||
|
||||
export function getNameLeaf(nameMrz: (bigint | number)[], i?: number): bigint {
|
||||
|
||||
@@ -782,6 +782,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"diacritics@npm:1.3.0":
|
||||
version: 1.3.0
|
||||
resolution: "diacritics@npm:1.3.0"
|
||||
checksum: 10c0/bc99c3d2e64315b1830f1573eafe1f7b06fd5dbc9687f35ea8e2e25ce8618d1444d0a2c8313b98467b0aff1d0ee35b8f9f67ef214e56e810b37da3cdb29785ac
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"diff@npm:^3.1.0":
|
||||
version: 3.5.0
|
||||
resolution: "diff@npm:3.5.0"
|
||||
@@ -1499,6 +1506,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"i18n-iso-countries@npm:^7.13.0":
|
||||
version: 7.13.0
|
||||
resolution: "i18n-iso-countries@npm:7.13.0"
|
||||
dependencies:
|
||||
diacritics: "npm:1.3.0"
|
||||
checksum: 10c0/7b9bb3d64e575857d7bcf0543fd86b50b9233689140c3e9b2dc9c125bbb71f0cbb800b9546a287ea6e9d745a3c446dc272db66863fa6d28b70add88cc0fa4fda
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"iconv-lite@npm:^0.6.2":
|
||||
version: 0.6.3
|
||||
resolution: "iconv-lite@npm:0.6.3"
|
||||
@@ -2397,6 +2413,7 @@ __metadata:
|
||||
country-iso-3-to-2: "npm:^1.1.1"
|
||||
elliptic: "npm:^6.5.5"
|
||||
fs: "npm:^0.0.1-security"
|
||||
i18n-iso-countries: "npm:^7.13.0"
|
||||
js-sha1: "npm:^0.7.0"
|
||||
js-sha256: "npm:^0.11.0"
|
||||
js-sha512: "npm:^0.9.0"
|
||||
|
||||
Reference in New Issue
Block a user