Feat/register input generation (#1657)

* feat: add helper function to generate register circuit inputs

* commit common
This commit is contained in:
Nesopie
2026-01-27 17:14:13 +05:30
committed by GitHub
parent 3f8bb75d9a
commit 9f7151be7a
5 changed files with 66 additions and 4 deletions

View File

@@ -3,7 +3,7 @@ import { wasm as wasmTester } from 'circom_tester';
import path from 'path';
import { packBytesAndPoseidon } from '@selfxyz/common/utils/hash';
import { poseidon2 } from 'poseidon-lite';
import { generateMockKycRegisterInput } from '@selfxyz/common/utils/kyc/generateInputs.js';
import { generateKycRegisterInput, generateMockKycRegisterInput } from '@selfxyz/common/utils/kyc/generateInputs.js';
import { KycRegisterInput } from '@selfxyz/common/utils/kyc/types';
import { KYC_ID_NUMBER_INDEX, KYC_ID_NUMBER_LENGTH, KYC_ID_TYPE_INDEX, KYC_ID_TYPE_LENGTH } from '@selfxyz/common/utils/kyc/constants';

View File

@@ -138,6 +138,7 @@ export {
generateMockKycRegisterInput,
NON_OFAC_DUMMY_INPUT,
OFAC_DUMMY_INPUT,
generateKycRegisterInput,
} from './src/utils/kyc/generateInputs.js';
export {

View File

@@ -0,0 +1,40 @@
//Helper function to destructure the kyc data from the api response
import { Point } from "@zk-kit/baby-jubjub";
import { KYC_ADDRESS_INDEX, KYC_ADDRESS_LENGTH, KYC_COUNTRY_INDEX, KYC_COUNTRY_LENGTH, KYC_DOB_INDEX, KYC_DOB_LENGTH, KYC_EXPIRY_DATE_INDEX, KYC_EXPIRY_DATE_LENGTH, KYC_FULL_NAME_INDEX, KYC_FULL_NAME_LENGTH, KYC_GENDER_INDEX, KYC_GENDER_LENGTH, KYC_ID_NUMBER_INDEX, KYC_ID_NUMBER_LENGTH, KYC_ID_TYPE_INDEX, KYC_ID_TYPE_LENGTH, KYC_ISSUANCE_DATE_INDEX, KYC_ISSUANCE_DATE_LENGTH, KYC_PHONE_NUMBER_INDEX, KYC_PHONE_NUMBER_LENGTH, KYC_PHOTO_HASH_INDEX, KYC_PHOTO_HASH_LENGTH } from "./constants.js";
import { KycData } from "./types.js";
//accepts a base64 signature and returns a signature object
export function deserializeSignature(signature: string): { R: Point<bigint>; s: bigint} {
const [Rx, Ry, s] = Buffer.from(signature, 'base64').toString('utf-8').split(',').map(BigInt);
return { R: [Rx, Ry] as Point<bigint>, s };
}
//accepts a base64 applicant info and returns a kyc data object
export function deserializeApplicantInfo(applicantInfoBase64: string): Omit<KycData, 'user_identifier' | 'current_date' | 'majority_age_ASCII' | 'selector_older_than'> {
const applicantInfo = Buffer.from(applicantInfoBase64, 'base64').toString('utf-8');
const country = applicantInfo.slice(KYC_COUNTRY_INDEX, KYC_COUNTRY_INDEX + KYC_COUNTRY_LENGTH).replace(/\x00/g, '');
const idType = applicantInfo.slice(KYC_ID_TYPE_INDEX, KYC_ID_TYPE_INDEX + KYC_ID_TYPE_LENGTH).replace(/\x00/g, '');
const idNumber = applicantInfo.slice(KYC_ID_NUMBER_INDEX, KYC_ID_NUMBER_INDEX + KYC_ID_NUMBER_LENGTH).replace(/\x00/g, '');
const issuanceDate = applicantInfo.slice(KYC_ISSUANCE_DATE_INDEX, KYC_ISSUANCE_DATE_INDEX + KYC_ISSUANCE_DATE_LENGTH).replace(/\x00/g, '');
const expiryDate = applicantInfo.slice(KYC_EXPIRY_DATE_INDEX, KYC_EXPIRY_DATE_INDEX + KYC_EXPIRY_DATE_LENGTH).replace(/\x00/g, '');
const fullName = applicantInfo.slice(KYC_FULL_NAME_INDEX, KYC_FULL_NAME_INDEX + KYC_FULL_NAME_LENGTH).replace(/\x00/g, '');
const dob = applicantInfo.slice(KYC_DOB_INDEX, KYC_DOB_INDEX + KYC_DOB_LENGTH).replace(/\x00/g, '');
const photoHash = applicantInfo.slice(KYC_PHOTO_HASH_INDEX, KYC_PHOTO_HASH_INDEX + KYC_PHOTO_HASH_LENGTH).replace(/\x00/g, '');
const phoneNumber = applicantInfo.slice(KYC_PHONE_NUMBER_INDEX, KYC_PHONE_NUMBER_INDEX + KYC_PHONE_NUMBER_LENGTH).replace(/\x00/g, '');
const gender = applicantInfo.slice(KYC_GENDER_INDEX, KYC_GENDER_INDEX + KYC_GENDER_LENGTH).replace(/\x00/g, '');
const address = applicantInfo.slice(KYC_ADDRESS_INDEX, KYC_ADDRESS_INDEX + KYC_ADDRESS_LENGTH).replace(/\x00/g, '');
return {
country,
idType,
idNumber,
issuanceDate,
expiryDate,
fullName,
dob,
photoHash,
phoneNumber,
gender,
address
};
}

View File

@@ -14,6 +14,7 @@ import { signEdDSA } from './ecdsa/ecdsa.js';
import { LeanIMT } from '@openpassport/zk-kit-lean-imt';
import { packBytesAndPoseidon } from '../hash.js';
import { COMMITMENT_TREE_DEPTH } from '../../constants/constants.js';
import { deserializeApplicantInfo, deserializeSignature } from './api.js';
export const OFAC_DUMMY_INPUT: KycData = {
country: 'KEN',
@@ -86,6 +87,26 @@ export const generateMockKycRegisterInput = async (
return kycRegisterInput;
};
export const generateKycRegisterInput = async (applicantInfoBase64: string, signatureBase64: string, pubkeyStr: [string, string], secret: string) => {
const applicantInfo = deserializeApplicantInfo(applicantInfoBase64);
const signature = deserializeSignature(signatureBase64);
const pubkey = [BigInt(pubkeyStr[0]), BigInt(pubkeyStr[1])] as [bigint, bigint];
const serializedData = serializeKycData(applicantInfo);
const msgPadded = Array.from(serializedData, (x) => x.charCodeAt(0));
const kycRegisterInput: KycRegisterInput = {
data_padded: msgPadded.map((x) => Number(x)),
s: signature.s,
R: signature.R,
pubKey: pubkey,
secret,
};
return kycRegisterInput;
}
export const generateCircuitInputsOfac = (data: KycData, smt: SMT, proofLevel: number) => {
const name = data.fullName;
const dob = data.dob;

View File

@@ -19,11 +19,11 @@ export type KycData = {
selector_older_than: string;
};
export const serializeKycData = (kycData: KycData) => {
export const serializeKycData = (kycData: Omit<KycData, 'user_identifier' | 'current_date' | 'majority_age_ASCII' | 'selector_older_than'>) => {
//ensure max length of each field
let serializedData = '';
serializedData += kycData.country.toUpperCase().padEnd(constants.KYC_COUNTRY_LENGTH, '\0');
serializedData += kycData.idType.toUpperCase().padEnd(constants.KYC_ID_TYPE_LENGTH, '\0');
serializedData += kycData.country.padEnd(constants.KYC_COUNTRY_LENGTH, '\0');
serializedData += kycData.idType.padEnd(constants.KYC_ID_TYPE_LENGTH, '\0');
serializedData += kycData.idNumber.padEnd(constants.KYC_ID_NUMBER_LENGTH, '\0');
serializedData += kycData.issuanceDate.padEnd(constants.KYC_ISSUANCE_DATE_LENGTH, '\0');
serializedData += kycData.expiryDate.padEnd(constants.KYC_EXPIRY_DATE_LENGTH, '\0');