mirror of
https://github.com/selfxyz/self.git
synced 2026-01-10 15:18:18 -05:00
fix: working tests
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(24, 64, 4, 512, 256, 20);
|
||||
@@ -1,5 +0,0 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(22, 64, 6, 512, 256, 20);
|
||||
@@ -1,5 +0,0 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(9, 64, 6, 512, 256, 20);
|
||||
@@ -1,5 +0,0 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(25, 64, 4, 640, 256, 20);
|
||||
@@ -1,5 +0,0 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(26, 64, 6, 640, 256, 20);
|
||||
@@ -2,4 +2,4 @@ pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(28, 32, 7, 384, 192, 20);
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(160, 160, 27, 32, 7, 320, 128, 20);
|
||||
@@ -2,4 +2,4 @@ pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(21, 64, 4, 384, 192, 20);
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(256, 224, 30, 32, 7, 448, 128, 20);
|
||||
@@ -2,4 +2,4 @@ pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(23, 64, 6, 384, 192, 20);
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(256, 256, 28, 32, 7, 448, 128, 20);
|
||||
@@ -0,0 +1,5 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(256, 256, 21, 64, 4, 448, 128, 20);
|
||||
@@ -0,0 +1,5 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(256, 256, 23, 64, 6, 448, 128, 20);
|
||||
@@ -0,0 +1,5 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(384, 384, 24, 64, 4, 640, 256, 20);
|
||||
@@ -0,0 +1,5 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(384, 384, 22, 64, 6, 640, 256, 20);
|
||||
@@ -2,4 +2,4 @@ pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(27, 32, 7, 320, 192, 20);
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(384, 384, 9, 64, 6, 640, 256, 20);
|
||||
@@ -0,0 +1,5 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(512, 512, 25, 64, 4, 768, 256, 20);
|
||||
@@ -0,0 +1,5 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(512, 512, 26, 64, 6, 768, 256, 20);
|
||||
@@ -331,7 +331,7 @@ function prod_dl(n, k, a, b) {
|
||||
// k * n <= 500
|
||||
// p is a prime
|
||||
// computes a^e mod p
|
||||
function mod_exp(n, k, a, p, e) {
|
||||
function mod_exp_dl(n, k, a, p, e) {
|
||||
var eBits[512];
|
||||
for (var i = 0; i < k; i++) {
|
||||
for (var j = 0; j < n; j++) {
|
||||
|
||||
@@ -49,7 +49,6 @@ include "./get.circom";
|
||||
// λ = (3 * x ** 2 + a) / (2 * y)
|
||||
// y3 = λ * (x - x3) - y
|
||||
template TangentCheck(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
|
||||
assert(CHUNK_SIZE == 64);
|
||||
|
||||
signal input in1[2][CHUNK_NUMBER];
|
||||
@@ -728,7 +727,6 @@ template EllipticCurvePipingerMult(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, WINDOW_SIZ
|
||||
if (i != 0){
|
||||
for (var j = 0; j < WINDOW_SIZE; j++){
|
||||
doublers[i + j - WINDOW_SIZE] = EllipticCurveDouble(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
doublers[i + j - WINDOW_SIZE].dummy <== dummy;
|
||||
|
||||
if (j == 0){
|
||||
for (var axis_idx = 0; axis_idx < 2; axis_idx++){
|
||||
|
||||
@@ -3,22 +3,29 @@ pragma circom 2.0.0;
|
||||
include "../sha2Common.circom";
|
||||
include "../sha256/sha256Schedule.circom";
|
||||
include "../sha256/sha256Rounds.circom";
|
||||
include "@zk-email/circuits/utils/array.circom";
|
||||
include "sha224InitialValue.circom";
|
||||
|
||||
template Sha224HashChunks(BLOCK_NUM) {
|
||||
|
||||
signal input in[BLOCK_NUM * 512];
|
||||
template Sha224HashChunks(MAX_BLOCKS) {
|
||||
signal input in[MAX_BLOCKS * 512];
|
||||
signal input paddedInLength;
|
||||
|
||||
signal output out[224];
|
||||
|
||||
signal inBlockIndex;
|
||||
|
||||
inBlockIndex <-- (paddedInLength >> 9);
|
||||
paddedInLength === inBlockIndex * 512;
|
||||
|
||||
signal states[BLOCK_NUM + 1][8][32];
|
||||
signal states[MAX_BLOCKS + 1][8][32];
|
||||
|
||||
component iv = Sha224InitialValue();
|
||||
iv.out ==> states[0];
|
||||
|
||||
component sch[BLOCK_NUM];
|
||||
component rds[BLOCK_NUM];
|
||||
component sch[MAX_BLOCKS];
|
||||
component rds[MAX_BLOCKS];
|
||||
|
||||
for (var m = 0; m < BLOCK_NUM; m++) {
|
||||
for (var m = 0; m < MAX_BLOCKS; m++) {
|
||||
|
||||
sch[m] = Sha2_224_256Shedule();
|
||||
rds[m] = Sha2_224_256Rounds(64);
|
||||
@@ -35,9 +42,15 @@ template Sha224HashChunks(BLOCK_NUM) {
|
||||
rds[m].outHash ==> states[m + 1];
|
||||
}
|
||||
|
||||
component arraySelectors[224];
|
||||
for (var j = 0; j < 7; j++) {
|
||||
for (var i = 0; i < 32; i++){
|
||||
out[j * 32 + i] <== states[BLOCK_NUM][j][31 - i];
|
||||
arraySelectors[j * 32 + i] = ItemAtIndex(MAX_BLOCKS + 1);
|
||||
for (var k = 0; k <= MAX_BLOCKS; k++) {
|
||||
arraySelectors[j * 32 + i].in[k] <== states[k][j][31 - i];
|
||||
}
|
||||
arraySelectors[j * 32 + i].index <== inBlockIndex;
|
||||
out[j * 32 + i] <== arraySelectors[j * 32 + i].out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,12 @@ pragma circom 2.0.0;
|
||||
include "../sha2Common.circom";
|
||||
include "../sha512/sha512Schedule.circom";
|
||||
include "../sha512/sha512Rounds.circom";
|
||||
include "../../../utils/array.circom";
|
||||
include "@zk-email/circuits/utils/array.circom";
|
||||
include "sha384InitialValue.circom";
|
||||
|
||||
template Sha384HashChunks(MAX_BLOCKS) {
|
||||
signal input in[MAX_BLOCKS * 1024];
|
||||
signal input paddedInLength;
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
signal output out[384];
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ pragma circom 2.0.0;
|
||||
include "../sha2Common.circom";
|
||||
include "sha512InitialValue.circom";
|
||||
include "sha512Schedule.circom";
|
||||
include "../../../utils/array.circom";
|
||||
include "@zk-email/circuits/utils/array.circom";
|
||||
include "sha512Rounds.circom";
|
||||
|
||||
template Sha512HashChunks(MAX_BLOCKS) {
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "../../sha2/sha224/sha224HashChunks.circom";
|
||||
|
||||
template Sha224Bytes(maxByteLength) {
|
||||
signal input paddedIn[maxByteLength];
|
||||
signal input paddedInLength;
|
||||
signal output out[224];
|
||||
|
||||
component sha = Sha224HashChunks((maxByteLength * 8) \ 512);
|
||||
sha.paddedInLength <== paddedInLength * 8;
|
||||
|
||||
component bytes[maxByteLength];
|
||||
for (var i = 0; i < maxByteLength; i++) {
|
||||
bytes[i] = Num2Bits(8);
|
||||
bytes[i].in <== paddedIn[i];
|
||||
for (var j = 0; j < 8; j++) {
|
||||
sha.in[i*8+j] <== bytes[i].out[7-j];
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < 224; i++) {
|
||||
out[i] <== sha.out[i];
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../../bitify/bitify.circom";
|
||||
include "../../../bitify/comparators.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "../../sha2/sha384/sha384HashChunks.circom";
|
||||
|
||||
template Sha384Bytes(maxByteLength) {
|
||||
@@ -20,7 +20,6 @@ template Sha384Bytes(maxByteLength) {
|
||||
sha.in[i*8+j] <== bytes[i].out[7-j];
|
||||
}
|
||||
}
|
||||
sha.dummy <== 0;
|
||||
|
||||
for (var i = 0; i < 384; i++) {
|
||||
out[i] <== sha.out[i];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../../bitify/bitify.circom";
|
||||
include "../../../bitify/comparators.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "../../sha2/sha512/sha512HashChunks.circom";
|
||||
|
||||
template Sha512Bytes(maxByteLength) {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "./dynamic/sha1Bytes.circom";
|
||||
include "./dynamic/sha256Bytes.circom";
|
||||
include "./dynamic/sha224Bytes.circom";
|
||||
include "@zk-email/circuits/lib/sha.circom";
|
||||
include "./dynamic/sha384Bytes.circom";
|
||||
include "./dynamic/sha512Bytes.circom";
|
||||
|
||||
@@ -20,6 +21,9 @@ template ShaBytesDynamic(hashLen, max_num_bits) {
|
||||
if (hashLen == 256) {
|
||||
hash <== Sha256Bytes(max_num_bits)(in_padded, in_len_padded_bytes);
|
||||
}
|
||||
if (hashLen == 224) {
|
||||
hash <== Sha224Bytes(max_num_bits)(in_padded, in_len_padded_bytes);
|
||||
}
|
||||
if (hashLen == 160) {
|
||||
hash <== Sha1Bytes(max_num_bits)(in_padded, in_len_padded_bytes);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,6 @@ template EcdsaVerifier(signatureAlgorithm, n, k) {
|
||||
ecdsa_verify.pubkey <== pubkey_xy;
|
||||
ecdsa_verify.signature <== [signature_r, signature_s];
|
||||
ecdsa_verify.hashed <== hash;
|
||||
ecdsa_verify.dummy <== 0;
|
||||
}
|
||||
if (signatureAlgorithm == 9 || signatureAlgorithm == 23) {
|
||||
component ecdsa_verify = verifyECDSABits(n, k, [
|
||||
@@ -98,7 +97,6 @@ template EcdsaVerifier(signatureAlgorithm, n, k) {
|
||||
ecdsa_verify.pubkey <== pubkey_xy;
|
||||
ecdsa_verify.signature <== [signature_r, signature_s];
|
||||
ecdsa_verify.hashed <== hash;
|
||||
ecdsa_verify.dummy <== 0;
|
||||
}
|
||||
if (signatureAlgorithm == 21 || signatureAlgorithm == 24 || signatureAlgorithm == 25) {
|
||||
component ecdsa_verify = verifyECDSABits(n, k, [
|
||||
@@ -123,7 +121,6 @@ template EcdsaVerifier(signatureAlgorithm, n, k) {
|
||||
ecdsa_verify.pubkey <== pubkey_xy;
|
||||
ecdsa_verify.signature <== [signature_r, signature_s];
|
||||
ecdsa_verify.hashed <== hash;
|
||||
ecdsa_verify.dummy <== 0;
|
||||
}
|
||||
if (signatureAlgorithm == 22 || signatureAlgorithm == 26) {
|
||||
component ecdsa_verify = verifyECDSABits(n, k, [
|
||||
@@ -154,9 +151,8 @@ template EcdsaVerifier(signatureAlgorithm, n, k) {
|
||||
ecdsa_verify.pubkey <== pubkey_xy;
|
||||
ecdsa_verify.signature <== [signature_r, signature_s];
|
||||
ecdsa_verify.hashed <== hash;
|
||||
ecdsa_verify.dummy <== 0;
|
||||
}
|
||||
if (signatureAlgorithm == 27 || signatureAlgorithm == 28) {
|
||||
if (signatureAlgorithm == 27 || signatureAlgorithm == 28 || signatureAlgorithm == 30) {
|
||||
component ecdsa_verify = verifyECDSABits(n, k, [
|
||||
3402800963,
|
||||
2953063001,
|
||||
@@ -188,7 +184,6 @@ template EcdsaVerifier(signatureAlgorithm, n, k) {
|
||||
ecdsa_verify.pubkey <== pubkey_xy;
|
||||
ecdsa_verify.signature <== [signature_r, signature_s];
|
||||
ecdsa_verify.hashed <== hash;
|
||||
ecdsa_verify.dummy <== 0;
|
||||
}
|
||||
if (signatureAlgorithm == 29) {
|
||||
component ecdsa_verify = verifyECDSABits(n, k, [
|
||||
@@ -225,6 +220,5 @@ template EcdsaVerifier(signatureAlgorithm, n, k) {
|
||||
ecdsa_verify.pubkey <== pubkey_xy;
|
||||
ecdsa_verify.signature <== [signature_r, signature_s];
|
||||
ecdsa_verify.hashed <== hash;
|
||||
ecdsa_verify.dummy <== 0;
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ pragma circom 2.1.9;
|
||||
27: ecdsa_sha1_brainpoolP224r1_224
|
||||
28: ecdsa_sha256_brainpoolP224r1_224
|
||||
29: ecdsa_sha512_brainpoolP512r1_512
|
||||
30: ecdsa_sha224_brainpoolP224r1_224
|
||||
*/
|
||||
|
||||
function getHashLength(signatureAlgorithm) {
|
||||
@@ -108,6 +109,9 @@ function getHashLength(signatureAlgorithm) {
|
||||
if (signatureAlgorithm == 29) {
|
||||
return 512;
|
||||
}
|
||||
if (signatureAlgorithm == 30) {
|
||||
return 224;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -187,6 +191,9 @@ function getKeyLength(signatureAlgorithm) {
|
||||
if (signatureAlgorithm == 29) {
|
||||
return 512;
|
||||
}
|
||||
if (signatureAlgorithm == 30) {
|
||||
return 224;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -267,6 +274,9 @@ function getKLengthFactor(signatureAlgorithm) {
|
||||
if (signatureAlgorithm == 29) {
|
||||
return 2;
|
||||
}
|
||||
if (signatureAlgorithm == 30) {
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../circomlib/signature/rsapss/rsapss.circom";
|
||||
include "secp256r1Verifier.circom";
|
||||
include "ecdsaVerifier.circom";
|
||||
include "../circomlib/signature/rsa/verifyRsa3Pkcs1v1_5.circom";
|
||||
include "../circomlib/signature/rsa/verifyRsa65537Pkcs1v1_5.circom";
|
||||
include "@zk-email/circuits/utils/bytes.circom";
|
||||
@@ -82,6 +82,7 @@ template SignatureVerifier(signatureAlgorithm, n, k) {
|
||||
|| signatureAlgorithm == 27
|
||||
|| signatureAlgorithm == 28
|
||||
|| signatureAlgorithm == 29
|
||||
|| signatureAlgorithm == 30
|
||||
) {
|
||||
EcdsaVerifier (signatureAlgorithm, n, k)(signature, pubKey, hash);
|
||||
}
|
||||
|
||||
@@ -9,33 +9,7 @@ import crypto from 'crypto';
|
||||
import { poseidon2 } from 'poseidon-lite';
|
||||
import { SMT } from '@openpassport/zk-kit-smt';
|
||||
import namejson from '../../common/ofacdata/outputs/nameSMT.json';
|
||||
import { log } from 'console';
|
||||
|
||||
// const sigAlgs = [
|
||||
// { sigAlg: 'rsa', hashFunction: 'sha1', domainParameter: '65537', keyLength: '2048' },
|
||||
// { sigAlg: 'rsa', hashFunction: 'sha256', domainParameter: '65537', keyLength: '2048' },
|
||||
// { sigAlg: 'rsapss', hashFunction: 'sha256', domainParameter: '65537', keyLength: '2048' },
|
||||
// { sigAlg: 'rsapss', hashFunction: 'sha256', domainParameter: '65537', keyLength: '3072' },
|
||||
// { sigAlg: 'rsapss', hashFunction: 'sha256', domainParameter: '65537', keyLength: '4096' },
|
||||
// { sigAlg: 'rsapss', hashFunction: 'sha256', domainParameter: '3', keyLength: '4096' },
|
||||
// { sigAlg: 'rsapss', hashFunction: 'sha256', domainParameter: '3', keyLength: '3072' },
|
||||
// { sigAlg: 'rsa', hashFunction: 'sha256', domainParameter: '3', keyLength: '2048' },
|
||||
// { sigAlg: 'rsa', hashFunction: 'sha256', domainParameter: '65537', keyLength: '3072' },
|
||||
// { sigAlg: 'ecdsa', hashFunction: 'sha1', domainParameter: 'brainpoolP224r1', keyLength: '224' },
|
||||
// { sigAlg: 'ecdsa', hashFunction: 'sha256', domainParameter: 'brainpoolP224r1', keyLength: '224' },
|
||||
// { sigAlg: 'ecdsa', hashFunction: 'sha256', domainParameter: 'secp256r1', keyLength: '256' },
|
||||
// { sigAlg: 'ecdsa', hashFunction: 'sha1', domainParameter: 'secp256r1', keyLength: '256' },
|
||||
// { sigAlg: 'ecdsa', hashFunction: 'sha256', domainParameter: 'brainpoolP256r1', keyLength: '256' },
|
||||
// { sigAlg: 'ecdsa', hashFunction: 'sha384', domainParameter: 'brainpoolP256r1', keyLength: '256' },
|
||||
// { sigAlg: 'ecdsa', hashFunction: 'sha512', domainParameter: 'brainpoolP256r1', keyLength: '256' },
|
||||
// { sigAlg: 'ecdsa', hashFunction: 'sha512', domainParameter: 'brainpoolP256r1', keyLength: '256' },
|
||||
// { sigAlg: 'ecdsa', hashFunction: 'sha384', domainParameter: 'secp384r1', keyLength: '384' },
|
||||
// { sigAlg: 'ecdsa', hashFunction: 'sha256', domainParameter: 'secp384r1', keyLength: '384' },
|
||||
// { sigAlg: 'ecdsa', hashFunction: 'sha384', domainParameter: 'brainpoolP384r1', keyLength: '384' },
|
||||
// ];
|
||||
// { sigAlg: 'ecdsa', hashFunction: 'sha512', domainParameter: 'brainpoolP384r1', keyLength: '384' },
|
||||
import { getCircuitNameFromPassportData } from '../../common/src/utils/circuitsName';
|
||||
import { parsePassportData } from '../../common/src/utils/parsePassportData';
|
||||
|
||||
const sigAlgs = [
|
||||
{
|
||||
@@ -70,6 +44,86 @@ const sigAlgs = [
|
||||
domainParameter: 'secp256r1',
|
||||
keyLength: '256',
|
||||
},
|
||||
{
|
||||
dgHashAlgo: 'sha256',
|
||||
eContentHashAlgo: 'sha256',
|
||||
sigAlg: 'ecdsa',
|
||||
hashFunction: 'sha256',
|
||||
domainParameter: 'brainpoolP256r1',
|
||||
keyLength: '256',
|
||||
},
|
||||
{
|
||||
dgHashAlgo: 'sha256',
|
||||
eContentHashAlgo: 'sha256',
|
||||
sigAlg: 'ecdsa',
|
||||
hashFunction: 'sha256',
|
||||
domainParameter: 'secp384r1',
|
||||
keyLength: '384',
|
||||
},
|
||||
{
|
||||
dgHashAlgo: 'sha384',
|
||||
eContentHashAlgo: 'sha384',
|
||||
sigAlg: 'ecdsa',
|
||||
hashFunction: 'sha384',
|
||||
domainParameter: 'brainpoolP256r1',
|
||||
keyLength: '256',
|
||||
},
|
||||
{
|
||||
dgHashAlgo: 'sha384',
|
||||
eContentHashAlgo: 'sha384',
|
||||
sigAlg: 'ecdsa',
|
||||
hashFunction: 'sha384',
|
||||
domainParameter: 'brainpoolP384r1',
|
||||
keyLength: '384',
|
||||
},
|
||||
{
|
||||
dgHashAlgo: 'sha384',
|
||||
eContentHashAlgo: 'sha384',
|
||||
sigAlg: 'ecdsa',
|
||||
hashFunction: 'sha384',
|
||||
domainParameter: 'secp384r1',
|
||||
keyLength: '384',
|
||||
},
|
||||
{
|
||||
dgHashAlgo: 'sha512',
|
||||
eContentHashAlgo: 'sha512',
|
||||
sigAlg: 'ecdsa',
|
||||
hashFunction: 'sha512',
|
||||
domainParameter: 'brainpoolP256r1',
|
||||
keyLength: '256',
|
||||
},
|
||||
{
|
||||
dgHashAlgo: 'sha256',
|
||||
eContentHashAlgo: 'sha224',
|
||||
sigAlg: 'ecdsa',
|
||||
hashFunction: 'sha224',
|
||||
domainParameter: 'brainpoolP224r1',
|
||||
keyLength: '224',
|
||||
},
|
||||
{
|
||||
dgHashAlgo: 'sha256',
|
||||
eContentHashAlgo: 'sha256',
|
||||
sigAlg: 'ecdsa',
|
||||
hashFunction: 'sha256',
|
||||
domainParameter: 'brainpoolP224r1',
|
||||
keyLength: '224',
|
||||
},
|
||||
{
|
||||
dgHashAlgo: 'sha1',
|
||||
eContentHashAlgo: 'sha1',
|
||||
sigAlg: 'ecdsa',
|
||||
hashFunction: 'sha1',
|
||||
domainParameter: 'brainpoolP224r1',
|
||||
keyLength: '224',
|
||||
},
|
||||
{
|
||||
dgHashAlgo: 'sha256',
|
||||
eContentHashAlgo: 'sha256',
|
||||
sigAlg: 'ecdsa',
|
||||
hashFunction: 'sha256',
|
||||
domainParameter: 'secp256r1',
|
||||
keyLength: '256',
|
||||
},
|
||||
];
|
||||
|
||||
const fullSigAlgs = [
|
||||
|
||||
@@ -40,19 +40,21 @@ export const DEFAULT_MAJORITY = '18';
|
||||
// rsa_sha256_65537_3072: 384,
|
||||
// rsa_sha256_3_2048: 384,
|
||||
// };
|
||||
export const hashAlgos = ['sha1', 'sha256', 'sha384', 'sha512'] as const;
|
||||
export const hashAlgos = ['sha1', 'sha224', 'sha256', 'sha384', 'sha512'] as const;
|
||||
export const MAX_PADDED_ECONTENT_LEN: Record<(typeof hashAlgos)[number], number> = {
|
||||
sha1: 320,
|
||||
sha224: 384,
|
||||
sha256: 448,
|
||||
sha384: 576,
|
||||
sha512: 704,
|
||||
sha384: 640,
|
||||
sha512: 768,
|
||||
};
|
||||
|
||||
export const MAX_PADDED_SIGNED_ATTR_LEN: Partial<Record<(typeof hashAlgos)[number], number>> = {
|
||||
export const MAX_PADDED_SIGNED_ATTR_LEN: Record<(typeof hashAlgos)[number], number> = {
|
||||
sha1: 128,
|
||||
sha224: 128,
|
||||
sha256: 128,
|
||||
sha384: 128,
|
||||
sha512: 192,
|
||||
sha384: 256,
|
||||
sha512: 256,
|
||||
};
|
||||
|
||||
export const MAX_CERT_BYTES: Partial<Record<keyof typeof SignatureAlgorithmIndex, number>> = {
|
||||
@@ -104,6 +106,7 @@ export enum SignatureAlgorithmIndex {
|
||||
ecdsa_sha1_brainpoolP224r1_224 = 27,
|
||||
ecdsa_sha256_brainpoolP224r1_224 = 28,
|
||||
ecdsa_sha512_brainpoolP512r1_512 = 29,
|
||||
ecdsa_sha224_brainpoolP224r1_224 = 30,
|
||||
}
|
||||
|
||||
export const attributeToPosition = {
|
||||
|
||||
@@ -1265,6 +1265,25 @@ jnD0AhwDAIPS8xytmOiI0MuVj3kwdnzTLdsGslSkmj8l
|
||||
-----END CERTIFICATE-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_key_sha224_braipoolP224r1 = `-----BEGIN EC PRIVATE KEY-----
|
||||
MGwCAQEEHD8zMUlakQzf4dhsIN/RlRKZqRRPX+y2LJj/6OWgCwYJKyQDAwIIAQEF
|
||||
oTwDOgAEVhYeSwufAC+rdeIw8skbC2bwM3g7giuR+5vl0brGHgiEIaUr33msAPHz
|
||||
epGlvTkSRQz+nOWMogI=
|
||||
-----END EC PRIVATE KEY-----`;
|
||||
|
||||
export const mock_dsc_sha224_brainpoolP224r1 = `-----BEGIN CERTIFICATE-----
|
||||
MIIB0DCCAX6gAwIBAgIUKS+C9XWWr12MLB1+rcVEaYGW53UwCgYIKoZIzj0EAwEw
|
||||
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
|
||||
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNTAxMDcwNzUxMDJaFw0yNjAxMDcw
|
||||
NzUxMDJaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
|
||||
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwUjAUBgcqhkjOPQIBBgkrJAMD
|
||||
AggBAQUDOgAEVhYeSwufAC+rdeIw8skbC2bwM3g7giuR+5vl0brGHgiEIaUr33ms
|
||||
APHzepGlvTkSRQz+nOWMogKjUzBRMB0GA1UdDgQWBBS7hFp/MRDFZ//5GxYHnpM+
|
||||
N8mqKTAfBgNVHSMEGDAWgBS7hFp/MRDFZ//5GxYHnpM+N8mqKTAPBgNVHRMBAf8E
|
||||
BTADAQH/MAoGCCqGSM49BAMBA0AAMD0CHQCT+jX3mCRjmvdXO2HKlb9faeYgKfiX
|
||||
frIJV5mBAhwEqIQRW2USNItxRt1iTO69eBj/20q67UOhDgK2
|
||||
-----END CERTIFICATE-----`;
|
||||
|
||||
export const mock_dsc_key_sha256_brainpoolP224r1 = `-----BEGIN EC PRIVATE KEY-----
|
||||
MGwCAQEEHEtm6OSi3EClphbb0ovVMLNX6SCQ/ZpYsFTjlnqgCwYJKyQDAwIIAQEF
|
||||
oTwDOgAEb8kcLsVLjpC1RWAjA/lRTHP2HVdW1ntmtfo1g2R6E6NkgLetsRXxc8Sn
|
||||
|
||||
@@ -56,12 +56,15 @@ import {
|
||||
mock_dsc_sha256_brainpoolP224r1,
|
||||
mock_dsc_key_sha512_brainpoolP512r1,
|
||||
mock_dsc_sha512_brainpoolP512r1,
|
||||
mock_dsc_key_sha224_braipoolP224r1,
|
||||
mock_dsc_sha224_brainpoolP224r1,
|
||||
} from '../constants/mockCertificates';
|
||||
import { countryCodes } from '../constants/constants';
|
||||
import { parseCertificateSimple } from './certificate_parsing/parseCertificateSimple';
|
||||
import { SignatureAlgorithm } from './types';
|
||||
import { PublicKeyDetailsECDSA, PublicKeyDetailsRSAPSS } from './certificate_parsing/dataStructure';
|
||||
import { getCurveForElliptic } from './certificate_parsing/curves';
|
||||
import { createHash } from 'crypto';
|
||||
|
||||
function generateRandomBytes(length: number): number[] {
|
||||
// Generate numbers between -128 and 127 to match the existing signed byte format
|
||||
@@ -219,6 +222,10 @@ export function genMockPassportData(
|
||||
privateKeyPem = mock_dsc_key_sha1_brainpoolP224r1;
|
||||
dsc = mock_dsc_sha1_brainpoolP224r1;
|
||||
break;
|
||||
case 'ecdsa_sha224_brainpoolP224r1_224':
|
||||
privateKeyPem = mock_dsc_key_sha224_braipoolP224r1;
|
||||
dsc = mock_dsc_sha224_brainpoolP224r1;
|
||||
break;
|
||||
case 'ecdsa_sha256_brainpoolP224r1_224':
|
||||
privateKeyPem = mock_dsc_key_sha256_brainpoolP224r1;
|
||||
dsc = mock_dsc_sha256_brainpoolP224r1;
|
||||
@@ -284,22 +291,16 @@ function sign(
|
||||
);
|
||||
const asn1Data = asn1.fromBER(privateKeyDer);
|
||||
const privateKeyBuffer = (asn1Data.result.valueBlock as any).value[1].valueBlock.valueHexView;
|
||||
// console.log('sig deets');
|
||||
// console.log('pk', privateKeyBuffer);
|
||||
// console.log('hashFUnction', hashAlgorithm);
|
||||
// console.log('message', Buffer.from(eContent).toString('hex'));
|
||||
|
||||
const keyPair = ec.keyFromPrivate(privateKeyBuffer);
|
||||
let md = forge.md[hashAlgorithm].create();
|
||||
md.update(forge.util.binary.raw.encode(new Uint8Array(eContent)));
|
||||
// let md = forge.md[hashAlgorithm].create();
|
||||
// md.update(forge.util.binary.raw.encode(new Uint8Array(eContent)));
|
||||
const hasher = createHash(hashAlgorithm);
|
||||
const msgHash = hasher.update(new Uint8Array(eContent)).digest('hex');
|
||||
|
||||
// console.log('message to sign', md.digest().toHex());
|
||||
const signature = keyPair.sign(md.digest().toHex(), 'hex');
|
||||
// console.log(Buffer.from(signature.toDER(), 'hex').toString('hex'));
|
||||
const signature = keyPair.sign(msgHash, 'hex');
|
||||
const signatureBytes = Array.from(Buffer.from(signature.toDER(), 'hex'));
|
||||
|
||||
// console.log('sig', JSON.stringify(signatureBytes));
|
||||
|
||||
return signatureBytes;
|
||||
} else {
|
||||
const privKey = forge.pki.privateKeyFromPem(privateKeyPem);
|
||||
|
||||
@@ -221,11 +221,12 @@ export function generateCircuitInputsProve(
|
||||
);
|
||||
}
|
||||
|
||||
// const paddingFunction =
|
||||
// hashFunction == 'sha1' || hashFunction == 'sha256' ? shaPad : sha384_512Pad;
|
||||
|
||||
const dg1PaddingFunction =
|
||||
MAX_PADDED_ECONTENT_LEN[passportMetadata.dg1HashFunction] <= 256 ? shaPad : sha384_512Pad;
|
||||
passportMetadata.dg1HashFunction === 'sha1' ||
|
||||
passportMetadata.dg1HashFunction === 'sha224' ||
|
||||
passportMetadata.dg1HashFunction === 'sha256'
|
||||
? shaPad
|
||||
: sha384_512Pad;
|
||||
|
||||
const [eContentPadded, eContentLen] = dg1PaddingFunction(
|
||||
new Uint8Array(eContent),
|
||||
@@ -233,7 +234,11 @@ export function generateCircuitInputsProve(
|
||||
);
|
||||
|
||||
const eContentPaddingFunction =
|
||||
MAX_PADDED_ECONTENT_LEN[passportMetadata.eContentHashFunction] <= 256 ? shaPad : sha384_512Pad;
|
||||
passportMetadata.eContentHashFunction === 'sha1' ||
|
||||
passportMetadata.eContentHashFunction === 'sha224' ||
|
||||
passportMetadata.eContentHashFunction === 'sha256'
|
||||
? shaPad
|
||||
: sha384_512Pad;
|
||||
const [signedAttrPadded, signedAttrPaddedLen] = eContentPaddingFunction(
|
||||
new Uint8Array(signedAttr),
|
||||
MAX_PADDED_SIGNED_ATTR_LEN[passportMetadata.eContentHashFunction]
|
||||
|
||||
@@ -2,10 +2,10 @@ import { PassportData } from '../../../common/src/utils/types';
|
||||
import { findSubarrayIndex, formatMrz, hash } from './utils';
|
||||
import { parseCertificateSimple } from './certificate_parsing/parseCertificateSimple';
|
||||
import {
|
||||
CertificateData,
|
||||
PublicKeyDetailsECDSA,
|
||||
PublicKeyDetailsRSA,
|
||||
PublicKeyDetailsRSAPSS,
|
||||
CertificateData,
|
||||
PublicKeyDetailsECDSA,
|
||||
PublicKeyDetailsRSA,
|
||||
PublicKeyDetailsRSAPSS,
|
||||
} from './certificate_parsing/dataStructure';
|
||||
import { getCSCAFromSKI } from './csca';
|
||||
import { hashAlgos } from '../constants/constants';
|
||||
@@ -14,225 +14,227 @@ import forge from 'node-forge';
|
||||
import * as asn1js from 'asn1js';
|
||||
import { initElliptic } from './elliptic';
|
||||
import { getCurveForElliptic } from './certificate_parsing/curves';
|
||||
import { createHash } from 'crypto';
|
||||
|
||||
export interface PassportMetadata {
|
||||
dataGroups: string;
|
||||
dg1HashFunction: string;
|
||||
dg1HashOffset: number;
|
||||
eContentSize: number;
|
||||
eContentHashFunction: string;
|
||||
eContentHashOffset: number;
|
||||
signedAttrSize: number;
|
||||
signedAttrHashFunction: string;
|
||||
signatureAlgorithm: string;
|
||||
signatureAlgorithmDetails: string;
|
||||
curveOrExponent: string;
|
||||
signatureAlgorithmBits: number;
|
||||
countryCode: string;
|
||||
cscaFound: boolean;
|
||||
cscaHashFunction: string;
|
||||
cscaSignature: string;
|
||||
cscaSignatureAlgorithmDetails: string;
|
||||
cscaCurveOrExponent: string;
|
||||
cscaSignatureAlgorithmBits: number;
|
||||
dsc: string;
|
||||
dataGroups: string;
|
||||
dg1HashFunction: string;
|
||||
dg1HashOffset: number;
|
||||
eContentSize: number;
|
||||
eContentHashFunction: string;
|
||||
eContentHashOffset: number;
|
||||
signedAttrSize: number;
|
||||
signedAttrHashFunction: string;
|
||||
signatureAlgorithm: string;
|
||||
signatureAlgorithmDetails: string;
|
||||
curveOrExponent: string;
|
||||
signatureAlgorithmBits: number;
|
||||
countryCode: string;
|
||||
cscaFound: boolean;
|
||||
cscaHashFunction: string;
|
||||
cscaSignature: string;
|
||||
cscaSignatureAlgorithmDetails: string;
|
||||
cscaCurveOrExponent: string;
|
||||
cscaSignatureAlgorithmBits: number;
|
||||
dsc: string;
|
||||
}
|
||||
|
||||
export function findHashSizeOfEContent(eContent: number[], signedAttr: number[]) {
|
||||
for (const hashFunction of hashAlgos) {
|
||||
const hashValue = hash(hashFunction, eContent);
|
||||
const hashOffset = findSubarrayIndex(signedAttr, hashValue);
|
||||
if (hashOffset !== -1) {
|
||||
return { hashFunction, offset: hashOffset };
|
||||
}
|
||||
for (const hashFunction of hashAlgos) {
|
||||
const hashValue = hash(hashFunction, eContent);
|
||||
const hashOffset = findSubarrayIndex(signedAttr, hashValue);
|
||||
if (hashOffset !== -1) {
|
||||
return { hashFunction, offset: hashOffset };
|
||||
}
|
||||
return { hashFunction: 'unknown', offset: -1 };
|
||||
}
|
||||
return { hashFunction: 'unknown', offset: -1 };
|
||||
}
|
||||
|
||||
export function findDG1HashInEContent(
|
||||
mrz: string,
|
||||
eContent: number[]
|
||||
mrz: string,
|
||||
eContent: number[]
|
||||
): { hash: number[]; hashFunction: string; offset: number } | null {
|
||||
const formattedMrz = formatMrz(mrz);
|
||||
const formattedMrz = formatMrz(mrz);
|
||||
|
||||
for (const hashFunction of hashAlgos) {
|
||||
const hashValue = hash(hashFunction, formattedMrz);
|
||||
const normalizedHash = hashValue.map((byte) => (byte > 127 ? byte - 256 : byte));
|
||||
const hashOffset = findSubarrayIndex(eContent, normalizedHash);
|
||||
for (const hashFunction of hashAlgos) {
|
||||
const hashValue = hash(hashFunction, formattedMrz);
|
||||
const normalizedHash = hashValue.map((byte) => (byte > 127 ? byte - 256 : byte));
|
||||
const hashOffset = findSubarrayIndex(eContent, normalizedHash);
|
||||
|
||||
if (hashOffset !== -1) {
|
||||
return { hash: hashValue, hashFunction, offset: hashOffset };
|
||||
}
|
||||
if (hashOffset !== -1) {
|
||||
return { hash: hashValue, hashFunction, offset: hashOffset };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getCountryCodeFromMrz(mrz: string): string {
|
||||
return mrz.substring(2, 5);
|
||||
return mrz.substring(2, 5);
|
||||
}
|
||||
|
||||
export function getCurveOrExponent(certData: CertificateData): string {
|
||||
if (certData.signatureAlgorithm === 'rsapss' || certData.signatureAlgorithm === 'rsa') {
|
||||
return (certData.publicKeyDetails as PublicKeyDetailsRSA).exponent;
|
||||
}
|
||||
return (certData.publicKeyDetails as PublicKeyDetailsECDSA).curve;
|
||||
if (certData.signatureAlgorithm === 'rsapss' || certData.signatureAlgorithm === 'rsa') {
|
||||
return (certData.publicKeyDetails as PublicKeyDetailsRSA).exponent;
|
||||
}
|
||||
return (certData.publicKeyDetails as PublicKeyDetailsECDSA).curve;
|
||||
}
|
||||
|
||||
export function getSimplePublicKeyDetails(certData: CertificateData): string {
|
||||
interface SimplePublicKeyDetails {
|
||||
exponent?: string;
|
||||
curve?: string;
|
||||
hashAlgorithm?: string;
|
||||
saltLength?: string;
|
||||
interface SimplePublicKeyDetails {
|
||||
exponent?: string;
|
||||
curve?: string;
|
||||
hashAlgorithm?: string;
|
||||
saltLength?: string;
|
||||
}
|
||||
const simplePublicKeyDetails: SimplePublicKeyDetails = {};
|
||||
if (certData.signatureAlgorithm === 'rsapss' || certData.signatureAlgorithm === 'rsa') {
|
||||
simplePublicKeyDetails.exponent = (certData.publicKeyDetails as PublicKeyDetailsRSA).exponent;
|
||||
if (certData.signatureAlgorithm === 'rsapss') {
|
||||
simplePublicKeyDetails.hashAlgorithm = (
|
||||
certData.publicKeyDetails as PublicKeyDetailsRSAPSS
|
||||
).hashAlgorithm;
|
||||
simplePublicKeyDetails.saltLength = (
|
||||
certData.publicKeyDetails as PublicKeyDetailsRSAPSS
|
||||
).saltLength;
|
||||
}
|
||||
const simplePublicKeyDetails: SimplePublicKeyDetails = {};
|
||||
if (certData.signatureAlgorithm === 'rsapss' || certData.signatureAlgorithm === 'rsa') {
|
||||
simplePublicKeyDetails.exponent = (certData.publicKeyDetails as PublicKeyDetailsRSA).exponent;
|
||||
if (certData.signatureAlgorithm === 'rsapss') {
|
||||
simplePublicKeyDetails.hashAlgorithm = (
|
||||
certData.publicKeyDetails as PublicKeyDetailsRSAPSS
|
||||
).hashAlgorithm;
|
||||
simplePublicKeyDetails.saltLength = (
|
||||
certData.publicKeyDetails as PublicKeyDetailsRSAPSS
|
||||
).saltLength;
|
||||
}
|
||||
} else if (certData.signatureAlgorithm === 'ecdsa') {
|
||||
simplePublicKeyDetails.curve = (certData.publicKeyDetails as PublicKeyDetailsECDSA).curve;
|
||||
}
|
||||
return JSON.stringify(simplePublicKeyDetails);
|
||||
} else if (certData.signatureAlgorithm === 'ecdsa') {
|
||||
simplePublicKeyDetails.curve = (certData.publicKeyDetails as PublicKeyDetailsECDSA).curve;
|
||||
}
|
||||
return JSON.stringify(simplePublicKeyDetails);
|
||||
}
|
||||
|
||||
export function verifySignature(passportData: PassportData, hashAlgorithm: string): boolean {
|
||||
const elliptic = initElliptic();
|
||||
const { dsc, signedAttr, encryptedDigest } = passportData;
|
||||
const { signatureAlgorithm, publicKeyDetails } = parseCertificateSimple(dsc);
|
||||
const elliptic = initElliptic();
|
||||
const { dsc, signedAttr, encryptedDigest } = passportData;
|
||||
const { signatureAlgorithm, publicKeyDetails } = parseCertificateSimple(dsc);
|
||||
|
||||
if (signatureAlgorithm === 'ecdsa') {
|
||||
const certBuffer = Buffer.from(
|
||||
dsc.replace(/(-----(BEGIN|END) CERTIFICATE-----|\n)/g, ''),
|
||||
'base64'
|
||||
);
|
||||
const asn1Data = asn1js.fromBER(certBuffer);
|
||||
const cert = new Certificate({ schema: asn1Data.result });
|
||||
const publicKeyInfo = cert.subjectPublicKeyInfo;
|
||||
const publicKeyBuffer = publicKeyInfo.subjectPublicKey.valueBlock.valueHexView;
|
||||
const curveForElliptic = getCurveForElliptic((publicKeyDetails as PublicKeyDetailsECDSA).curve);
|
||||
const ec = new elliptic.ec(curveForElliptic);
|
||||
if (signatureAlgorithm === 'ecdsa') {
|
||||
const certBuffer = Buffer.from(
|
||||
dsc.replace(/(-----(BEGIN|END) CERTIFICATE-----|\n)/g, ''),
|
||||
'base64'
|
||||
);
|
||||
const asn1Data = asn1js.fromBER(certBuffer);
|
||||
const cert = new Certificate({ schema: asn1Data.result });
|
||||
const publicKeyInfo = cert.subjectPublicKeyInfo;
|
||||
const publicKeyBuffer = publicKeyInfo.subjectPublicKey.valueBlock.valueHexView;
|
||||
const curveForElliptic = getCurveForElliptic((publicKeyDetails as PublicKeyDetailsECDSA).curve);
|
||||
const ec = new elliptic.ec(curveForElliptic);
|
||||
|
||||
const key = ec.keyFromPublic(publicKeyBuffer);
|
||||
const md = forge.md[hashAlgorithm].create();
|
||||
md.update(forge.util.binary.raw.encode(new Uint8Array(signedAttr)));
|
||||
const msgHash = md.digest().toHex();
|
||||
const signature_crypto = Buffer.from(encryptedDigest).toString('hex');
|
||||
const key = ec.keyFromPublic(publicKeyBuffer);
|
||||
const hasher = createHash(hashAlgorithm);
|
||||
const msgHash = hasher.update(new Uint8Array(signedAttr)).digest('hex');
|
||||
const signature_crypto = Buffer.from(encryptedDigest).toString('hex');
|
||||
|
||||
return key.verify(msgHash, signature_crypto);
|
||||
} else {
|
||||
const cert = forge.pki.certificateFromPem(dsc);
|
||||
const publicKey = cert.publicKey as forge.pki.rsa.PublicKey;
|
||||
return key.verify(msgHash, signature_crypto);
|
||||
} else {
|
||||
const cert = forge.pki.certificateFromPem(dsc);
|
||||
const publicKey = cert.publicKey as forge.pki.rsa.PublicKey;
|
||||
try {
|
||||
const md = forge.md[hashAlgorithm].create();
|
||||
md.update(forge.util.binary.raw.encode(new Uint8Array(signedAttr)));
|
||||
|
||||
const md = forge.md[hashAlgorithm].create();
|
||||
md.update(forge.util.binary.raw.encode(new Uint8Array(signedAttr)));
|
||||
const signature = Buffer.from(encryptedDigest).toString('binary');
|
||||
|
||||
const signature = Buffer.from(encryptedDigest).toString('binary');
|
||||
|
||||
if (signatureAlgorithm === 'rsapss') {
|
||||
try {
|
||||
const pss = forge.pss.create({
|
||||
md: forge.md[hashAlgorithm].create(),
|
||||
mgf: forge.mgf.mgf1.create(forge.md[hashAlgorithm].create()),
|
||||
saltLength: parseInt((publicKeyDetails as PublicKeyDetailsRSAPSS).saltLength),
|
||||
});
|
||||
return publicKey.verify(md.digest().bytes(), signature, pss);
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return publicKey.verify(md.digest().bytes(), signature);
|
||||
if (signatureAlgorithm === 'rsapss') {
|
||||
try {
|
||||
const pss = forge.pss.create({
|
||||
md: forge.md[hashAlgorithm].create(),
|
||||
mgf: forge.mgf.mgf1.create(forge.md[hashAlgorithm].create()),
|
||||
saltLength: parseInt((publicKeyDetails as PublicKeyDetailsRSAPSS).saltLength),
|
||||
});
|
||||
return publicKey.verify(md.digest().bytes(), signature, pss);
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return publicKey.verify(md.digest().bytes(), signature);
|
||||
}
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function brutforceHashAlgorithm(passportData: PassportData): any {
|
||||
for (const hashFunction of hashAlgos) {
|
||||
if (verifySignature(passportData, hashFunction)) {
|
||||
return hashFunction;
|
||||
}
|
||||
for (const hashFunction of hashAlgos) {
|
||||
if (verifySignature(passportData, hashFunction)) {
|
||||
return hashFunction;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function parsePassportData(passportData: PassportData): PassportMetadata {
|
||||
const dg1HashInfo = passportData.mrz
|
||||
? findDG1HashInEContent(passportData.mrz, passportData.eContent)
|
||||
: null;
|
||||
const dg1HashInfo = passportData.mrz
|
||||
? findDG1HashInEContent(passportData.mrz, passportData.eContent)
|
||||
: null;
|
||||
|
||||
const dg1HashFunction = dg1HashInfo?.hashFunction || 'unknown';
|
||||
const dg1HashOffset = dg1HashInfo?.offset || 0;
|
||||
const dg1HashFunction = dg1HashInfo?.hashFunction || 'unknown';
|
||||
const dg1HashOffset = dg1HashInfo?.offset || 0;
|
||||
|
||||
const { hashFunction: eContentHashFunction, offset: eContentHashOffset } = findHashSizeOfEContent(
|
||||
passportData.eContent,
|
||||
passportData.signedAttr
|
||||
);
|
||||
const { hashFunction: eContentHashFunction, offset: eContentHashOffset } = findHashSizeOfEContent(
|
||||
passportData.eContent,
|
||||
passportData.signedAttr
|
||||
);
|
||||
|
||||
const signatureHashAlgo = brutforceHashAlgorithm(passportData);
|
||||
const signatureHashAlgo = brutforceHashAlgorithm(passportData);
|
||||
|
||||
let parsedDsc = null;
|
||||
let parsedCsca = null;
|
||||
let csca = null;
|
||||
let dscSignature = 'unknown';
|
||||
let dscSignatureAlgorithmDetails = 'unknown';
|
||||
let dscSignatureAlgorithmBits = 0;
|
||||
let cscaHashFunction = 'unknown';
|
||||
let cscaSignature = 'unknown';
|
||||
let cscaSignatureAlgorithmDetails = 'unknown';
|
||||
let cscaSignatureAlgorithmBits = 0;
|
||||
let parsedDsc = null;
|
||||
let parsedCsca = null;
|
||||
let csca = null;
|
||||
let dscSignature = 'unknown';
|
||||
let dscSignatureAlgorithmDetails = 'unknown';
|
||||
let dscSignatureAlgorithmBits = 0;
|
||||
let cscaHashFunction = 'unknown';
|
||||
let cscaSignature = 'unknown';
|
||||
let cscaSignatureAlgorithmDetails = 'unknown';
|
||||
let cscaSignatureAlgorithmBits = 0;
|
||||
|
||||
if (passportData.dsc) {
|
||||
parsedDsc = parseCertificateSimple(passportData.dsc);
|
||||
dscSignature = parsedDsc.signatureAlgorithm;
|
||||
dscSignatureAlgorithmDetails = getSimplePublicKeyDetails(parsedDsc);
|
||||
dscSignatureAlgorithmBits = parseInt(parsedDsc.publicKeyDetails?.bits || '0');
|
||||
if (passportData.dsc) {
|
||||
parsedDsc = parseCertificateSimple(passportData.dsc);
|
||||
dscSignature = parsedDsc.signatureAlgorithm;
|
||||
dscSignatureAlgorithmDetails = getSimplePublicKeyDetails(parsedDsc);
|
||||
dscSignatureAlgorithmBits = parseInt(parsedDsc.publicKeyDetails?.bits || '0');
|
||||
|
||||
if (parsedDsc.authorityKeyIdentifier) {
|
||||
try {
|
||||
csca = getCSCAFromSKI(parsedDsc.authorityKeyIdentifier, true);
|
||||
if (csca) {
|
||||
parsedCsca = parseCertificateSimple(csca);
|
||||
cscaHashFunction = parsedCsca.hashAlgorithm;
|
||||
cscaSignature = parsedCsca.signatureAlgorithm;
|
||||
cscaSignatureAlgorithmDetails = getSimplePublicKeyDetails(parsedCsca);
|
||||
cscaSignatureAlgorithmBits = parseInt(parsedCsca.publicKeyDetails?.bits || '0');
|
||||
}
|
||||
} catch (error) {
|
||||
}
|
||||
if (parsedDsc.authorityKeyIdentifier) {
|
||||
try {
|
||||
csca = getCSCAFromSKI(parsedDsc.authorityKeyIdentifier, true);
|
||||
if (csca) {
|
||||
parsedCsca = parseCertificateSimple(csca);
|
||||
cscaHashFunction = parsedCsca.hashAlgorithm;
|
||||
cscaSignature = parsedCsca.signatureAlgorithm;
|
||||
cscaSignatureAlgorithmDetails = getSimplePublicKeyDetails(parsedCsca);
|
||||
cscaSignatureAlgorithmBits = parseInt(parsedCsca.publicKeyDetails?.bits || '0');
|
||||
}
|
||||
} catch (error) {}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
dataGroups:
|
||||
passportData.dgPresents
|
||||
?.toString()
|
||||
.split(',')
|
||||
.map((item) => item.replace('DG', ''))
|
||||
.join(',') || 'None',
|
||||
dg1HashFunction,
|
||||
dg1HashOffset,
|
||||
eContentSize: passportData.eContent?.length || 0,
|
||||
eContentHashFunction,
|
||||
eContentHashOffset,
|
||||
signedAttrSize: passportData.signedAttr?.length || 0,
|
||||
signedAttrHashFunction: signatureHashAlgo,
|
||||
signatureAlgorithm: dscSignature,
|
||||
signatureAlgorithmDetails: dscSignatureAlgorithmDetails,
|
||||
curveOrExponent: parsedDsc ? getCurveOrExponent(parsedDsc) : 'unknown',
|
||||
signatureAlgorithmBits: dscSignatureAlgorithmBits,
|
||||
countryCode: passportData.mrz ? getCountryCodeFromMrz(passportData.mrz) : 'unknown',
|
||||
cscaFound: !!csca,
|
||||
cscaHashFunction,
|
||||
cscaSignature,
|
||||
cscaSignatureAlgorithmDetails,
|
||||
cscaCurveOrExponent: parsedCsca ? getCurveOrExponent(parsedCsca) : 'unknown',
|
||||
cscaSignatureAlgorithmBits: cscaSignatureAlgorithmBits,
|
||||
dsc: passportData.dsc,
|
||||
};
|
||||
return {
|
||||
dataGroups:
|
||||
passportData.dgPresents
|
||||
?.toString()
|
||||
.split(',')
|
||||
.map((item) => item.replace('DG', ''))
|
||||
.join(',') || 'None',
|
||||
dg1HashFunction,
|
||||
dg1HashOffset,
|
||||
eContentSize: passportData.eContent?.length || 0,
|
||||
eContentHashFunction,
|
||||
eContentHashOffset,
|
||||
signedAttrSize: passportData.signedAttr?.length || 0,
|
||||
signedAttrHashFunction: signatureHashAlgo,
|
||||
signatureAlgorithm: dscSignature,
|
||||
signatureAlgorithmDetails: dscSignatureAlgorithmDetails,
|
||||
curveOrExponent: parsedDsc ? getCurveOrExponent(parsedDsc) : 'unknown',
|
||||
signatureAlgorithmBits: dscSignatureAlgorithmBits,
|
||||
countryCode: passportData.mrz ? getCountryCodeFromMrz(passportData.mrz) : 'unknown',
|
||||
cscaFound: !!csca,
|
||||
cscaHashFunction,
|
||||
cscaSignature,
|
||||
cscaSignatureAlgorithmDetails,
|
||||
cscaCurveOrExponent: parsedCsca ? getCurveOrExponent(parsedCsca) : 'unknown',
|
||||
cscaSignatureAlgorithmBits: cscaSignatureAlgorithmBits,
|
||||
dsc: passportData.dsc,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ export type SignatureAlgorithm =
|
||||
| 'ecdsa_sha384_brainpoolP384r1_384'
|
||||
| 'ecdsa_sha512_brainpoolP384r1_384'
|
||||
| 'ecdsa_sha1_brainpoolP224r1_224'
|
||||
| 'ecdsa_sha224_brainpoolP224r1_224'
|
||||
| 'ecdsa_sha256_brainpoolP224r1_224'
|
||||
| 'ecdsa_sha512_brainpoolP512r1_512'
|
||||
| 'rsapss_sha256_65537_4096';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LeanIMT } from '@openpassport/zk-kit-lean-imt';
|
||||
import { sha256 } from 'js-sha256';
|
||||
import { sha224, sha256 } from 'js-sha256';
|
||||
import { sha1 } from 'js-sha1';
|
||||
import { sha384, sha512 } from 'js-sha512';
|
||||
import { SMT } from '@openpassport/zk-kit-smt';
|
||||
@@ -248,6 +248,9 @@ export function hash(hashFunction: string, bytesArray: number[]): number[] {
|
||||
case 'sha1':
|
||||
hashResult = sha1(unsignedBytesArray);
|
||||
break;
|
||||
case 'sha224':
|
||||
hashResult = sha224(unsignedBytesArray);
|
||||
break;
|
||||
case 'sha256':
|
||||
hashResult = sha256(unsignedBytesArray);
|
||||
break;
|
||||
@@ -323,6 +326,8 @@ export function getHashLen(hashFunction: string) {
|
||||
switch (hashFunction) {
|
||||
case 'sha1':
|
||||
return 20;
|
||||
case 'sha224':
|
||||
return 28;
|
||||
case 'sha256':
|
||||
return 32;
|
||||
case 'sha384':
|
||||
|
||||
Reference in New Issue
Block a user