mirror of
https://github.com/selfxyz/self.git
synced 2026-04-05 03:00:53 -04:00
fix app imports
This commit is contained in:
@@ -72,6 +72,12 @@ export const attributeToPosition = {
|
||||
older_than: [88, 89]
|
||||
};
|
||||
|
||||
export const circuitToSelectorMode = {
|
||||
'register': [0, 0],
|
||||
'prove_onchain': [1, 0],
|
||||
'prove_offchain': [1, 1],
|
||||
}
|
||||
|
||||
export const MAX_DATAHASHES_LEN = 320; // max formatted and concatenated datagroup hashes length in bytes
|
||||
export const n_dsc = 64;
|
||||
export const k_dsc = 32;
|
||||
|
||||
@@ -1,89 +1,265 @@
|
||||
import {
|
||||
ECDSA_K_LENGTH_FACTOR,
|
||||
k_dsc,
|
||||
k_dsc_ecdsa,
|
||||
} from '../constants/constants';
|
||||
import { parseDSC } from './certificates/handleCertificate';
|
||||
import {
|
||||
bigIntToHex,
|
||||
castToScope,
|
||||
castToUUID,
|
||||
UserIdType,
|
||||
} from './utils';
|
||||
import { unpackReveal } from './revealBitmap';
|
||||
import { getAttributeFromUnpackedReveal } from '../../../sdk/utils/utils';
|
||||
|
||||
export interface OpenPassportAttestation {
|
||||
'@context': string[];
|
||||
type: string[];
|
||||
issuer: string;
|
||||
issuanceDate: string;
|
||||
credentialSubject: {
|
||||
userId: string;
|
||||
application: string;
|
||||
scope?: string;
|
||||
merkle_root?: string;
|
||||
attestation_id?: string;
|
||||
current_date?: string;
|
||||
issuing_state?: string;
|
||||
name?: string;
|
||||
passport_number?: string;
|
||||
nationality?: string;
|
||||
date_of_birth?: string;
|
||||
gender?: string;
|
||||
expiry_date?: string;
|
||||
older_than?: string;
|
||||
owner_of?: string;
|
||||
pubKey?: string[];
|
||||
valid?: boolean;
|
||||
nullifier?: string;
|
||||
ECDSA_K_LENGTH_FACTOR,
|
||||
k_dsc,
|
||||
k_dsc_ecdsa,
|
||||
} from '../constants/constants';
|
||||
import { parseDSC } from './certificates/handleCertificate';
|
||||
import {
|
||||
bigIntToHex,
|
||||
castToScope,
|
||||
castToUUID,
|
||||
UserIdType,
|
||||
} from './utils';
|
||||
import { unpackReveal } from './revealBitmap';
|
||||
import { getAttributeFromUnpackedReveal } from './utils'
|
||||
|
||||
export interface OpenPassportAttestation {
|
||||
'@context': string[];
|
||||
type: string[];
|
||||
issuer: string;
|
||||
issuanceDate: string;
|
||||
credentialSubject: {
|
||||
userId: string;
|
||||
application: string;
|
||||
scope?: string;
|
||||
merkle_root?: string;
|
||||
attestation_id?: string;
|
||||
current_date?: string;
|
||||
issuing_state?: string;
|
||||
name?: string;
|
||||
passport_number?: string;
|
||||
nationality?: string;
|
||||
date_of_birth?: string;
|
||||
gender?: string;
|
||||
expiry_date?: string;
|
||||
older_than?: string;
|
||||
owner_of?: string;
|
||||
pubKey?: string[];
|
||||
valid?: boolean;
|
||||
nullifier?: string;
|
||||
};
|
||||
proof: {
|
||||
type: string;
|
||||
verificationMethod: string;
|
||||
value: {
|
||||
proof: string[];
|
||||
publicSignals: string[];
|
||||
};
|
||||
proof: {
|
||||
type: string;
|
||||
verificationMethod: string;
|
||||
value: {
|
||||
proof: string[];
|
||||
publicSignals: string[];
|
||||
};
|
||||
vkey: string;
|
||||
};
|
||||
dscProof: {
|
||||
type: string;
|
||||
verificationMethod: string;
|
||||
value: {
|
||||
proof: string[];
|
||||
publicSignals: string[];
|
||||
};
|
||||
vkey: string;
|
||||
};
|
||||
dsc: {
|
||||
type: string;
|
||||
value: string;
|
||||
encoding: string;
|
||||
vkey: string;
|
||||
};
|
||||
dscProof: {
|
||||
type: string;
|
||||
verificationMethod: string;
|
||||
value: {
|
||||
proof: string[];
|
||||
publicSignals: string[];
|
||||
};
|
||||
vkey: string;
|
||||
};
|
||||
dsc: {
|
||||
type: string;
|
||||
value: string;
|
||||
encoding: string;
|
||||
};
|
||||
}
|
||||
|
||||
export function buildAttestation(options: {
|
||||
proof: string[];
|
||||
publicSignals: string[];
|
||||
dscProof?: string[];
|
||||
dscPublicSignals?: string[];
|
||||
dsc: string;
|
||||
userIdType?: UserIdType;
|
||||
}): OpenPassportDynamicAttestation {
|
||||
const {
|
||||
proof,
|
||||
publicSignals,
|
||||
dscProof,
|
||||
dscPublicSignals,
|
||||
dsc,
|
||||
userIdType = 'uuid',
|
||||
} = options;
|
||||
|
||||
// Parse the DSC (Document Signing Certificate)
|
||||
const dscParsed = parseDSC(dsc);
|
||||
|
||||
// Determine the scaling factor based on the signature algorithm
|
||||
let kScaled: number;
|
||||
const { signatureAlgorithm } = dscParsed;
|
||||
switch (signatureAlgorithm) {
|
||||
case 'ecdsa':
|
||||
kScaled = ECDSA_K_LENGTH_FACTOR * k_dsc_ecdsa;
|
||||
break;
|
||||
default:
|
||||
kScaled = k_dsc;
|
||||
}
|
||||
|
||||
export function buildAttestation(options: {
|
||||
proof: string[];
|
||||
publicSignals: string[];
|
||||
dscProof?: string[];
|
||||
dscPublicSignals?: string[];
|
||||
dsc: string;
|
||||
userIdType?: UserIdType;
|
||||
}): OpenPassportDynamicAttestation {
|
||||
const {
|
||||
proof,
|
||||
publicSignals,
|
||||
dscProof,
|
||||
dscPublicSignals,
|
||||
dsc,
|
||||
userIdType = 'uuid',
|
||||
} = options;
|
||||
|
||||
// Parse the DSC (Document Signing Certificate)
|
||||
const dscParsed = parseDSC(dsc);
|
||||
|
||||
// Determine the scaling factor based on the signature algorithm
|
||||
|
||||
// Parse the public signals
|
||||
const parsedPublicSignals = parsePublicSignalsProve(publicSignals, kScaled);
|
||||
|
||||
// Get user identifier
|
||||
const rawUserId = parsedPublicSignals.user_identifier;
|
||||
let userId: string;
|
||||
switch (userIdType) {
|
||||
case 'ascii':
|
||||
userId = castToScope(BigInt(rawUserId));
|
||||
break;
|
||||
case 'hex':
|
||||
userId = bigIntToHex(BigInt(rawUserId));
|
||||
break;
|
||||
case 'uuid':
|
||||
userId = castToUUID(BigInt(rawUserId));
|
||||
break;
|
||||
default:
|
||||
userId = rawUserId;
|
||||
}
|
||||
|
||||
const scope = castToScope(BigInt(parsedPublicSignals.scope));
|
||||
|
||||
// Unpack the revealed data
|
||||
const unpackedReveal = unpackReveal(
|
||||
parsedPublicSignals.revealedData_packed
|
||||
);
|
||||
|
||||
// Extract attributes from unpackedReveal
|
||||
const attributeNames = [
|
||||
'issuing_state',
|
||||
'name',
|
||||
'passport_number',
|
||||
'nationality',
|
||||
'date_of_birth',
|
||||
'gender',
|
||||
'expiry_date',
|
||||
'older_than',
|
||||
'owner_of',
|
||||
];
|
||||
|
||||
const credentialSubject: any = {
|
||||
userId: userId,
|
||||
application: scope,
|
||||
nullifier: bigIntToHex(BigInt(parsedPublicSignals.nullifier)),
|
||||
scope: scope,
|
||||
current_date: parsedPublicSignals.current_date.toString(),
|
||||
};
|
||||
|
||||
attributeNames.forEach((attrName) => {
|
||||
const value = getAttributeFromUnpackedReveal(unpackedReveal, attrName);
|
||||
if (value !== undefined && value !== null) {
|
||||
credentialSubject[attrName] = value;
|
||||
}
|
||||
});
|
||||
|
||||
// Include pubKey if needed
|
||||
credentialSubject.pubKey = parsedPublicSignals.pubKey_disclosed;
|
||||
|
||||
const attestation: OpenPassportAttestation = {
|
||||
'@context': [
|
||||
'https://www.w3.org/2018/credentials/v1',
|
||||
'https://openpassport.app',
|
||||
],
|
||||
type: ['OpenPassportAttestation', 'PassportCredential'],
|
||||
issuer: 'https://openpassport.app',
|
||||
issuanceDate: new Date().toISOString(),
|
||||
credentialSubject: credentialSubject,
|
||||
proof: {
|
||||
type: 'ZeroKnowledgeProof',
|
||||
verificationMethod:
|
||||
'https://github.com/zk-passport/openpassport',
|
||||
value: {
|
||||
proof: proof,
|
||||
publicSignals: publicSignals,
|
||||
},
|
||||
vkey: '',
|
||||
},
|
||||
dscProof: {
|
||||
type: 'ZeroKnowledgeProof',
|
||||
verificationMethod:
|
||||
'https://github.com/zk-passport/openpassport',
|
||||
value: {
|
||||
proof: dscProof || [],
|
||||
publicSignals: dscPublicSignals || [],
|
||||
},
|
||||
vkey: '',
|
||||
},
|
||||
dsc: {
|
||||
type: 'X509Certificate',
|
||||
value: dsc || '',
|
||||
encoding: 'PEM',
|
||||
},
|
||||
};
|
||||
|
||||
// Return an instance of OpenPassportDynamicAttestation
|
||||
return new OpenPassportDynamicAttestation(attestation, userIdType);
|
||||
}
|
||||
// New OpenPassportDynamicAttestation class extending OpenPassportAttestation
|
||||
export class OpenPassportDynamicAttestation implements OpenPassportAttestation {
|
||||
'@context': string[];
|
||||
type: string[];
|
||||
issuer: string;
|
||||
issuanceDate: string;
|
||||
credentialSubject: {
|
||||
userId: string;
|
||||
application: string;
|
||||
scope?: string;
|
||||
merkle_root?: string;
|
||||
attestation_id?: string;
|
||||
current_date?: string;
|
||||
issuing_state?: string;
|
||||
name?: string;
|
||||
passport_number?: string;
|
||||
nationality?: string;
|
||||
date_of_birth?: string;
|
||||
gender?: string;
|
||||
expiry_date?: string;
|
||||
older_than?: string;
|
||||
owner_of?: string;
|
||||
pubKey?: string[];
|
||||
valid?: boolean;
|
||||
nullifier?: string;
|
||||
};
|
||||
proof: {
|
||||
type: string;
|
||||
verificationMethod: string;
|
||||
value: {
|
||||
proof: string[];
|
||||
publicSignals: string[];
|
||||
};
|
||||
vkey;
|
||||
};
|
||||
dscProof: {
|
||||
type: string;
|
||||
verificationMethod: string;
|
||||
value: {
|
||||
proof: string[];
|
||||
publicSignals: string[];
|
||||
};
|
||||
vkey;
|
||||
};
|
||||
dsc: {
|
||||
type: string;
|
||||
value: string;
|
||||
encoding: string;
|
||||
};
|
||||
|
||||
private parsedPublicSignals: any;
|
||||
private userIdType: UserIdType;
|
||||
|
||||
constructor(attestation: OpenPassportAttestation, userIdType: UserIdType = 'uuid') {
|
||||
this['@context'] = attestation['@context'];
|
||||
this.type = attestation.type;
|
||||
this.issuer = attestation.issuer;
|
||||
this.issuanceDate = attestation.issuanceDate;
|
||||
this.credentialSubject = attestation.credentialSubject;
|
||||
this.proof = attestation.proof;
|
||||
this.dscProof = attestation.dscProof;
|
||||
this.dsc = attestation.dsc;
|
||||
this.userIdType = userIdType;
|
||||
this.parsedPublicSignals = this.parsePublicSignals();
|
||||
}
|
||||
|
||||
private parsePublicSignals() {
|
||||
const dscParsed = parseDSC(this.dsc.value);
|
||||
|
||||
let kScaled: number;
|
||||
const { signatureAlgorithm } = dscParsed;
|
||||
switch (signatureAlgorithm) {
|
||||
@@ -93,216 +269,42 @@ import {
|
||||
default:
|
||||
kScaled = k_dsc;
|
||||
}
|
||||
|
||||
|
||||
// Parse the public signals
|
||||
const parsedPublicSignals = parsePublicSignalsProve(publicSignals, kScaled);
|
||||
|
||||
// Get user identifier
|
||||
const rawUserId = parsedPublicSignals.user_identifier;
|
||||
let userId: string;
|
||||
switch (userIdType) {
|
||||
case 'ascii':
|
||||
userId = castToScope(BigInt(rawUserId));
|
||||
break;
|
||||
case 'hex':
|
||||
userId = bigIntToHex(BigInt(rawUserId));
|
||||
break;
|
||||
case 'uuid':
|
||||
userId = castToUUID(BigInt(rawUserId));
|
||||
break;
|
||||
default:
|
||||
userId = rawUserId;
|
||||
}
|
||||
|
||||
const scope = castToScope(BigInt(parsedPublicSignals.scope));
|
||||
|
||||
// Unpack the revealed data
|
||||
const unpackedReveal = unpackReveal(
|
||||
parsedPublicSignals.revealedData_packed
|
||||
);
|
||||
|
||||
// Extract attributes from unpackedReveal
|
||||
const attributeNames = [
|
||||
'issuing_state',
|
||||
'name',
|
||||
'passport_number',
|
||||
'nationality',
|
||||
'date_of_birth',
|
||||
'gender',
|
||||
'expiry_date',
|
||||
'older_than',
|
||||
'owner_of',
|
||||
];
|
||||
|
||||
const credentialSubject: any = {
|
||||
userId: userId,
|
||||
application: scope,
|
||||
nullifier: bigIntToHex(BigInt(parsedPublicSignals.nullifier)),
|
||||
scope: scope,
|
||||
current_date: parsedPublicSignals.current_date.toString(),
|
||||
};
|
||||
|
||||
attributeNames.forEach((attrName) => {
|
||||
const value = getAttributeFromUnpackedReveal(unpackedReveal, attrName);
|
||||
if (value !== undefined && value !== null) {
|
||||
credentialSubject[attrName] = value;
|
||||
}
|
||||
});
|
||||
|
||||
// Include pubKey if needed
|
||||
credentialSubject.pubKey = parsedPublicSignals.pubKey_disclosed;
|
||||
|
||||
const attestation: OpenPassportAttestation = {
|
||||
'@context': [
|
||||
'https://www.w3.org/2018/credentials/v1',
|
||||
'https://openpassport.app',
|
||||
],
|
||||
type: ['OpenPassportAttestation', 'PassportCredential'],
|
||||
issuer: 'https://openpassport.app',
|
||||
issuanceDate: new Date().toISOString(),
|
||||
credentialSubject: credentialSubject,
|
||||
proof: {
|
||||
type: 'ZeroKnowledgeProof',
|
||||
verificationMethod:
|
||||
'https://github.com/zk-passport/openpassport',
|
||||
value: {
|
||||
proof: proof,
|
||||
publicSignals: publicSignals,
|
||||
},
|
||||
vkey: '',
|
||||
},
|
||||
dscProof: {
|
||||
type: 'ZeroKnowledgeProof',
|
||||
verificationMethod:
|
||||
'https://github.com/zk-passport/openpassport',
|
||||
value: {
|
||||
proof: dscProof || [],
|
||||
publicSignals: dscPublicSignals || [],
|
||||
},
|
||||
vkey: '',
|
||||
},
|
||||
dsc: {
|
||||
type: 'X509Certificate',
|
||||
value: dsc || '',
|
||||
encoding: 'PEM',
|
||||
},
|
||||
};
|
||||
|
||||
// Return an instance of OpenPassportDynamicAttestation
|
||||
return new OpenPassportDynamicAttestation(attestation, userIdType);
|
||||
return parsePublicSignalsProve(this.proof.value.publicSignals, kScaled);
|
||||
}
|
||||
// New OpenPassportDynamicAttestation class extending OpenPassportAttestation
|
||||
export class OpenPassportDynamicAttestation implements OpenPassportAttestation {
|
||||
'@context': string[];
|
||||
type: string[];
|
||||
issuer: string;
|
||||
issuanceDate: string;
|
||||
credentialSubject: {
|
||||
userId: string;
|
||||
application: string;
|
||||
scope?: string;
|
||||
merkle_root?: string;
|
||||
attestation_id?: string;
|
||||
current_date?: string;
|
||||
issuing_state?: string;
|
||||
name?: string;
|
||||
passport_number?: string;
|
||||
nationality?: string;
|
||||
date_of_birth?: string;
|
||||
gender?: string;
|
||||
expiry_date?: string;
|
||||
older_than?: string;
|
||||
owner_of?: string;
|
||||
pubKey?: string[];
|
||||
valid?: boolean;
|
||||
nullifier?: string;
|
||||
};
|
||||
proof: {
|
||||
type: string;
|
||||
verificationMethod: string;
|
||||
value: {
|
||||
proof: string[];
|
||||
publicSignals: string[];
|
||||
};
|
||||
vkey;
|
||||
};
|
||||
dscProof: {
|
||||
type: string;
|
||||
verificationMethod: string;
|
||||
value: {
|
||||
proof: string[];
|
||||
publicSignals: string[];
|
||||
};
|
||||
vkey;
|
||||
};
|
||||
dsc: {
|
||||
type: string;
|
||||
value: string;
|
||||
encoding: string;
|
||||
};
|
||||
|
||||
private parsedPublicSignals: any;
|
||||
private userIdType: UserIdType;
|
||||
|
||||
constructor(attestation: OpenPassportAttestation, userIdType: UserIdType = 'uuid') {
|
||||
this['@context'] = attestation['@context'];
|
||||
this.type = attestation.type;
|
||||
this.issuer = attestation.issuer;
|
||||
this.issuanceDate = attestation.issuanceDate;
|
||||
this.credentialSubject = attestation.credentialSubject;
|
||||
this.proof = attestation.proof;
|
||||
this.dscProof = attestation.dscProof;
|
||||
this.dsc = attestation.dsc;
|
||||
this.userIdType = userIdType;
|
||||
this.parsedPublicSignals = this.parsePublicSignals();
|
||||
getUserId(): string {
|
||||
const rawUserId = (this.parsedPublicSignals as any).user_identifier;
|
||||
switch (this.userIdType) {
|
||||
case 'ascii':
|
||||
return castToScope(BigInt(rawUserId));
|
||||
case 'hex':
|
||||
return bigIntToHex(BigInt(rawUserId));
|
||||
case 'uuid':
|
||||
return castToUUID(BigInt(rawUserId));
|
||||
default:
|
||||
return rawUserId;
|
||||
}
|
||||
}
|
||||
|
||||
private parsePublicSignals() {
|
||||
const dscParsed = parseDSC(this.dsc.value);
|
||||
|
||||
let kScaled: number;
|
||||
const { signatureAlgorithm } = dscParsed;
|
||||
switch (signatureAlgorithm) {
|
||||
case 'ecdsa':
|
||||
kScaled = ECDSA_K_LENGTH_FACTOR * k_dsc_ecdsa;
|
||||
break;
|
||||
default:
|
||||
kScaled = k_dsc;
|
||||
}
|
||||
|
||||
// Parse the public signals
|
||||
return parsePublicSignalsProve(this.proof.value.publicSignals, kScaled);
|
||||
}
|
||||
|
||||
getUserId(): string {
|
||||
const rawUserId = (this.parsedPublicSignals as any).user_identifier;
|
||||
switch (this.userIdType) {
|
||||
case 'ascii':
|
||||
return castToScope(BigInt(rawUserId));
|
||||
case 'hex':
|
||||
return bigIntToHex(BigInt(rawUserId));
|
||||
case 'uuid':
|
||||
return castToUUID(BigInt(rawUserId));
|
||||
default:
|
||||
return rawUserId;
|
||||
}
|
||||
}
|
||||
|
||||
getNullifier(): string {
|
||||
return bigIntToHex(BigInt(this.parsedPublicSignals.nullifier));
|
||||
}
|
||||
getNullifier(): string {
|
||||
return bigIntToHex(BigInt(this.parsedPublicSignals.nullifier));
|
||||
}
|
||||
}
|
||||
|
||||
export function parsePublicSignalsProve(publicSignals, kScaled) {
|
||||
return {
|
||||
nullifier: publicSignals[0],
|
||||
revealedData_packed: [publicSignals[1], publicSignals[2], publicSignals[3]],
|
||||
older_than: [publicSignals[4], publicSignals[5]],
|
||||
pubKey_disclosed: publicSignals.slice(6, 6 + kScaled),
|
||||
commitment: publicSignals[6 + kScaled],
|
||||
blinded_dsc_commitment: publicSignals[7 + kScaled],
|
||||
current_date: publicSignals.slice(8 + kScaled, 8 + kScaled + 6),
|
||||
user_identifier: publicSignals[8 + kScaled + 6],
|
||||
scope: publicSignals[9 + kScaled + 6],
|
||||
};
|
||||
return {
|
||||
nullifier: publicSignals[0],
|
||||
revealedData_packed: [publicSignals[1], publicSignals[2], publicSignals[3]],
|
||||
older_than: [publicSignals[4], publicSignals[5]],
|
||||
pubKey_disclosed: publicSignals.slice(6, 6 + kScaled),
|
||||
forbidden_countries_list_packed_disclosed: publicSignals.slice(6 + kScaled, 6 + kScaled + 2),
|
||||
ofac_result: publicSignals[8 + kScaled],
|
||||
commitment: publicSignals[9 + kScaled],
|
||||
blinded_dsc_commitment: publicSignals[10 + kScaled],
|
||||
current_date: publicSignals.slice(11 + kScaled, 11 + kScaled + 6),
|
||||
user_identifier: publicSignals[12 + kScaled + 6],
|
||||
scope: publicSignals[13 + kScaled + 6],
|
||||
};
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import { sha1 } from 'js-sha1';
|
||||
import { sha384, sha512_256 } from 'js-sha512';
|
||||
import { SMT } from '@ashpect/smt';
|
||||
import forge from 'node-forge';
|
||||
import { n_dsc, k_dsc, n_dsc_ecdsa, k_dsc_ecdsa, n_csca, k_csca } from '../constants/constants';
|
||||
import { n_dsc, k_dsc, n_dsc_ecdsa, k_dsc_ecdsa, n_csca, k_csca, attributeToPosition } from '../constants/constants';
|
||||
|
||||
export function formatMrz(mrz: string) {
|
||||
const mrzCharcodes = [...mrz].map((char) => char.charCodeAt(0));
|
||||
@@ -548,3 +548,13 @@ export function formatCountriesList(countries: string[]) {
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
export function getAttributeFromUnpackedReveal(unpackedReveal: string[], attribute: string) {
|
||||
const position = attributeToPosition[attribute];
|
||||
let attributeValue = '';
|
||||
for (let i = position[0]; i <= position[1]; i++) {
|
||||
attributeValue += unpackedReveal[i];
|
||||
}
|
||||
return attributeValue;
|
||||
}
|
||||
Reference in New Issue
Block a user