mirror of
https://github.com/selfxyz/self.git
synced 2026-01-10 07:08:10 -05:00
refactor mockPassportData generation
- Now using only genMockPassportData.ts - Tests in `/common` verify them - Mock DSCs for ecdsa - Factor tests into unique files - Broke register ecdsa sig verif, will fix
This commit is contained in:
@@ -12,6 +12,7 @@ import getCountryISO2 from "country-iso-3-to-2";
|
||||
import { flag } from 'country-emoji';
|
||||
import { getSignatureAlgorithm, getCircuitName } from '../../../common/src/utils/handleCertificate';
|
||||
import { downloadZkey } from '../utils/zkeyDownload';
|
||||
|
||||
const MockDataScreen: React.FC = () => {
|
||||
const [signatureAlgorithm, setSignatureAlgorithm] = useState("rsa_sha256");
|
||||
const listOfSignatureAlgorithms = ["rsa_sha1", "rsa_sha256", "rsapss_sha256"];
|
||||
|
||||
104
circuits/tests/prove/prove.test.ts
Normal file
104
circuits/tests/prove/prove.test.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import { describe } from 'mocha';
|
||||
import { expect } from 'chai';
|
||||
import path from 'path';
|
||||
import { wasm as wasm_tester } from 'circom_tester';
|
||||
import { generateCircuitInputsProve } from '../../../common/src/utils/generateInputs';
|
||||
import { n_dsc, k_dsc } from '../../../common/src/constants/constants';
|
||||
import { genMockPassportData } from '../../../common/src/utils/genMockPassportData';
|
||||
import { getCircuitName } from '../../../common/src/utils/handleCertificate';
|
||||
import { SignatureAlgorithm } from '../../../common/tests/genMockPassportData.test';
|
||||
|
||||
const sigAlgs = [
|
||||
{ sigAlg: 'rsa', hashFunction: 'sha1' },
|
||||
{ sigAlg: 'rsa', hashFunction: 'sha256' },
|
||||
{ sigAlg: 'rsapss', hashFunction: 'sha256' },
|
||||
];
|
||||
|
||||
sigAlgs.forEach(({ sigAlg, hashFunction }) => {
|
||||
describe(`Prove - ${hashFunction.toUpperCase()} ${sigAlg.toUpperCase()}`, function () {
|
||||
this.timeout(0);
|
||||
let circuit: any;
|
||||
|
||||
const passportData = genMockPassportData(`${sigAlg}_${hashFunction}` as SignatureAlgorithm, 'FRA', '000101', '300101');
|
||||
const majority = '18';
|
||||
const user_identifier = crypto.randomUUID();
|
||||
const scope = '@coboyApp';
|
||||
const bitmap = Array(90).fill('1');
|
||||
|
||||
const inputs = generateCircuitInputsProve(
|
||||
passportData,
|
||||
n_dsc,
|
||||
k_dsc,
|
||||
scope,
|
||||
bitmap,
|
||||
majority,
|
||||
user_identifier
|
||||
);
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, `../../circuits/prove/${getCircuitName('prove', sigAlg, hashFunction)}.circom`),
|
||||
{
|
||||
include: [
|
||||
'node_modules',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
],
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should compile and load the circuit', async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
it('should calculate the witness with correct inputs', async function () {
|
||||
const w = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(w);
|
||||
|
||||
const nullifier = (await circuit.getOutput(w, ['nullifier'])).nullifier;
|
||||
expect(nullifier).to.be.not.null;
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid mrz', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
mrz: Array(93)
|
||||
.fill(0)
|
||||
.map((byte) => BigInt(byte).toString()),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid dataHashes', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
dataHashes: inputs.dataHashes.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid signature', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
signature: inputs.signature.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,95 +0,0 @@
|
||||
import { describe } from 'mocha';
|
||||
import { assert, expect } from 'chai';
|
||||
import path from 'path';
|
||||
import { wasm as wasm_tester } from 'circom_tester';
|
||||
import { mockPassportData_sha1_rsa_65537 } from '../../../common/src/constants/mockPassportData';
|
||||
import { generateCircuitInputsProve } from '../../../common/src/utils/generateInputs';
|
||||
import crypto from 'crypto';
|
||||
import { DEFAULT_MAJORITY, k_dsc, n_dsc } from '../../../common/src/constants/constants';
|
||||
|
||||
describe('PROVE - RSA SHA1', function () {
|
||||
this.timeout(0);
|
||||
let circuit: any;
|
||||
|
||||
const passportData = mockPassportData_sha1_rsa_65537;
|
||||
const majority = DEFAULT_MAJORITY;
|
||||
const user_identifier = crypto.randomUUID();
|
||||
const scope = '@coboyApp';
|
||||
const bitmap = Array(90).fill('1');
|
||||
|
||||
const inputs = generateCircuitInputsProve(
|
||||
passportData,
|
||||
n_dsc,
|
||||
k_dsc,
|
||||
scope,
|
||||
bitmap,
|
||||
majority,
|
||||
user_identifier
|
||||
);
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, '../../circuits/prove/prove_rsa_65537_sha1.circom'),
|
||||
{
|
||||
include: [
|
||||
'node_modules',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
],
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should compile and load the circuit', async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
it('should calculate the witness with correct inputs', async function () {
|
||||
const w = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(w);
|
||||
|
||||
const nullifier = (await circuit.getOutput(w, ['nullifier'])).nullifier;
|
||||
expect(nullifier).to.be.not.null;
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid mrz', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
mrz: Array(93)
|
||||
.fill(0)
|
||||
.map((byte) => BigInt(byte).toString()),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid dataHashes', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
dataHashes: inputs.dataHashes.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid signature', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
signature: inputs.signature.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,95 +0,0 @@
|
||||
import { describe } from 'mocha';
|
||||
import { assert, expect } from 'chai';
|
||||
import path from 'path';
|
||||
import { wasm as wasm_tester } from 'circom_tester';
|
||||
import { mockPassportData_sha256_rsa_65537 } from '../../../common/src/constants/mockPassportData';
|
||||
import { generateCircuitInputsProve } from '../../../common/src/utils/generateInputs';
|
||||
import crypto from 'crypto';
|
||||
import { k_dsc, n_dsc } from '../../../common/src/constants/constants';
|
||||
|
||||
describe('PROVE - RSA SHA256', function () {
|
||||
this.timeout(0);
|
||||
let circuit: any;
|
||||
|
||||
const passportData = mockPassportData_sha256_rsa_65537;
|
||||
const majority = '18';
|
||||
const user_identifier = crypto.randomUUID();
|
||||
const scope = '@coboyApp';
|
||||
const bitmap = Array(90).fill('1');
|
||||
|
||||
const inputs = generateCircuitInputsProve(
|
||||
passportData,
|
||||
n_dsc,
|
||||
k_dsc,
|
||||
scope,
|
||||
bitmap,
|
||||
majority,
|
||||
user_identifier
|
||||
);
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, '../../circuits/prove/prove_rsa_65537_sha256.circom'),
|
||||
{
|
||||
include: [
|
||||
'node_modules',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
],
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should compile and load the circuit', async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
it('should calculate the witness with correct inputs', async function () {
|
||||
const w = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(w);
|
||||
|
||||
const nullifier = (await circuit.getOutput(w, ['nullifier'])).nullifier;
|
||||
expect(nullifier).to.be.not.null;
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid mrz', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
mrz: Array(93)
|
||||
.fill(0)
|
||||
.map((byte) => BigInt(byte).toString()),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid dataHashes', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
dataHashes: inputs.dataHashes.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid signature', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
signature: inputs.signature.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,96 +0,0 @@
|
||||
import { describe } from 'mocha';
|
||||
import { assert, expect } from 'chai';
|
||||
import path from 'path';
|
||||
import { wasm as wasm_tester } from 'circom_tester';
|
||||
import { mockPassportData_sha256_rsapss_65537 } from '../../../common/src/constants/mockPassportData';
|
||||
import { generateCircuitInputsProve } from '../../../common/src/utils/generateInputs';
|
||||
import crypto from 'crypto';
|
||||
|
||||
describe('PROVE - RSAPSS SHA256', function () {
|
||||
this.timeout(0);
|
||||
let circuit: any;
|
||||
|
||||
const passportData = mockPassportData_sha256_rsapss_65537;
|
||||
const n_dsc = 64;
|
||||
const k_dsc = 32;
|
||||
const majority = '18';
|
||||
const user_identifier = crypto.randomUUID();
|
||||
const scope = '@coboyApp';
|
||||
const bitmap = Array(90).fill('1');
|
||||
|
||||
const inputs = generateCircuitInputsProve(
|
||||
passportData,
|
||||
n_dsc,
|
||||
k_dsc,
|
||||
scope,
|
||||
bitmap,
|
||||
majority,
|
||||
user_identifier
|
||||
);
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, '../../circuits/prove/prove_rsapss_65537_sha256.circom'),
|
||||
{
|
||||
include: [
|
||||
'node_modules',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
],
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should compile and load the circuit', async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
it('should calculate the witness with correct inputs', async function () {
|
||||
const w = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(w);
|
||||
|
||||
const nullifier = (await circuit.getOutput(w, ['nullifier'])).nullifier;
|
||||
expect(nullifier).to.be.not.null;
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid mrz', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
mrz: Array(93)
|
||||
.fill(0)
|
||||
.map((byte) => BigInt(byte).toString()),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid dataHashes', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
dataHashes: inputs.dataHashes.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid signature', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
signature: inputs.signature.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
});
|
||||
127
circuits/tests/register/register.test.ts
Normal file
127
circuits/tests/register/register.test.ts
Normal file
@@ -0,0 +1,127 @@
|
||||
import { describe } from 'mocha';
|
||||
import { assert, expect } from 'chai';
|
||||
import path from 'path';
|
||||
import { wasm as wasm_tester } from 'circom_tester';
|
||||
import { poseidon6 } from 'poseidon-lite';
|
||||
import { generateCircuitInputsRegister } from '../../../common/src/utils/generateInputs';
|
||||
import { hexToDecimal, packBytes } from '../../../common/src/utils/utils';
|
||||
import { computeLeafFromModulusBigInt } from '../../../common/src/utils/csca';
|
||||
import { n_dsc, k_dsc, n_dsc_ecdsa, k_dsc_ecdsa, PASSPORT_ATTESTATION_ID } from '../../../common/src/constants/constants';
|
||||
import { genMockPassportData } from '../../../common/src/utils/genMockPassportData';
|
||||
import { getCircuitName, getSignatureAlgorithm } from '../../../common/src/utils/handleCertificate';
|
||||
import { SignatureAlgorithm } from '../../../common/tests/genMockPassportData.test';
|
||||
|
||||
const sigAlgs = [
|
||||
// { sigAlg: 'rsa', hashFunction: 'sha1' },
|
||||
// { sigAlg: 'rsa', hashFunction: 'sha256' },
|
||||
// { sigAlg: 'rsapss', hashFunction: 'sha256' },
|
||||
{ sigAlg: 'ecdsa', hashFunction: 'sha256' },
|
||||
// { sigAlg: 'ecdsa', hashFunction: 'sha1' },
|
||||
];
|
||||
|
||||
sigAlgs.forEach(({ sigAlg, hashFunction }) => {
|
||||
describe(`Register - ${hashFunction.toUpperCase()} ${sigAlg.toUpperCase()}`, function () {
|
||||
this.timeout(0);
|
||||
let circuit: any;
|
||||
|
||||
const passportData = genMockPassportData(`${sigAlg}_${hashFunction}` as SignatureAlgorithm, 'FRA', '000101', '300101');
|
||||
const secret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
const dscSecret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
|
||||
const { modulus, x, y } = getSignatureAlgorithm(passportData.dsc as string);
|
||||
|
||||
const inputs = generateCircuitInputsRegister(
|
||||
secret,
|
||||
dscSecret,
|
||||
PASSPORT_ATTESTATION_ID,
|
||||
passportData,
|
||||
sigAlg === 'ecdsa' ? n_dsc_ecdsa : n_dsc,
|
||||
sigAlg === 'ecdsa' ? k_dsc_ecdsa : k_dsc
|
||||
);
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, `../../circuits/register/${getCircuitName('register', sigAlg, hashFunction)}.circom`),
|
||||
{
|
||||
include: [
|
||||
'node_modules',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
],
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should compile and load the circuit', async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
it('should calculate the witness with correct inputs', async function () {
|
||||
const w = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(w);
|
||||
|
||||
const nullifier = (await circuit.getOutput(w, ['nullifier'])).nullifier;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'nullifier', nullifier);
|
||||
const commitment_circom = (await circuit.getOutput(w, ['commitment'])).commitment;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'commitment', commitment_circom);
|
||||
const blinded_dsc_commitment = (await circuit.getOutput(w, ['blinded_dsc_commitment']))
|
||||
.blinded_dsc_commitment;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'blinded_dsc_commitment', blinded_dsc_commitment);
|
||||
|
||||
// const mrz_bytes = packBytes(inputs.mrz);
|
||||
// const commitment_bytes = poseidon6([
|
||||
// inputs.secret[0],
|
||||
// PASSPORT_ATTESTATION_ID,
|
||||
// computeLeafFromModulusBigInt(BigInt(hexToDecimal(modulus as string))),
|
||||
// mrz_bytes[0],
|
||||
// mrz_bytes[1],
|
||||
// mrz_bytes[2],
|
||||
// ]);
|
||||
// const commitment_js = commitment_bytes.toString();
|
||||
// //console.log('commitment_js', commitment_js)
|
||||
// //console.log('commitment_circom', commitment_circom)
|
||||
// expect(commitment_circom).to.be.equal(commitment_js);
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid mrz', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
mrz: Array(93)
|
||||
.fill(0)
|
||||
.map((byte) => BigInt(byte).toString()),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid dataHashes', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
dataHashes: inputs.dataHashes.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid signature', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
signature: inputs.signature.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,115 +0,0 @@
|
||||
import { describe } from 'mocha';
|
||||
import { assert, expect } from 'chai';
|
||||
import path from 'path';
|
||||
import { wasm as wasm_tester } from 'circom_tester';
|
||||
import { poseidon6 } from 'poseidon-lite';
|
||||
import { mockPassportData_sha1_rsa_65537 } from '../../../common/src/constants/mockPassportData';
|
||||
import { generateCircuitInputsRegister } from '../../../common/src/utils/generateInputs';
|
||||
import { packBytes } from '../../../common/src/utils/utils';
|
||||
import { computeLeafFromModulusBigInt } from '../../../common/src/utils/csca';
|
||||
import { k_dsc, n_dsc, PASSPORT_ATTESTATION_ID } from '../../../common/src/constants/constants';
|
||||
|
||||
describe('Register - SHA1 RSA', function () {
|
||||
this.timeout(0);
|
||||
let circuit: any;
|
||||
|
||||
const passportData = mockPassportData_sha1_rsa_65537;
|
||||
const secret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
const dscSecret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
|
||||
const inputs = generateCircuitInputsRegister(
|
||||
secret,
|
||||
dscSecret,
|
||||
PASSPORT_ATTESTATION_ID,
|
||||
passportData,
|
||||
n_dsc,
|
||||
k_dsc
|
||||
);
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, '../../circuits/register/register_rsa_65537_sha1.circom'),
|
||||
{
|
||||
include: [
|
||||
'node_modules',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
'./node_modules/dmpierre/sha1-circom/circuits',
|
||||
'./node_modules/@zk-email/circuits',
|
||||
],
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should compile and load the circuit', async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
it('should calculate the witness with correct inputs', async function () {
|
||||
const w = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(w);
|
||||
|
||||
const nullifier = (await circuit.getOutput(w, ['nullifier'])).nullifier;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'nullifier', nullifier);
|
||||
const commitment_circom = (await circuit.getOutput(w, ['commitment'])).commitment;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'commitment', commitment_circom);
|
||||
const blinded_dsc_commitment = (await circuit.getOutput(w, ['blinded_dsc_commitment']))
|
||||
.blinded_dsc_commitment;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'blinded_dsc_commitment', blinded_dsc_commitment);
|
||||
|
||||
const mrz_bytes = packBytes(inputs.mrz);
|
||||
const commitment_bytes = poseidon6([
|
||||
inputs.secret[0],
|
||||
PASSPORT_ATTESTATION_ID,
|
||||
computeLeafFromModulusBigInt(BigInt(passportData.pubKey.modulus)),
|
||||
mrz_bytes[0],
|
||||
mrz_bytes[1],
|
||||
mrz_bytes[2],
|
||||
]);
|
||||
const commitment_js = commitment_bytes.toString();
|
||||
//console.log('commitment_js', commitment_js)
|
||||
//console.log('commitment_circom', commitment_circom)
|
||||
expect(commitment_circom).to.be.equal(commitment_js);
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid mrz', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
mrz: Array(93)
|
||||
.fill(0)
|
||||
.map((byte) => BigInt(byte).toString()),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid dataHashes', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
dataHashes: inputs.dataHashes.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid signature', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
signature: inputs.signature.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,113 +0,0 @@
|
||||
import { describe } from 'mocha';
|
||||
import { assert, expect } from 'chai';
|
||||
import path from 'path';
|
||||
import { wasm as wasm_tester } from 'circom_tester';
|
||||
import { poseidon6 } from 'poseidon-lite';
|
||||
import { mockPassportData_sha256_rsa_65537 } from '../../../common/src/constants/mockPassportData';
|
||||
import { generateCircuitInputsRegister } from '../../../common/src/utils/generateInputs';
|
||||
import { packBytes } from '../../../common/src/utils/utils';
|
||||
import { computeLeafFromModulusBigInt } from '../../../common/src/utils/csca';
|
||||
import { k_dsc, n_dsc, PASSPORT_ATTESTATION_ID } from '../../../common/src/constants/constants';
|
||||
|
||||
describe('Register - SHA256 RSA', function () {
|
||||
this.timeout(0);
|
||||
let circuit: any;
|
||||
|
||||
const passportData = mockPassportData_sha256_rsa_65537;
|
||||
const secret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
const dscSecret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
|
||||
const inputs = generateCircuitInputsRegister(
|
||||
secret,
|
||||
dscSecret,
|
||||
PASSPORT_ATTESTATION_ID,
|
||||
passportData,
|
||||
n_dsc,
|
||||
k_dsc
|
||||
);
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, '../../circuits/register/register_rsa_65537_sha256.circom'),
|
||||
{
|
||||
include: [
|
||||
'node_modules',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
],
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should compile and load the circuit', async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
it('should calculate the witness with correct inputs', async function () {
|
||||
const w = await circuit.calculateWitness(inputs);
|
||||
await circuit.checkConstraints(w);
|
||||
|
||||
const nullifier = (await circuit.getOutput(w, ['nullifier'])).nullifier;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'nullifier', nullifier);
|
||||
const commitment_circom = (await circuit.getOutput(w, ['commitment'])).commitment;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'commitment', commitment_circom);
|
||||
const blinded_dsc_commitment = (await circuit.getOutput(w, ['blinded_dsc_commitment']))
|
||||
.blinded_dsc_commitment;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'blinded_dsc_commitment', blinded_dsc_commitment);
|
||||
|
||||
const mrz_bytes = packBytes(inputs.mrz);
|
||||
const commitment_bytes = poseidon6([
|
||||
inputs.secret[0],
|
||||
PASSPORT_ATTESTATION_ID,
|
||||
computeLeafFromModulusBigInt(BigInt(passportData.pubKey.modulus)),
|
||||
mrz_bytes[0],
|
||||
mrz_bytes[1],
|
||||
mrz_bytes[2],
|
||||
]);
|
||||
const commitment_js = commitment_bytes.toString();
|
||||
//console.log('commitment_js', commitment_js)
|
||||
//console.log('commitment_circom', commitment_circom)
|
||||
expect(commitment_circom).to.be.equal(commitment_js);
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid mrz', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
mrz: Array(93)
|
||||
.fill(0)
|
||||
.map((byte) => BigInt(byte).toString()),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid dataHashes', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
dataHashes: inputs.dataHashes.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid signature', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
signature: inputs.signature.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,118 +0,0 @@
|
||||
import { describe } from 'mocha';
|
||||
import { assert, expect } from 'chai';
|
||||
import path from 'path';
|
||||
import { wasm as wasm_tester } from 'circom_tester';
|
||||
import { poseidon6 } from 'poseidon-lite';
|
||||
import { mockPassportData_sha256_rsapss_65537 } from '../../../common/src/constants/mockPassportData';
|
||||
import { generateCircuitInputsRegister } from '../../../common/src/utils/generateInputs';
|
||||
import { packBytes } from '../../../common/src/utils/utils';
|
||||
import { computeLeafFromModulusBigInt } from '../../../common/src/utils/csca';
|
||||
import { PASSPORT_ATTESTATION_ID } from '../../../common/src/constants/constants';
|
||||
|
||||
describe('Register - SHA256 RSASSAPSS', function () {
|
||||
this.timeout(0);
|
||||
let circuit: any;
|
||||
|
||||
const passportData = mockPassportData_sha256_rsapss_65537;
|
||||
const secret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
const dscSecret = BigInt(Math.floor(Math.random() * Math.pow(2, 254))).toString();
|
||||
const n_dsc = 64;
|
||||
const k_dsc = 32;
|
||||
|
||||
const inputs = generateCircuitInputsRegister(
|
||||
secret,
|
||||
dscSecret,
|
||||
PASSPORT_ATTESTATION_ID,
|
||||
passportData,
|
||||
n_dsc,
|
||||
k_dsc
|
||||
);
|
||||
|
||||
before(async () => {
|
||||
circuit = await wasm_tester(
|
||||
path.join(__dirname, '../../circuits/register/register_rsapss_65537_sha256.circom'),
|
||||
{
|
||||
include: [
|
||||
'node_modules',
|
||||
'node_modules/@zk-email/circuits/helpers/sha.circom',
|
||||
'./node_modules/@zk-kit/binary-merkle-root.circom/src',
|
||||
'./node_modules/circomlib/circuits',
|
||||
],
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should compile and load the circuit', async function () {
|
||||
expect(circuit).to.not.be.undefined;
|
||||
});
|
||||
|
||||
it('should calculate the witness with correct inputs', async function () {
|
||||
console.time('calculateWitness');
|
||||
const w = await circuit.calculateWitness(inputs);
|
||||
console.timeEnd('calculateWitness');
|
||||
await circuit.checkConstraints(w);
|
||||
|
||||
const nullifier = (await circuit.getOutput(w, ['nullifier'])).nullifier;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'nullifier', nullifier);
|
||||
const commitment_circom = (await circuit.getOutput(w, ['commitment'])).commitment;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'commitment', commitment_circom);
|
||||
const blinded_dsc_commitment = (await circuit.getOutput(w, ['blinded_dsc_commitment']))
|
||||
.blinded_dsc_commitment;
|
||||
console.log('\x1b[34m%s\x1b[0m', 'blinded_dsc_commitment', blinded_dsc_commitment);
|
||||
|
||||
const mrz_bytes = packBytes(inputs.mrz);
|
||||
const commitment_bytes = poseidon6([
|
||||
inputs.secret[0],
|
||||
PASSPORT_ATTESTATION_ID,
|
||||
computeLeafFromModulusBigInt(BigInt(passportData.pubKey.modulus)),
|
||||
mrz_bytes[0],
|
||||
mrz_bytes[1],
|
||||
mrz_bytes[2],
|
||||
]);
|
||||
const commitment_js = commitment_bytes.toString();
|
||||
//console.log('commitment_js', commitment_js)
|
||||
//console.log('commitment_circom', commitment_circom)
|
||||
expect(commitment_circom).to.be.equal(commitment_js);
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid mrz', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
mrz: Array(93)
|
||||
.fill(0)
|
||||
.map((byte) => BigInt(byte).toString()),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid dataHashes', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
dataHashes: inputs.dataHashes.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should fail to calculate witness with invalid signature', async function () {
|
||||
try {
|
||||
const invalidInputs = {
|
||||
...inputs,
|
||||
signature: inputs.signature.map((byte: string) => String((parseInt(byte, 10) + 1) % 256)),
|
||||
};
|
||||
await circuit.calculateWitness(invalidInputs);
|
||||
expect.fail('Expected an error but none was thrown.');
|
||||
} catch (error) {
|
||||
expect(error.message).to.include('Assert Failed');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,11 @@
|
||||
{
|
||||
"name": "openpassport-common",
|
||||
"version": "0.0.1",
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"test": "yarn ts-mocha tests/**/*.test.ts --exit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ashpect/smt": "https://github.com/ashpect/smt#main",
|
||||
"@babel/runtime": "^7.23.4",
|
||||
@@ -8,6 +15,7 @@
|
||||
"asn1.js": "^5.4.1",
|
||||
"asn1js": "^3.0.5",
|
||||
"axios": "^1.7.2",
|
||||
"chai": "^4.3.8",
|
||||
"elliptic": "^6.5.5",
|
||||
"fs": "^0.0.1-security",
|
||||
"js-sha1": "^0.7.0",
|
||||
@@ -15,10 +23,12 @@
|
||||
"js-sha512": "^0.9.0",
|
||||
"json-to-ts": "^2.1.0",
|
||||
"jsrsasign": "^11.1.0",
|
||||
"mocha": "^10.7.3",
|
||||
"node-forge": "https://github.com/remicolin/forge",
|
||||
"path": "^0.12.7",
|
||||
"pkijs": "^3.2.4",
|
||||
"poseidon-lite": "^0.2.0",
|
||||
"ts-mocha": "^10.0.0",
|
||||
"typescript-parser": "^2.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# How to generate mock passport data based on your real data?
|
||||
|
||||
- Build the app and scan your passport to log your passport data.
|
||||
- Copy one of the files of this folder and paste your passport data.
|
||||
- Adapt the `verify` function to verify it. Once this is done, adapt the `genMockPassportData` to generate a mock one.
|
||||
- Once the mock passport data generated is verified correctly by the same `verify` function that verifies yours, you're all set!
|
||||
- Run the script to generate a mock passport data and add it to `common/src/utils/mockPassportData.ts`
|
||||
- Do a PR
|
||||
- DM us to collect your bounty!
|
||||
@@ -1,629 +0,0 @@
|
||||
{
|
||||
"mrz": "P<FRADUPONT<<ALPHONSE<HUGUES<ALBERT<<<<<<<<<24HB818324FRA0402111M3111115<<<<<<<<<<<<<<02",
|
||||
"signatureAlgorithm": "sha256WithRSASSAPSS",
|
||||
"pubKey": {
|
||||
"modulus": "24462187253413274681146293990014601117483150253485750502784042435672184694412963307122026240846907391312882376801424642119473345751861224453041335405750030091821974208795494089279845074559882616814677854700627123408815125641207116387150180075958682953326415376187334908428885389819481874887447587379894859906385655519567588675165038354987379327125622417796020195813417774532495071662150990707566936780047952622227454986438290561518433120591444215515025611804148686981931860883842745085825036432179109865379231910853752492302597965268640127145219080386320748404798990484447108886155687702517815916586904444799519356177",
|
||||
"exponent": "65537"
|
||||
},
|
||||
"dataGroupHashes": [
|
||||
-114,
|
||||
-118,
|
||||
-62,
|
||||
50,
|
||||
66,
|
||||
9,
|
||||
-21,
|
||||
-98,
|
||||
-47,
|
||||
-62,
|
||||
-12,
|
||||
-83,
|
||||
77,
|
||||
111,
|
||||
103,
|
||||
117,
|
||||
-85,
|
||||
-35,
|
||||
-96,
|
||||
21,
|
||||
-11,
|
||||
-19,
|
||||
-27,
|
||||
-99,
|
||||
-119,
|
||||
62,
|
||||
-62,
|
||||
-36,
|
||||
-103,
|
||||
117,
|
||||
-80,
|
||||
-33,
|
||||
31,
|
||||
-123,
|
||||
108,
|
||||
84,
|
||||
-98,
|
||||
102,
|
||||
70,
|
||||
11,
|
||||
-91,
|
||||
-81,
|
||||
-60,
|
||||
12,
|
||||
-55,
|
||||
-126,
|
||||
25,
|
||||
-125,
|
||||
46,
|
||||
125,
|
||||
-100,
|
||||
-62,
|
||||
28,
|
||||
23,
|
||||
55,
|
||||
-123,
|
||||
-99,
|
||||
-92,
|
||||
-121,
|
||||
-120,
|
||||
-36,
|
||||
78,
|
||||
-66,
|
||||
82,
|
||||
-76,
|
||||
-21,
|
||||
-34,
|
||||
33,
|
||||
79,
|
||||
50,
|
||||
-104,
|
||||
-120,
|
||||
-114,
|
||||
35,
|
||||
116,
|
||||
-32,
|
||||
6,
|
||||
-14,
|
||||
-100,
|
||||
-115,
|
||||
-128,
|
||||
-8,
|
||||
10,
|
||||
61,
|
||||
98,
|
||||
86,
|
||||
-8,
|
||||
45,
|
||||
-49,
|
||||
-46,
|
||||
90,
|
||||
-24,
|
||||
-81,
|
||||
38,
|
||||
0,
|
||||
-62,
|
||||
104,
|
||||
108,
|
||||
-19,
|
||||
-10,
|
||||
97,
|
||||
-26,
|
||||
116,
|
||||
-58,
|
||||
69,
|
||||
110,
|
||||
26,
|
||||
87,
|
||||
17,
|
||||
89,
|
||||
110,
|
||||
-57,
|
||||
108,
|
||||
-6,
|
||||
36,
|
||||
21,
|
||||
39,
|
||||
87,
|
||||
110,
|
||||
102,
|
||||
-6,
|
||||
-43,
|
||||
-82,
|
||||
-125,
|
||||
-85,
|
||||
-82,
|
||||
-120,
|
||||
-101,
|
||||
87,
|
||||
-112,
|
||||
111,
|
||||
15,
|
||||
-104,
|
||||
127,
|
||||
85,
|
||||
25,
|
||||
-102,
|
||||
81,
|
||||
20,
|
||||
58,
|
||||
51,
|
||||
75,
|
||||
-63,
|
||||
116,
|
||||
-22,
|
||||
0,
|
||||
60,
|
||||
30,
|
||||
29,
|
||||
30,
|
||||
-73,
|
||||
-115,
|
||||
72,
|
||||
-9,
|
||||
-1,
|
||||
-53,
|
||||
100,
|
||||
124,
|
||||
41,
|
||||
-22,
|
||||
106,
|
||||
78,
|
||||
31,
|
||||
11,
|
||||
114,
|
||||
-119,
|
||||
-19,
|
||||
17,
|
||||
92,
|
||||
71,
|
||||
-122,
|
||||
47,
|
||||
62,
|
||||
78,
|
||||
-67,
|
||||
-23,
|
||||
-55,
|
||||
-42,
|
||||
53,
|
||||
4,
|
||||
47,
|
||||
-67,
|
||||
-55,
|
||||
-123,
|
||||
6,
|
||||
121,
|
||||
34,
|
||||
-125,
|
||||
64,
|
||||
-114,
|
||||
91,
|
||||
-34,
|
||||
-46,
|
||||
-63,
|
||||
62,
|
||||
-34,
|
||||
104,
|
||||
82,
|
||||
36,
|
||||
41,
|
||||
-118,
|
||||
-3,
|
||||
70,
|
||||
15,
|
||||
-108,
|
||||
-48,
|
||||
-100,
|
||||
45,
|
||||
105,
|
||||
-85,
|
||||
-15,
|
||||
-61,
|
||||
-71,
|
||||
43,
|
||||
-39,
|
||||
-94,
|
||||
-110,
|
||||
-55,
|
||||
-34,
|
||||
89,
|
||||
-18,
|
||||
38,
|
||||
76,
|
||||
123,
|
||||
-40,
|
||||
13,
|
||||
51,
|
||||
-29,
|
||||
72,
|
||||
-11,
|
||||
59,
|
||||
-63,
|
||||
-18,
|
||||
-90,
|
||||
103,
|
||||
49,
|
||||
23,
|
||||
-92,
|
||||
-85,
|
||||
-68,
|
||||
-62,
|
||||
-59,
|
||||
-100,
|
||||
-69,
|
||||
-7,
|
||||
28,
|
||||
-58,
|
||||
95,
|
||||
69,
|
||||
15,
|
||||
-74,
|
||||
56,
|
||||
54,
|
||||
38
|
||||
],
|
||||
"eContent": [
|
||||
49,
|
||||
102,
|
||||
48,
|
||||
21,
|
||||
6,
|
||||
9,
|
||||
42,
|
||||
-122,
|
||||
72,
|
||||
-122,
|
||||
-9,
|
||||
13,
|
||||
1,
|
||||
9,
|
||||
3,
|
||||
49,
|
||||
8,
|
||||
6,
|
||||
6,
|
||||
103,
|
||||
-127,
|
||||
8,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
48,
|
||||
28,
|
||||
6,
|
||||
9,
|
||||
42,
|
||||
-122,
|
||||
72,
|
||||
-122,
|
||||
-9,
|
||||
13,
|
||||
1,
|
||||
9,
|
||||
5,
|
||||
49,
|
||||
15,
|
||||
23,
|
||||
13,
|
||||
49,
|
||||
57,
|
||||
49,
|
||||
50,
|
||||
49,
|
||||
54,
|
||||
49,
|
||||
55,
|
||||
50,
|
||||
50,
|
||||
51,
|
||||
56,
|
||||
90,
|
||||
48,
|
||||
47,
|
||||
6,
|
||||
9,
|
||||
42,
|
||||
-122,
|
||||
72,
|
||||
-122,
|
||||
-9,
|
||||
13,
|
||||
1,
|
||||
9,
|
||||
4,
|
||||
49,
|
||||
34,
|
||||
4,
|
||||
32,
|
||||
-122,
|
||||
-17,
|
||||
-90,
|
||||
-50,
|
||||
-85,
|
||||
-36,
|
||||
1,
|
||||
-60,
|
||||
98,
|
||||
23,
|
||||
122,
|
||||
117,
|
||||
-121,
|
||||
-30,
|
||||
85,
|
||||
120,
|
||||
53,
|
||||
83,
|
||||
-125,
|
||||
-57,
|
||||
-15,
|
||||
70,
|
||||
39,
|
||||
-114,
|
||||
64,
|
||||
123,
|
||||
39,
|
||||
-78,
|
||||
-76,
|
||||
-122,
|
||||
-50,
|
||||
-17
|
||||
],
|
||||
"encryptedDigest": [
|
||||
87,
|
||||
20,
|
||||
96,
|
||||
-119,
|
||||
-78,
|
||||
21,
|
||||
117,
|
||||
-35,
|
||||
91,
|
||||
41,
|
||||
86,
|
||||
-58,
|
||||
-21,
|
||||
72,
|
||||
-36,
|
||||
58,
|
||||
-79,
|
||||
-29,
|
||||
74,
|
||||
-103,
|
||||
-98,
|
||||
-46,
|
||||
-58,
|
||||
-84,
|
||||
110,
|
||||
29,
|
||||
-89,
|
||||
-15,
|
||||
127,
|
||||
121,
|
||||
92,
|
||||
125,
|
||||
106,
|
||||
81,
|
||||
-16,
|
||||
-96,
|
||||
-9,
|
||||
112,
|
||||
-33,
|
||||
-36,
|
||||
-52,
|
||||
-114,
|
||||
-14,
|
||||
-80,
|
||||
-61,
|
||||
-59,
|
||||
33,
|
||||
-104,
|
||||
120,
|
||||
-8,
|
||||
8,
|
||||
-29,
|
||||
-56,
|
||||
14,
|
||||
-79,
|
||||
-122,
|
||||
60,
|
||||
-23,
|
||||
-100,
|
||||
72,
|
||||
51,
|
||||
-31,
|
||||
-68,
|
||||
-70,
|
||||
37,
|
||||
18,
|
||||
-91,
|
||||
47,
|
||||
-19,
|
||||
-40,
|
||||
-4,
|
||||
-59,
|
||||
-66,
|
||||
88,
|
||||
103,
|
||||
32,
|
||||
-108,
|
||||
-77,
|
||||
-15,
|
||||
-44,
|
||||
-100,
|
||||
13,
|
||||
46,
|
||||
-45,
|
||||
-41,
|
||||
115,
|
||||
-18,
|
||||
110,
|
||||
-3,
|
||||
12,
|
||||
-17,
|
||||
85,
|
||||
111,
|
||||
-51,
|
||||
12,
|
||||
6,
|
||||
114,
|
||||
0,
|
||||
92,
|
||||
58,
|
||||
-26,
|
||||
-13,
|
||||
-40,
|
||||
34,
|
||||
43,
|
||||
11,
|
||||
87,
|
||||
-72,
|
||||
-1,
|
||||
-119,
|
||||
-86,
|
||||
13,
|
||||
79,
|
||||
-1,
|
||||
-72,
|
||||
16,
|
||||
-89,
|
||||
109,
|
||||
79,
|
||||
-99,
|
||||
-26,
|
||||
-110,
|
||||
-17,
|
||||
79,
|
||||
-2,
|
||||
-37,
|
||||
-59,
|
||||
-61,
|
||||
-3,
|
||||
-50,
|
||||
57,
|
||||
121,
|
||||
-10,
|
||||
-19,
|
||||
106,
|
||||
-76,
|
||||
-43,
|
||||
-33,
|
||||
-68,
|
||||
-1,
|
||||
5,
|
||||
22,
|
||||
-5,
|
||||
-39,
|
||||
-13,
|
||||
-10,
|
||||
73,
|
||||
33,
|
||||
28,
|
||||
-48,
|
||||
-24,
|
||||
-119,
|
||||
-49,
|
||||
127,
|
||||
-115,
|
||||
-99,
|
||||
59,
|
||||
10,
|
||||
-62,
|
||||
-47,
|
||||
-33,
|
||||
99,
|
||||
54,
|
||||
112,
|
||||
116,
|
||||
62,
|
||||
99,
|
||||
68,
|
||||
-87,
|
||||
-78,
|
||||
104,
|
||||
-84,
|
||||
-105,
|
||||
61,
|
||||
104,
|
||||
-56,
|
||||
-11,
|
||||
-56,
|
||||
-102,
|
||||
-39,
|
||||
-70,
|
||||
81,
|
||||
-58,
|
||||
-7,
|
||||
98,
|
||||
30,
|
||||
29,
|
||||
-116,
|
||||
6,
|
||||
-127,
|
||||
-103,
|
||||
-5,
|
||||
98,
|
||||
-64,
|
||||
-83,
|
||||
84,
|
||||
-4,
|
||||
100,
|
||||
70,
|
||||
112,
|
||||
29,
|
||||
114,
|
||||
109,
|
||||
-3,
|
||||
-72,
|
||||
-13,
|
||||
-4,
|
||||
-10,
|
||||
-14,
|
||||
-82,
|
||||
14,
|
||||
-38,
|
||||
112,
|
||||
-112,
|
||||
15,
|
||||
-10,
|
||||
-101,
|
||||
87,
|
||||
23,
|
||||
77,
|
||||
-31,
|
||||
101,
|
||||
121,
|
||||
-6,
|
||||
-125,
|
||||
117,
|
||||
126,
|
||||
103,
|
||||
100,
|
||||
10,
|
||||
95,
|
||||
-90,
|
||||
-103,
|
||||
-92,
|
||||
-118,
|
||||
32,
|
||||
124,
|
||||
-115,
|
||||
-116,
|
||||
4,
|
||||
73,
|
||||
-15,
|
||||
60,
|
||||
-16,
|
||||
-23,
|
||||
110,
|
||||
30,
|
||||
-122,
|
||||
42,
|
||||
-28,
|
||||
57,
|
||||
-59,
|
||||
-60,
|
||||
118,
|
||||
53,
|
||||
122
|
||||
],
|
||||
"photoBase64": "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABjElEQVR42mL8//8/AyUYiBQYmIw3..."
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
import assert from 'assert';
|
||||
import { PassportData } from '../../../common/src/utils/types';
|
||||
import {
|
||||
hash,
|
||||
assembleEContent,
|
||||
formatAndConcatenateDataHashes,
|
||||
formatMrz,
|
||||
arraysAreEqual,
|
||||
findSubarrayIndex,
|
||||
} from '../../../common/src/utils/utils';
|
||||
import * as forge from 'node-forge';
|
||||
import { writeFileSync } from 'fs';
|
||||
import elliptic from 'elliptic';
|
||||
import * as crypto from 'crypto';
|
||||
import { sampleDataHashes_large } from '../../src/constants/sampleDataHashes';
|
||||
|
||||
const sampleMRZ =
|
||||
'P<FRADUPONT<<ALPHONSE<HUGUES<ALBERT<<<<<<<<<24HB818324FRA0402111M3111115<<<<<<<<<<<<<<02';
|
||||
const signatureAlgorithm = 'ecdsa-with-SHA1';
|
||||
const hashLen = 20;
|
||||
|
||||
export function genMockPassportData_sha1WithECDSA(): PassportData {
|
||||
const mrzHash = hash(signatureAlgorithm, formatMrz(sampleMRZ));
|
||||
sampleDataHashes_large.unshift([1, mrzHash]);
|
||||
const concatenatedDataHashes = formatAndConcatenateDataHashes(
|
||||
[[1, mrzHash], ...sampleDataHashes_large],
|
||||
hashLen,
|
||||
33
|
||||
);
|
||||
const eContent = assembleEContent(hash(signatureAlgorithm, concatenatedDataHashes));
|
||||
|
||||
const ec = new elliptic.ec('p256');
|
||||
const keyPair = ec.genKeyPair();
|
||||
const pubKey = keyPair.getPublic();
|
||||
|
||||
const md = forge.md.sha1.create();
|
||||
md.update(forge.util.binary.raw.encode(new Uint8Array(eContent)));
|
||||
const signature = keyPair.sign(md.digest().toHex(), 'hex');
|
||||
const signatureBytes = Array.from(Buffer.from(signature.toDER(), 'hex'));
|
||||
|
||||
const Qx = pubKey.getX().toString(16);
|
||||
const Qy = pubKey.getY().toString(16);
|
||||
|
||||
return {
|
||||
mrz: sampleMRZ,
|
||||
signatureAlgorithm: signatureAlgorithm,
|
||||
pubKey: {
|
||||
publicKeyQ: `(${Qx},${Qy},1,fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc)`,
|
||||
},
|
||||
dataGroupHashes: concatenatedDataHashes,
|
||||
eContent: eContent,
|
||||
encryptedDigest: signatureBytes,
|
||||
photoBase64: 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABjElEQVR42mL8//8/AyUYiBQYmIw3...',
|
||||
};
|
||||
}
|
||||
|
||||
function verify(passportData: PassportData): boolean {
|
||||
const { mrz, signatureAlgorithm, pubKey, dataGroupHashes, eContent, encryptedDigest } =
|
||||
passportData;
|
||||
const formattedMrz = formatMrz(mrz);
|
||||
const mrzHash = hash(signatureAlgorithm, formattedMrz);
|
||||
const dg1HashOffset = findSubarrayIndex(dataGroupHashes, mrzHash);
|
||||
console.log('dg1HashOffset', dg1HashOffset);
|
||||
assert(dg1HashOffset !== -1, 'MRZ hash index not found in dataGroupHashes');
|
||||
|
||||
const concatHash = hash(signatureAlgorithm, dataGroupHashes);
|
||||
assert(
|
||||
arraysAreEqual(concatHash, eContent.slice(eContent.length - concatHash.length)),
|
||||
'concatHash is not at the right place in eContent'
|
||||
);
|
||||
|
||||
const cleanPublicKeyQ = pubKey.publicKeyQ.replace(/[()]/g, '').split(',');
|
||||
const Qx = cleanPublicKeyQ[0];
|
||||
const Qy = cleanPublicKeyQ[1];
|
||||
|
||||
const ec = new elliptic.ec('p256');
|
||||
const key = ec.keyFromPublic({ x: Qx, y: Qy }, 'hex');
|
||||
|
||||
const messageBuffer = Buffer.from(eContent);
|
||||
const msgHash = crypto.createHash('sha1').update(messageBuffer).digest();
|
||||
|
||||
const signature = Buffer.from(encryptedDigest).toString('hex');
|
||||
|
||||
const isValid = key.verify(msgHash, signature);
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
const mockPassportData = genMockPassportData_sha1WithECDSA();
|
||||
console.log('Passport Data:', JSON.stringify(mockPassportData, null, 2));
|
||||
console.log('Signature valid:', verify(mockPassportData));
|
||||
|
||||
writeFileSync(__dirname + '/passportData.json', JSON.stringify(mockPassportData, null, 2));
|
||||
@@ -1,81 +0,0 @@
|
||||
import { readFileSync, writeFileSync } from "fs";
|
||||
import { PassportData } from "../../src/utils/types";
|
||||
import { hash, assembleEContent, formatAndConcatenateDataHashes, formatMrz, hexToDecimal, arraysAreEqual, findSubarrayIndex } from "../../src/utils/utils";
|
||||
import * as forge from 'node-forge';
|
||||
import { assert } from "console";
|
||||
import { mock_dsc_key_sha1_rsa_4096 } from "../../src/constants/mockCertificates";
|
||||
import { sampleDataHashes_small } from "../../src/constants/sampleDataHashes";
|
||||
|
||||
const sampleMRZ = "P<FRADUPONT<<ALPHONSE<HUGUES<ALBERT<<<<<<<<<24HB818324FRA0402111M3111115<<<<<<<<<<<<<<02"
|
||||
const signatureAlgorithm = 'sha1WithRSAEncryption'
|
||||
const hashLen = 20
|
||||
|
||||
export function genMockPassportData_sha1WithRSAEncryption_65537(): PassportData {
|
||||
const mrzHash = hash(signatureAlgorithm, formatMrz(sampleMRZ));
|
||||
const concatenatedDataHashes = formatAndConcatenateDataHashes(
|
||||
[[1, mrzHash], ...sampleDataHashes_small],
|
||||
hashLen,
|
||||
31 // could have been different
|
||||
);
|
||||
|
||||
const eContent = assembleEContent(hash(signatureAlgorithm, concatenatedDataHashes));
|
||||
|
||||
const privKey = forge.pki.privateKeyFromPem(mock_dsc_key_sha1_rsa_4096);
|
||||
const modulus = privKey.n.toString(16);
|
||||
|
||||
const md = forge.md.sha1.create();
|
||||
md.update(forge.util.binary.raw.encode(new Uint8Array(eContent)));
|
||||
|
||||
const signature = privKey.sign(md)
|
||||
const signatureBytes = Array.from(signature, (c: string) => c.charCodeAt(0));
|
||||
|
||||
return {
|
||||
mrz: sampleMRZ,
|
||||
signatureAlgorithm: signatureAlgorithm,
|
||||
pubKey: {
|
||||
modulus: hexToDecimal(modulus),
|
||||
exponent: '65537',
|
||||
},
|
||||
dataGroupHashes: concatenatedDataHashes,
|
||||
eContent: eContent,
|
||||
encryptedDigest: signatureBytes,
|
||||
photoBase64: "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABjElEQVR42mL8//8/AyUYiBQYmIw3..."
|
||||
}
|
||||
}
|
||||
|
||||
function verify(passportData: PassportData): boolean {
|
||||
const { mrz, signatureAlgorithm, pubKey, dataGroupHashes, eContent, encryptedDigest } = passportData;
|
||||
const formattedMrz = formatMrz(mrz);
|
||||
const mrzHash = hash(signatureAlgorithm, formattedMrz);
|
||||
const dg1HashOffset = findSubarrayIndex(dataGroupHashes, mrzHash)
|
||||
console.log('dg1HashOffset', dg1HashOffset);
|
||||
assert(dg1HashOffset !== -1, 'MRZ hash index not found in dataGroupHashes');
|
||||
|
||||
const concatHash = hash(signatureAlgorithm, dataGroupHashes)
|
||||
assert(
|
||||
arraysAreEqual(
|
||||
concatHash,
|
||||
eContent.slice(eContent.length - concatHash.length)
|
||||
),
|
||||
'concatHash is not at the right place in eContent'
|
||||
);
|
||||
|
||||
const modulus = new forge.jsbn.BigInteger(pubKey.modulus, 10);
|
||||
const exponent = new forge.jsbn.BigInteger(pubKey.exponent, 10);
|
||||
const rsaPublicKey = forge.pki.rsa.setPublicKey(modulus, exponent);
|
||||
|
||||
const md = forge.md.sha1.create();
|
||||
md.update(forge.util.binary.raw.encode(new Uint8Array(eContent)));
|
||||
|
||||
const signature = Buffer.from(encryptedDigest).toString(
|
||||
'binary',
|
||||
);
|
||||
|
||||
return rsaPublicKey.verify(md.digest().bytes(), signature);
|
||||
}
|
||||
|
||||
const mockPassportData = genMockPassportData_sha1WithRSAEncryption_65537();
|
||||
console.log("Passport Data:", JSON.stringify(mockPassportData, null, 2));
|
||||
console.log("Signature valid:", verify(mockPassportData));
|
||||
|
||||
writeFileSync(__dirname + '/passportData.json', JSON.stringify(mockPassportData, null, 2));
|
||||
@@ -1,88 +0,0 @@
|
||||
import assert from 'assert';
|
||||
import { PassportData } from '../../../common/src/utils/types';
|
||||
import {
|
||||
hash,
|
||||
assembleEContent,
|
||||
formatAndConcatenateDataHashes,
|
||||
formatMrz,
|
||||
arraysAreEqual,
|
||||
findSubarrayIndex,
|
||||
} from '../../../common/src/utils/utils';
|
||||
import * as asn1 from 'asn1js';
|
||||
import { Certificate } from 'pkijs';
|
||||
import { writeFileSync } from 'fs';
|
||||
import elliptic from 'elliptic';
|
||||
import { sampleDataHashes_large } from '../../src/constants/sampleDataHashes';
|
||||
import { mock_dsc_key_sha256_ecdsa, mock_dsc_sha256_ecdsa } from "../../src/constants/mockCertificates";
|
||||
|
||||
const sampleMRZ =
|
||||
'P<FRADUPONT<<ALPHONSE<HUGUES<ALBERT<<<<<<<<<24HB818324FRA0402111M3111115<<<<<<<<<<<<<<02';
|
||||
const signatureAlgorithm = 'ecdsa-with-SHA256';
|
||||
const hashLen = 32;
|
||||
const ec = new elliptic.ec('p256');
|
||||
|
||||
export function genMockPassportData_sha256WithECDSA(): PassportData {
|
||||
const mrzHash = hash(signatureAlgorithm, formatMrz(sampleMRZ));
|
||||
sampleDataHashes_large.unshift([1, mrzHash]);
|
||||
const concatenatedDataHashes = formatAndConcatenateDataHashes(
|
||||
[[1, mrzHash], ...sampleDataHashes_large],
|
||||
hashLen,
|
||||
33
|
||||
);
|
||||
const eContent = assembleEContent(hash(signatureAlgorithm, concatenatedDataHashes));
|
||||
|
||||
const privateKeyDer = Buffer.from(mock_dsc_key_sha256_ecdsa.replace(/-----BEGIN EC PRIVATE KEY-----|\n|-----END EC PRIVATE KEY-----/g, ''), 'base64');
|
||||
const asn1Data = asn1.fromBER(privateKeyDer);
|
||||
const privateKeyBuffer = (asn1Data.result.valueBlock as any).value[1].valueBlock.valueHexView;
|
||||
|
||||
const keyPair = ec.keyFromPrivate(privateKeyBuffer);
|
||||
|
||||
const eContentHash = hash(signatureAlgorithm, eContent);
|
||||
const signature = keyPair.sign(eContentHash);
|
||||
const signatureBytes = signature.toDER();
|
||||
|
||||
return {
|
||||
mrz: sampleMRZ,
|
||||
signatureAlgorithm: signatureAlgorithm,
|
||||
dsc: mock_dsc_sha256_ecdsa,
|
||||
dataGroupHashes: concatenatedDataHashes,
|
||||
eContent: eContent,
|
||||
encryptedDigest: signatureBytes,
|
||||
photoBase64: 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABjElEQVR42mL8//8/AyUYiBQYmIw3...',
|
||||
};
|
||||
}
|
||||
|
||||
function verify(passportData: PassportData): boolean {
|
||||
const { mrz, signatureAlgorithm, dsc, dataGroupHashes, eContent, encryptedDigest } =
|
||||
passportData;
|
||||
const formattedMrz = formatMrz(mrz);
|
||||
const mrzHash = hash(signatureAlgorithm, formattedMrz);
|
||||
const dg1HashOffset = findSubarrayIndex(dataGroupHashes, mrzHash);
|
||||
console.log('dg1HashOffset', dg1HashOffset);
|
||||
assert(dg1HashOffset !== -1, 'MRZ hash index not found in dataGroupHashes');
|
||||
|
||||
const concatHash = hash(signatureAlgorithm, dataGroupHashes);
|
||||
assert(
|
||||
arraysAreEqual(concatHash, eContent.slice(eContent.length - concatHash.length)),
|
||||
'concatHash is not at the right place in eContent'
|
||||
);
|
||||
|
||||
const certBuffer = Buffer.from(dsc.replace(/(-----(BEGIN|END) CERTIFICATE-----|\n)/g, ''), 'base64');
|
||||
const asn1Data = asn1.fromBER(certBuffer);
|
||||
const cert = new Certificate({ schema: asn1Data.result });
|
||||
const publicKeyInfo = cert.subjectPublicKeyInfo;
|
||||
const publicKeyBuffer = publicKeyInfo.subjectPublicKey.valueBlock.valueHexView;
|
||||
|
||||
const key = ec.keyFromPublic(publicKeyBuffer);
|
||||
|
||||
const eContentHash = hash(signatureAlgorithm, eContent);
|
||||
const signature = Buffer.from(encryptedDigest).toString('hex');
|
||||
|
||||
return key.verify(eContentHash, signature);
|
||||
}
|
||||
|
||||
const mockPassportData = genMockPassportData_sha256WithECDSA();
|
||||
console.log('Passport Data:', JSON.stringify(mockPassportData, null, 2));
|
||||
console.log('Signature valid:', verify(mockPassportData));
|
||||
|
||||
writeFileSync(__dirname + '/passportData.json', JSON.stringify(mockPassportData, null, 2));
|
||||
@@ -1,81 +0,0 @@
|
||||
import assert from "assert";
|
||||
import { PassportData } from "../../src/utils/types";
|
||||
import { hash, assembleEContent, formatAndConcatenateDataHashes, formatMrz, hexToDecimal, arraysAreEqual, findSubarrayIndex } from "../../src/utils/utils";
|
||||
import * as forge from 'node-forge';
|
||||
import { writeFileSync, readFileSync } from "fs";
|
||||
import { mock_dsc_key_sha256_rsa_4096 } from "../../src/constants/mockCertificates";
|
||||
import { sampleDataHashes_large } from "../../src/constants/sampleDataHashes";
|
||||
|
||||
const sampleMRZ = "P<FRADUPONT<<ALPHONSE<HUGUES<ALBERT<<<<<<<<<24HB818324FRA0402111M3111115<<<<<<<<<<<<<<02"
|
||||
const signatureAlgorithm = 'sha256WithRSAEncryption'
|
||||
const hashLen = 32
|
||||
|
||||
export function genMockPassportData_sha256WithRSAEncryption_65537(): PassportData {
|
||||
const mrzHash = hash(signatureAlgorithm, formatMrz(sampleMRZ));
|
||||
const concatenatedDataHashes = formatAndConcatenateDataHashes(
|
||||
[[1, mrzHash], ...sampleDataHashes_large],
|
||||
hashLen,
|
||||
31
|
||||
);
|
||||
|
||||
const eContent = assembleEContent(hash(signatureAlgorithm, concatenatedDataHashes));
|
||||
|
||||
const privKey = forge.pki.privateKeyFromPem(mock_dsc_key_sha256_rsa_4096);
|
||||
const modulus = privKey.n.toString(16);
|
||||
|
||||
const md = forge.md.sha256.create();
|
||||
md.update(forge.util.binary.raw.encode(new Uint8Array(eContent)));
|
||||
|
||||
const signature = privKey.sign(md)
|
||||
const signatureBytes = Array.from(signature, (c: string) => c.charCodeAt(0));
|
||||
|
||||
return {
|
||||
mrz: sampleMRZ,
|
||||
signatureAlgorithm: signatureAlgorithm,
|
||||
pubKey: {
|
||||
modulus: hexToDecimal(modulus),
|
||||
exponent: '65537',
|
||||
},
|
||||
dataGroupHashes: concatenatedDataHashes,
|
||||
eContent: eContent,
|
||||
encryptedDigest: signatureBytes,
|
||||
photoBase64: "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABjElEQVR42mL8//8/AyUYiBQYmIw3..."
|
||||
}
|
||||
}
|
||||
|
||||
function verify(passportData: PassportData): boolean {
|
||||
const { mrz, signatureAlgorithm, pubKey, dataGroupHashes, eContent, encryptedDigest } = passportData;
|
||||
const formattedMrz = formatMrz(mrz);
|
||||
const mrzHash = hash(signatureAlgorithm, formattedMrz);
|
||||
const dg1HashOffset = findSubarrayIndex(dataGroupHashes, mrzHash)
|
||||
console.log('dg1HashOffset', dg1HashOffset);
|
||||
assert(dg1HashOffset !== -1, 'MRZ hash index not found in dataGroupHashes');
|
||||
|
||||
const concatHash = hash(signatureAlgorithm, dataGroupHashes)
|
||||
assert(
|
||||
arraysAreEqual(
|
||||
concatHash,
|
||||
eContent.slice(eContent.length - hashLen)
|
||||
),
|
||||
'concatHash is not at the right place in eContent'
|
||||
);
|
||||
|
||||
const modulus = new forge.jsbn.BigInteger(pubKey.modulus, 10);
|
||||
const exponent = new forge.jsbn.BigInteger(pubKey.exponent, 10);
|
||||
const rsaPublicKey = forge.pki.rsa.setPublicKey(modulus, exponent);
|
||||
|
||||
const md = forge.md.sha256.create();
|
||||
md.update(forge.util.binary.raw.encode(new Uint8Array(eContent)));
|
||||
|
||||
const signature = Buffer.from(encryptedDigest).toString(
|
||||
'binary',
|
||||
);
|
||||
|
||||
return rsaPublicKey.verify(md.digest().bytes(), signature);
|
||||
}
|
||||
|
||||
const mockPassportData = genMockPassportData_sha256WithRSAEncryption_65537();
|
||||
console.log("Passport Data:", JSON.stringify(mockPassportData, null, 2));
|
||||
console.log("Signature valid:", verify(mockPassportData));
|
||||
|
||||
writeFileSync(__dirname + '/passportData.json', JSON.stringify(mockPassportData, null, 2));
|
||||
@@ -1,103 +0,0 @@
|
||||
import assert from "assert";
|
||||
import { PassportData } from "../../src/utils/types";
|
||||
import { hash, assembleEContent, formatAndConcatenateDataHashes, formatMrz, arraysAreEqual, findSubarrayIndex } from "../../src/utils/utils";
|
||||
import * as forge from 'node-forge';
|
||||
import crypto from 'crypto';
|
||||
import { readFileSync, writeFileSync } from "fs";
|
||||
import { mock_dsc_key_sha256_rsapss_2048 } from "../../src/constants/mockCertificates";
|
||||
import { mock_dsc_sha256_rsapss_2048 } from "../../src/constants/mockCertificates";
|
||||
import { sampleDataHashes_large } from "../../src/constants/sampleDataHashes";
|
||||
|
||||
const sampleMRZ = "P<FRADUPONT<<ALPHONSE<HUGUES<ALBERT<<<<<<<<<24HB818324FRA0402111M3111115<<<<<<<<<<<<<<02"
|
||||
const signatureAlgorithm = 'sha256WithRSASSAPSS'
|
||||
const hashLen = 32
|
||||
|
||||
export function genMockPassportData_sha256WithRSASSAPSS_65537(): PassportData {
|
||||
const privateKeyPem = forge.pki.privateKeyFromPem(mock_dsc_key_sha256_rsapss_2048);
|
||||
const privateKeyPemString = forge.pki.privateKeyToPem(privateKeyPem);
|
||||
const certificate = forge.pki.certificateFromPem(mock_dsc_sha256_rsapss_2048);
|
||||
|
||||
const publicKey = certificate.publicKey as forge.pki.rsa.PublicKey;
|
||||
|
||||
const modulus = (publicKey as any).n.toString(10);
|
||||
const exponent = (publicKey as any).e.toString(10);
|
||||
const salt = Buffer.from('dee959c7e06411361420ff80185ed57f3e6776afdee959c7e064113614201420', 'hex');
|
||||
|
||||
const mrzHash = hash(signatureAlgorithm, formatMrz(sampleMRZ));
|
||||
const concatenatedDataHashes = formatAndConcatenateDataHashes(
|
||||
[[1, mrzHash], ...sampleDataHashes_large],
|
||||
hashLen,
|
||||
30
|
||||
);
|
||||
|
||||
const eContent = assembleEContent(hash(signatureAlgorithm, concatenatedDataHashes));
|
||||
|
||||
const my_message = Buffer.from(eContent);
|
||||
const hash_algorithm = 'sha256';
|
||||
|
||||
const private_key = {
|
||||
key: privateKeyPemString,
|
||||
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
|
||||
saltLength: salt.length,
|
||||
};
|
||||
|
||||
const signature = crypto.sign(hash_algorithm, my_message, private_key);
|
||||
const signatureArray = Array.from(signature, byte => byte < 128 ? byte : byte - 256);
|
||||
|
||||
return {
|
||||
mrz: sampleMRZ,
|
||||
signatureAlgorithm: signatureAlgorithm,
|
||||
pubKey: {
|
||||
modulus: modulus,
|
||||
exponent: exponent,
|
||||
},
|
||||
dataGroupHashes: concatenatedDataHashes,
|
||||
eContent: eContent,
|
||||
encryptedDigest: signatureArray,
|
||||
photoBase64: "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABjElEQVR42mL8//8/AyUYiBQYmIw3..."
|
||||
}
|
||||
}
|
||||
|
||||
function verify(passportData: PassportData): boolean {
|
||||
const { mrz, signatureAlgorithm, pubKey, dataGroupHashes, eContent, encryptedDigest } = passportData;
|
||||
const formattedMrz = formatMrz(mrz);
|
||||
const mrzHash = hash(signatureAlgorithm, formattedMrz);
|
||||
const dg1HashOffset = findSubarrayIndex(dataGroupHashes, mrzHash)
|
||||
console.log('dg1HashOffset', dg1HashOffset);
|
||||
assert(dg1HashOffset !== -1, 'MRZ hash index not found in dataGroupHashes');
|
||||
|
||||
const concatHash = hash(signatureAlgorithm, dataGroupHashes)
|
||||
assert(
|
||||
arraysAreEqual(
|
||||
concatHash,
|
||||
eContent.slice(eContent.length - concatHash.length)
|
||||
),
|
||||
'concatHash is not at the right place in eContent'
|
||||
);
|
||||
|
||||
const modulus = new forge.jsbn.BigInteger(pubKey.modulus, 10);
|
||||
const exponent = new forge.jsbn.BigInteger(pubKey.exponent, 10);
|
||||
const publicKey = forge.pki.setRsaPublicKey(modulus, exponent);
|
||||
const pem = forge.pki.publicKeyToPem(publicKey);
|
||||
const rsa_public = Buffer.from(pem);
|
||||
|
||||
const message = Buffer.from(eContent);
|
||||
const signature = Buffer.from(encryptedDigest);
|
||||
const hash_algorithm = "sha256";
|
||||
|
||||
const public_key = {
|
||||
key: rsa_public,
|
||||
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
|
||||
saltLength: 32,
|
||||
};
|
||||
|
||||
const isVerified = crypto.verify(hash_algorithm, message, public_key, signature);
|
||||
|
||||
return isVerified;
|
||||
}
|
||||
|
||||
const mockPassportData = genMockPassportData_sha256WithRSASSAPSS_65537();
|
||||
console.log("Passport Data:", JSON.stringify(mockPassportData, null, 2));
|
||||
console.log("Signature valid:", verify(mockPassportData));
|
||||
|
||||
writeFileSync(__dirname + '/passportData.json', JSON.stringify(mockPassportData, null, 2));
|
||||
@@ -1,88 +0,0 @@
|
||||
import assert from "assert";
|
||||
import { PassportData } from "../../src/utils/types";
|
||||
import { hash, assembleEContent, formatAndConcatenateDataHashes, formatMrz, arraysAreEqual, findSubarrayIndex } from "../../src/utils/utils";
|
||||
import * as forge from 'node-forge';
|
||||
import { writeFileSync } from "fs";
|
||||
import elliptic from 'elliptic';
|
||||
import * as crypto from 'crypto';
|
||||
import { sampleDataHashes_large } from "../../src/constants/sampleDataHashes";
|
||||
|
||||
const sampleMRZ = "P<FRADUPONT<<ALPHONSE<HUGUES<ALBERT<<<<<<<<<24HB818324FRA0402111M3111115<<<<<<<<<<<<<<02"
|
||||
const signatureAlgorithm = 'SHA384withECDSA'
|
||||
const hashLen = 46
|
||||
|
||||
export function genMockPassportData_SHA384withECDSA(): PassportData {
|
||||
const mrzHash = hash(signatureAlgorithm, formatMrz(sampleMRZ));
|
||||
sampleDataHashes_large.unshift([1, mrzHash]);
|
||||
const concatenatedDataHashes = formatAndConcatenateDataHashes(
|
||||
[[1, mrzHash], ...sampleDataHashes_large],
|
||||
hashLen,
|
||||
33
|
||||
);
|
||||
const eContent = assembleEContent(hash(signatureAlgorithm, concatenatedDataHashes));
|
||||
|
||||
const ec = new elliptic.ec('p384');
|
||||
const keyPair = ec.genKeyPair();
|
||||
const pubKey = keyPair.getPublic();
|
||||
|
||||
const md = forge.md.sha384.create();
|
||||
md.update(forge.util.binary.raw.encode(new Uint8Array(eContent)));
|
||||
const signature = keyPair.sign(md.digest().toHex(), 'hex');
|
||||
const signatureBytes = Array.from(Buffer.from(signature.toDER(), 'hex'));
|
||||
|
||||
const Qx = pubKey.getX().toString(16);
|
||||
const Qy = pubKey.getY().toString(16);
|
||||
|
||||
return {
|
||||
mrz: sampleMRZ,
|
||||
signatureAlgorithm: signatureAlgorithm,
|
||||
pubKey: {
|
||||
publicKeyQ: `(${Qx},${Qy},1,fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc)`
|
||||
},
|
||||
dataGroupHashes: concatenatedDataHashes,
|
||||
eContent: eContent,
|
||||
encryptedDigest: signatureBytes,
|
||||
photoBase64: "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABjElEQVR42mL8//8/AyUYiBQYmIw3..."
|
||||
}
|
||||
}
|
||||
|
||||
function verify(passportData: PassportData): boolean {
|
||||
const { mrz, signatureAlgorithm, pubKey, dataGroupHashes, eContent, encryptedDigest } = passportData;
|
||||
const formattedMrz = formatMrz(mrz);
|
||||
const mrzHash = hash(signatureAlgorithm, formattedMrz);
|
||||
const dg1HashOffset = findSubarrayIndex(dataGroupHashes, mrzHash)
|
||||
console.log('dg1HashOffset', dg1HashOffset);
|
||||
assert(dg1HashOffset !== -1, 'MRZ hash index not found in dataGroupHashes');
|
||||
|
||||
const concatHash = hash(signatureAlgorithm, dataGroupHashes)
|
||||
assert(
|
||||
arraysAreEqual(
|
||||
concatHash,
|
||||
eContent.slice(eContent.length - concatHash.length)
|
||||
),
|
||||
'concatHash is not at the right place in eContent'
|
||||
);
|
||||
|
||||
const cleanPublicKeyQ = pubKey.publicKeyQ.replace(/[()]/g, '').split(',');
|
||||
const Qx = cleanPublicKeyQ[0];
|
||||
const Qy = cleanPublicKeyQ[1];
|
||||
|
||||
const ec = new elliptic.ec('p384');
|
||||
const key = ec.keyFromPublic({ x: Qx, y: Qy }, 'hex');
|
||||
|
||||
const messageBuffer = Buffer.from(eContent);
|
||||
const msgHash = crypto.createHash('sha384').update(messageBuffer).digest();
|
||||
|
||||
const signature = Buffer.from(encryptedDigest).toString('hex');
|
||||
|
||||
const isValid = key.verify(msgHash, signature);
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
|
||||
const mockPassportData = genMockPassportData_SHA384withECDSA();
|
||||
console.log("Passport Data:", JSON.stringify(mockPassportData, null, 2));
|
||||
console.log("Signature valid:", verify(mockPassportData));
|
||||
|
||||
writeFileSync(__dirname + '/passportData.json', JSON.stringify(mockPassportData, null, 2));
|
||||
@@ -1,93 +0,0 @@
|
||||
import assert from 'assert';
|
||||
import { PassportData } from '../../../common/src/utils/types';
|
||||
import {
|
||||
hash,
|
||||
assembleEContent,
|
||||
formatAndConcatenateDataHashes,
|
||||
formatMrz,
|
||||
arraysAreEqual,
|
||||
findSubarrayIndex,
|
||||
} from '../../../common/src/utils/utils';
|
||||
import * as forge from 'node-forge';
|
||||
import { writeFileSync } from 'fs';
|
||||
import elliptic from 'elliptic';
|
||||
import * as crypto from 'crypto';
|
||||
import { sampleDataHashes_large } from '../../src/constants/sampleDataHashes';
|
||||
|
||||
const sampleMRZ =
|
||||
'P<FRADUPONT<<ALPHONSE<HUGUES<ALBERT<<<<<<<<<24HB818324FRA0402111M3111115<<<<<<<<<<<<<<02';
|
||||
const signatureAlgorithm = 'ecdsa-with-SHA512';
|
||||
const hashLen = 64;
|
||||
|
||||
export function genMockPassportData_sha512WithECDSA(): PassportData {
|
||||
const mrzHash = hash(signatureAlgorithm, formatMrz(sampleMRZ));
|
||||
sampleDataHashes_large.unshift([1, mrzHash]);
|
||||
const concatenatedDataHashes = formatAndConcatenateDataHashes(
|
||||
[[1, mrzHash], ...sampleDataHashes_large],
|
||||
hashLen,
|
||||
33
|
||||
);
|
||||
const eContent = assembleEContent(hash(signatureAlgorithm, concatenatedDataHashes));
|
||||
|
||||
const ec = new elliptic.ec('p256');
|
||||
const keyPair = ec.genKeyPair();
|
||||
const pubKey = keyPair.getPublic();
|
||||
|
||||
const md = forge.md.sha512.create();
|
||||
md.update(forge.util.binary.raw.encode(new Uint8Array(eContent)));
|
||||
const signature = keyPair.sign(md.digest().toHex(), 'hex');
|
||||
const signatureBytes = Array.from(Buffer.from(signature.toDER(), 'hex'));
|
||||
|
||||
const Qx = pubKey.getX().toString(16);
|
||||
const Qy = pubKey.getY().toString(16);
|
||||
|
||||
return {
|
||||
mrz: sampleMRZ,
|
||||
signatureAlgorithm: signatureAlgorithm,
|
||||
pubKey: {
|
||||
publicKeyQ: `(${Qx},${Qy},1,fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc)`,
|
||||
},
|
||||
dataGroupHashes: concatenatedDataHashes,
|
||||
eContent: eContent,
|
||||
encryptedDigest: signatureBytes,
|
||||
photoBase64: 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABjElEQVR42mL8//8/AyUYiBQYmIw3...',
|
||||
};
|
||||
}
|
||||
|
||||
function verify(passportData: PassportData): boolean {
|
||||
const { mrz, signatureAlgorithm, pubKey, dataGroupHashes, eContent, encryptedDigest } =
|
||||
passportData;
|
||||
const formattedMrz = formatMrz(mrz);
|
||||
const mrzHash = hash(signatureAlgorithm, formattedMrz);
|
||||
const dg1HashOffset = findSubarrayIndex(dataGroupHashes, mrzHash);
|
||||
console.log('dg1HashOffset', dg1HashOffset);
|
||||
assert(dg1HashOffset !== -1, 'MRZ hash index not found in dataGroupHashes');
|
||||
|
||||
const concatHash = hash(signatureAlgorithm, dataGroupHashes);
|
||||
assert(
|
||||
arraysAreEqual(concatHash, eContent.slice(eContent.length - concatHash.length)),
|
||||
'concatHash is not at the right place in eContent'
|
||||
);
|
||||
|
||||
const cleanPublicKeyQ = pubKey.publicKeyQ.replace(/[()]/g, '').split(',');
|
||||
const Qx = cleanPublicKeyQ[0];
|
||||
const Qy = cleanPublicKeyQ[1];
|
||||
|
||||
const ec = new elliptic.ec('p256');
|
||||
const key = ec.keyFromPublic({ x: Qx, y: Qy }, 'hex');
|
||||
|
||||
const messageBuffer = Buffer.from(eContent);
|
||||
const msgHash = crypto.createHash('sha512').update(messageBuffer).digest();
|
||||
|
||||
const signature = Buffer.from(encryptedDigest).toString('hex');
|
||||
|
||||
const isValid = key.verify(msgHash, signature);
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
const mockPassportData = genMockPassportData_sha512WithECDSA();
|
||||
console.log('Passport Data:', JSON.stringify(mockPassportData, null, 2));
|
||||
console.log('Signature valid:', verify(mockPassportData));
|
||||
|
||||
writeFileSync(__dirname + '/passportData.json', JSON.stringify(mockPassportData, null, 2));
|
||||
@@ -52,6 +52,8 @@ export const attributeToPosition = {
|
||||
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;
|
||||
export const n_dsc_ecdsa = 43; // 43 * 6 = 258 > 254 Cirom field size
|
||||
export const k_dsc_ecdsa = 6;
|
||||
export const n_csca = 121;
|
||||
export const k_csca = 34;
|
||||
export const max_cert_bytes = 1664;
|
||||
|
||||
@@ -470,4 +470,51 @@ xncatW0Ixvl73iXA6WG45093oyEwHzAdBgNVHQ4EFgQUUa6p5iCBqbhslwC79LHX
|
||||
EyYTiP0wCgYIKoZIzj0EAwIDSAAwRQIhAP6XA1AWr8v6f7EJz3u5GuudyCKqiuBY
|
||||
mDhB0W8OhhR2AiAMTm++57YJkbQNxzL75nypXSdZmBfiQXSNM0NFpHEuIQ==
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
|
||||
export const mock_dsc_key_sha1_ecdsa = `-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIK2wRGm6xnmTnHhOtyUxp/PFPTySoaD+f2JNXy9JAmRVoAoGCCqGSM49
|
||||
AwEHoUQDQgAEzqM5vQEv7vhD7ZXecfkSvC/vfDffjuEyUK3DLlvjbxUIXeaJ+dUg
|
||||
zb8+rYwVh+Ai/DDxCLuSy2wn4gbOFwzOGA==
|
||||
-----END EC PRIVATE KEY-----
|
||||
`
|
||||
|
||||
export const mock_dsc_sha1_ecdsa = `-----BEGIN CERTIFICATE-----
|
||||
MIICBDCCAaygAwIBAgIULaL4N+BRrqV1D8UeefZegXfkWogwCQYHKoZIzj0EATBy
|
||||
MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFU3RhdGUxDTALBgNVBAcMBENpdHkxFTAT
|
||||
BgNVBAoMDE9yZ2FuaXphdGlvbjETMBEGA1UECwwKRGVwYXJ0bWVudDEYMBYGA1UE
|
||||
AwwPd3d3LmV4YW1wbGUuY29tMB4XDTI0MDkxMzEyNTgzNVoXDTI1MDkxMzEyNTgz
|
||||
NVowcjELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5
|
||||
MRUwEwYDVQQKDAxPcmdhbml6YXRpb24xEzARBgNVBAsMCkRlcGFydG1lbnQxGDAW
|
||||
BgNVBAMMD3d3dy5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA
|
||||
BM6jOb0BL+74Q+2V3nH5Erwv73w3347hMlCtwy5b428VCF3mifnVIM2/Pq2MFYfg
|
||||
Ivww8Qi7kstsJ+IGzhcMzhijITAfMB0GA1UdDgQWBBTRmLBSAQr3AAI4didYznX/
|
||||
mEvuzDAJBgcqhkjOPQQBA0cAMEQCIB25iNcA7Y3D3E0fv8GIaV0Ei8Ydu4AVuTJW
|
||||
C8tZvjhWAiBqAuBYm104bRLWaT2uSZexQJgvTPB6j6SdUi0SmR0acw==
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
|
||||
export const mock_dsc_key_sha384_ecdsa = `-----BEGIN EC PRIVATE KEY-----
|
||||
MIGkAgEBBDAw/8AnnGTU8TWWt+SDVr2Gi3TEruQ5tkZ9PObCFtW1nQZaId/f/UFk
|
||||
nJgnT7zm72qgBwYFK4EEACKhZANiAARBQCmC0UscKfL8KkVMtO69SU17NIrpLsw5
|
||||
ibVLxHqcnKMm0FLy0gwU3DFqFF9gPD64EmyoxyE+mo+I3l5rEZPWMqVZOoxCRSww
|
||||
f6GeHkgco/zGFxnEaklZL7g6gwyUNp8=
|
||||
-----END EC PRIVATE KEY-----
|
||||
`
|
||||
|
||||
export const mock_dsc_sha384_ecdsa = `-----BEGIN CERTIFICATE-----
|
||||
MIICRDCCAcqgAwIBAgIUDWqj4BMk0L+D4RpvoSSyc6Lz3mswCgYIKoZIzj0EAwMw
|
||||
cjELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5MRUw
|
||||
EwYDVQQKDAxPcmdhbml6YXRpb24xEzARBgNVBAsMCkRlcGFydG1lbnQxGDAWBgNV
|
||||
BAMMD3d3dy5leGFtcGxlLmNvbTAeFw0yNDA5MTMxMzA4MTdaFw0yNTA5MTMxMzA4
|
||||
MTdaMHIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVTdGF0ZTENMAsGA1UEBwwEQ2l0
|
||||
eTEVMBMGA1UECgwMT3JnYW5pemF0aW9uMRMwEQYDVQQLDApEZXBhcnRtZW50MRgw
|
||||
FgYDVQQDDA93d3cuZXhhbXBsZS5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARB
|
||||
QCmC0UscKfL8KkVMtO69SU17NIrpLsw5ibVLxHqcnKMm0FLy0gwU3DFqFF9gPD64
|
||||
EmyoxyE+mo+I3l5rEZPWMqVZOoxCRSwwf6GeHkgco/zGFxnEaklZL7g6gwyUNp+j
|
||||
ITAfMB0GA1UdDgQWBBTalDCeljqgJiT5+YCzAq1vS0zaFDAKBggqhkjOPQQDAwNo
|
||||
ADBlAjAu9tM+LZ8PB90F3Wd+mg//Eia6oTM9APo2+E9isiV/sgRwy3HFfAbYnH7c
|
||||
xy29Ef4CMQCiGvLgkcYMSx3J1bWcq8nuxPBywf440ruiFf95wzm/erjDRFG3u7Dh
|
||||
d+9Msdsovrc=
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
@@ -0,0 +1,8 @@
|
||||
-----BEGIN EC PARAMETERS-----
|
||||
BggqhkjOPQMBBw==
|
||||
-----END EC PARAMETERS-----
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIK2wRGm6xnmTnHhOtyUxp/PFPTySoaD+f2JNXy9JAmRVoAoGCCqGSM49
|
||||
AwEHoUQDQgAEzqM5vQEv7vhD7ZXecfkSvC/vfDffjuEyUK3DLlvjbxUIXeaJ+dUg
|
||||
zb8+rYwVh+Ai/DDxCLuSy2wn4gbOFwzOGA==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -0,0 +1,13 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICBDCCAaygAwIBAgIULaL4N+BRrqV1D8UeefZegXfkWogwCQYHKoZIzj0EATBy
|
||||
MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFU3RhdGUxDTALBgNVBAcMBENpdHkxFTAT
|
||||
BgNVBAoMDE9yZ2FuaXphdGlvbjETMBEGA1UECwwKRGVwYXJ0bWVudDEYMBYGA1UE
|
||||
AwwPd3d3LmV4YW1wbGUuY29tMB4XDTI0MDkxMzEyNTgzNVoXDTI1MDkxMzEyNTgz
|
||||
NVowcjELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5
|
||||
MRUwEwYDVQQKDAxPcmdhbml6YXRpb24xEzARBgNVBAsMCkRlcGFydG1lbnQxGDAW
|
||||
BgNVBAMMD3d3dy5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA
|
||||
BM6jOb0BL+74Q+2V3nH5Erwv73w3347hMlCtwy5b428VCF3mifnVIM2/Pq2MFYfg
|
||||
Ivww8Qi7kstsJ+IGzhcMzhijITAfMB0GA1UdDgQWBBTRmLBSAQr3AAI4didYznX/
|
||||
mEvuzDAJBgcqhkjOPQQBA0cAMEQCIB25iNcA7Y3D3E0fv8GIaV0Ei8Ydu4AVuTJW
|
||||
C8tZvjhWAiBqAuBYm104bRLWaT2uSZexQJgvTPB6j6SdUi0SmR0acw==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,9 @@
|
||||
-----BEGIN EC PARAMETERS-----
|
||||
BgUrgQQAIg==
|
||||
-----END EC PARAMETERS-----
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MIGkAgEBBDAw/8AnnGTU8TWWt+SDVr2Gi3TEruQ5tkZ9PObCFtW1nQZaId/f/UFk
|
||||
nJgnT7zm72qgBwYFK4EEACKhZANiAARBQCmC0UscKfL8KkVMtO69SU17NIrpLsw5
|
||||
ibVLxHqcnKMm0FLy0gwU3DFqFF9gPD64EmyoxyE+mo+I3l5rEZPWMqVZOoxCRSww
|
||||
f6GeHkgco/zGFxnEaklZL7g6gwyUNp8=
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -0,0 +1,15 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICRDCCAcqgAwIBAgIUDWqj4BMk0L+D4RpvoSSyc6Lz3mswCgYIKoZIzj0EAwMw
|
||||
cjELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5MRUw
|
||||
EwYDVQQKDAxPcmdhbml6YXRpb24xEzARBgNVBAsMCkRlcGFydG1lbnQxGDAWBgNV
|
||||
BAMMD3d3dy5leGFtcGxlLmNvbTAeFw0yNDA5MTMxMzA4MTdaFw0yNTA5MTMxMzA4
|
||||
MTdaMHIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVTdGF0ZTENMAsGA1UEBwwEQ2l0
|
||||
eTEVMBMGA1UECgwMT3JnYW5pemF0aW9uMRMwEQYDVQQLDApEZXBhcnRtZW50MRgw
|
||||
FgYDVQQDDA93d3cuZXhhbXBsZS5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARB
|
||||
QCmC0UscKfL8KkVMtO69SU17NIrpLsw5ibVLxHqcnKMm0FLy0gwU3DFqFF9gPD64
|
||||
EmyoxyE+mo+I3l5rEZPWMqVZOoxCRSwwf6GeHkgco/zGFxnEaklZL7g6gwyUNp+j
|
||||
ITAfMB0GA1UdDgQWBBTalDCeljqgJiT5+YCzAq1vS0zaFDAKBggqhkjOPQQDAwNo
|
||||
ADBlAjAu9tM+LZ8PB90F3Wd+mg//Eia6oTM9APo2+E9isiV/sgRwy3HFfAbYnH7c
|
||||
xy29Ef4CMQCiGvLgkcYMSx3J1bWcq8nuxPBywf440ruiFf95wzm/erjDRFG3u7Dh
|
||||
d+9Msdsovrc=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,96 +1,150 @@
|
||||
import { PassportData } from "./types";
|
||||
import { hash, assembleEContent, formatAndConcatenateDataHashes, formatMrz, hexToDecimal } from "./utils";
|
||||
import { PassportData } from './types';
|
||||
import {
|
||||
hash,
|
||||
assembleEContent,
|
||||
formatAndConcatenateDataHashes,
|
||||
formatMrz,
|
||||
} from './utils';
|
||||
import * as forge from 'node-forge';
|
||||
import { mock_dsc_key_sha1_rsa_4096, mock_dsc_key_sha256_rsa_4096, mock_dsc_key_sha256_rsapss_2048, mock_dsc_key_sha256_rsapss_4096, mock_dsc_sha1_rsa_4096, mock_dsc_sha256_rsa_4096, mock_dsc_sha256_rsapss_2048, mock_dsc_sha256_rsapss_4096 } from "../constants/mockCertificates";
|
||||
import { sampleDataHashes_small, sampleDataHashes_large } from "../constants/sampleDataHashes";
|
||||
import { countryCodes } from "../constants/constants";
|
||||
import * as asn1 from 'asn1js';
|
||||
import elliptic from 'elliptic';
|
||||
import {
|
||||
mock_dsc_key_sha1_rsa_4096,
|
||||
mock_dsc_key_sha256_ecdsa,
|
||||
mock_dsc_key_sha256_rsa_4096,
|
||||
mock_dsc_key_sha256_rsapss_2048,
|
||||
mock_dsc_key_sha256_rsapss_4096,
|
||||
mock_dsc_sha1_rsa_4096,
|
||||
mock_dsc_sha256_ecdsa,
|
||||
mock_dsc_sha256_rsa_4096,
|
||||
mock_dsc_sha256_rsapss_2048,
|
||||
mock_dsc_sha256_rsapss_4096,
|
||||
mock_dsc_key_sha1_ecdsa,
|
||||
mock_dsc_sha1_ecdsa,
|
||||
mock_dsc_key_sha384_ecdsa,
|
||||
mock_dsc_sha384_ecdsa,
|
||||
} from '../constants/mockCertificates';
|
||||
import { sampleDataHashes_small, sampleDataHashes_large } from '../constants/sampleDataHashes';
|
||||
import { countryCodes } from '../constants/constants';
|
||||
import { getSignatureAlgorithm } from './handleCertificate';
|
||||
|
||||
export function genMockPassportData(
|
||||
signatureType: 'rsa_sha1' | 'rsa_sha256' | 'rsapss_sha256',
|
||||
nationality: keyof typeof countryCodes,
|
||||
birthDate: string,
|
||||
expiryDate: string,
|
||||
signatureType: 'rsa_sha1' | 'rsa_sha256' | 'rsapss_sha256' | 'ecdsa_sha256' | 'ecdsa_sha1' | 'ecdsa_sha384',
|
||||
nationality: keyof typeof countryCodes,
|
||||
birthDate: string,
|
||||
expiryDate: string
|
||||
): PassportData {
|
||||
if (birthDate.length !== 6 || expiryDate.length !== 6) {
|
||||
throw new Error("birthdate and expiry date have to be in the \"YYMMDD\" format");
|
||||
}
|
||||
if (birthDate.length !== 6 || expiryDate.length !== 6) {
|
||||
throw new Error('birthdate and expiry date have to be in the "YYMMDD" format');
|
||||
}
|
||||
|
||||
const mrz = `P<${nationality}DUPONT<<ALPHONSE<HUGUES<ALBERT<<<<<<<<<24HB818324${nationality}${birthDate}1M${expiryDate}5<<<<<<<<<<<<<<02`;
|
||||
let signatureAlgorithm: string;
|
||||
let hashLen: number;
|
||||
let sampleDataHashes: [number, number[]][];
|
||||
let privateKeyPem: string;
|
||||
let dsc: string;
|
||||
const mrz = `P<${nationality}DUPONT<<ALPHONSE<HUGUES<ALBERT<<<<<<<<<24HB818324${nationality}${birthDate}1M${expiryDate}5<<<<<<<<<<<<<<02`;
|
||||
|
||||
switch (signatureType) {
|
||||
case 'rsa_sha1':
|
||||
signatureAlgorithm = 'sha1WithRSAEncryption';
|
||||
hashLen = 20;
|
||||
sampleDataHashes = sampleDataHashes_small;
|
||||
privateKeyPem = mock_dsc_key_sha1_rsa_4096;
|
||||
dsc = mock_dsc_sha1_rsa_4096;
|
||||
break;
|
||||
case 'rsa_sha256':
|
||||
signatureAlgorithm = 'sha256WithRSAEncryption';
|
||||
hashLen = 32;
|
||||
sampleDataHashes = sampleDataHashes_large;
|
||||
privateKeyPem = mock_dsc_key_sha256_rsa_4096;
|
||||
dsc = mock_dsc_sha256_rsa_4096;
|
||||
break;
|
||||
case 'rsapss_sha256':
|
||||
signatureAlgorithm = 'sha256WithRSASSAPSS';
|
||||
hashLen = 32;
|
||||
sampleDataHashes = sampleDataHashes_large;
|
||||
privateKeyPem = mock_dsc_key_sha256_rsapss_4096;
|
||||
dsc = mock_dsc_sha256_rsapss_4096;
|
||||
break;
|
||||
}
|
||||
let privateKeyPem: string;
|
||||
let dsc: string;
|
||||
let sampleDataHashes: [number, number[]][];
|
||||
|
||||
const mrzHash = hash(signatureAlgorithm, formatMrz(mrz));
|
||||
const concatenatedDataHashes = formatAndConcatenateDataHashes(
|
||||
[[1, mrzHash], ...sampleDataHashes],
|
||||
hashLen,
|
||||
30
|
||||
);
|
||||
switch (signatureType) {
|
||||
case 'rsa_sha1':
|
||||
sampleDataHashes = sampleDataHashes_small;
|
||||
privateKeyPem = mock_dsc_key_sha1_rsa_4096;
|
||||
dsc = mock_dsc_sha1_rsa_4096;
|
||||
break;
|
||||
case 'rsa_sha256':
|
||||
sampleDataHashes = sampleDataHashes_large;
|
||||
privateKeyPem = mock_dsc_key_sha256_rsa_4096;
|
||||
dsc = mock_dsc_sha256_rsa_4096;
|
||||
break;
|
||||
case 'rsapss_sha256':
|
||||
sampleDataHashes = sampleDataHashes_large;
|
||||
privateKeyPem = mock_dsc_key_sha256_rsapss_4096;
|
||||
dsc = mock_dsc_sha256_rsapss_4096;
|
||||
break;
|
||||
case 'ecdsa_sha256':
|
||||
sampleDataHashes = sampleDataHashes_large;
|
||||
privateKeyPem = mock_dsc_key_sha256_ecdsa;
|
||||
dsc = mock_dsc_sha256_ecdsa;
|
||||
break;
|
||||
case 'ecdsa_sha1':
|
||||
sampleDataHashes = sampleDataHashes_small;
|
||||
privateKeyPem = mock_dsc_key_sha1_ecdsa;
|
||||
dsc = mock_dsc_sha1_ecdsa;
|
||||
break;
|
||||
case 'ecdsa_sha384':
|
||||
sampleDataHashes = sampleDataHashes_small;
|
||||
privateKeyPem = mock_dsc_key_sha384_ecdsa;
|
||||
dsc = mock_dsc_sha384_ecdsa;
|
||||
break;
|
||||
}
|
||||
|
||||
const eContent = assembleEContent(hash(signatureAlgorithm, concatenatedDataHashes));
|
||||
const { hashFunction, hashLen } = getSignatureAlgorithm(dsc);
|
||||
|
||||
const privKey = forge.pki.privateKeyFromPem(privateKeyPem);
|
||||
const modulus = privKey.n.toString(16);
|
||||
const mrzHash = hash(hashFunction, formatMrz(mrz));
|
||||
const concatenatedDataHashes = formatAndConcatenateDataHashes(
|
||||
[[1, mrzHash], ...sampleDataHashes],
|
||||
hashLen,
|
||||
30
|
||||
);
|
||||
|
||||
let signature: number[];
|
||||
if (signatureType === 'rsapss_sha256') {
|
||||
const privateKey = forge.pki.privateKeyFromPem(privateKeyPem);
|
||||
const md = forge.md.sha256.create();
|
||||
md.update(forge.util.binary.raw.encode(new Uint8Array(eContent)));
|
||||
const pss = forge.pss.create({
|
||||
md: forge.md.sha256.create(),
|
||||
mgf: forge.mgf.mgf1.create(forge.md.sha256.create()),
|
||||
saltLength: 32
|
||||
});
|
||||
const signatureBytes = privateKey.sign(md, pss);
|
||||
signature = Array.from(signatureBytes, (c: string) => c.charCodeAt(0));
|
||||
} else {
|
||||
const md = signatureType === 'rsa_sha1' ? forge.md.sha1.create() : forge.md.sha256.create();
|
||||
md.update(forge.util.binary.raw.encode(new Uint8Array(eContent)));
|
||||
const forgeSignature = privKey.sign(md);
|
||||
signature = Array.from(forgeSignature, (c: string) => c.charCodeAt(0));
|
||||
}
|
||||
const eContent = assembleEContent(hash(hashFunction, concatenatedDataHashes));
|
||||
|
||||
const signatureBytes = Array.from(signature, byte => byte < 128 ? byte : byte - 256);
|
||||
const signature = sign(privateKeyPem, dsc, eContent);
|
||||
const signatureBytes = Array.from(signature, (byte) => (byte < 128 ? byte : byte - 256));
|
||||
|
||||
return {
|
||||
dsc: dsc,
|
||||
mrz: mrz,
|
||||
signatureAlgorithm: signatureAlgorithm,
|
||||
pubKey: {
|
||||
modulus: hexToDecimal(modulus),
|
||||
exponent: '65537',
|
||||
},
|
||||
dataGroupHashes: concatenatedDataHashes,
|
||||
eContent: eContent,
|
||||
encryptedDigest: signatureBytes,
|
||||
photoBase64: "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABjElEQVR42mL8//8/AyUYiBQYmIy3...",
|
||||
mockUser: true
|
||||
};
|
||||
return {
|
||||
dsc: dsc,
|
||||
mrz: mrz,
|
||||
dataGroupHashes: concatenatedDataHashes,
|
||||
eContent: eContent,
|
||||
encryptedDigest: signatureBytes,
|
||||
photoBase64: 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABjElEQVR42mL8//8/AyUYiBQYmIy3...',
|
||||
mockUser: true,
|
||||
};
|
||||
}
|
||||
|
||||
function sign(
|
||||
privateKeyPem: string,
|
||||
dsc: string,
|
||||
eContent: number[]
|
||||
): number[] {
|
||||
const { signatureAlgorithm, hashFunction, curve } = getSignatureAlgorithm(dsc);
|
||||
|
||||
if (signatureAlgorithm === 'rsapss') {
|
||||
const privateKey = forge.pki.privateKeyFromPem(privateKeyPem);
|
||||
const md = forge.md.sha256.create();
|
||||
md.update(forge.util.binary.raw.encode(new Uint8Array(eContent)));
|
||||
const pss = forge.pss.create({
|
||||
md: forge.md.sha256.create(),
|
||||
mgf: forge.mgf.mgf1.create(forge.md.sha256.create()),
|
||||
saltLength: 32,
|
||||
});
|
||||
const signatureBytes = privateKey.sign(md, pss);
|
||||
return Array.from(signatureBytes, (c: string) => c.charCodeAt(0));
|
||||
} else if (signatureAlgorithm === 'ecdsa') {
|
||||
const curveForElliptic = curve === 'secp256r1' ? 'p256' : 'p384';
|
||||
const ec = new elliptic.ec(curveForElliptic);
|
||||
|
||||
const privateKeyDer = Buffer.from(
|
||||
privateKeyPem.replace(/-----BEGIN EC PRIVATE KEY-----|\n|-----END EC PRIVATE KEY-----/g, ''),
|
||||
'base64'
|
||||
);
|
||||
const asn1Data = asn1.fromBER(privateKeyDer);
|
||||
const privateKeyBuffer = (asn1Data.result.valueBlock as any).value[1].valueBlock.valueHexView;
|
||||
|
||||
const keyPair = ec.keyFromPrivate(privateKeyBuffer);
|
||||
|
||||
console.log('privateKeyBuffer', privateKeyBuffer);
|
||||
|
||||
const eContentHash = hash(hashFunction, eContent);
|
||||
const signature = keyPair.sign(eContentHash);
|
||||
const signatureBytes = signature.toDER();
|
||||
|
||||
return signatureBytes;
|
||||
} else {
|
||||
const privKey = forge.pki.privateKeyFromPem(privateKeyPem);
|
||||
const md = hashFunction === 'sha1' ? forge.md.sha1.create() : forge.md.sha256.create();
|
||||
md.update(forge.util.binary.raw.encode(new Uint8Array(eContent)));
|
||||
const forgeSignature = privKey.sign(md);
|
||||
return Array.from(forgeSignature, (c: string) => c.charCodeAt(0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
mockPassportDatas,
|
||||
} from "../constants/mockPassportData";
|
||||
import { SMT } from "@ashpect/smt"
|
||||
import { getSignatureAlgorithm } from './handleCertificate';
|
||||
|
||||
export function generateCircuitInputsRegister(
|
||||
secret: string,
|
||||
@@ -40,8 +41,11 @@ export function generateCircuitInputsRegister(
|
||||
k_dsc: number,
|
||||
mocks: PassportData[] = mockPassportDatas
|
||||
) {
|
||||
const { mrz, signatureAlgorithm, pubKey, dataGroupHashes, eContent, encryptedDigest } =
|
||||
passportData;
|
||||
const { mrz, dsc, dataGroupHashes, eContent, encryptedDigest } =
|
||||
passportData;
|
||||
|
||||
const { signatureAlgorithm, hashFunction, hashLen, x, y, modulus } = getSignatureAlgorithm(dsc);
|
||||
|
||||
|
||||
// const tree = getCSCAModulusMerkleTree();
|
||||
|
||||
@@ -51,39 +55,40 @@ export function generateCircuitInputsRegister(
|
||||
// }
|
||||
// }
|
||||
|
||||
if (
|
||||
![
|
||||
'sha256WithRSAEncryption',
|
||||
'sha1WithRSAEncryption',
|
||||
'sha256WithRSASSAPSS',
|
||||
'ecdsa-with-SHA1',
|
||||
'ecdsa-with-SHA256',
|
||||
].includes(signatureAlgorithm)
|
||||
) {
|
||||
console.error(`${signatureAlgorithm} has not been implemented.`);
|
||||
throw new Error(`${signatureAlgorithm} has not been implemented.`);
|
||||
|
||||
const supportedAlgorithms = [
|
||||
{ signatureAlgorithm: 'rsa', hashFunction: 'sha1' },
|
||||
{ signatureAlgorithm: 'rsa', hashFunction: 'sha256' },
|
||||
{ signatureAlgorithm: 'rsapss', hashFunction: 'sha256' },
|
||||
{ signatureAlgorithm: 'ecdsa', hashFunction: 'sha1' },
|
||||
{ signatureAlgorithm: 'ecdsa', hashFunction: 'sha256' },
|
||||
];
|
||||
|
||||
const isSupported = supportedAlgorithms.some(
|
||||
(alg) => alg.signatureAlgorithm === signatureAlgorithm && alg.hashFunction === hashFunction
|
||||
);
|
||||
|
||||
if (!isSupported) {
|
||||
throw new Error(`Verification of ${signatureAlgorithm} with ${hashFunction} has not been implemented.`);
|
||||
}
|
||||
|
||||
const hashLen = getHashLen(signatureAlgorithm);
|
||||
const formattedMrz = formatMrz(mrz);
|
||||
const mrzHash = hash(signatureAlgorithm, formattedMrz);
|
||||
const mrzHash = hash(hashFunction, formattedMrz);
|
||||
|
||||
const dg1HashOffset = findSubarrayIndex(dataGroupHashes, mrzHash);
|
||||
// console.log('dg1HashOffset', dg1HashOffset);
|
||||
|
||||
assert(dg1HashOffset !== -1, 'MRZ hash index not found in dataGroupHashes');
|
||||
|
||||
const concatHash = hash(signatureAlgorithm, dataGroupHashes);
|
||||
const concatHash = hash(hashFunction, dataGroupHashes);
|
||||
|
||||
assert(
|
||||
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}`);
|
||||
@@ -109,9 +114,8 @@ export function generateCircuitInputsRegister(
|
||||
let signatureComponents: any;
|
||||
let dscModulusComponents: any;
|
||||
|
||||
if (signatureAlgorithm.startsWith('ecdsa-with-')) {
|
||||
const curve_params = pubKey.publicKeyQ.replace(/[()]/g, '').split(',');
|
||||
const { r, s } = extractRSFromSignature(passportData.encryptedDigest);
|
||||
if (signatureAlgorithm === 'ecdsa') {
|
||||
const { r, s } = extractRSFromSignature(encryptedDigest);
|
||||
|
||||
signatureComponents = {
|
||||
signature_r: BigintToArray(n_dsc, k_dsc, BigInt(hexToDecimal(r))),
|
||||
@@ -119,13 +123,13 @@ export function generateCircuitInputsRegister(
|
||||
};
|
||||
|
||||
dscModulusComponents = {
|
||||
dsc_modulus_x: BigintToArray(n_dsc, k_dsc, BigInt(hexToDecimal(curve_params[0]))),
|
||||
dsc_modulus_y: BigintToArray(n_dsc, k_dsc, BigInt(hexToDecimal(curve_params[1])))
|
||||
dsc_modulus_x: BigintToArray(n_dsc, k_dsc, BigInt(hexToDecimal(x))),
|
||||
dsc_modulus_y: BigintToArray(n_dsc, k_dsc, BigInt(hexToDecimal(y)))
|
||||
};
|
||||
} else {
|
||||
signatureComponents = {
|
||||
signature: splitToWords(
|
||||
BigInt(bytesToBigDecimal(passportData.encryptedDigest)),
|
||||
BigInt(bytesToBigDecimal(encryptedDigest)),
|
||||
BigInt(n_dsc),
|
||||
BigInt(k_dsc)
|
||||
)
|
||||
@@ -133,13 +137,15 @@ export function generateCircuitInputsRegister(
|
||||
|
||||
dscModulusComponents = {
|
||||
dsc_modulus: splitToWords(
|
||||
BigInt(passportData.pubKey.modulus as string),
|
||||
BigInt(hexToDecimal(modulus as string)),
|
||||
BigInt(n_dsc),
|
||||
BigInt(k_dsc)
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
console.log(signatureComponents);
|
||||
console.log(dscModulusComponents);
|
||||
return {
|
||||
secret: [secret],
|
||||
mrz: formattedMrz.map((byte) => String(byte)),
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import * as asn1 from 'asn1js';
|
||||
import { Certificate } from 'pkijs';
|
||||
import { vkey_prove_rsa_65537_sha256 } from '../constants/vkey';
|
||||
import { getHashLen } from './utils';
|
||||
import { getNamedCurve } from '../../../registry/src/utils/curves';
|
||||
import elliptic from 'elliptic';
|
||||
|
||||
export const getSignatureAlgorithm = (pemContent: string) => {
|
||||
const certBuffer = Buffer.from(pemContent.replace(/(-----(BEGIN|END) CERTIFICATE-----|\n)/g, ''), 'base64');
|
||||
@@ -8,7 +10,41 @@ export const getSignatureAlgorithm = (pemContent: string) => {
|
||||
const cert = new Certificate({ schema: asn1Data.result });
|
||||
const signatureAlgorithmOid = cert.signatureAlgorithm.algorithmId;
|
||||
const { signatureAlgorithm, hashFunction } = getSignatureAlgorithmDetails(signatureAlgorithmOid);
|
||||
return { signatureAlgorithm, hashFunction };
|
||||
const hashLen = getHashLen(hashFunction);
|
||||
|
||||
let publicKeyDetails;
|
||||
if (signatureAlgorithm === 'ecdsa') {
|
||||
const subjectPublicKeyInfo = cert.subjectPublicKeyInfo;
|
||||
const algorithmParams = subjectPublicKeyInfo.algorithm.algorithmParams;
|
||||
const curveOid = asn1.fromBER(algorithmParams.valueBeforeDecode).result.valueBlock.toString();
|
||||
const curve = getNamedCurve(curveOid);
|
||||
|
||||
// const publicKeyBuffer = subjectPublicKeyInfo.subjectPublicKey.valueBlock.valueHex;
|
||||
// console.log("publicKeyBuffer", publicKeyBuffer);
|
||||
// const x = publicKeyBuffer.slice(2, 34); // Adjusted to slice correctly for x
|
||||
// const y = publicKeyBuffer.slice(34, 66); // Adjusted to slice correctly for y
|
||||
// publicKeyDetails = { curve, x: Buffer.from(x).toString('hex'), y: Buffer.from(y).toString('hex') };
|
||||
|
||||
const publicKeyBuffer = subjectPublicKeyInfo.subjectPublicKey.valueBlock.valueHexView;
|
||||
const curveForElliptic = curve === 'secp256r1' ? 'p256' : 'p384';
|
||||
const ec = new elliptic.ec(curveForElliptic);
|
||||
const key = ec.keyFromPublic(publicKeyBuffer);
|
||||
console.log(key);
|
||||
const x = key.getPublic().getX().toString('hex');
|
||||
const y = key.getPublic().getY().toString('hex');
|
||||
console.log(`Size of x: ${Buffer.byteLength(x, 'hex')} bytes`);
|
||||
console.log(`Size of y: ${Buffer.byteLength(y, 'hex')} bytes`);
|
||||
publicKeyDetails = { curve, x, y };
|
||||
} else {
|
||||
const publicKey = cert.subjectPublicKeyInfo.subjectPublicKey;
|
||||
const asn1PublicKey = asn1.fromBER(publicKey.valueBlock.valueHexView);
|
||||
const rsaPublicKey = asn1PublicKey.result.valueBlock;
|
||||
const modulus = Buffer.from((rsaPublicKey as any).value[0].valueBlock.valueHexView).toString('hex');
|
||||
const exponent = Buffer.from((rsaPublicKey as any).value[1].valueBlock.valueHexView).toString('hex');
|
||||
publicKeyDetails = { modulus, exponent };
|
||||
}
|
||||
console.log(publicKeyDetails);
|
||||
return { signatureAlgorithm, hashFunction, hashLen, ...publicKeyDetails };
|
||||
}
|
||||
|
||||
export const getCircuitName = (circuitType: string, signatureAlgorithm: string, hashFunction: string) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export type PassportData = {
|
||||
mrz: string;
|
||||
signatureAlgorithm: string;
|
||||
signatureAlgorithm?: string;
|
||||
dsc?: string;
|
||||
pubKey?: { modulus?: string, exponent?: string, curveName?: string, publicKeyQ?: string };
|
||||
dataGroupHashes: number[];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { LeanIMT } from '@zk-kit/lean-imt';
|
||||
import { sha256 } from 'js-sha256';
|
||||
import { sha1 } from 'js-sha1';
|
||||
import { sha384 } from 'js-sha512';
|
||||
import { sha384, sha512_256 } from 'js-sha512';
|
||||
import { SMT } from '@ashpect/smt';
|
||||
import forge from 'node-forge';
|
||||
|
||||
@@ -184,26 +184,22 @@ export function hexToDecimal(hex: string): string {
|
||||
}
|
||||
|
||||
// hash logic here because the one in utils.ts only works with node
|
||||
|
||||
export function hash(signatureAlgorithm: string, bytesArray: number[]): number[] {
|
||||
export function hash(hasFunction: string, bytesArray: number[]): number[] {
|
||||
const unsignedBytesArray = bytesArray.map((byte) => byte & 0xff);
|
||||
let hashResult: string;
|
||||
|
||||
switch (signatureAlgorithm) {
|
||||
case 'sha1WithRSAEncryption':
|
||||
switch (hasFunction) {
|
||||
case 'sha1':
|
||||
hashResult = sha1(unsignedBytesArray);
|
||||
break;
|
||||
case 'SHA384withECDSA':
|
||||
case 'sha256':
|
||||
hashResult = sha256(unsignedBytesArray);
|
||||
break;
|
||||
case 'sha384':
|
||||
hashResult = sha384(unsignedBytesArray);
|
||||
break;
|
||||
case 'sha256WithRSAEncryption':
|
||||
hashResult = sha256(unsignedBytesArray);
|
||||
break;
|
||||
case 'sha256WithRSASSAPSS':
|
||||
hashResult = sha256(unsignedBytesArray);
|
||||
break;
|
||||
case 'ecdsa-with-SHA1':
|
||||
hashResult = sha1(unsignedBytesArray);
|
||||
case 'sha512':
|
||||
hashResult = sha512_256(unsignedBytesArray);
|
||||
break;
|
||||
default:
|
||||
hashResult = sha256(unsignedBytesArray); // Default to sha256
|
||||
@@ -273,23 +269,18 @@ export function getCurrentDateYYMMDD(dayDiff: number = 0): number[] {
|
||||
return Array.from(yymmdd).map((char) => parseInt(char));
|
||||
}
|
||||
|
||||
export function getHashLen(signatureAlgorithm: string) {
|
||||
switch (signatureAlgorithm) {
|
||||
case 'sha1WithRSAEncryption':
|
||||
case 'ecdsa-with-SHA1':
|
||||
export function getHashLen(hashFunction: string) {
|
||||
switch (hashFunction) {
|
||||
case 'sha1':
|
||||
return 20;
|
||||
case 'sha256WithRSAEncryption':
|
||||
case 'rsassaPss':
|
||||
case 'ecdsa-with-SHA256':
|
||||
case 'sha256':
|
||||
return 32;
|
||||
case 'sha384WithRSAEncryption':
|
||||
case 'ecdsa-with-SHA384':
|
||||
case 'sha384':
|
||||
return 48;
|
||||
case 'sha512WithRSAEncryption':
|
||||
case 'ecdsa-with-SHA512':
|
||||
case 'sha512':
|
||||
return 64;
|
||||
default:
|
||||
console.log(`${signatureAlgorithm} not found in getHashLen`);
|
||||
console.log(`${hashFunction} not found in getHashLen`);
|
||||
return 32;
|
||||
}
|
||||
}
|
||||
|
||||
85
common/tests/genMockPassportData.test.ts
Normal file
85
common/tests/genMockPassportData.test.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { assert, expect } from 'chai';
|
||||
import { describe, it } from 'mocha';
|
||||
import { genMockPassportData } from '../src/utils/genMockPassportData';
|
||||
import * as forge from 'node-forge';
|
||||
import { PassportData } from '../src/utils/types';
|
||||
import { formatMrz, hash, arraysAreEqual, findSubarrayIndex } from '../src/utils/utils';
|
||||
import { getSignatureAlgorithm } from '../src/utils/handleCertificate';
|
||||
import * as asn1 from 'asn1js';
|
||||
import { Certificate } from 'pkijs';
|
||||
import elliptic from 'elliptic';
|
||||
|
||||
export type SignatureAlgorithm = 'rsa_sha1' | 'rsa_sha256' | 'rsapss_sha256' | 'ecdsa_sha256' | 'ecdsa_sha1' | 'ecdsa_sha384';
|
||||
|
||||
const sigAlgs: SignatureAlgorithm[] = [
|
||||
'rsa_sha1',
|
||||
'rsa_sha256',
|
||||
'rsapss_sha256',
|
||||
'ecdsa_sha256',
|
||||
'ecdsa_sha1',
|
||||
'ecdsa_sha384',
|
||||
];
|
||||
|
||||
describe('Mock Passport Data Generator', function () {
|
||||
this.timeout(0);
|
||||
|
||||
sigAlgs.forEach(sigAlg => {
|
||||
it(`should generate valid passport data for ${sigAlg}`, () => {
|
||||
const passportData = genMockPassportData(sigAlg, 'FRA', '000101', '300101');
|
||||
expect(passportData).to.exist;
|
||||
expect(verify(passportData)).to.be.true;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function verify(passportData: PassportData): boolean {
|
||||
const { mrz, dsc, dataGroupHashes, eContent, encryptedDigest } = passportData;
|
||||
const { signatureAlgorithm, hashFunction, hashLen, curve } = getSignatureAlgorithm(dsc);
|
||||
const formattedMrz = formatMrz(mrz);
|
||||
const mrzHash = hash(hashFunction, formattedMrz);
|
||||
const dg1HashOffset = findSubarrayIndex(dataGroupHashes, mrzHash)
|
||||
assert(dg1HashOffset !== -1, 'MRZ hash index not found in dataGroupHashes');
|
||||
|
||||
const concatHash = hash(hashFunction, dataGroupHashes)
|
||||
assert(
|
||||
arraysAreEqual(
|
||||
concatHash,
|
||||
eContent.slice(eContent.length - hashLen)
|
||||
),
|
||||
'concatHash is not at the right place in eContent'
|
||||
);
|
||||
|
||||
if (signatureAlgorithm === 'ecdsa') {
|
||||
const certBuffer = Buffer.from(dsc.replace(/(-----(BEGIN|END) CERTIFICATE-----|\n)/g, ''), 'base64');
|
||||
const asn1Data = asn1.fromBER(certBuffer);
|
||||
const cert = new Certificate({ schema: asn1Data.result });
|
||||
const publicKeyInfo = cert.subjectPublicKeyInfo;
|
||||
const publicKeyBuffer = publicKeyInfo.subjectPublicKey.valueBlock.valueHexView;
|
||||
const curveForElliptic = curve === 'secp256r1' ? 'p256' : 'p384';
|
||||
const ec = new elliptic.ec(curveForElliptic);
|
||||
|
||||
const key = ec.keyFromPublic(publicKeyBuffer);
|
||||
const eContentHash = hash(hashFunction, eContent);
|
||||
const signature = Buffer.from(encryptedDigest).toString('hex');
|
||||
return key.verify(eContentHash, signature);
|
||||
} else {
|
||||
const cert = forge.pki.certificateFromPem(dsc);
|
||||
const publicKey = cert.publicKey as forge.pki.rsa.PublicKey;
|
||||
|
||||
const md = forge.md[hashFunction].create();
|
||||
md.update(forge.util.binary.raw.encode(new Uint8Array(eContent)));
|
||||
|
||||
const signature = Buffer.from(encryptedDigest).toString('binary');
|
||||
|
||||
if (signatureAlgorithm === 'rsapss') {
|
||||
const pss = forge.pss.create({
|
||||
md: forge.md[hashFunction].create(),
|
||||
mgf: forge.mgf.mgf1.create(forge.md[hashFunction].create()),
|
||||
saltLength: hashLen
|
||||
});
|
||||
return publicKey.verify(md.digest().bytes(), signature, pss);
|
||||
} else {
|
||||
return publicKey.verify(md.digest().bytes(), signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
Arguments:
|
||||
/Users/remicolin/.nvm/versions/node/v20.11.1/bin/node /opt/homebrew/Cellar/yarn/1.22.19/libexec/bin/yarn.js add path jrrsasign asn1.js
|
||||
|
||||
PATH:
|
||||
/Users/remicolin/.nvm/versions/node/v20.11.1/bin:/Users/remicolin/.gem/ruby/3.1.3/bin:/Users/remicolin/.rubies/ruby-3.1.3/lib/ruby/gems/3.1.0/bin:/Users/remicolin/.rubies/ruby-3.1.3/bin:/Users/remicolin/.jenv/shims:/Users/remicolin/.jenv/bin:/Users/remicolin/.cairo/target/release:/Library/Frameworks/Python.framework/Versions/3.9/bin:/Library/Frameworks/Python.framework/Versions/3.11/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Library/Apple/usr/bin:/Users/remicolin/.nvm/versions/node/v20.11.1/bin:/Users/remicolin/.jenv/shims:/Users/remicolin/.jenv/bin:/Users/remicolin/.cairo/target/release:/Library/Frameworks/Python.framework/Versions/3.9/bin:/Library/Frameworks/Python.framework/Versions/3.11/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/Users/remicolin/.cargo/bin:/Users/remicolin/.foundry/bin:/Users/remicolin/Library/Android/sdk/platform-tools:/Users/remicolin/.foundry/bin:/Users/remicolin/Library/Android/sdk/platform-tools
|
||||
|
||||
Yarn version:
|
||||
1.22.19
|
||||
|
||||
Node version:
|
||||
20.11.1
|
||||
|
||||
Platform:
|
||||
darwin arm64
|
||||
|
||||
Trace:
|
||||
Error: https://registry.yarnpkg.com/jrrsasign: Not found
|
||||
at params.callback [as _callback] (/opt/homebrew/Cellar/yarn/1.22.19/libexec/lib/cli.js:66145:18)
|
||||
at self.callback (/opt/homebrew/Cellar/yarn/1.22.19/libexec/lib/cli.js:140890:22)
|
||||
at Request.emit (node:events:518:28)
|
||||
at Request.<anonymous> (/opt/homebrew/Cellar/yarn/1.22.19/libexec/lib/cli.js:141862:10)
|
||||
at Request.emit (node:events:518:28)
|
||||
at IncomingMessage.<anonymous> (/opt/homebrew/Cellar/yarn/1.22.19/libexec/lib/cli.js:141784:12)
|
||||
at Object.onceWrapper (node:events:632:28)
|
||||
at IncomingMessage.emit (node:events:530:35)
|
||||
at endReadableNT (node:internal/streams/readable:1696:12)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:82:21)
|
||||
|
||||
npm manifest:
|
||||
{
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.23.4",
|
||||
"@zk-kit/imt": "https://gitpkg.now.sh/0xturboblitz/zk-kit/packages/imt?6d417675",
|
||||
"@zk-kit/lean-imt": "^2.0.1",
|
||||
"fs": "^0.0.1-security",
|
||||
"js-sha1": "^0.7.0",
|
||||
"js-sha256": "^0.10.1",
|
||||
"js-sha512": "^0.9.0",
|
||||
"node-forge": "^1.3.1",
|
||||
"poseidon-lite": "^0.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node-forge": "^1.3.10"
|
||||
}
|
||||
}
|
||||
|
||||
yarn manifest:
|
||||
No manifest
|
||||
|
||||
Lockfile:
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@babel/runtime@^7.23.4":
|
||||
version "7.23.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.4.tgz#36fa1d2b36db873d25ec631dcc4923fdc1cf2e2e"
|
||||
integrity sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.14.0"
|
||||
|
||||
"@types/node-forge@^1.3.10":
|
||||
version "1.3.10"
|
||||
resolved "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.10.tgz"
|
||||
integrity sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node@*":
|
||||
version "20.10.0"
|
||||
resolved "https://registry.npmjs.org/@types/node/-/node-20.10.0.tgz"
|
||||
integrity sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==
|
||||
dependencies:
|
||||
undici-types "~5.26.4"
|
||||
|
||||
"@zk-kit/imt@https://gitpkg.now.sh/0xturboblitz/zk-kit/packages/imt?6d417675":
|
||||
version "2.0.0-beta.1"
|
||||
resolved "https://gitpkg.now.sh/0xturboblitz/zk-kit/packages/imt?6d417675#38244ea6eef75dc1ad7fff3ff2a22dd5f1a2593a"
|
||||
|
||||
"@zk-kit/lean-imt@^2.0.1":
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@zk-kit/lean-imt/-/lean-imt-2.0.1.tgz#78af48b384b083e4a3f003036a40a4ea3cb102c0"
|
||||
integrity sha512-yc0rh9BCY6VvvKrZUNejfucuWscy1iRb9JrppuJktsiA9HcEukB3oX9CB7N/CUmCtqzmdwybet6N2aglGL/SUQ==
|
||||
dependencies:
|
||||
"@zk-kit/utils" "1.0.0"
|
||||
|
||||
"@zk-kit/utils@1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@zk-kit/utils/-/utils-1.0.0.tgz#db1af01a4e60f5290734a26c2fd9e863bff049e3"
|
||||
integrity sha512-v5UjrZiaRNAN2UJmTFHvlMktaA2Efc2qN1Mwd4060ExX12yRhY8ZhzdlDODhnuHkvW5zPukuBHgQhHMScNP3Pg==
|
||||
dependencies:
|
||||
buffer "^6.0.3"
|
||||
|
||||
base64-js@^1.3.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||
|
||||
buffer@^6.0.3:
|
||||
version "6.0.3"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
|
||||
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
|
||||
dependencies:
|
||||
base64-js "^1.3.1"
|
||||
ieee754 "^1.2.1"
|
||||
|
||||
fs@^0.0.1-security:
|
||||
version "0.0.1-security"
|
||||
resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.1-security.tgz#8a7bd37186b6dddf3813f23858b57ecaaf5e41d4"
|
||||
integrity sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==
|
||||
|
||||
ieee754@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||
|
||||
js-sha1@^0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/js-sha1/-/js-sha1-0.7.0.tgz#fecaf5f36bb09a51b01da46b43a207c8452c9c1e"
|
||||
integrity sha512-oQZ1Mo7440BfLSv9TX87VNEyU52pXPVG19F9PL3gTgNt0tVxlZ8F4O6yze3CLuLx28TxotxvlyepCNaaV0ZjMw==
|
||||
|
||||
js-sha256@^0.10.1:
|
||||
version "0.10.1"
|
||||
resolved "https://registry.npmjs.org/js-sha256/-/js-sha256-0.10.1.tgz"
|
||||
integrity sha512-5obBtsz9301ULlsgggLg542s/jqtddfOpV5KJc4hajc9JV8GeY2gZHSVpYBn4nWqAUTJ9v+xwtbJ1mIBgIH5Vw==
|
||||
|
||||
js-sha512@^0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/js-sha512/-/js-sha512-0.9.0.tgz#ed569aa1e4bdaf0b83363c29db1ab87b1192d9ae"
|
||||
integrity sha512-mirki9WS/SUahm+1TbAPkqvbCiCfOAAsyXeHxK1UkullnJVVqoJG2pL9ObvT05CN+tM7fxhfYm0NbXn+1hWoZg==
|
||||
|
||||
node-forge@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz"
|
||||
integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==
|
||||
|
||||
poseidon-lite@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/poseidon-lite/-/poseidon-lite-0.2.0.tgz#dbc242ebd9c10c32d507a533fa497231d168fd72"
|
||||
integrity sha512-vivDZnGmz8W4G/GzVA72PXkfYStjilu83rjjUfpL4PueKcC8nfX6hCPh2XhoC5FBgC6y0TA3YuUeUo5YCcNoig==
|
||||
|
||||
regenerator-runtime@^0.14.0:
|
||||
version "0.14.0"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
|
||||
integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==
|
||||
|
||||
undici-types@~5.26.4:
|
||||
version "5.26.5"
|
||||
resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz"
|
||||
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
|
||||
640
common/yarn.lock
640
common/yarn.lock
@@ -18,6 +18,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426"
|
||||
integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==
|
||||
|
||||
"@types/json5@^0.0.29":
|
||||
version "0.0.29"
|
||||
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||
integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
|
||||
|
||||
"@types/node-forge@^1.3.10":
|
||||
version "1.3.10"
|
||||
resolved "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.10.tgz"
|
||||
@@ -57,6 +62,36 @@
|
||||
dependencies:
|
||||
buffer "^6.0.3"
|
||||
|
||||
ansi-colors@^4.1.3:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b"
|
||||
integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==
|
||||
|
||||
ansi-regex@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
||||
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
||||
|
||||
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
|
||||
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
|
||||
dependencies:
|
||||
color-convert "^2.0.1"
|
||||
|
||||
anymatch@~3.1.2:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
|
||||
integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
|
||||
dependencies:
|
||||
normalize-path "^3.0.0"
|
||||
picomatch "^2.0.4"
|
||||
|
||||
argparse@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
||||
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
|
||||
|
||||
array-buffer-byte-length@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz#1e5583ec16763540a27ae52eed99ff899223568f"
|
||||
@@ -104,6 +139,11 @@ arraybuffer.prototype.slice@^1.0.3:
|
||||
is-array-buffer "^3.0.4"
|
||||
is-shared-array-buffer "^1.0.2"
|
||||
|
||||
arrify@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
|
||||
integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==
|
||||
|
||||
asn1.js@^5.4.1:
|
||||
version "5.4.1"
|
||||
resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07"
|
||||
@@ -123,6 +163,11 @@ asn1js@^3.0.5:
|
||||
pvutils "^1.1.3"
|
||||
tslib "^2.4.0"
|
||||
|
||||
assertion-error@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
|
||||
integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
@@ -144,21 +189,55 @@ axios@^1.7.2:
|
||||
form-data "^4.0.0"
|
||||
proxy-from-env "^1.1.0"
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
base64-js@^1.3.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||
|
||||
binary-extensions@^2.0.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
|
||||
integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
|
||||
|
||||
bn.js@^4.0.0, bn.js@^4.11.9:
|
||||
version "4.12.0"
|
||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
|
||||
integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
|
||||
|
||||
brace-expansion@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
|
||||
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
|
||||
braces@~3.0.2:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
|
||||
integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
|
||||
dependencies:
|
||||
fill-range "^7.1.1"
|
||||
|
||||
brorand@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
|
||||
integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==
|
||||
|
||||
browser-stdout@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
|
||||
integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
|
||||
|
||||
buffer-from@^1.0.0, buffer-from@^1.1.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
|
||||
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
|
||||
|
||||
buffer@^6.0.3:
|
||||
version "6.0.3"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
|
||||
@@ -183,6 +262,75 @@ call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bin
|
||||
get-intrinsic "^1.2.4"
|
||||
set-function-length "^1.2.1"
|
||||
|
||||
camelcase@^6.0.0:
|
||||
version "6.3.0"
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
|
||||
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
|
||||
|
||||
chai@^4.3.8:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/chai/-/chai-4.5.0.tgz#707e49923afdd9b13a8b0b47d33d732d13812fd8"
|
||||
integrity sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==
|
||||
dependencies:
|
||||
assertion-error "^1.1.0"
|
||||
check-error "^1.0.3"
|
||||
deep-eql "^4.1.3"
|
||||
get-func-name "^2.0.2"
|
||||
loupe "^2.3.6"
|
||||
pathval "^1.1.1"
|
||||
type-detect "^4.1.0"
|
||||
|
||||
chalk@^4.1.0:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
||||
dependencies:
|
||||
ansi-styles "^4.1.0"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
check-error@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.3.tgz#a6502e4312a7ee969f646e83bb3ddd56281bd694"
|
||||
integrity sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==
|
||||
dependencies:
|
||||
get-func-name "^2.0.2"
|
||||
|
||||
chokidar@^3.5.3:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b"
|
||||
integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==
|
||||
dependencies:
|
||||
anymatch "~3.1.2"
|
||||
braces "~3.0.2"
|
||||
glob-parent "~5.1.2"
|
||||
is-binary-path "~2.1.0"
|
||||
is-glob "~4.0.1"
|
||||
normalize-path "~3.0.0"
|
||||
readdirp "~3.6.0"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
cliui@^7.0.2:
|
||||
version "7.0.4"
|
||||
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
|
||||
integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
|
||||
dependencies:
|
||||
string-width "^4.2.0"
|
||||
strip-ansi "^6.0.0"
|
||||
wrap-ansi "^7.0.0"
|
||||
|
||||
color-convert@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
||||
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
|
||||
dependencies:
|
||||
color-name "~1.1.4"
|
||||
|
||||
color-name@~1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
combined-stream@^1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||
@@ -217,6 +365,25 @@ data-view-byte-offset@^1.0.0:
|
||||
es-errors "^1.3.0"
|
||||
is-data-view "^1.0.1"
|
||||
|
||||
debug@^4.3.5:
|
||||
version "4.3.7"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52"
|
||||
integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==
|
||||
dependencies:
|
||||
ms "^2.1.3"
|
||||
|
||||
decamelize@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837"
|
||||
integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==
|
||||
|
||||
deep-eql@^4.1.3:
|
||||
version "4.1.4"
|
||||
resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.4.tgz#d0d3912865911bb8fac5afb4e3acfa6a28dc72b7"
|
||||
integrity sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==
|
||||
dependencies:
|
||||
type-detect "^4.0.0"
|
||||
|
||||
define-data-property@^1.0.1, define-data-property@^1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
|
||||
@@ -240,6 +407,16 @@ delayed-stream@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
|
||||
|
||||
diff@^3.1.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
|
||||
integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
|
||||
|
||||
diff@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531"
|
||||
integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==
|
||||
|
||||
elliptic@^6.5.5:
|
||||
version "6.5.5"
|
||||
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.5.tgz#c715e09f78b6923977610d4c2346d6ce22e6dded"
|
||||
@@ -253,6 +430,11 @@ elliptic@^6.5.5:
|
||||
minimalistic-assert "^1.0.1"
|
||||
minimalistic-crypto-utils "^1.0.1"
|
||||
|
||||
emoji-regex@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
|
||||
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
|
||||
|
||||
es-abstract@^1.17.0-next.1, es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.2:
|
||||
version "1.23.3"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0"
|
||||
@@ -362,6 +544,36 @@ es7-shim@^6.0.0:
|
||||
string.prototype.trimleft "^2.0.0"
|
||||
string.prototype.trimright "^2.0.0"
|
||||
|
||||
escalade@^3.1.1:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5"
|
||||
integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
|
||||
|
||||
escape-string-regexp@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
||||
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
||||
|
||||
fill-range@^7.1.1:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
|
||||
integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
|
||||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
find-up@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
|
||||
integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
|
||||
dependencies:
|
||||
locate-path "^6.0.0"
|
||||
path-exists "^4.0.0"
|
||||
|
||||
flat@^5.0.2:
|
||||
version "5.0.2"
|
||||
resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241"
|
||||
integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
|
||||
|
||||
follow-redirects@^1.15.6:
|
||||
version "1.15.6"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b"
|
||||
@@ -383,11 +595,21 @@ form-data@^4.0.0:
|
||||
combined-stream "^1.0.8"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
|
||||
|
||||
fs@^0.0.1-security:
|
||||
version "0.0.1-security"
|
||||
resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.1-security.tgz#8a7bd37186b6dddf3813f23858b57ecaaf5e41d4"
|
||||
integrity sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==
|
||||
|
||||
fsevents@~2.3.2:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
|
||||
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
|
||||
|
||||
function-bind@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
|
||||
@@ -408,6 +630,16 @@ functions-have-names@^1.2.3:
|
||||
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
|
||||
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
|
||||
|
||||
get-caller-file@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||
|
||||
get-func-name@^2.0.1, get-func-name@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41"
|
||||
integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==
|
||||
|
||||
get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
|
||||
@@ -428,6 +660,24 @@ get-symbol-description@^1.0.2:
|
||||
es-errors "^1.3.0"
|
||||
get-intrinsic "^1.2.4"
|
||||
|
||||
glob-parent@~5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
||||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
glob@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e"
|
||||
integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^5.0.1"
|
||||
once "^1.3.0"
|
||||
|
||||
globalthis@^1.0.3:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236"
|
||||
@@ -448,6 +698,11 @@ has-bigints@^1.0.1, has-bigints@^1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa"
|
||||
integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==
|
||||
|
||||
has-flag@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
|
||||
|
||||
has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
|
||||
@@ -487,6 +742,11 @@ hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2:
|
||||
dependencies:
|
||||
function-bind "^1.1.2"
|
||||
|
||||
he@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||
|
||||
hmac-drbg@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
||||
@@ -501,16 +761,24 @@ ieee754@^1.2.1:
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
|
||||
dependencies:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
inherits@2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==
|
||||
|
||||
inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
internal-slot@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802"
|
||||
@@ -535,6 +803,13 @@ is-bigint@^1.0.1:
|
||||
dependencies:
|
||||
has-bigints "^1.0.1"
|
||||
|
||||
is-binary-path@~2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
|
||||
integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
|
||||
dependencies:
|
||||
binary-extensions "^2.0.0"
|
||||
|
||||
is-boolean-object@^1.1.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719"
|
||||
@@ -562,6 +837,23 @@ is-date-object@^1.0.1:
|
||||
dependencies:
|
||||
has-tostringtag "^1.0.0"
|
||||
|
||||
is-extglob@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
|
||||
|
||||
is-fullwidth-code-point@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
|
||||
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
|
||||
|
||||
is-glob@^4.0.1, is-glob@~4.0.1:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
||||
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
||||
dependencies:
|
||||
is-extglob "^2.1.1"
|
||||
|
||||
is-negative-zero@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747"
|
||||
@@ -574,6 +866,16 @@ is-number-object@^1.0.4:
|
||||
dependencies:
|
||||
has-tostringtag "^1.0.0"
|
||||
|
||||
is-number@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
|
||||
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
|
||||
|
||||
is-plain-obj@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
|
||||
integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
|
||||
|
||||
is-regex@^1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
|
||||
@@ -610,6 +912,11 @@ is-typed-array@^1.1.13:
|
||||
dependencies:
|
||||
which-typed-array "^1.1.14"
|
||||
|
||||
is-unicode-supported@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
|
||||
integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==
|
||||
|
||||
is-weakref@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2"
|
||||
@@ -637,6 +944,13 @@ js-sha512@^0.9.0:
|
||||
resolved "https://registry.yarnpkg.com/js-sha512/-/js-sha512-0.9.0.tgz#ed569aa1e4bdaf0b83363c29db1ab87b1192d9ae"
|
||||
integrity sha512-mirki9WS/SUahm+1TbAPkqvbCiCfOAAsyXeHxK1UkullnJVVqoJG2pL9ObvT05CN+tM7fxhfYm0NbXn+1hWoZg==
|
||||
|
||||
js-yaml@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
|
||||
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
|
||||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
|
||||
json-to-ts@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/json-to-ts/-/json-to-ts-2.1.0.tgz#c68c0b210a811e8dccbe2752e68efbc0ca62bfc5"
|
||||
@@ -646,11 +960,25 @@ json-to-ts@^2.1.0:
|
||||
hash.js "^1.0.3"
|
||||
pluralize "^3.1.0"
|
||||
|
||||
json5@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593"
|
||||
integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==
|
||||
dependencies:
|
||||
minimist "^1.2.0"
|
||||
|
||||
jsrsasign@^11.1.0:
|
||||
version "11.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsrsasign/-/jsrsasign-11.1.0.tgz#195e788102731102fbf3e36b33fde28936f4bf57"
|
||||
integrity sha512-Ov74K9GihaK9/9WncTe1mPmvrO7Py665TUfUKvraXBpu+xcTWitrtuOwcjf4KMU9maPaYn0OuaWy0HOzy/GBXg==
|
||||
|
||||
locate-path@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
|
||||
integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
|
||||
dependencies:
|
||||
p-locate "^5.0.0"
|
||||
|
||||
lodash-es@^4.17.10:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
|
||||
@@ -661,6 +989,26 @@ lodash@^4.17.10:
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
||||
log-symbols@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
|
||||
integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==
|
||||
dependencies:
|
||||
chalk "^4.1.0"
|
||||
is-unicode-supported "^0.1.0"
|
||||
|
||||
loupe@^2.3.6:
|
||||
version "2.3.7"
|
||||
resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.7.tgz#6e69b7d4db7d3ab436328013d37d1c8c3540c697"
|
||||
integrity sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==
|
||||
dependencies:
|
||||
get-func-name "^2.0.1"
|
||||
|
||||
make-error@^1.1.1:
|
||||
version "1.3.6"
|
||||
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
|
||||
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
|
||||
|
||||
mime-db@1.52.0:
|
||||
version "1.52.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
|
||||
@@ -683,10 +1031,65 @@ minimalistic-crypto-utils@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
|
||||
integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==
|
||||
|
||||
minimatch@^5.0.1, minimatch@^5.1.6:
|
||||
version "5.1.6"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"
|
||||
integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
|
||||
dependencies:
|
||||
brace-expansion "^2.0.1"
|
||||
|
||||
minimist@^1.2.0, minimist@^1.2.6:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
|
||||
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
|
||||
|
||||
mkdirp@^0.5.1:
|
||||
version "0.5.6"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
|
||||
integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==
|
||||
dependencies:
|
||||
minimist "^1.2.6"
|
||||
|
||||
mocha@^10.7.3:
|
||||
version "10.7.3"
|
||||
resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.7.3.tgz#ae32003cabbd52b59aece17846056a68eb4b0752"
|
||||
integrity sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==
|
||||
dependencies:
|
||||
ansi-colors "^4.1.3"
|
||||
browser-stdout "^1.3.1"
|
||||
chokidar "^3.5.3"
|
||||
debug "^4.3.5"
|
||||
diff "^5.2.0"
|
||||
escape-string-regexp "^4.0.0"
|
||||
find-up "^5.0.0"
|
||||
glob "^8.1.0"
|
||||
he "^1.2.0"
|
||||
js-yaml "^4.1.0"
|
||||
log-symbols "^4.1.0"
|
||||
minimatch "^5.1.6"
|
||||
ms "^2.1.3"
|
||||
serialize-javascript "^6.0.2"
|
||||
strip-json-comments "^3.1.1"
|
||||
supports-color "^8.1.1"
|
||||
workerpool "^6.5.1"
|
||||
yargs "^16.2.0"
|
||||
yargs-parser "^20.2.9"
|
||||
yargs-unparser "^2.0.0"
|
||||
|
||||
ms@^2.1.3:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||
|
||||
"node-forge@https://github.com/remicolin/forge":
|
||||
version "1.3.2-0"
|
||||
resolved "https://github.com/remicolin/forge#17a11a632dd0e50343b3b8393245a2696f78afbb"
|
||||
|
||||
normalize-path@^3.0.0, normalize-path@~3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||
|
||||
object-inspect@^1.13.1:
|
||||
version "1.13.2"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff"
|
||||
@@ -738,6 +1141,32 @@ object.values@^1.0.3:
|
||||
define-properties "^1.2.1"
|
||||
es-object-atoms "^1.0.0"
|
||||
|
||||
once@^1.3.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
p-limit@^3.0.2:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
|
||||
integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
|
||||
dependencies:
|
||||
yocto-queue "^0.1.0"
|
||||
|
||||
p-locate@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
|
||||
integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
|
||||
dependencies:
|
||||
p-limit "^3.0.2"
|
||||
|
||||
path-exists@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
|
||||
integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
|
||||
|
||||
path@^0.12.7:
|
||||
version "0.12.7"
|
||||
resolved "https://registry.yarnpkg.com/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f"
|
||||
@@ -746,6 +1175,16 @@ path@^0.12.7:
|
||||
process "^0.11.1"
|
||||
util "^0.10.3"
|
||||
|
||||
pathval@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d"
|
||||
integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==
|
||||
|
||||
picomatch@^2.0.4, picomatch@^2.2.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
||||
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
|
||||
|
||||
pkijs@^3.2.4:
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/pkijs/-/pkijs-3.2.4.tgz#55ed72b363a20fbd42b139ee3b72e54483635171"
|
||||
@@ -795,6 +1234,20 @@ pvutils@^1.1.3:
|
||||
resolved "https://registry.yarnpkg.com/pvutils/-/pvutils-1.1.3.tgz#f35fc1d27e7cd3dfbd39c0826d173e806a03f5a3"
|
||||
integrity sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==
|
||||
|
||||
randombytes@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
|
||||
integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
|
||||
dependencies:
|
||||
safe-buffer "^5.1.0"
|
||||
|
||||
readdirp@~3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
|
||||
integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
|
||||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
regenerator-runtime@^0.14.0:
|
||||
version "0.14.0"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
|
||||
@@ -810,6 +1263,11 @@ regexp.prototype.flags@^1.5.2:
|
||||
es-errors "^1.3.0"
|
||||
set-function-name "^2.0.1"
|
||||
|
||||
require-directory@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||
integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
|
||||
|
||||
safe-array-concat@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz#81d77ee0c4e8b863635227c721278dd524c20edb"
|
||||
@@ -820,6 +1278,11 @@ safe-array-concat@^1.1.2:
|
||||
has-symbols "^1.0.3"
|
||||
isarray "^2.0.5"
|
||||
|
||||
safe-buffer@^5.1.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
safe-regex-test@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377"
|
||||
@@ -834,6 +1297,13 @@ safer-buffer@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
serialize-javascript@^6.0.2:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2"
|
||||
integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==
|
||||
dependencies:
|
||||
randombytes "^2.1.0"
|
||||
|
||||
set-function-length@^1.2.1:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"
|
||||
@@ -866,6 +1336,19 @@ side-channel@^1.0.4:
|
||||
get-intrinsic "^1.2.4"
|
||||
object-inspect "^1.13.1"
|
||||
|
||||
source-map-support@^0.5.6:
|
||||
version "0.5.21"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
|
||||
integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
|
||||
dependencies:
|
||||
buffer-from "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
|
||||
source-map@^0.6.0:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
|
||||
string-at@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/string-at/-/string-at-1.1.0.tgz#332e090c5724418266a27a09394924b9fad41275"
|
||||
@@ -874,6 +1357,15 @@ string-at@^1.0.1:
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.17.0-next.1"
|
||||
|
||||
string-width@^4.1.0, string-width@^4.2.0:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
dependencies:
|
||||
emoji-regex "^8.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.1"
|
||||
|
||||
string.prototype.padend@^3.0.0:
|
||||
version "3.1.6"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz#ba79cf8992609a91c872daa47c6bb144ee7f62a5"
|
||||
@@ -940,6 +1432,77 @@ string.prototype.trimstart@^1.0.3, string.prototype.trimstart@^1.0.8:
|
||||
define-properties "^1.2.1"
|
||||
es-object-atoms "^1.0.0"
|
||||
|
||||
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-bom@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
||||
integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==
|
||||
|
||||
strip-json-comments@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
|
||||
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
|
||||
|
||||
supports-color@^7.1.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
|
||||
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
supports-color@^8.1.1:
|
||||
version "8.1.1"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
|
||||
integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
to-regex-range@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
||||
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
|
||||
dependencies:
|
||||
is-number "^7.0.0"
|
||||
|
||||
ts-mocha@^10.0.0:
|
||||
version "10.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-10.0.0.tgz#41a8d099ac90dbbc64b06976c5025ffaebc53cb9"
|
||||
integrity sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw==
|
||||
dependencies:
|
||||
ts-node "7.0.1"
|
||||
optionalDependencies:
|
||||
tsconfig-paths "^3.5.0"
|
||||
|
||||
ts-node@7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf"
|
||||
integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==
|
||||
dependencies:
|
||||
arrify "^1.0.0"
|
||||
buffer-from "^1.1.0"
|
||||
diff "^3.1.0"
|
||||
make-error "^1.1.1"
|
||||
minimist "^1.2.0"
|
||||
mkdirp "^0.5.1"
|
||||
source-map-support "^0.5.6"
|
||||
yn "^2.0.0"
|
||||
|
||||
tsconfig-paths@^3.5.0:
|
||||
version "3.15.0"
|
||||
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4"
|
||||
integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==
|
||||
dependencies:
|
||||
"@types/json5" "^0.0.29"
|
||||
json5 "^1.0.2"
|
||||
minimist "^1.2.6"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
tslib@^1.9.3:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
@@ -950,6 +1513,11 @@ tslib@^2.4.0, tslib@^2.6.1, tslib@^2.6.3:
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01"
|
||||
integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==
|
||||
|
||||
type-detect@^4.0.0, type-detect@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.1.0.tgz#deb2453e8f08dcae7ae98c626b13dddb0155906c"
|
||||
integrity sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==
|
||||
|
||||
typed-array-buffer@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz#1867c5d83b20fcb5ccf32649e5e2fc7424474ff3"
|
||||
@@ -1052,3 +1620,65 @@ which-typed-array@^1.1.14, which-typed-array@^1.1.15:
|
||||
for-each "^0.3.3"
|
||||
gopd "^1.0.1"
|
||||
has-tostringtag "^1.0.2"
|
||||
|
||||
workerpool@^6.5.1:
|
||||
version "6.5.1"
|
||||
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544"
|
||||
integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==
|
||||
|
||||
wrap-ansi@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
dependencies:
|
||||
ansi-styles "^4.0.0"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
|
||||
|
||||
y18n@^5.0.5:
|
||||
version "5.0.8"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
|
||||
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
|
||||
|
||||
yargs-parser@^20.2.2, yargs-parser@^20.2.9:
|
||||
version "20.2.9"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
|
||||
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
|
||||
|
||||
yargs-unparser@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb"
|
||||
integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==
|
||||
dependencies:
|
||||
camelcase "^6.0.0"
|
||||
decamelize "^4.0.0"
|
||||
flat "^5.0.2"
|
||||
is-plain-obj "^2.1.0"
|
||||
|
||||
yargs@^16.2.0:
|
||||
version "16.2.0"
|
||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
|
||||
integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
|
||||
dependencies:
|
||||
cliui "^7.0.2"
|
||||
escalade "^3.1.1"
|
||||
get-caller-file "^2.0.5"
|
||||
require-directory "^2.1.1"
|
||||
string-width "^4.2.0"
|
||||
y18n "^5.0.5"
|
||||
yargs-parser "^20.2.2"
|
||||
|
||||
yn@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a"
|
||||
integrity sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==
|
||||
|
||||
yocto-queue@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
||||
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
|
||||
|
||||
Reference in New Issue
Block a user