mirror of
https://github.com/selfxyz/self.git
synced 2026-04-05 03:00:53 -04:00
yarn format
This commit is contained in:
@@ -81,4 +81,4 @@
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
import { groth16 } from 'snarkjs';
|
||||
import {
|
||||
n_dsc,
|
||||
k_dsc,
|
||||
ECDSA_K_LENGTH_FACTOR,
|
||||
k_dsc_ecdsa,
|
||||
circuitNameFromMode,
|
||||
countryNames,
|
||||
countryCodes,
|
||||
n_dsc,
|
||||
k_dsc,
|
||||
ECDSA_K_LENGTH_FACTOR,
|
||||
k_dsc_ecdsa,
|
||||
circuitNameFromMode,
|
||||
countryNames,
|
||||
countryCodes,
|
||||
} from '../../common/src/constants/constants';
|
||||
import {
|
||||
areArraysEqual,
|
||||
getCurrentDateFormatted,
|
||||
getVkeyFromArtifacts,
|
||||
verifyDSCValidity,
|
||||
areArraysEqual,
|
||||
getCurrentDateFormatted,
|
||||
getVkeyFromArtifacts,
|
||||
verifyDSCValidity,
|
||||
} from '../utils/utils';
|
||||
import {
|
||||
OpenPassportAttestation,
|
||||
parsePublicSignalsDisclose
|
||||
OpenPassportAttestation,
|
||||
parsePublicSignalsDisclose,
|
||||
} from '../../common/src/utils/openPassportAttestation';
|
||||
import {
|
||||
parsePublicSignalsDsc,
|
||||
parsePublicSignalsProve,
|
||||
parsePublicSignalsDsc,
|
||||
parsePublicSignalsProve,
|
||||
} from '../../common/src/utils/openPassportAttestation';
|
||||
import { Mode } from 'fs';
|
||||
import forge from 'node-forge';
|
||||
import { parseCertificate } from '../../common/src/utils/certificates/handleCertificate';
|
||||
import {
|
||||
castToScope,
|
||||
formatForbiddenCountriesListFromCircuitOutput,
|
||||
getAttributeFromUnpackedReveal,
|
||||
getOlderThanFromCircuitOutput,
|
||||
splitToWords,
|
||||
castToScope,
|
||||
formatForbiddenCountriesListFromCircuitOutput,
|
||||
getAttributeFromUnpackedReveal,
|
||||
getOlderThanFromCircuitOutput,
|
||||
splitToWords,
|
||||
} from '../../common/src/utils/utils';
|
||||
import { unpackReveal } from '../../common/src/utils/revealBitmap';
|
||||
import { getCSCAModulusMerkleTree } from '../../common/src/utils/csca';
|
||||
@@ -38,263 +38,255 @@ import { OpenPassportVerifierReport } from './OpenPassportVerifierReport';
|
||||
import { fetchTreeFromUrl } from '../../common/src/utils/pubkeyTree';
|
||||
|
||||
export class AttestationVerifier {
|
||||
protected devMode: boolean;
|
||||
protected scope: string;
|
||||
protected report: OpenPassportVerifierReport;
|
||||
protected minimumAge: { enabled: boolean; value: string } = { enabled: false, value: '18' };
|
||||
protected nationality: { enabled: boolean; value: (typeof countryNames)[number] } = {
|
||||
enabled: false,
|
||||
value: '' as (typeof countryNames)[number],
|
||||
};
|
||||
protected excludedCountries: { enabled: boolean; value: (typeof countryNames)[number][] } = {
|
||||
enabled: false,
|
||||
value: [],
|
||||
};
|
||||
protected ofac: boolean = false;
|
||||
protected commitmentMerkleTreeUrl: string = '';
|
||||
protected devMode: boolean;
|
||||
protected scope: string;
|
||||
protected report: OpenPassportVerifierReport;
|
||||
protected minimumAge: { enabled: boolean; value: string } = { enabled: false, value: '18' };
|
||||
protected nationality: { enabled: boolean; value: (typeof countryNames)[number] } = {
|
||||
enabled: false,
|
||||
value: '' as (typeof countryNames)[number],
|
||||
};
|
||||
protected excludedCountries: { enabled: boolean; value: (typeof countryNames)[number][] } = {
|
||||
enabled: false,
|
||||
value: [],
|
||||
};
|
||||
protected ofac: boolean = false;
|
||||
protected commitmentMerkleTreeUrl: string = '';
|
||||
|
||||
constructor(devMode: boolean = false) {
|
||||
this.devMode = devMode;
|
||||
this.report = new OpenPassportVerifierReport();
|
||||
}
|
||||
|
||||
constructor(devMode: boolean = false) {
|
||||
this.devMode = devMode;
|
||||
this.report = new OpenPassportVerifierReport();
|
||||
public async verify(attestation: OpenPassportAttestation): Promise<OpenPassportVerifierReport> {
|
||||
const kScaled =
|
||||
attestation.proof.signatureAlgorithm === 'ecdsa'
|
||||
? ECDSA_K_LENGTH_FACTOR * k_dsc_ecdsa
|
||||
: k_dsc;
|
||||
|
||||
let parsedPublicSignals;
|
||||
if (attestation.proof.mode === 'vc_and_disclose') {
|
||||
parsedPublicSignals = parsePublicSignalsDisclose(attestation.proof.value.publicSignals);
|
||||
} else {
|
||||
parsedPublicSignals = parsePublicSignalsProve(attestation.proof.value.publicSignals, kScaled);
|
||||
}
|
||||
|
||||
public async verify(attestation: OpenPassportAttestation): Promise<OpenPassportVerifierReport> {
|
||||
const kScaled =
|
||||
attestation.proof.signatureAlgorithm === 'ecdsa'
|
||||
? ECDSA_K_LENGTH_FACTOR * k_dsc_ecdsa
|
||||
: k_dsc;
|
||||
this.verifyAttribute('scope', castToScope(parsedPublicSignals.scope), this.scope);
|
||||
|
||||
let parsedPublicSignals;
|
||||
if (attestation.proof.mode === 'vc_and_disclose') {
|
||||
parsedPublicSignals = parsePublicSignalsDisclose(
|
||||
attestation.proof.value.publicSignals
|
||||
);
|
||||
} else {
|
||||
parsedPublicSignals = parsePublicSignalsProve(
|
||||
attestation.proof.value.publicSignals,
|
||||
kScaled
|
||||
);
|
||||
}
|
||||
await this.verifyProof(
|
||||
attestation.proof.mode,
|
||||
attestation.proof.value.proof,
|
||||
attestation.proof.value.publicSignals,
|
||||
attestation.proof.signatureAlgorithm,
|
||||
attestation.proof.hashFunction
|
||||
);
|
||||
|
||||
this.verifyAttribute('scope', castToScope(parsedPublicSignals.scope), this.scope);
|
||||
switch (attestation.proof.mode) {
|
||||
case 'register':
|
||||
await this.verifyRegister(attestation);
|
||||
break;
|
||||
case 'prove_onchain':
|
||||
await this.verifyProveOnChain(attestation);
|
||||
break;
|
||||
case 'prove_offchain':
|
||||
await this.verifyProveOffChain(attestation);
|
||||
break;
|
||||
case 'vc_and_disclose':
|
||||
await this.verifyDisclose(attestation);
|
||||
break;
|
||||
}
|
||||
return this.report;
|
||||
}
|
||||
|
||||
await this.verifyProof(
|
||||
attestation.proof.mode,
|
||||
attestation.proof.value.proof,
|
||||
attestation.proof.value.publicSignals,
|
||||
attestation.proof.signatureAlgorithm,
|
||||
attestation.proof.hashFunction
|
||||
private async verifyRegister(attestation: OpenPassportAttestation) {
|
||||
// verify dscProof
|
||||
await this.verifyDscProof(attestation);
|
||||
// verify that the blinded dscCommitments of proof and dscProof match
|
||||
this.verifyBlindedDscCommitments(attestation);
|
||||
// verify the root of the csca merkle tree
|
||||
this.verifyCSCARoot(attestation);
|
||||
}
|
||||
|
||||
private async verifyProveOffChain(attestation: OpenPassportAttestation) {
|
||||
// verify disclose attributes
|
||||
this.verifyDiscloseAttributes(attestation);
|
||||
// verify certificate chain
|
||||
this.verifyCertificateChain(attestation);
|
||||
}
|
||||
|
||||
private async verifyProveOnChain(attestation: OpenPassportAttestation) {
|
||||
// verify attributes
|
||||
this.verifyDiscloseAttributes(attestation);
|
||||
// verify the dsc proof
|
||||
await this.verifyDscProof(attestation);
|
||||
// verify that the blinded dscCommitments of proof and dscProof match
|
||||
this.verifyBlindedDscCommitments(attestation);
|
||||
// verify the root of the csca merkle tree
|
||||
this.verifyCSCARoot(attestation);
|
||||
}
|
||||
|
||||
private async verifyDisclose(attestation: OpenPassportAttestation) {
|
||||
// verify the root of the commitment
|
||||
this.verifyCommitment(attestation);
|
||||
// verify disclose attributes
|
||||
this.verifyDiscloseAttributes(attestation);
|
||||
}
|
||||
|
||||
private verifyDiscloseAttributes(attestation: OpenPassportAttestation) {
|
||||
let parsedPublicSignals;
|
||||
if (attestation.proof.mode === 'vc_and_disclose') {
|
||||
parsedPublicSignals = parsePublicSignalsDisclose(attestation.proof.value.publicSignals);
|
||||
} else {
|
||||
parsedPublicSignals = parsePublicSignalsProve(attestation.proof.value.publicSignals, k_dsc);
|
||||
}
|
||||
this.verifyAttribute(
|
||||
'current_date',
|
||||
parsedPublicSignals.current_date.toString(),
|
||||
getCurrentDateFormatted().toString()
|
||||
);
|
||||
|
||||
const unpackedReveal = unpackReveal(parsedPublicSignals.revealedData_packed);
|
||||
if (this.minimumAge.enabled) {
|
||||
const attributeValueInt = getOlderThanFromCircuitOutput(parsedPublicSignals.older_than);
|
||||
const selfAttributeOlderThan = parseInt(this.minimumAge.value);
|
||||
if (attributeValueInt < selfAttributeOlderThan) {
|
||||
this.report.exposeAttribute(
|
||||
'older_than',
|
||||
attributeValueInt.toString(),
|
||||
this.minimumAge.value.toString()
|
||||
);
|
||||
} else {
|
||||
console.log('\x1b[32m%s\x1b[0m', '- minimum age verified');
|
||||
}
|
||||
}
|
||||
if (this.nationality.enabled) {
|
||||
const attributeValue = getAttributeFromUnpackedReveal(unpackedReveal, 'nationality');
|
||||
this.verifyAttribute('nationality', countryCodes[attributeValue], this.nationality.value);
|
||||
}
|
||||
if (this.ofac) {
|
||||
const attributeValue = parsedPublicSignals.ofac_result.toString();
|
||||
this.verifyAttribute('ofac', attributeValue, '1');
|
||||
}
|
||||
if (this.excludedCountries.enabled) {
|
||||
const formattedCountryList = formatForbiddenCountriesListFromCircuitOutput(
|
||||
parsedPublicSignals.forbidden_countries_list_packed_disclosed
|
||||
);
|
||||
const formattedCountryListFullCountryNames = formattedCountryList.map(
|
||||
(countryCode) => countryCodes[countryCode]
|
||||
);
|
||||
this.verifyAttribute(
|
||||
'forbidden_countries_list',
|
||||
formattedCountryListFullCountryNames.toString(),
|
||||
this.excludedCountries.value.toString()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
switch (attestation.proof.mode) {
|
||||
case 'register':
|
||||
await this.verifyRegister(attestation);
|
||||
break;
|
||||
case 'prove_onchain':
|
||||
await this.verifyProveOnChain(attestation);
|
||||
break;
|
||||
case 'prove_offchain':
|
||||
await this.verifyProveOffChain(attestation);
|
||||
break;
|
||||
case 'vc_and_disclose':
|
||||
await this.verifyDisclose(attestation);
|
||||
break;
|
||||
}
|
||||
return this.report;
|
||||
private verifyCSCARoot(attestation: OpenPassportAttestation) {
|
||||
// verify the root of the csca merkle tree
|
||||
const parsedDscPublicSignals = parsePublicSignalsDsc(attestation.dscProof.value.publicSignals);
|
||||
const cscaMerkleTreeFromDscProof = parsedDscPublicSignals.merkle_root;
|
||||
const cscaMerkleTree = getCSCAModulusMerkleTree();
|
||||
const cscaRoot = cscaMerkleTree.root;
|
||||
this.verifyAttribute('merkle_root_csca', cscaRoot, cscaMerkleTreeFromDscProof);
|
||||
}
|
||||
|
||||
private async verifyCommitment(attestation: OpenPassportAttestation) {
|
||||
const tree = await fetchTreeFromUrl(this.commitmentMerkleTreeUrl);
|
||||
const parsedPublicSignals = parsePublicSignalsDisclose(attestation.proof.value.publicSignals);
|
||||
this.verifyAttribute(
|
||||
'merkle_root_commitment',
|
||||
tree.root.toString(),
|
||||
parsedPublicSignals.merkle_root
|
||||
);
|
||||
}
|
||||
|
||||
private verifyCertificateChain(attestation: OpenPassportAttestation) {
|
||||
const dscCertificate = forge.pki.certificateFromPem(attestation.dsc.value);
|
||||
const verified_certificate = verifyDSCValidity(dscCertificate, this.devMode);
|
||||
if (!verified_certificate) {
|
||||
this.report.exposeAttribute('dsc', attestation.dsc.value, 'certificate chain is not valid');
|
||||
} else {
|
||||
console.log('\x1b[32m%s\x1b[0m', '- certificate verified');
|
||||
}
|
||||
|
||||
private async verifyRegister(attestation: OpenPassportAttestation) {
|
||||
// verify dscProof
|
||||
await this.verifyDscProof(attestation);
|
||||
// verify that the blinded dscCommitments of proof and dscProof match
|
||||
this.verifyBlindedDscCommitments(attestation);
|
||||
// verify the root of the csca merkle tree
|
||||
this.verifyCSCARoot(attestation);
|
||||
}
|
||||
const parsedDsc = parseCertificate(attestation.dsc.value);
|
||||
const signatureAlgorithmDsc = parsedDsc.signatureAlgorithm;
|
||||
if (signatureAlgorithmDsc === 'ecdsa') {
|
||||
throw new Error('ECDSA not supported yet');
|
||||
} else {
|
||||
const dscModulus = parsedDsc.modulus;
|
||||
const dscModulusBigInt = BigInt(`0x${dscModulus}`);
|
||||
const dscModulusWords = splitToWords(dscModulusBigInt, n_dsc, k_dsc);
|
||||
const pubKeyFromProof = parsePublicSignalsProve(
|
||||
attestation.proof.value.publicSignals,
|
||||
k_dsc
|
||||
).pubKey_disclosed;
|
||||
|
||||
private async verifyProveOffChain(attestation: OpenPassportAttestation) {
|
||||
// verify disclose attributes
|
||||
this.verifyDiscloseAttributes(attestation);
|
||||
// verify certificate chain
|
||||
this.verifyCertificateChain(attestation);
|
||||
}
|
||||
|
||||
private async verifyProveOnChain(attestation: OpenPassportAttestation) {
|
||||
// verify attributes
|
||||
this.verifyDiscloseAttributes(attestation);
|
||||
// verify the dsc proof
|
||||
await this.verifyDscProof(attestation);
|
||||
// verify that the blinded dscCommitments of proof and dscProof match
|
||||
this.verifyBlindedDscCommitments(attestation);
|
||||
// verify the root of the csca merkle tree
|
||||
this.verifyCSCARoot(attestation);
|
||||
}
|
||||
|
||||
private async verifyDisclose(attestation: OpenPassportAttestation) {
|
||||
// verify the root of the commitment
|
||||
this.verifyCommitment(attestation);
|
||||
// verify disclose attributes
|
||||
this.verifyDiscloseAttributes(attestation);
|
||||
}
|
||||
|
||||
private verifyDiscloseAttributes(attestation: OpenPassportAttestation) {
|
||||
let parsedPublicSignals;
|
||||
if (attestation.proof.mode === 'vc_and_disclose') {
|
||||
parsedPublicSignals = parsePublicSignalsDisclose(
|
||||
attestation.proof.value.publicSignals
|
||||
);
|
||||
} else {
|
||||
parsedPublicSignals = parsePublicSignalsProve(
|
||||
attestation.proof.value.publicSignals,
|
||||
k_dsc
|
||||
);
|
||||
}
|
||||
this.verifyAttribute(
|
||||
'current_date',
|
||||
parsedPublicSignals.current_date.toString(),
|
||||
getCurrentDateFormatted().toString()
|
||||
const verified_modulus = areArraysEqual(dscModulusWords, pubKeyFromProof);
|
||||
if (!verified_modulus) {
|
||||
this.report.exposeAttribute(
|
||||
'pubKey',
|
||||
pubKeyFromProof,
|
||||
'pubKey from proof does not match pubKey from DSC certificate'
|
||||
);
|
||||
|
||||
const unpackedReveal = unpackReveal(parsedPublicSignals.revealedData_packed);
|
||||
if (this.minimumAge.enabled) {
|
||||
const attributeValueInt = getOlderThanFromCircuitOutput(parsedPublicSignals.older_than);
|
||||
const selfAttributeOlderThan = parseInt(this.minimumAge.value);
|
||||
if (attributeValueInt < selfAttributeOlderThan) {
|
||||
this.report.exposeAttribute(
|
||||
'older_than',
|
||||
attributeValueInt.toString(),
|
||||
this.minimumAge.value.toString()
|
||||
);
|
||||
} else {
|
||||
console.log('\x1b[32m%s\x1b[0m', '- minimum age verified');
|
||||
}
|
||||
}
|
||||
if (this.nationality.enabled) {
|
||||
const attributeValue = getAttributeFromUnpackedReveal(unpackedReveal, 'nationality');
|
||||
this.verifyAttribute('nationality', countryCodes[attributeValue], this.nationality.value);
|
||||
}
|
||||
if (this.ofac) {
|
||||
const attributeValue = parsedPublicSignals.ofac_result.toString();
|
||||
this.verifyAttribute('ofac', attributeValue, '1');
|
||||
}
|
||||
if (this.excludedCountries.enabled) {
|
||||
const formattedCountryList = formatForbiddenCountriesListFromCircuitOutput(
|
||||
parsedPublicSignals.forbidden_countries_list_packed_disclosed
|
||||
);
|
||||
const formattedCountryListFullCountryNames = formattedCountryList.map(
|
||||
(countryCode) => countryCodes[countryCode]
|
||||
);
|
||||
this.verifyAttribute(
|
||||
'forbidden_countries_list',
|
||||
formattedCountryListFullCountryNames.toString(),
|
||||
this.excludedCountries.value.toString()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
console.log('\x1b[32m%s\x1b[0m', '- modulus verified');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private verifyCSCARoot(attestation: OpenPassportAttestation) {
|
||||
// verify the root of the csca merkle tree
|
||||
const parsedDscPublicSignals = parsePublicSignalsDsc(attestation.dscProof.value.publicSignals);
|
||||
const cscaMerkleTreeFromDscProof = parsedDscPublicSignals.merkle_root;
|
||||
const cscaMerkleTree = getCSCAModulusMerkleTree();
|
||||
const cscaRoot = cscaMerkleTree.root;
|
||||
this.verifyAttribute('merkle_root_csca', cscaRoot, cscaMerkleTreeFromDscProof);
|
||||
}
|
||||
|
||||
private async verifyCommitment(attestation: OpenPassportAttestation) {
|
||||
const tree = await fetchTreeFromUrl(this.commitmentMerkleTreeUrl);
|
||||
const parsedPublicSignals = parsePublicSignalsDisclose(attestation.proof.value.publicSignals);
|
||||
this.verifyAttribute('merkle_root_commitment', tree.root.toString(), parsedPublicSignals.merkle_root);
|
||||
|
||||
}
|
||||
|
||||
private verifyCertificateChain(attestation: OpenPassportAttestation) {
|
||||
const dscCertificate = forge.pki.certificateFromPem(attestation.dsc.value);
|
||||
const verified_certificate = verifyDSCValidity(dscCertificate, this.devMode);
|
||||
if (!verified_certificate) {
|
||||
this.report.exposeAttribute('dsc', attestation.dsc.value, 'certificate chain is not valid');
|
||||
} else {
|
||||
console.log('\x1b[32m%s\x1b[0m', '- certificate verified');
|
||||
}
|
||||
|
||||
const parsedDsc = parseCertificate(attestation.dsc.value);
|
||||
const signatureAlgorithmDsc = parsedDsc.signatureAlgorithm;
|
||||
if (signatureAlgorithmDsc === 'ecdsa') {
|
||||
throw new Error('ECDSA not supported yet');
|
||||
} else {
|
||||
const dscModulus = parsedDsc.modulus;
|
||||
const dscModulusBigInt = BigInt(`0x${dscModulus}`);
|
||||
const dscModulusWords = splitToWords(dscModulusBigInt, n_dsc, k_dsc);
|
||||
const pubKeyFromProof = parsePublicSignalsProve(
|
||||
attestation.proof.value.publicSignals,
|
||||
k_dsc
|
||||
).pubKey_disclosed;
|
||||
|
||||
const verified_modulus = areArraysEqual(dscModulusWords, pubKeyFromProof);
|
||||
if (!verified_modulus) {
|
||||
this.report.exposeAttribute(
|
||||
'pubKey',
|
||||
pubKeyFromProof,
|
||||
'pubKey from proof does not match pubKey from DSC certificate'
|
||||
);
|
||||
} else {
|
||||
console.log('\x1b[32m%s\x1b[0m', '- modulus verified');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private verifyBlindedDscCommitments(attestation: OpenPassportAttestation) {
|
||||
const parsedPublicSignals = parsePublicSignalsProve(
|
||||
attestation.proof.value.publicSignals,
|
||||
k_dsc
|
||||
);
|
||||
const proofBlindedDscCommitment = parsedPublicSignals.blinded_dsc_commitment;
|
||||
|
||||
const parsedDscPublicSignals = parsePublicSignalsDsc(attestation.dscProof.value.publicSignals);
|
||||
const dscBlindedDscCommitment = parsedDscPublicSignals.blinded_dsc_commitment;
|
||||
|
||||
this.verifyAttribute(
|
||||
'blinded_dsc_commitment',
|
||||
proofBlindedDscCommitment,
|
||||
dscBlindedDscCommitment
|
||||
);
|
||||
}
|
||||
|
||||
private async verifyProof(
|
||||
mode: Mode,
|
||||
proof: string[],
|
||||
publicSignals: string[],
|
||||
signatureAlgorithm: string,
|
||||
hashFunction: string
|
||||
): Promise<void> {
|
||||
const circuitName = circuitNameFromMode[mode];
|
||||
const vkey = getVkeyFromArtifacts(circuitName, signatureAlgorithm, hashFunction);
|
||||
const isVerified = await groth16.verify(vkey, publicSignals, proof as any);
|
||||
this.verifyAttribute('proof', isVerified.toString(), 'true');
|
||||
}
|
||||
|
||||
private async verifyDscProof(attestation: OpenPassportAttestation) {
|
||||
const dscSignatureAlgorithm = attestation.dscProof.signatureAlgorithm;
|
||||
const dscHashFunction = attestation.dscProof.hashFunction;
|
||||
const vkey = getVkeyFromArtifacts('dsc', dscSignatureAlgorithm, dscHashFunction);
|
||||
const isVerified = await groth16.verify(
|
||||
vkey,
|
||||
attestation.dscProof.value.publicSignals,
|
||||
attestation.dscProof.value.proof as any
|
||||
);
|
||||
this.verifyAttribute('dscProof', isVerified.toString(), 'true');
|
||||
}
|
||||
|
||||
private verifyAttribute(
|
||||
attribute: keyof OpenPassportVerifierReport,
|
||||
value: string,
|
||||
expectedValue: string
|
||||
) {
|
||||
if (value !== expectedValue) {
|
||||
this.report.exposeAttribute(attribute, value, expectedValue);
|
||||
} else {
|
||||
console.log('\x1b[32m%s\x1b[0m', `- attribute ${attribute} verified`);
|
||||
}
|
||||
private verifyBlindedDscCommitments(attestation: OpenPassportAttestation) {
|
||||
const parsedPublicSignals = parsePublicSignalsProve(
|
||||
attestation.proof.value.publicSignals,
|
||||
k_dsc
|
||||
);
|
||||
const proofBlindedDscCommitment = parsedPublicSignals.blinded_dsc_commitment;
|
||||
|
||||
const parsedDscPublicSignals = parsePublicSignalsDsc(attestation.dscProof.value.publicSignals);
|
||||
const dscBlindedDscCommitment = parsedDscPublicSignals.blinded_dsc_commitment;
|
||||
|
||||
this.verifyAttribute(
|
||||
'blinded_dsc_commitment',
|
||||
proofBlindedDscCommitment,
|
||||
dscBlindedDscCommitment
|
||||
);
|
||||
}
|
||||
|
||||
private async verifyProof(
|
||||
mode: Mode,
|
||||
proof: string[],
|
||||
publicSignals: string[],
|
||||
signatureAlgorithm: string,
|
||||
hashFunction: string
|
||||
): Promise<void> {
|
||||
const circuitName = circuitNameFromMode[mode];
|
||||
const vkey = getVkeyFromArtifacts(circuitName, signatureAlgorithm, hashFunction);
|
||||
const isVerified = await groth16.verify(vkey, publicSignals, proof as any);
|
||||
this.verifyAttribute('proof', isVerified.toString(), 'true');
|
||||
}
|
||||
|
||||
private async verifyDscProof(attestation: OpenPassportAttestation) {
|
||||
const dscSignatureAlgorithm = attestation.dscProof.signatureAlgorithm;
|
||||
const dscHashFunction = attestation.dscProof.hashFunction;
|
||||
const vkey = getVkeyFromArtifacts('dsc', dscSignatureAlgorithm, dscHashFunction);
|
||||
const isVerified = await groth16.verify(
|
||||
vkey,
|
||||
attestation.dscProof.value.publicSignals,
|
||||
attestation.dscProof.value.proof as any
|
||||
);
|
||||
this.verifyAttribute('dscProof', isVerified.toString(), 'true');
|
||||
}
|
||||
|
||||
private verifyAttribute(
|
||||
attribute: keyof OpenPassportVerifierReport,
|
||||
value: string,
|
||||
expectedValue: string
|
||||
) {
|
||||
if (value !== expectedValue) {
|
||||
this.report.exposeAttribute(attribute, value, expectedValue);
|
||||
} else {
|
||||
console.log('\x1b[32m%s\x1b[0m', `- attribute ${attribute} verified`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ export class OpenPassportVerifier extends AttestationVerifier {
|
||||
break;
|
||||
case 'register':
|
||||
if (!this.commitmentMerkleTreeUrl) {
|
||||
throw new Error('Commitment merkle tree URL is required for mode \'register\'');
|
||||
throw new Error("Commitment merkle tree URL is required for mode 'register'");
|
||||
}
|
||||
const argsRegisterOnChain: ArgumentsRegister = {
|
||||
modalServerUrl: this.modalServerUrl,
|
||||
|
||||
1
sdk/src/QRcode/OpenPassportQRcode.d.ts
vendored
1
sdk/src/QRcode/OpenPassportQRcode.d.ts
vendored
@@ -15,4 +15,3 @@ interface OpenPassportQRcodeProps {
|
||||
declare const OpenPassportQRcode: React.FC<OpenPassportQRcodeProps>;
|
||||
|
||||
export { OpenPassportQRcode, OpenPassportQRcodeProps };
|
||||
|
||||
|
||||
@@ -18,54 +18,54 @@ const handleWebSocketMessage =
|
||||
openPassportVerifier: OpenPassportVerifier,
|
||||
onSuccess: (proof: OpenPassportAttestation) => void
|
||||
) =>
|
||||
async (data) => {
|
||||
console.log('received mobile status:', data.status);
|
||||
switch (data.status) {
|
||||
case 'mobile_connected':
|
||||
setProofStep(QRcodeSteps.MOBILE_CONNECTED);
|
||||
break;
|
||||
case 'mobile_disconnected':
|
||||
setProofStep(QRcodeSteps.WAITING_FOR_MOBILE);
|
||||
break;
|
||||
case 'proof_generation_started':
|
||||
setProofStep(QRcodeSteps.PROOF_GENERATION_STARTED);
|
||||
break;
|
||||
case 'proof_generated':
|
||||
setProofStep(QRcodeSteps.PROOF_GENERATED);
|
||||
break;
|
||||
case 'proof_generation_failed':
|
||||
setProofVerified(false);
|
||||
setProofStep(QRcodeSteps.PROOF_VERIFIED);
|
||||
console.log('Proof generation failed');
|
||||
break;
|
||||
}
|
||||
async (data) => {
|
||||
console.log('received mobile status:', data.status);
|
||||
switch (data.status) {
|
||||
case 'mobile_connected':
|
||||
setProofStep(QRcodeSteps.MOBILE_CONNECTED);
|
||||
break;
|
||||
case 'mobile_disconnected':
|
||||
setProofStep(QRcodeSteps.WAITING_FOR_MOBILE);
|
||||
break;
|
||||
case 'proof_generation_started':
|
||||
setProofStep(QRcodeSteps.PROOF_GENERATION_STARTED);
|
||||
break;
|
||||
case 'proof_generated':
|
||||
setProofStep(QRcodeSteps.PROOF_GENERATED);
|
||||
break;
|
||||
case 'proof_generation_failed':
|
||||
setProofVerified(false);
|
||||
setProofStep(QRcodeSteps.PROOF_VERIFIED);
|
||||
console.log('Proof generation failed');
|
||||
break;
|
||||
}
|
||||
|
||||
if (data.proof) {
|
||||
console.log(data.proof);
|
||||
try {
|
||||
const local_proofVerified = await openPassportVerifier.verify(data.proof);
|
||||
setProofVerified(local_proofVerified.valid);
|
||||
setProofStep(QRcodeSteps.PROOF_VERIFIED);
|
||||
setTimeout(() => {
|
||||
newSocket.emit('proof_verified', {
|
||||
sessionId,
|
||||
proofVerified: local_proofVerified.toString(),
|
||||
});
|
||||
if (local_proofVerified) {
|
||||
onSuccess(data.proof);
|
||||
}
|
||||
}, 1500); // wait for animation to finish before sending the proof to mobile
|
||||
} catch (error) {
|
||||
console.error('Error verifying proof:', error);
|
||||
setProofVerified(false);
|
||||
setProofStep(QRcodeSteps.PROOF_VERIFIED);
|
||||
if (data.proof) {
|
||||
console.log(data.proof);
|
||||
try {
|
||||
const local_proofVerified = await openPassportVerifier.verify(data.proof);
|
||||
setProofVerified(local_proofVerified.valid);
|
||||
setProofStep(QRcodeSteps.PROOF_VERIFIED);
|
||||
setTimeout(() => {
|
||||
newSocket.emit('proof_verified', {
|
||||
sessionId,
|
||||
proofVerified: { valid: false, error: error.message },
|
||||
proofVerified: local_proofVerified.toString(),
|
||||
});
|
||||
}
|
||||
if (local_proofVerified) {
|
||||
onSuccess(data.proof);
|
||||
}
|
||||
}, 1500); // wait for animation to finish before sending the proof to mobile
|
||||
} catch (error) {
|
||||
console.error('Error verifying proof:', error);
|
||||
setProofVerified(false);
|
||||
setProofStep(QRcodeSteps.PROOF_VERIFIED);
|
||||
newSocket.emit('proof_verified', {
|
||||
sessionId,
|
||||
proofVerified: { valid: false, error: error.message },
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export function initWebSocket(
|
||||
websocketUrl: string,
|
||||
|
||||
@@ -8,7 +8,12 @@ export default function Prove() {
|
||||
const userId = uuidv4();
|
||||
const scope = 'scope';
|
||||
|
||||
const openPassportVerifierDisclose = new OpenPassportVerifier('vc_and_disclose', scope).setCommitmentMerkleTreeUrl(COMMITMENT_TREE_TRACKER_URL).excludeCountries('Albania').setMinimumAge(20).enableOFACCheck().setNationality('Germany');
|
||||
const openPassportVerifierDisclose = new OpenPassportVerifier('vc_and_disclose', scope)
|
||||
.setCommitmentMerkleTreeUrl(COMMITMENT_TREE_TRACKER_URL)
|
||||
.excludeCountries('Albania')
|
||||
.setMinimumAge(20)
|
||||
.enableOFACCheck()
|
||||
.setNationality('Germany');
|
||||
return (
|
||||
<div className="h-screen w-full bg-white flex flex-col items-center justify-center gap-4">
|
||||
<OpenPassportQRcode
|
||||
@@ -16,8 +21,7 @@ export default function Prove() {
|
||||
userId={userId}
|
||||
userIdType={'uuid'}
|
||||
openPassportVerifier={openPassportVerifierDisclose}
|
||||
onSuccess={(attestation) => {
|
||||
}}
|
||||
onSuccess={(attestation) => {}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -8,7 +8,10 @@ import axios from 'axios';
|
||||
export default function Prove() {
|
||||
const userId = uuidv4();
|
||||
const scope = 'scope';
|
||||
const openPassportVerifier = new OpenPassportVerifier('register', scope).setCommitmentMerkleTreeUrl(COMMITMENT_TREE_TRACKER_URL);
|
||||
const openPassportVerifier = new OpenPassportVerifier(
|
||||
'register',
|
||||
scope
|
||||
).setCommitmentMerkleTreeUrl(COMMITMENT_TREE_TRACKER_URL);
|
||||
return (
|
||||
<div className="h-screen w-full bg-white flex flex-col items-center justify-center gap-4">
|
||||
<OpenPassportQRcode
|
||||
@@ -17,11 +20,14 @@ export default function Prove() {
|
||||
userIdType={'uuid'}
|
||||
openPassportVerifier={openPassportVerifier}
|
||||
onSuccess={(attestation) => {
|
||||
axios.post('https://proofofpassport-merkle-tree.xyz/api/verifier/register', attestation).then((response) => {
|
||||
console.log('Registration response:', response);
|
||||
}).catch((error) => {
|
||||
console.error('Error registering attestation:', error);
|
||||
});
|
||||
axios
|
||||
.post('https://proofofpassport-merkle-tree.xyz/api/verifier/register', attestation)
|
||||
.then((response) => {
|
||||
console.log('Registration response:', response);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error registering attestation:', error);
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -23,10 +23,5 @@
|
||||
"utils/utils.ts",
|
||||
"../common/src/utils/openPassportAttestation.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"**/__tests__/*",
|
||||
"dist",
|
||||
"common/src/utils/csca.ts"
|
||||
]
|
||||
}
|
||||
"exclude": ["node_modules", "**/__tests__/*", "dist", "common/src/utils/csca.ts"]
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
vkey_dsc_rsa_65537_sha1,
|
||||
vkey_dsc_rsa_65537_sha256,
|
||||
vkey_dsc_rsapss_65537_sha256,
|
||||
vkey_vc_and_disclose
|
||||
vkey_vc_and_disclose,
|
||||
} from '../../common/src/constants/vkey';
|
||||
import { getCircuitName } from '../../common/src/utils/certificates/handleCertificate';
|
||||
|
||||
@@ -28,7 +28,10 @@ export function getVkeyFromArtifacts(
|
||||
signatureAlgorithm: string,
|
||||
hashFunction: string
|
||||
) {
|
||||
const circuitName = circuit === 'vc_and_disclose' ? circuit : getCircuitName(circuit, signatureAlgorithm, hashFunction);
|
||||
const circuitName =
|
||||
circuit === 'vc_and_disclose'
|
||||
? circuit
|
||||
: getCircuitName(circuit, signatureAlgorithm, hashFunction);
|
||||
// console.log('\x1b[90m%s\x1b[0m', 'circuit name:', circuitName);
|
||||
switch (circuitName) {
|
||||
case 'vc_and_disclose':
|
||||
|
||||
Reference in New Issue
Block a user