mirror of
https://github.com/selfxyz/self.git
synced 2026-04-27 03:01:15 -04:00
Merge pull request #279 from zk-passport/feat/other-ecdsa-circuits
Add support for other ecdsa curves
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(160, 160, 27, 32, 7, 320, 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, 224, 30, 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, 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);
|
||||
@@ -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, 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);
|
||||
@@ -427,7 +427,7 @@ template BigModInvOptimised(CHUNK_SIZE, CHUNK_NUMBER) {
|
||||
out[i] <-- inv[i];
|
||||
}
|
||||
|
||||
component mult = BigMultModP(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
component mult = BigMultModPNonOptimised(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult.in[0] <== in;
|
||||
mult.in[1] <== out;
|
||||
mult.in[2] <== modulus;
|
||||
@@ -919,4 +919,4 @@ template BigIsEqual(CHUNK_SIZE, CHUNK_NUMBER) {
|
||||
}
|
||||
}
|
||||
out <== equalResults[CHUNK_NUMBER - 1];
|
||||
}
|
||||
}
|
||||
@@ -332,7 +332,7 @@ function prod_dl(n, k, a, b) {
|
||||
// p is a prime
|
||||
// computes a^e mod p
|
||||
function mod_exp_dl(n, k, a, p, e) {
|
||||
var eBits[500];
|
||||
var eBits[512];
|
||||
for (var i = 0; i < k; i++) {
|
||||
for (var j = 0; j < n; j++) {
|
||||
eBits[j + n * i] = (e[i] >> j) & 1;
|
||||
|
||||
@@ -3,8 +3,11 @@ pragma circom 2.1.6;
|
||||
include "../bigInt/bigIntOverflow.circom";
|
||||
include "../bigInt/bigIntFunc.circom";
|
||||
include "./powers/secp256k1pows.circom";
|
||||
include "./powers/brainpoolP224r1pows.circom";
|
||||
include "./powers/brainpoolP256r1pows.circom";
|
||||
include "./powers/brainpoolP384r1pows.circom";
|
||||
include "./powers/brainpoolP512r1pows.circom";
|
||||
include "./powers/p224pows.circom";
|
||||
include "./powers/p256pows.circom";
|
||||
include "./powers/p384pows.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
@@ -46,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];
|
||||
@@ -202,13 +204,13 @@ template EllipticCurvePrecomputePipinger(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, WIND
|
||||
|
||||
for (var i = 2; i < PRECOMPUTE_NUMBER; i++){
|
||||
if (i % 2 == 0){
|
||||
doublers[i \ 2 - 1] = EllipticCurveDoubleOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
doublers[i \ 2 - 1] = EllipticCurveDouble(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
doublers[i \ 2 - 1].in <== out[i \ 2];
|
||||
doublers[i \ 2 - 1].out ==> out[i];
|
||||
|
||||
}
|
||||
else {
|
||||
adders[i \ 2 - 1] = EllipticCurveAddOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
adders[i \ 2 - 1] = EllipticCurveAdd(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
adders[i \ 2 - 1].in1 <== out[1];
|
||||
adders[i \ 2 - 1].in2 <== out[i - 1];
|
||||
adders[i \ 2 - 1].out ==> out[i];
|
||||
@@ -712,7 +714,7 @@ template EllipticCurvePipingerMult(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, WINDOW_SIZ
|
||||
res[0] <== precomputed[0];
|
||||
|
||||
for (var i = 0; i < CHUNK_NUMBER * CHUNK_SIZE; i += WINDOW_SIZE){
|
||||
adders[i \ WINDOW_SIZE] = EllipticCurveAddOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
adders[i \ WINDOW_SIZE] = EllipticCurveAdd(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
bits2Num[i \ WINDOW_SIZE] = Bits2Num(WINDOW_SIZE);
|
||||
for (var j = 0; j < WINDOW_SIZE; j++){
|
||||
bits2Num[i \ WINDOW_SIZE].in[j] <== scalarBits[i + (WINDOW_SIZE - 1) - j];
|
||||
@@ -724,7 +726,7 @@ 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] = EllipticCurveDoubleOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
doublers[i + j - WINDOW_SIZE] = EllipticCurveDouble(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
|
||||
if (j == 0){
|
||||
for (var axis_idx = 0; axis_idx < 2; axis_idx++){
|
||||
@@ -1261,7 +1263,6 @@ template EllipticCurveAddNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
// This chunking will be added late
|
||||
// Complexity is field \ 8 - 1 additions
|
||||
template EllipicCurveScalarGeneratorMultiplicationNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
|
||||
signal input scalar[CHUNK_NUMBER];
|
||||
|
||||
signal output out[2][CHUNK_NUMBER];
|
||||
@@ -1279,6 +1280,19 @@ template EllipicCurveScalarGeneratorMultiplicationNonOptimised(CHUNK_SIZE, CHUNK
|
||||
powers = get_g_pow_stride8_table_p384(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
}
|
||||
}
|
||||
if (CHUNK_NUMBER == 7) {
|
||||
if (P[0] == 2127085823 && P[1] == 2547681781 && P[2] == 2963212119 && P[3] == 1976686471 && P[4] == 706228261 && P[5] == 641951366 && P[6] == 3619763370 ){
|
||||
powers = get_g_pow_stride8_table_brainpoolP224r1(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
}
|
||||
if (P[0] == 1 && P[1] == 0 && P[2] == 0 && P[3] == 4294967295 && P[4] == 4294967295 && P[5] == 4294967295 && P[6] == 4294967295 ){
|
||||
powers = get_g_pow_stride8_table_p224(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
}
|
||||
}
|
||||
if (CHUNK_NUMBER == 8) {
|
||||
if (P[0] == 2930260431521597683 && P[1] == 2918894611604883077 && P[2] == 12595900938455318758 && P[3] == 9029043254863489090 && P[4] == 15448363540090652785 && P[5] == 14641358191536493070 && P[6] == 4599554755319692295 && P[7] == 12312170373589877899 ){
|
||||
powers = get_g_pow_stride8_table_brainpoolP512r1(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
}
|
||||
}
|
||||
|
||||
component num2bits[CHUNK_NUMBER];
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++){
|
||||
@@ -1612,13 +1626,6 @@ template EllipicCurveScalarPrecomputeMultiplicationNonOptimised(CHUNK_SIZE, CHUN
|
||||
}
|
||||
}
|
||||
out <== resultingPoints[parts - 2];
|
||||
|
||||
for (var i = 0; i < 6; i++){
|
||||
log(out[0][i]);
|
||||
}
|
||||
for (var i = 0; i < 6; i++){
|
||||
log(out[1][i]);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -1712,4 +1719,4 @@ template EllipicCurveScalarPrecomputeMultiplication(CHUNK_SIZE, CHUNK_NUMBER, A,
|
||||
out <== scalarMultNonOptimised.out;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,8 @@ pragma circom 2.1.6;
|
||||
// Now there is only secp256k1 \ brainpoolP256r1 generator (64 4 chunking) and brainpoolP384r1
|
||||
// Other curves / chunking will be added later
|
||||
template EllipticCurveGetGenerator(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
assert (CHUNK_SIZE == 64);
|
||||
|
||||
signal output gen[2][CHUNK_NUMBER];
|
||||
|
||||
if (CHUNK_NUMBER == 4){
|
||||
if (P[0] == 18446744069414583343 && P[1] == 18446744073709551615 && P[2] == 18446744073709551615 && P[3] == 18446744073709551615){
|
||||
gen[0] <== [6481385041966929816, 188021827762530521, 6170039885052185351, 8772561819708210092];
|
||||
@@ -31,9 +30,23 @@ template EllipticCurveGetGenerator(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
gen[0] <== [17259960781858189086, 16728304380777219754, 15816583608832692456, 9819997727167172579, 11720119409086381931, 2097662510161151487];
|
||||
gen[1] <== [4792396531824874261, 1028586674454626577, 16256874595948243240, 7113166411453454436, 6679378719998465362, 9997460611710698148];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (CHUNK_NUMBER == 7) {
|
||||
if (P[0] == 1 && P[1] == 0 && P[2] == 0 && P[3] == 4294967295 && P[4] == 4294967295 && P[5] == 4294967295 && P[6] == 4294967295 ){
|
||||
gen[0] <== [291249441, 875725014, 1455558946, 1241760211, 840143033, 1807007615, 3071151293];
|
||||
gen[1] <== [2231402036, 1154843033, 1510426468, 3443750304, 1277353958, 3052872699, 3174523784];
|
||||
}
|
||||
if (P[0] == 2127085823 && P[1] == 2547681781 && P[2] == 2963212119 && P[3] == 1976686471 && P[4] == 706228261 && P[5] == 641951366 && P[6] == 3619763370 ){
|
||||
gen[0] <== [3994206333, 1277062909, 2655838999, 2826815116, 872948658, 746478836, 227551661];
|
||||
gen[1] <== [1981022925, 3399743187, 894148249, 1322101796, 617003166, 1925214831, 1487558391];
|
||||
}
|
||||
}
|
||||
if (CHUNK_NUMBER == 8) {
|
||||
if (P[0] == 2930260431521597683 && P[1] == 2918894611604883077 && P[2] == 12595900938455318758 && P[3] == 9029043254863489090 && P[4] == 15448363540090652785 && P[5] == 14641358191536493070 && P[6] == 4599554755319692295 && P[7] == 12312170373589877899 ){
|
||||
gen[0] <== [10030961170254002210, 8965910700118138472, 5823550673135435103, 18391328107359425677, 12987082728901970318, 9650544882960897729, 6494527313417104019, 9344657780867258724];
|
||||
gen[1] <== [8704646705537616018, 15116942582920270854, 6614182396149851054, 12888420639989254238, 11529432042984931601, 17440742611955841818, 13901133935883592445, 9069748673103213292];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We can`t "if" signal in circom, so we always need to do all opertions, even we won`t use results of them
|
||||
@@ -41,8 +54,6 @@ template EllipticCurveGetGenerator(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
// We will ignore result, but we still should get it, so we need to pout something anyway
|
||||
// Dummy point = G * 2**256
|
||||
template EllipticCurveGetDummy(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
assert (CHUNK_SIZE == 64);
|
||||
|
||||
signal output dummyPoint[2][CHUNK_NUMBER];
|
||||
if (CHUNK_NUMBER == 4){
|
||||
if (P[0] == 18446744069414583343 && P[1] == 18446744073709551615 && P[2] == 18446744073709551615 && P[3] == 18446744073709551615){
|
||||
@@ -87,15 +98,26 @@ template EllipticCurveGetDummy(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
dummyPoint[1] <== [9174881270872499347, 7148726877058227897, 1584493337432922624, 1438582915076653591, 16161625210166602047, 946254366129831718];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (CHUNK_NUMBER == 7) {
|
||||
if (P[0] == 1 && P[1] == 0 && P[2] == 0 && P[3] == 4294967295 && P[4] == 4294967295 && P[5] == 4294967295 && P[6] == 4294967295 ){
|
||||
dummyPoint[0] <== [2477436510, 406882550, 2884834286, 2269163287, 3636783260, 3699382582, 912817446];
|
||||
dummyPoint[1] <== [582933619, 1778719645, 3780674687, 3008581200, 3586474874, 866709652, 3566930607];
|
||||
}
|
||||
if (P[0] == 2127085823 && P[1] == 2547681781 && P[2] == 2963212119 && P[3] == 1976686471 && P[4] == 706228261 && P[5] == 641951366 && P[6] == 3619763370 ){
|
||||
dummyPoint[0] <== [1011829107, 766339764, 2646701381, 2557417204, 2772323181, 3776113163, 1766619938];
|
||||
dummyPoint[1] <== [3055119978, 1933167529, 3830194223, 368418451, 674341366, 2229791193, 2172448247];
|
||||
}
|
||||
}
|
||||
if (CHUNK_NUMBER == 8) {
|
||||
if (P[0] == 2930260431521597683 && P[1] == 2918894611604883077 && P[2] == 12595900938455318758 && P[3] == 9029043254863489090 && P[4] == 15448363540090652785 && P[5] == 14641358191536493070 && P[6] == 4599554755319692295 && P[7] == 12312170373589877899 ){
|
||||
dummyPoint[0] <== [14574916302597975989, 11319969548132449701, 10903266595883857697, 1994548485485214030, 8766324413095117920, 13859543515914586224, 15359012927175766703, 8888157292894416277];
|
||||
dummyPoint[1] <== [15424904851015096434, 4509353341016380105, 2660624093915944643, 18108652003744254071, 16457937165138284712, 13988121693385681648, 3974402614675683080, 4273228049790294330];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get order of eliptic curve
|
||||
template EllipicCurveGetOrder(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
assert (CHUNK_SIZE == 64);
|
||||
|
||||
signal output order[CHUNK_NUMBER];
|
||||
if (CHUNK_NUMBER == 4){
|
||||
if (P[0] == 18446744069414583343 && P[1] == 18446744073709551615 && P[2] == 18446744073709551615 && P[3] == 18446744073709551615){
|
||||
@@ -116,4 +138,17 @@ template EllipicCurveGetOrder(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
order <== [4289733633151100261, 14932448379039367952, 2240099277684876711, 1526563086152259251, 1107163671716839903, 10140169582434348328];
|
||||
}
|
||||
}
|
||||
if (CHUNK_NUMBER == 7) {
|
||||
if (P[0] == 1 && P[1] == 0 && P[2] == 0 && P[3] == 4294967295 && P[4] == 4294967295 && P[5] == 4294967295 && P[6] == 4294967295 ){
|
||||
order <== [1549543997, 333261125, 3770216510, 4294907554, 4294967295, 4294967295, 4294967295];
|
||||
}
|
||||
if (P[0] == 2127085823 && P[1] == 2547681781 && P[2] == 2963212119 && P[3] == 1976686471 && P[4] == 706228261 && P[5] == 641951366 && P[6] == 3619763370 ){
|
||||
order <== [2779222943, 1843313827, 3507928139, 1976630168, 706228261, 641951366, 3619763370];
|
||||
}
|
||||
}
|
||||
if (CHUNK_NUMBER == 8) {
|
||||
if (P[0] == 2930260431521597683 && P[1] == 2918894611604883077 && P[2] == 12595900938455318758 && P[3] == 9029043254863489090 && P[4] == 15448363540090652785 && P[5] == 14641358191536493070 && P[6] == 4599554755319692295 && P[7] == 12312170373589877899 ){
|
||||
order <== [13080589130439131241, 2139723849122306781, 4721568021488603207, 6142448377308718617, 15448363540090652784, 14641358191536493070, 4599554755319692295, 12312170373589877899];
|
||||
}
|
||||
}
|
||||
}
|
||||
107528
circuits/circuits/utils/circomlib/ec/powers/brainpoolP224r1pows.circom
Normal file
107528
circuits/circuits/utils/circomlib/ec/powers/brainpoolP224r1pows.circom
Normal file
File diff suppressed because it is too large
Load Diff
278536
circuits/circuits/utils/circomlib/ec/powers/brainpoolP512r1pows.circom
Normal file
278536
circuits/circuits/utils/circomlib/ec/powers/brainpoolP512r1pows.circom
Normal file
File diff suppressed because it is too large
Load Diff
107528
circuits/circuits/utils/circomlib/ec/powers/p224pows.circom
Normal file
107528
circuits/circuits/utils/circomlib/ec/powers/p224pows.circom
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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,24 +3,29 @@ pragma circom 2.0.0;
|
||||
include "../sha2Common.circom";
|
||||
include "../sha512/sha512Schedule.circom";
|
||||
include "../sha512/sha512Rounds.circom";
|
||||
include "@zk-email/circuits/utils/array.circom";
|
||||
include "sha384InitialValue.circom";
|
||||
|
||||
template Sha384HashChunks(BLOCK_NUM) {
|
||||
|
||||
signal input in[BLOCK_NUM * 1024];
|
||||
template Sha384HashChunks(MAX_BLOCKS) {
|
||||
signal input in[MAX_BLOCKS * 1024];
|
||||
signal input paddedInLength;
|
||||
|
||||
signal output out[384];
|
||||
|
||||
signal inBlockIndex;
|
||||
|
||||
inBlockIndex <-- (paddedInLength >> 10);
|
||||
paddedInLength === inBlockIndex * 1024;
|
||||
|
||||
signal states[BLOCK_NUM + 1][8][64];
|
||||
signal states[MAX_BLOCKS + 1][8][64];
|
||||
|
||||
component iv = Sha384InitialValues();
|
||||
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_384_512Schedule();
|
||||
rds[m] = Sha2_384_512Rounds(80);
|
||||
@@ -37,9 +42,15 @@ template Sha384HashChunks(BLOCK_NUM) {
|
||||
rds[m].outHash ==> states[m + 1];
|
||||
}
|
||||
|
||||
component arraySelectors[384];
|
||||
for (var j = 0; j < 6; j++) {
|
||||
for (var i = 0; i < 64; i++){
|
||||
out[j * 64 + i] <== states[BLOCK_NUM][j][63 - i];
|
||||
arraySelectors[j * 64 + i] = ItemAtIndex(MAX_BLOCKS + 1);
|
||||
for (var k = 0; k <= MAX_BLOCKS; k++) {
|
||||
arraySelectors[j * 64 + i].in[k] <== states[k][j][63 - i];
|
||||
}
|
||||
arraySelectors[j * 64 + i].index <== inBlockIndex;
|
||||
out[j * 64 + i] <== arraySelectors[j * 64 + i].out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,23 +3,31 @@ pragma circom 2.0.0;
|
||||
include "../sha2Common.circom";
|
||||
include "sha512InitialValue.circom";
|
||||
include "sha512Schedule.circom";
|
||||
include "@zk-email/circuits/utils/array.circom";
|
||||
include "sha512Rounds.circom";
|
||||
|
||||
template Sha512HashChunks(BLOCK_NUM) {
|
||||
|
||||
signal input in[BLOCK_NUM * 1024];
|
||||
template Sha512HashChunks(MAX_BLOCKS) {
|
||||
signal input in[MAX_BLOCKS * 1024];
|
||||
signal input paddedInLength;
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
signal output out[512];
|
||||
|
||||
signal inBlockIndex;
|
||||
|
||||
inBlockIndex <-- (paddedInLength >> 10);
|
||||
paddedInLength === inBlockIndex * 1024;
|
||||
|
||||
signal states[BLOCK_NUM + 1][8][64];
|
||||
signal states[MAX_BLOCKS + 1][8][64];
|
||||
|
||||
component iv = Sha512InitialValue();
|
||||
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_384_512Schedule();
|
||||
rds[m] = Sha2_384_512Rounds(80);
|
||||
@@ -36,9 +44,15 @@ template Sha512HashChunks(BLOCK_NUM) {
|
||||
rds[m].outHash ==> states[m + 1];
|
||||
}
|
||||
|
||||
component arraySelectors[512];
|
||||
for (var j = 0; j < 8; j++) {
|
||||
for (var i = 0; i < 64; i++){
|
||||
out[j * 64 + i] <== states[BLOCK_NUM][j][63 - i];
|
||||
arraySelectors[j * 64 + i] = ItemAtIndex(MAX_BLOCKS + 1);
|
||||
for (var k = 0; k <= MAX_BLOCKS; k++) {
|
||||
arraySelectors[j * 64 + i].in[k] <== states[k][j][63 - i];
|
||||
}
|
||||
arraySelectors[j * 64 + i].index <== inBlockIndex;
|
||||
out[j * 64 + i] <== arraySelectors[j * 64 + i].out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,18 +1,16 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
include "../../other/fp.circom";
|
||||
include "../../other/array.circom";
|
||||
include "../../sha2/sha384/sha384_hash_bits.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "../../sha2/sha384/sha384HashChunks.circom";
|
||||
|
||||
template Sha384Bytes(maxByteLength) {
|
||||
signal input paddedIn[maxByteLength];
|
||||
signal input paddedInLength;
|
||||
signal output out[384];
|
||||
|
||||
var maxBits = maxByteLength * 8;
|
||||
component sha = Sha384Dynamic(maxBits);
|
||||
component sha = Sha384HashChunks((maxByteLength * 8) \ 1024);
|
||||
sha.paddedInLength <== paddedInLength * 8;
|
||||
|
||||
component bytes[maxByteLength];
|
||||
for (var i = 0; i < maxByteLength; i++) {
|
||||
@@ -22,7 +20,6 @@ template Sha384Bytes(maxByteLength) {
|
||||
sha.in[i*8+j] <== bytes[i].out[7-j];
|
||||
}
|
||||
}
|
||||
sha.paddedInLength <== paddedInLength * 8;
|
||||
|
||||
for (var i = 0; i < 384; i++) {
|
||||
out[i] <== sha.out[i];
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
include "../../other/fp.circom";
|
||||
include "../../other/array.circom";
|
||||
include "../../sha2/sha512/sha512_hash_bits.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "../../sha2/sha512/sha512HashChunks.circom";
|
||||
|
||||
template Sha512Bytes(maxByteLength) {
|
||||
signal input paddedIn[maxByteLength];
|
||||
signal input paddedInLength;
|
||||
signal output out[512];
|
||||
|
||||
var maxBits = maxByteLength * 8;
|
||||
component sha = Sha512Dynamic(maxBits);
|
||||
component sha = Sha512HashChunks((maxByteLength * 8) \ 1024);
|
||||
sha.paddedInLength <== paddedInLength * 8;
|
||||
|
||||
component bytes[maxByteLength];
|
||||
for (var i = 0; i < maxByteLength; i++) {
|
||||
@@ -22,9 +20,9 @@ template Sha512Bytes(maxByteLength) {
|
||||
sha.in[i*8+j] <== bytes[i].out[7-j];
|
||||
}
|
||||
}
|
||||
sha.paddedInLength <== paddedInLength * 8;
|
||||
sha.dummy <== 0;
|
||||
|
||||
for (var i = 0; i < 512; i++) {
|
||||
out[i] <== sha.out[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,30 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "./dynamic/sha1Bytes.circom";
|
||||
include "./dynamic/sha224Bytes.circom";
|
||||
include "@zk-email/circuits/lib/sha.circom";
|
||||
// include "./dynamic/sha384Bytes.circom";
|
||||
// include "./dynamic/sha512Bytes.circom";
|
||||
include "./dynamic/sha384Bytes.circom";
|
||||
include "./dynamic/sha512Bytes.circom";
|
||||
|
||||
template ShaBytesDynamic(hashLen, max_num_bytes) {
|
||||
signal input in_padded[max_num_bytes];
|
||||
template ShaBytesDynamic(hashLen, max_num_bits) {
|
||||
signal input in_padded[max_num_bits];
|
||||
signal input in_len_padded_bytes;
|
||||
|
||||
signal output hash[hashLen];
|
||||
|
||||
// if (hashLen == 512) {
|
||||
// hash <== Sha512Bytes(max_num_bytes)(in_padded, in_len_padded_bytes);
|
||||
// }
|
||||
// if (hashLen == 384) {
|
||||
// hash <== Sha384Bytes(max_num_bytes)(in_padded, in_len_padded_bytes);
|
||||
// }
|
||||
if (hashLen == 512) {
|
||||
hash <== Sha512Bytes(max_num_bits)(in_padded, in_len_padded_bytes);
|
||||
}
|
||||
if (hashLen == 384) {
|
||||
hash <== Sha384Bytes(max_num_bits)(in_padded, in_len_padded_bytes);
|
||||
}
|
||||
if (hashLen == 256) {
|
||||
hash <== Sha256Bytes(max_num_bytes)(in_padded, in_len_padded_bytes);
|
||||
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_bytes)(in_padded, in_len_padded_bytes);
|
||||
hash <== Sha1Bytes(max_num_bits)(in_padded, in_len_padded_bytes);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,8 +16,6 @@ include "../bigInt/bigInt.circom";
|
||||
// (x1, y1) = h * s_inv * G + r * s_inv * (x, y)
|
||||
// x1 === r
|
||||
template verifyECDSABits(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, ALGO){
|
||||
assert(CHUNK_SIZE == 64 && CHUNK_NUMBER == 4);
|
||||
|
||||
signal input pubkey[2][CHUNK_NUMBER];
|
||||
signal input signature[2][CHUNK_NUMBER];
|
||||
signal input hashed[ALGO];
|
||||
@@ -47,74 +45,13 @@ template verifyECDSABits(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, ALGO){
|
||||
modInv.out ==> sinv;
|
||||
|
||||
// (s ^ -1 mod n) * h mod n
|
||||
component mult = BigMultModP(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
component mult = BigMultModPNonOptimised(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult.in[0] <== sinv;
|
||||
mult.in[1] <== hashedChunked;
|
||||
mult.in[2] <== order;
|
||||
|
||||
// (s ^ -1 mod n) * r mod n
|
||||
component mult2 = BigMultModP(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult2.in[0] <== sinv;
|
||||
mult2.in[1] <== signature[0];
|
||||
mult2.in[2] <== order;
|
||||
|
||||
// h * s_inv * G
|
||||
component scalarMult1 = EllipicCurveScalarGeneratorMultiplication(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
scalarMult1.scalar <== mult.out;
|
||||
|
||||
// r * s_inv * (x, y)
|
||||
component scalarMult2 = EllipticCurvePipingerMult(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, 4);
|
||||
scalarMult2.scalar <== mult2.out;
|
||||
scalarMult2.in <== pubkey;
|
||||
|
||||
// (x1, y1) = h * s_inv * G + r * s_inv * (x, y)
|
||||
component add = EllipticCurveAdd(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
add.in1 <== scalarMult1.out;
|
||||
add.in2 <== scalarMult2.out;
|
||||
|
||||
// x1 === r
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++){
|
||||
add.out[0][i] === signature[0][i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Use this one if yours message is chunk bigint
|
||||
// pubkey[2] = [x, y] - pubkey for signature
|
||||
// signature[2] = [r, s] - signature
|
||||
// hashed = h - hashed message
|
||||
// n is curve order
|
||||
// s_inv = s ^ -1 mod n
|
||||
// (x1, y1) = h * s_inv * G + r * s_inv * (x, y)
|
||||
// x1 === r
|
||||
template verifyECDSABigInt(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
assert(CHUNK_SIZE == 64 && CHUNK_NUMBER == 4);
|
||||
|
||||
signal input pubkey[2][CHUNK_NUMBER];
|
||||
signal input signature[2][CHUNK_NUMBER];
|
||||
signal input hashed[CHUNK_NUMBER];
|
||||
|
||||
component getOrder = EllipicCurveGetOrder(CHUNK_SIZE,CHUNK_NUMBER, A, B, P);
|
||||
signal order[CHUNK_NUMBER];
|
||||
order <== getOrder.order;
|
||||
|
||||
// s_inv = s ^ -1 mod n
|
||||
signal sinv[CHUNK_NUMBER];
|
||||
|
||||
component modInv = BigModInvOptimised(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
|
||||
modInv.in <== signature[1];
|
||||
modInv.modulus <== order;
|
||||
modInv.out ==> sinv;
|
||||
|
||||
// (s ^ -1 mod n) * h mod n
|
||||
component mult = BigMultModP(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult.in[0] <== sinv;
|
||||
mult.in[1] <== hashed;
|
||||
mult.in[2] <== order;
|
||||
|
||||
// (s ^ -1 mod n) * r mod n
|
||||
component mult2 = BigMultModP(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
component mult2 = BigMultModPNonOptimised(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult2.in[0] <== sinv;
|
||||
mult2.in[1] <== signature[0];
|
||||
mult2.in[2] <== order;
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
pragma circom 2.1.6;
|
||||
|
||||
include "../ec/curve.circom";
|
||||
include "../ec/get.circom";
|
||||
include "../bigInt/bigInt.circom";
|
||||
|
||||
// Here is ecdsa signature verification
|
||||
// For now, only 256 bit curves are allowed with chunking 64 4
|
||||
//--------------------------------------------------------------------------------------------------------------------------------
|
||||
// Use this one if you hash message in circuit (message is bits, not chunked int)!!!
|
||||
// signature[2] = [r, s] - signature
|
||||
// pubkey[2] = [x, y] - pubkey for signature
|
||||
// hashed[ALGO] = h - hashed message by some algo (typically sha-2 256 for 256 bit curves)
|
||||
// n is curve order
|
||||
// s_inv = s ^ -1 mod n
|
||||
// (x1, y1) = h * s_inv * G + r * s_inv * (x, y)
|
||||
// x1 === r
|
||||
template verifyECDSABits(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, ALGO){
|
||||
assert(CHUNK_SIZE == 64 && CHUNK_NUMBER == 4);
|
||||
|
||||
signal input pubkey[2][CHUNK_NUMBER];
|
||||
signal input signature[2][CHUNK_NUMBER];
|
||||
signal input hashed[ALGO];
|
||||
|
||||
signal hashedChunked[CHUNK_NUMBER];
|
||||
|
||||
component bits2Num[CHUNK_NUMBER];
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++) {
|
||||
bits2Num[i] = Bits2Num(CHUNK_SIZE);
|
||||
for (var j = 0; j < CHUNK_SIZE; j++) {
|
||||
bits2Num[i].in[CHUNK_SIZE - 1 - j] <== hashed[i * CHUNK_SIZE + j];
|
||||
}
|
||||
hashedChunked[CHUNK_NUMBER - 1 - i] <== bits2Num[i].out;
|
||||
}
|
||||
|
||||
component getOrder = EllipicCurveGetOrder(CHUNK_SIZE,CHUNK_NUMBER, A, B, P);
|
||||
signal order[CHUNK_NUMBER];
|
||||
order <== getOrder.order;
|
||||
|
||||
// s_inv = s ^ -1 mod n
|
||||
signal sinv[CHUNK_NUMBER];
|
||||
|
||||
component modInv = BigModInvOptimised(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
|
||||
modInv.in <== signature[1];
|
||||
modInv.modulus <== order;
|
||||
modInv.out ==> sinv;
|
||||
|
||||
// (s ^ -1 mod n) * h mod n
|
||||
component mult = BigMultModP(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult.in[0] <== sinv;
|
||||
mult.in[1] <== hashedChunked;
|
||||
mult.in[2] <== order;
|
||||
|
||||
// (s ^ -1 mod n) * r mod n
|
||||
component mult2 = BigMultModP(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult2.in[0] <== sinv;
|
||||
mult2.in[1] <== signature[0];
|
||||
mult2.in[2] <== order;
|
||||
|
||||
// h * s_inv * G
|
||||
component scalarMult1 = EllipicCurveScalarGeneratorMultiplication(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
scalarMult1.scalar <== mult.out;
|
||||
|
||||
// r * s_inv * (x, y)
|
||||
component scalarMult2 = EllipticCurvePipingerMult(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, 4);
|
||||
scalarMult2.scalar <== mult2.out;
|
||||
scalarMult2.in <== pubkey;
|
||||
|
||||
// (x1, y1) = h * s_inv * G + r * s_inv * (x, y)
|
||||
component add = EllipticCurveAdd(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
add.in1 <== scalarMult1.out;
|
||||
add.in2 <== scalarMult2.out;
|
||||
|
||||
// x1 === r
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++){
|
||||
add.out[0][i] === signature[0][i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Use this one if yours message is chunk bigint
|
||||
// pubkey[2] = [x, y] - pubkey for signature
|
||||
// signature[2] = [r, s] - signature
|
||||
// hashed = h - hashed message
|
||||
// n is curve order
|
||||
// s_inv = s ^ -1 mod n
|
||||
// (x1, y1) = h * s_inv * G + r * s_inv * (x, y)
|
||||
// x1 === r
|
||||
template verifyECDSABigInt(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
assert(CHUNK_SIZE == 64 && CHUNK_NUMBER == 4);
|
||||
|
||||
signal input pubkey[2][CHUNK_NUMBER];
|
||||
signal input signature[2][CHUNK_NUMBER];
|
||||
signal input hashed[CHUNK_NUMBER];
|
||||
|
||||
component getOrder = EllipicCurveGetOrder(CHUNK_SIZE,CHUNK_NUMBER, A, B, P);
|
||||
signal order[CHUNK_NUMBER];
|
||||
order <== getOrder.order;
|
||||
|
||||
// s_inv = s ^ -1 mod n
|
||||
signal sinv[CHUNK_NUMBER];
|
||||
|
||||
component modInv = BigModInvOptimised(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
|
||||
modInv.in <== signature[1];
|
||||
modInv.modulus <== order;
|
||||
modInv.out ==> sinv;
|
||||
|
||||
// (s ^ -1 mod n) * h mod n
|
||||
component mult = BigMultModP(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult.in[0] <== sinv;
|
||||
mult.in[1] <== hashed;
|
||||
mult.in[2] <== order;
|
||||
|
||||
// (s ^ -1 mod n) * r mod n
|
||||
component mult2 = BigMultModP(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult2.in[0] <== sinv;
|
||||
mult2.in[1] <== signature[0];
|
||||
mult2.in[2] <== order;
|
||||
|
||||
// h * s_inv * G
|
||||
component scalarMult1 = EllipicCurveScalarGeneratorMultiplication(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
scalarMult1.scalar <== mult.out;
|
||||
|
||||
// r * s_inv * (x, y)
|
||||
component scalarMult2 = EllipticCurvePipingerMult(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, 4);
|
||||
scalarMult2.scalar <== mult2.out;
|
||||
scalarMult2.in <== pubkey;
|
||||
|
||||
// (x1, y1) = h * s_inv * G + r * s_inv * (x, y)
|
||||
component add = EllipticCurveAdd(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
add.in1 <== scalarMult1.out;
|
||||
add.in2 <== scalarMult2.out;
|
||||
|
||||
// x1 === r
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++){
|
||||
add.out[0][i] === signature[0][i];
|
||||
}
|
||||
}
|
||||
224
circuits/circuits/utils/passport/ecdsaVerifier.circom
Normal file
224
circuits/circuits/utils/passport/ecdsaVerifier.circom
Normal file
@@ -0,0 +1,224 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "./signatureAlgorithm.circom";
|
||||
include "../circomlib/signature/ecdsa.circom";
|
||||
|
||||
template EcdsaVerifier(signatureAlgorithm, n, k) {
|
||||
var kLengthFactor = getKLengthFactor(signatureAlgorithm);
|
||||
var kScaled = k * kLengthFactor;
|
||||
|
||||
var HASH_LEN_BITS = getHashLength(signatureAlgorithm);
|
||||
|
||||
signal input signature[kScaled];
|
||||
signal input pubKey[kScaled];
|
||||
signal input hashParsed[HASH_LEN_BITS];
|
||||
|
||||
signal hash[n * k];
|
||||
|
||||
if (HASH_LEN_BITS >= n * k) {
|
||||
for (var i = 0; i < n * k; i++) {
|
||||
hash[i] <== hashParsed[i];
|
||||
}
|
||||
}
|
||||
if (HASH_LEN_BITS < n * k) {
|
||||
for (var i = n * k - 1; i >= 0; i--) {
|
||||
if (i <= n * k - 1 - HASH_LEN_BITS) {
|
||||
hash[i] <== 0;
|
||||
} else {
|
||||
hash[i] <== hashParsed[i - n * k + HASH_LEN_BITS];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signal signature_r[k]; // ECDSA signature component r
|
||||
signal signature_s[k]; // ECDSA signature component s
|
||||
signal pubKey_x[k];
|
||||
signal pubKey_y[k];
|
||||
|
||||
for (var i = 0; i < k; i++) {
|
||||
signature_r[i] <== signature[i];
|
||||
signature_s[i] <== signature[i + k];
|
||||
pubKey_x[i] <== pubKey[i];
|
||||
pubKey_y[i] <== pubKey[i + k];
|
||||
}
|
||||
signal pubkey_xy[2][k] <== [pubKey_x, pubKey_y];
|
||||
|
||||
// verify eContentHash signature
|
||||
if (signatureAlgorithm == 7 || signatureAlgorithm == 8) {
|
||||
component ecdsa_verify = verifyECDSABits(n, k, [
|
||||
18446744073709551612,
|
||||
4294967295,
|
||||
0,
|
||||
18446744069414584321
|
||||
],
|
||||
[
|
||||
4309448131093880907,
|
||||
7285987128567378166,
|
||||
12964664127075681980,
|
||||
6540974713487397863
|
||||
],
|
||||
[
|
||||
18446744073709551615,
|
||||
4294967295,
|
||||
0,
|
||||
18446744069414584321
|
||||
], n * k);
|
||||
|
||||
ecdsa_verify.pubkey <== pubkey_xy;
|
||||
ecdsa_verify.signature <== [signature_r, signature_s];
|
||||
ecdsa_verify.hashed <== hash;
|
||||
}
|
||||
if (signatureAlgorithm == 9 || signatureAlgorithm == 23) {
|
||||
component ecdsa_verify = verifyECDSABits(n, k, [
|
||||
4294967292,
|
||||
18446744069414584320,
|
||||
18446744073709551614,
|
||||
18446744073709551615,
|
||||
18446744073709551615,
|
||||
18446744073709551615
|
||||
],
|
||||
[
|
||||
3064076045283764975,
|
||||
14291673747578343837,
|
||||
221811693264799578,
|
||||
1737717031765098770,
|
||||
10992729701402291481,
|
||||
12912154004749740004
|
||||
],
|
||||
[
|
||||
4294967295,
|
||||
18446744069414584320,
|
||||
18446744073709551614,
|
||||
18446744073709551615,
|
||||
18446744073709551615,
|
||||
18446744073709551615
|
||||
], n * k);
|
||||
|
||||
ecdsa_verify.pubkey <== pubkey_xy;
|
||||
ecdsa_verify.signature <== [signature_r, signature_s];
|
||||
ecdsa_verify.hashed <== hash;
|
||||
}
|
||||
if (signatureAlgorithm == 21 || signatureAlgorithm == 24 || signatureAlgorithm == 25) {
|
||||
component ecdsa_verify = verifyECDSABits(n, k, [
|
||||
16810331318623712729,
|
||||
18122579188607900780,
|
||||
17219079075415130087,
|
||||
9032542404991529047
|
||||
],
|
||||
[
|
||||
7767825457231955894,
|
||||
10773760575486288334,
|
||||
17523706096862592191,
|
||||
2800214691157789508
|
||||
],
|
||||
[
|
||||
2311270323689771895,
|
||||
7943213001558335528,
|
||||
4496292894210231666,
|
||||
12248480212390422972
|
||||
], n * k);
|
||||
|
||||
ecdsa_verify.pubkey <== pubkey_xy;
|
||||
ecdsa_verify.signature <== [signature_r, signature_s];
|
||||
ecdsa_verify.hashed <== hash;
|
||||
}
|
||||
if (signatureAlgorithm == 22 || signatureAlgorithm == 26) {
|
||||
component ecdsa_verify = verifyECDSABits(n, k, [
|
||||
335737924824737830,
|
||||
9990533504564909291,
|
||||
1410020238645393679,
|
||||
14032832221039175559,
|
||||
4355552632119865248,
|
||||
8918115475071440140
|
||||
],
|
||||
[
|
||||
4230998357940653073,
|
||||
8985869839777909140,
|
||||
3352946025465340629,
|
||||
3438355245973688998,
|
||||
10032249017711215740,
|
||||
335737924824737830
|
||||
],
|
||||
[
|
||||
9747760000893709395,
|
||||
12453481191562877553,
|
||||
1347097566612230435,
|
||||
1526563086152259252,
|
||||
1107163671716839903,
|
||||
10140169582434348328
|
||||
], n * k);
|
||||
|
||||
ecdsa_verify.pubkey <== pubkey_xy;
|
||||
ecdsa_verify.signature <== [signature_r, signature_s];
|
||||
ecdsa_verify.hashed <== hash;
|
||||
}
|
||||
if (signatureAlgorithm == 27 || signatureAlgorithm == 28 || signatureAlgorithm == 30) {
|
||||
component ecdsa_verify = verifyECDSABits(n, k, [
|
||||
3402800963,
|
||||
2953063001,
|
||||
1310206680,
|
||||
3243445073,
|
||||
697828262,
|
||||
2848877596,
|
||||
1755702828
|
||||
],
|
||||
[
|
||||
946618379,
|
||||
1725674354,
|
||||
1042363858,
|
||||
2837670371,
|
||||
2265387953,
|
||||
3487842616,
|
||||
629208636
|
||||
],
|
||||
[
|
||||
2127085823,
|
||||
2547681781,
|
||||
2963212119,
|
||||
1976686471,
|
||||
706228261,
|
||||
641951366,
|
||||
3619763370
|
||||
], n * k);
|
||||
|
||||
ecdsa_verify.pubkey <== pubkey_xy;
|
||||
ecdsa_verify.signature <== [signature_r, signature_s];
|
||||
ecdsa_verify.hashed <== hash;
|
||||
}
|
||||
if (signatureAlgorithm == 29) {
|
||||
component ecdsa_verify = verifyECDSABits(n, k, [
|
||||
16699818341992010954,
|
||||
9156125524185237433,
|
||||
733789637240866997,
|
||||
3309403945136634529,
|
||||
12120384836935902140,
|
||||
10721906936585459216,
|
||||
16299214545461923013,
|
||||
8660601516620528521
|
||||
],
|
||||
[
|
||||
2885045271355914019,
|
||||
10970857440773072349,
|
||||
8645948983640342119,
|
||||
3166813089265986637,
|
||||
10059573399531886503,
|
||||
12116154835845181897,
|
||||
16904370861210688858,
|
||||
4465624766311842250
|
||||
],
|
||||
[
|
||||
2930260431521597683,
|
||||
2918894611604883077,
|
||||
12595900938455318758,
|
||||
9029043254863489090,
|
||||
15448363540090652785,
|
||||
14641358191536493070,
|
||||
4599554755319692295,
|
||||
12312170373589877899
|
||||
], n * k);
|
||||
|
||||
ecdsa_verify.pubkey <== pubkey_xy;
|
||||
ecdsa_verify.signature <== [signature_r, signature_s];
|
||||
ecdsa_verify.hashed <== hash;
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,6 @@ template PassportVerifier(DG_HASH_ALGO, ECONTENT_HASH_ALGO, signatureAlgorithm,
|
||||
}
|
||||
|
||||
signal dg1Sha[DG_HASH_ALGO] <== ShaHashBits(93 * 8, DG_HASH_ALGO)(dg1Bits);
|
||||
|
||||
|
||||
component dg1ShaBytes[DG_HASH_ALGO_BYTES];
|
||||
for (var i = 0; i < DG_HASH_ALGO_BYTES; i++) {
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "./signatureAlgorithm.circom";
|
||||
include "../circomlib/signatures/ecdsa.circom";
|
||||
|
||||
template Secp256r1Verifier(signatureAlgorithm, n, k) {
|
||||
var kLengthFactor = getKLengthFactor(signatureAlgorithm);
|
||||
var kScaled = k * kLengthFactor;
|
||||
|
||||
var HASH_LEN_BITS = getHashLength(signatureAlgorithm);
|
||||
|
||||
signal input signature[kScaled];
|
||||
signal input pubKey[kScaled];
|
||||
signal input hashParsed[HASH_LEN_BITS];
|
||||
|
||||
signal hash[n * k];
|
||||
|
||||
for (var i = n * k - 1; i >= 0; i--) {
|
||||
if (i <= n * k - 1 - HASH_LEN_BITS) {
|
||||
hash[i] <== 0;
|
||||
}else {
|
||||
hash[i] <== hashParsed[i - n * k + HASH_LEN_BITS];
|
||||
}
|
||||
}
|
||||
|
||||
signal signature_r[k]; // ECDSA signature component r
|
||||
signal signature_s[k]; // ECDSA signature component s
|
||||
signal pubKey_x[k];
|
||||
signal pubKey_y[k];
|
||||
|
||||
for (var i = 0; i < k; i++) {
|
||||
signature_r[i] <== signature[i];
|
||||
signature_s[i] <== signature[i + k];
|
||||
pubKey_x[i] <== pubKey[i];
|
||||
pubKey_y[i] <== pubKey[i + k];
|
||||
}
|
||||
signal pubkey_xy[2][k] <== [pubKey_x, pubKey_y];
|
||||
|
||||
// verify eContentHash signature
|
||||
component ecdsa_verify = verifyECDSABits(n, k, [
|
||||
18446744073709551612,
|
||||
4294967295,
|
||||
0,
|
||||
18446744069414584321
|
||||
],
|
||||
[
|
||||
4309448131093880907,
|
||||
7285987128567378166,
|
||||
12964664127075681980,
|
||||
6540974713487397863
|
||||
],
|
||||
[
|
||||
18446744073709551615,
|
||||
4294967295,
|
||||
0,
|
||||
18446744069414584321
|
||||
], n * k);
|
||||
|
||||
ecdsa_verify.pubkey <== pubkey_xy;
|
||||
ecdsa_verify.signature <== [signature_r, signature_s];
|
||||
ecdsa_verify.hashed <== hash;
|
||||
}
|
||||
@@ -18,6 +18,16 @@ pragma circom 2.1.9;
|
||||
17: rsapss_sha256_3_4096
|
||||
18: rsapss_sha384_65537_3072
|
||||
19: rsapss_sha256_65537_3072
|
||||
21: ecdsa_sha256_brainpoolP256r1_256
|
||||
22: ecdsa_sha384_brainpoolP384r1_384
|
||||
23: ecdsa_sha256_secp384r1_384
|
||||
24: ecdsa_sha384_brainpoolP256r1_256
|
||||
25: ecdsa_sha512_brainpoolP256r1_256
|
||||
26: ecdsa_sha512_brainpoolP384r1_384
|
||||
27: ecdsa_sha1_brainpoolP224r1_224
|
||||
28: ecdsa_sha256_brainpoolP224r1_224
|
||||
29: ecdsa_sha512_brainpoolP512r1_512
|
||||
30: ecdsa_sha224_brainpoolP224r1_224
|
||||
*/
|
||||
|
||||
function getHashLength(signatureAlgorithm) {
|
||||
@@ -72,6 +82,36 @@ function getHashLength(signatureAlgorithm) {
|
||||
if (signatureAlgorithm == 20) {
|
||||
return 256;
|
||||
}
|
||||
if (signatureAlgorithm == 21) {
|
||||
return 256;
|
||||
}
|
||||
if (signatureAlgorithm == 22) {
|
||||
return 384;
|
||||
}
|
||||
if (signatureAlgorithm == 23) {
|
||||
return 256;
|
||||
}
|
||||
if (signatureAlgorithm == 24) {
|
||||
return 384;
|
||||
}
|
||||
if (signatureAlgorithm == 25) {
|
||||
return 512;
|
||||
}
|
||||
if (signatureAlgorithm == 26) {
|
||||
return 512;
|
||||
}
|
||||
if (signatureAlgorithm == 27) {
|
||||
return 160;
|
||||
}
|
||||
if (signatureAlgorithm == 28) {
|
||||
return 256;
|
||||
}
|
||||
if (signatureAlgorithm == 29) {
|
||||
return 512;
|
||||
}
|
||||
if (signatureAlgorithm == 30) {
|
||||
return 224;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -124,6 +164,36 @@ function getKeyLength(signatureAlgorithm) {
|
||||
if (signatureAlgorithm == 19) {
|
||||
return 3072;
|
||||
}
|
||||
if (signatureAlgorithm == 21) {
|
||||
return 256;
|
||||
}
|
||||
if (signatureAlgorithm == 22) {
|
||||
return 384;
|
||||
}
|
||||
if (signatureAlgorithm == 23) {
|
||||
return 384;
|
||||
}
|
||||
if (signatureAlgorithm == 24) {
|
||||
return 256;
|
||||
}
|
||||
if (signatureAlgorithm == 25) {
|
||||
return 256;
|
||||
}
|
||||
if (signatureAlgorithm == 26) {
|
||||
return 384;
|
||||
}
|
||||
if (signatureAlgorithm == 27) {
|
||||
return 224;
|
||||
}
|
||||
if (signatureAlgorithm == 28) {
|
||||
return 224;
|
||||
}
|
||||
if (signatureAlgorithm == 29) {
|
||||
return 512;
|
||||
}
|
||||
if (signatureAlgorithm == 30) {
|
||||
return 224;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -177,6 +247,36 @@ function getKLengthFactor(signatureAlgorithm) {
|
||||
if (signatureAlgorithm == 19) {
|
||||
return 1;
|
||||
}
|
||||
if (signatureAlgorithm == 21) {
|
||||
return 2;
|
||||
}
|
||||
if (signatureAlgorithm == 22) {
|
||||
return 2;
|
||||
}
|
||||
if (signatureAlgorithm == 23) {
|
||||
return 2;
|
||||
}
|
||||
if (signatureAlgorithm == 24) {
|
||||
return 2;
|
||||
}
|
||||
if (signatureAlgorithm == 25) {
|
||||
return 2;
|
||||
}
|
||||
if (signatureAlgorithm == 26) {
|
||||
return 2;
|
||||
}
|
||||
if (signatureAlgorithm == 27) {
|
||||
return 2;
|
||||
}
|
||||
if (signatureAlgorithm == 28) {
|
||||
return 2;
|
||||
}
|
||||
if (signatureAlgorithm == 29) {
|
||||
return 2;
|
||||
}
|
||||
if (signatureAlgorithm == 30) {
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
// include "../rsa/rsaPkcs1.circom";
|
||||
// include "secp256r1Verifier.circom";
|
||||
include "../circomlib/signature/rsapss/rsapss.circom";
|
||||
include "secp256r1Verifier.circom";
|
||||
// include "../rsapss/rsapss.circom";
|
||||
// include "../rsa/rsa.circom";
|
||||
// include "../circomlib/signature/rsa/verifyLargeRsaPkcs1v1_5.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";
|
||||
@@ -74,13 +69,22 @@ template SignatureVerifier(signatureAlgorithm, n, k) {
|
||||
rsaPssShaVerification.hashed <== hash; // send the raw hash
|
||||
|
||||
}
|
||||
if (signatureAlgorithm == 7) {
|
||||
Secp256r1Verifier (signatureAlgorithm, n, k)(signature, pubKey, hash);
|
||||
}
|
||||
if (signatureAlgorithm == 8) {
|
||||
Secp256r1Verifier (signatureAlgorithm,n,k)(signature, pubKey, hash);
|
||||
}
|
||||
if (signatureAlgorithm == 9) {
|
||||
if (
|
||||
signatureAlgorithm == 7
|
||||
|| signatureAlgorithm == 8
|
||||
|| signatureAlgorithm == 9
|
||||
|| signatureAlgorithm == 21
|
||||
|| signatureAlgorithm == 22
|
||||
|| signatureAlgorithm == 23
|
||||
|| signatureAlgorithm == 24
|
||||
|| signatureAlgorithm == 25
|
||||
|| signatureAlgorithm == 26
|
||||
|| signatureAlgorithm == 27
|
||||
|| signatureAlgorithm == 28
|
||||
|| signatureAlgorithm == 29
|
||||
|| signatureAlgorithm == 30
|
||||
) {
|
||||
EcdsaVerifier (signatureAlgorithm, n, k)(signature, pubKey, hash);
|
||||
}
|
||||
if (signatureAlgorithm == 10) {
|
||||
component rsa = VerifyRsa65537Pkcs1v1_5(n, k, 256);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"scripts": {
|
||||
"test": "yarn ts-mocha --max-old-space-size=8192 'tests/**/*.test.ts' 'tests/*.test.ts' --exit",
|
||||
"test-dsc": "yarn ts-mocha --max-old-space-size=8192 'tests/dsc.test.ts' --exit",
|
||||
"test-prove": "yarn ts-mocha --max-old-space-size=8192 'tests/prove.test.ts' --exit",
|
||||
"test-prove": "yarn ts-mocha --max-old-space-size=40960 'tests/prove.test.ts' --exit",
|
||||
"test-rsa": "yarn ts-mocha --max-old-space-size=8192 'tests/utils/rsaPkcs1v1_5.test.ts' --exit",
|
||||
"install-circuits": "cd ../common && yarn && cd ../circuits && yarn",
|
||||
"format": "prettier --write .",
|
||||
@@ -35,6 +35,7 @@
|
||||
"circomlibjs": "^0.1.7",
|
||||
"crypto": "^1.0.1",
|
||||
"elliptic": "^6.5.5",
|
||||
"hash.js": "^1.1.7",
|
||||
"js-sha256": "^0.10.1",
|
||||
"jsrsasign": "^11.1.0",
|
||||
"modpow": "^1.0.0",
|
||||
|
||||
@@ -16,7 +16,7 @@ build_circuit() {
|
||||
yarn snarkjs groth16 setup build/prove/${CIRCUIT_NAME}/${CIRCUIT_NAME}.r1cs build/powersOfTau28_hez_final_${POWEROFTAU}.ptau build/prove/${CIRCUIT_NAME}/${CIRCUIT_NAME}.zkey
|
||||
|
||||
echo "building vkey"
|
||||
yarn snarkjs zkey contribute build/prove/${CIRCUIT_NAME}/${CIRCUIT_NAME}.zkey build/prove/${CIRCUIT_NAME}/${CIRCUIT_NAME}_final.zkey -e="random text"
|
||||
# yarn snarkjs zkey contribute build/prove/${CIRCUIT_NAME}/${CIRCUIT_NAME}.zkey build/prove/${CIRCUIT_NAME}/${CIRCUIT_NAME}_final.zkey -e="random text"
|
||||
yarn snarkjs zkey export verificationkey build/prove/${CIRCUIT_NAME}/${CIRCUIT_NAME}_final.zkey build/prove/${CIRCUIT_NAME}/${CIRCUIT_NAME}_vkey.json
|
||||
|
||||
yarn snarkjs zkey export solidityverifier build/prove/${CIRCUIT_NAME}/${CIRCUIT_NAME}_final.zkey build/prove/${CIRCUIT_NAME}/Verifier_${CIRCUIT_NAME}.sol
|
||||
|
||||
@@ -10,7 +10,6 @@ import { poseidon2 } from 'poseidon-lite';
|
||||
import { SMT } from '@openpassport/zk-kit-smt';
|
||||
import namejson from '../../common/ofacdata/outputs/nameSMT.json';
|
||||
import { getCircuitNameFromPassportData } from '../../common/src/utils/circuitsName';
|
||||
import { parsePassportData } from '../../common/src/utils/parsePassportData';
|
||||
|
||||
const sigAlgs = [
|
||||
{
|
||||
@@ -45,6 +44,14 @@ const sigAlgs = [
|
||||
domainParameter: 'secp256r1',
|
||||
keyLength: '256',
|
||||
},
|
||||
{
|
||||
dgHashAlgo: 'sha256',
|
||||
eContentHashAlgo: 'sha224',
|
||||
sigAlg: 'ecdsa',
|
||||
hashFunction: 'sha224',
|
||||
domainParameter: 'brainpoolP224r1',
|
||||
keyLength: '224',
|
||||
},
|
||||
];
|
||||
|
||||
const fullSigAlgs = [
|
||||
@@ -136,6 +143,86 @@ const fullSigAlgs = [
|
||||
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 testSuite = process.env.FULL_TEST_SUITE === 'true' ? fullSigAlgs : sigAlgs;
|
||||
|
||||
7183
circuits/yarn.lock
7183
circuits/yarn.lock
File diff suppressed because it is too large
Load Diff
@@ -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'];
|
||||
export const MAX_PADDED_ECONTENT_LEN: Partial<Record<(typeof hashAlgos)[number], number>> = {
|
||||
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>> = {
|
||||
@@ -95,6 +97,16 @@ export enum SignatureAlgorithmIndex {
|
||||
rsapss_sha256_3_4096 = 17,
|
||||
rsapss_sha384_65537_3072 = 18,
|
||||
rsapss_sha256_65537_3072 = 19,
|
||||
ecdsa_sha256_brainpoolP256r1_256 = 21,
|
||||
ecdsa_sha384_brainpoolP384r1_384 = 22,
|
||||
ecdsa_sha256_secp384r1_384 = 23,
|
||||
ecdsa_sha384_brainpoolP256r1_256 = 24,
|
||||
ecdsa_sha512_brainpoolP256r1_256 = 25,
|
||||
ecdsa_sha512_brainpoolP384r1_384 = 26,
|
||||
ecdsa_sha1_brainpoolP224r1_224 = 27,
|
||||
ecdsa_sha256_brainpoolP224r1_224 = 28,
|
||||
ecdsa_sha512_brainpoolP512r1_512 = 29,
|
||||
ecdsa_sha224_brainpoolP224r1_224 = 30,
|
||||
}
|
||||
|
||||
export const attributeToPosition = {
|
||||
|
||||
@@ -1244,27 +1244,228 @@ d+9Msdsovrc=
|
||||
-----END CERTIFICATE-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_key_sha256_brainpoolP256r1 = `-----BEGIN EC PRIVATE KEY-----
|
||||
MHgCAQEEICM/qGkSEYZJeejSAl3to/52G9Vw+GDKdvw2BA4Hq4TRoAsGCSskAwMC
|
||||
CAEBB6FEA0IABCga+ftPaAL6Bljws48myO1IDRDjaBkyFR3W/esrhP2pb3poTpqd
|
||||
KDjKkI9hUU1t3cllGYBP4UzL9IUhe4J7I6s=
|
||||
export const mock_dsc_key_sha1_brainpoolP224r1 = `-----BEGIN EC PRIVATE KEY-----
|
||||
MGwCAQEEHEtm6OSi3EClphbb0ovVMLNX6SCQ/ZpYsFTjlnqgCwYJKyQDAwIIAQEF
|
||||
oTwDOgAEb8kcLsVLjpC1RWAjA/lRTHP2HVdW1ntmtfo1g2R6E6NkgLetsRXxc8Sn
|
||||
CJ71v4bL9/50ksOiv+U=
|
||||
-----END EC PRIVATE KEY-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_sha1_brainpoolP224r1 = `-----BEGIN CERTIFICATE-----
|
||||
MIIBzTCCAX2gAwIBAgIUL2Uxhvbe1w8fdNbH+/nFp0LvkEYwCQYHKoZIzj0EATBF
|
||||
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
|
||||
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMB4XDTI0MTIzMDA4NDQ0MVoXDTI1MTIzMDA4
|
||||
NDQ0MVowRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNV
|
||||
BAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDBSMBQGByqGSM49AgEGCSskAwMC
|
||||
CAEBBQM6AARvyRwuxUuOkLVFYCMD+VFMc/YdV1bWe2a1+jWDZHoTo2SAt62xFfFz
|
||||
xKcInvW/hsv3/nSSw6K/5aNTMFEwHQYDVR0OBBYEFHWg+dJpv6bTRvEWrInb/XtX
|
||||
XIzPMB8GA1UdIwQYMBaAFHWg+dJpv6bTRvEWrInb/XtXXIzPMA8GA1UdEwEB/wQF
|
||||
MAMBAf8wCQYHKoZIzj0EAQM/ADA8Ahx0BuqVqweU/EHvq42lTIH6ku+wPMoqvUL/
|
||||
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
|
||||
CJ71v4bL9/50ksOiv+U=
|
||||
-----END EC PRIVATE KEY-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_sha256_brainpoolP224r1 = `-----BEGIN CERTIFICATE-----
|
||||
MIIB0DCCAX6gAwIBAgIUVaUBruPv+13YqSDtb28faYlca1UwCgYIKoZIzj0EAwIw
|
||||
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
|
||||
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEyMzAxNDA2NTZaFw0yNTEyMzAx
|
||||
NDA2NTZaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
|
||||
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwUjAUBgcqhkjOPQIBBgkrJAMD
|
||||
AggBAQUDOgAEb8kcLsVLjpC1RWAjA/lRTHP2HVdW1ntmtfo1g2R6E6NkgLetsRXx
|
||||
c8SnCJ71v4bL9/50ksOiv+WjUzBRMB0GA1UdDgQWBBR1oPnSab+m00bxFqyJ2/17
|
||||
V1yMzzAfBgNVHSMEGDAWgBR1oPnSab+m00bxFqyJ2/17V1yMzzAPBgNVHRMBAf8E
|
||||
BTADAQH/MAoGCCqGSM49BAMCA0AAMD0CHQCXfviMoPED3c43XbavcZkccHVwxOYq
|
||||
aUpntBqzAhwqxYeED8F9yQVTF3NWcAd1kmySSE79HoCpjdTZ
|
||||
-----END CERTIFICATE-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_key_sha256_brainpoolP256r1 = `-----BEGIN EC PRIVATE KEY-----
|
||||
MHgCAQEEIGJigSc0XAA6G8o5znqeZyr6vM33jfVLKjIenqGZni8poAsGCSskAwMC
|
||||
CAEBB6FEA0IABDu2bqyQM7+NJRN1jSaQK0DW2a99g2U6JjGGIVMq0n2gZYOKFx9E
|
||||
SguAfoUpJmMXDsyPwTHlPtn/vLMfRzgbtPQ=
|
||||
-----END EC PRIVATE KEY-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_sha256_brainpoolP256r1 = `-----BEGIN CERTIFICATE-----
|
||||
MIICDzCCAbagAwIBAgIUcNlflnEgBabRuI8TtmhfuXeBDxAwCgYIKoZIzj0EAwIw
|
||||
ZjELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5MRUw
|
||||
EwYDVQQKDAxPcmdhbml6YXRpb24xDTALBgNVBAsMBFVuaXQxEjAQBgNVBAMMCW1v
|
||||
Y2tfY3NjYTAeFw0yNDEwMDMxODE2MzFaFw0yNTEwMDMxODE2MzFaMGUxCzAJBgNV
|
||||
BAYTAlVTMQ4wDAYDVQQIDAVTdGF0ZTENMAsGA1UEBwwEQ2l0eTEVMBMGA1UECgwM
|
||||
T3JnYW5pemF0aW9uMQ0wCwYDVQQLDARVbml0MREwDwYDVQQDDAhtb2NrX2RzYzBa
|
||||
MBQGByqGSM49AgEGCSskAwMCCAEBBwNCAARcehJ7rf3trDknfb3agrcH08G7q0lZ
|
||||
GL6fpY3beLTxeJMFF36REb8HLnOUFGw78hfPH8etWuA9H7HVZ/vB8Cd8o0IwQDAd
|
||||
BgNVHQ4EFgQUQE/6d9aMviaMEi9k91hdsVguoekwHwYDVR0jBBgwFoAUXOj0kKh6
|
||||
5e3xwozKdrj0y/kxpVkwCgYIKoZIzj0EAwIDRwAwRAIgfcPQcDu6hK7ad5EM1Owf
|
||||
hlAwf+ljOVwK1ZhDh5lJLicCIEJdrWnH+dUOBL+NecPbLmcFVBCelST9iNCUXTKD
|
||||
CLpT
|
||||
MIIB4DCCAYagAwIBAgIUbHVEhdtUOw6RyVe/hvzTuRzEuR4wCgYIKoZIzj0EAwIw
|
||||
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
|
||||
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEyMjcxMTU3NDNaFw0yNTEyMjcx
|
||||
MTU3NDNaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
|
||||
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwWjAUBgcqhkjOPQIBBgkrJAMD
|
||||
AggBAQcDQgAEO7ZurJAzv40lE3WNJpArQNbZr32DZTomMYYhUyrSfaBlg4oXH0RK
|
||||
C4B+hSkmYxcOzI/BMeU+2f+8sx9HOBu09KNTMFEwHQYDVR0OBBYEFP1eFopMfvFG
|
||||
0FAMe9ufMERzT7I7MB8GA1UdIwQYMBaAFP1eFopMfvFG0FAMe9ufMERzT7I7MA8G
|
||||
A1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIhAKMCAoCHlvYyR9nuUXWS
|
||||
Tvkpy9dRVAEaF2QmoiMtCHKnAiAe9FkZw6iO8h4GWKyeiAsvnk/tiRcLwkOQoLNc
|
||||
7hTFLQ==
|
||||
-----END CERTIFICATE-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_key_sha384_brainpoolP256r1 = `-----BEGIN EC PRIVATE KEY-----
|
||||
MHgCAQEEIIhHbA4GKMOiNXQcXTiFlQUX2YFKz5U/Ya+vQa/YFo6foAsGCSskAwMC
|
||||
CAEBB6FEA0IABKje0Lfu0ACxcGqEJc2vF6AYckbw9LaoHIKRyM6ko91AFuNhEIsx
|
||||
pUF1FV+lornr3u0I7bOxL4PlOD+nZuRXGQE=
|
||||
-----END EC PRIVATE KEY-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_sha384_brainpoolP256r1 = `-----BEGIN CERTIFICATE-----
|
||||
MIIB3zCCAYagAwIBAgIUNxoAJFWOPOCE9KOmtQZpg4NiEzMwCgYIKoZIzj0EAwMw
|
||||
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
|
||||
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEyMjgwNjE0MTZaFw0yNTEyMjgw
|
||||
NjE0MTZaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
|
||||
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwWjAUBgcqhkjOPQIBBgkrJAMD
|
||||
AggBAQcDQgAEqN7Qt+7QALFwaoQlza8XoBhyRvD0tqgcgpHIzqSj3UAW42EQizGl
|
||||
QXUVX6Wiueve7Qjts7Evg+U4P6dm5FcZAaNTMFEwHQYDVR0OBBYEFHB+vSzRl9Vy
|
||||
UedDOcm9V+sbVYlLMB8GA1UdIwQYMBaAFHB+vSzRl9VyUedDOcm9V+sbVYlLMA8G
|
||||
A1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwMDRwAwRAIgFv62dVvKdRlqCcRfQdax
|
||||
iSfNPb3k7L2E0ETWSZ0KLvICIC8csz7X6VOTuVspKl1YXlBM6hOx7gTVdaGKmTR2
|
||||
WtFT
|
||||
-----END CERTIFICATE-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_key_sha512_brainpoolP256r1 = `-----BEGIN EC PRIVATE KEY-----
|
||||
MHgCAQEEIFuQVhd8HfMpFLdTH60+UA1HfePAQkfeaGH6V9FJe5kioAsGCSskAwMC
|
||||
CAEBB6FEA0IABCAx2ey4sj3xDzMbrJyjyINrSw57z98QcllbStcRHCz2YIfUUvsh
|
||||
KwkgnEMAWec4iy3jeZ8yeLcoGk0fi6iCoLk=
|
||||
-----END EC PRIVATE KEY-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_sha512_brainpoolP256r1 = `-----BEGIN CERTIFICATE-----
|
||||
MIIB3zCCAYagAwIBAgIUQYSjqrXJx+UTzjryNw2jl8a8bUowCgYIKoZIzj0EAwQw
|
||||
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
|
||||
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEyMjgwODU5NDFaFw0yNTEyMjgw
|
||||
ODU5NDFaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
|
||||
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwWjAUBgcqhkjOPQIBBgkrJAMD
|
||||
AggBAQcDQgAEIDHZ7LiyPfEPMxusnKPIg2tLDnvP3xByWVtK1xEcLPZgh9RS+yEr
|
||||
CSCcQwBZ5ziLLeN5nzJ4tygaTR+LqIKguaNTMFEwHQYDVR0OBBYEFDxCzGkoR6xw
|
||||
Im2XGg/24tJ+2fgyMB8GA1UdIwQYMBaAFDxCzGkoR6xwIm2XGg/24tJ+2fgyMA8G
|
||||
A1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwQDRwAwRAIgPC4h2/aUem5OMnwMy42R
|
||||
9j/NhYacXZGKXZv5KVBq5o4CIE/LcOS7bs7K3uNOdFxdJDCpK56YGV4H3O1paLpt
|
||||
VqPW
|
||||
-----END CERTIFICATE-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_key_sha256_secp384r1 = `-----BEGIN EC PRIVATE KEY-----
|
||||
MIGkAgEBBDBZthN5/vhpqE/ALHj35A/pMkfSDRxFKKweTYs2IxR0eW6RJQlZhdgk
|
||||
TGP7rQ4EKF6gBwYFK4EEACKhZANiAASsl16vufqKa/qdJWIEDO5no2useouKh4Zk
|
||||
AdtBf3fWjDnsT3J9ulxe0Ep+QbC8010o3dGQZL5UqwzoarLGrFentQ4wTJYzLXX2
|
||||
VHrLCyDjwswia1U3+I9ZYLp1TA9+88A=
|
||||
-----END EC PRIVATE KEY-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_sha256_secp384r1 = `-----BEGIN CERTIFICATE-----
|
||||
MIICHDCCAaKgAwIBAgIUIxGxDq5DcnphGZhSQNaAMWC5WtcwCgYIKoZIzj0EAwIw
|
||||
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
|
||||
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEyMjgwNTMwMzlaFw0yNTEyMjgw
|
||||
NTMwMzlaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
|
||||
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwdjAQBgcqhkjOPQIBBgUrgQQA
|
||||
IgNiAASsl16vufqKa/qdJWIEDO5no2useouKh4ZkAdtBf3fWjDnsT3J9ulxe0Ep+
|
||||
QbC8010o3dGQZL5UqwzoarLGrFentQ4wTJYzLXX2VHrLCyDjwswia1U3+I9ZYLp1
|
||||
TA9+88CjUzBRMB0GA1UdDgQWBBQuToV7daaeM2l+EdWsqXX4NP1gFjAfBgNVHSME
|
||||
GDAWgBQuToV7daaeM2l+EdWsqXX4NP1gFjAPBgNVHRMBAf8EBTADAQH/MAoGCCqG
|
||||
SM49BAMCA2gAMGUCMFEUPb/G0QxEiAW0d1S7njA4UPPtgugQ44PDjWhFrwEowtEv
|
||||
gmDwQUgL/nKb+7GsSQIxANABnyvZSR9heu9rqqYxeW/0eGoQoDnSiZowdf7Z6fJP
|
||||
aiTuTmjxvd1KKxrCkmuSDg==
|
||||
-----END CERTIFICATE-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_key_sha384_brainpoolP384r1 = `-----BEGIN EC PRIVATE KEY-----
|
||||
MIGoAgEBBDAAqX21j3nsvbpheKxpL3Vbj9Q5rkMqZ1LTVOpykpFezXH8R+d9tYgl
|
||||
lMBGmlszFJSgCwYJKyQDAwIIAQELoWQDYgAEf0p2YN3Lru5iZ8KRhZfUthvwBa9u
|
||||
SZgsKlmeBE7epzdpJvkGL3QSHO2GiF7Nv8MYEerqpwyynlAL9YK8HAqAXOoOa+rP
|
||||
RvG+mFXRYyRZTMwIH5/ULI29H+tLqsRejx4x
|
||||
-----END EC PRIVATE KEY-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_sha384_brainpoolP384r1 = `-----BEGIN CERTIFICATE-----
|
||||
MIICHzCCAaagAwIBAgIUIWM2gNwyhyOd0Tv2h8Hm63b/s54wCgYIKoZIzj0EAwMw
|
||||
RTELMAkGA1UEBhMCSU4xEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
|
||||
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEyMjcwOTQzMjBaFw0yNTEyMjcw
|
||||
OTQzMjBaMEUxCzAJBgNVBAYTAklOMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
|
||||
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwejAUBgcqhkjOPQIBBgkrJAMD
|
||||
AggBAQsDYgAEf0p2YN3Lru5iZ8KRhZfUthvwBa9uSZgsKlmeBE7epzdpJvkGL3QS
|
||||
HO2GiF7Nv8MYEerqpwyynlAL9YK8HAqAXOoOa+rPRvG+mFXRYyRZTMwIH5/ULI29
|
||||
H+tLqsRejx4xo1MwUTAdBgNVHQ4EFgQUpCaQbwuQL/GaEmjSH4oVu8zku44wHwYD
|
||||
VR0jBBgwFoAUpCaQbwuQL/GaEmjSH4oVu8zku44wDwYDVR0TAQH/BAUwAwEB/zAK
|
||||
BggqhkjOPQQDAwNnADBkAjArBhymHpn9modIUw0Q/t3wxyzGYO9UpuiAxJiiRWVM
|
||||
SduwTA4zUXYzfQUEn50j4lQCMHbwK7l1rwHW0FlpAMG3GDFgTNUaCU2I/m3J4A/E
|
||||
bKeq3jWgsSb2o7VSgneDGG70Qw==
|
||||
-----END CERTIFICATE-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_key_sha512_brainpoolP384r1 = `-----BEGIN EC PRIVATE KEY-----
|
||||
MIGoAgEBBDB4JkHrXVXl2oWIH04Wh0ERPrGi+oW6Gm4Qs+QMlzMlZFz/pGn9BbFo
|
||||
VwHIejJ8fuWgCwYJKyQDAwIIAQELoWQDYgAEgFY8mpSYBoiXECveGnKHO/9PW96k
|
||||
WT80fBf3/tz8vytQGhLzqFS4kcxSsoO9lJXnfLk+PTqKyHGX8wPAqD9MvGcD8pj1
|
||||
uvEviUV7Hp99wos7JXGGdm8koJhAvfGSt6N3
|
||||
-----END EC PRIVATE KEY-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_sha512_brainpoolP384r1 = `-----BEGIN CERTIFICATE-----
|
||||
MIICIDCCAaagAwIBAgIUUxZNjQROjb8L3QFE3qKEAOuGA/4wCgYIKoZIzj0EAwQw
|
||||
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
|
||||
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEyMjgxMDA3MDdaFw0yNTEyMjgx
|
||||
MDA3MDdaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
|
||||
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwejAUBgcqhkjOPQIBBgkrJAMD
|
||||
AggBAQsDYgAEgFY8mpSYBoiXECveGnKHO/9PW96kWT80fBf3/tz8vytQGhLzqFS4
|
||||
kcxSsoO9lJXnfLk+PTqKyHGX8wPAqD9MvGcD8pj1uvEviUV7Hp99wos7JXGGdm8k
|
||||
oJhAvfGSt6N3o1MwUTAdBgNVHQ4EFgQUUgkQRw5jvunoflxxAvX5Yc+ROgswHwYD
|
||||
VR0jBBgwFoAUUgkQRw5jvunoflxxAvX5Yc+ROgswDwYDVR0TAQH/BAUwAwEB/zAK
|
||||
BggqhkjOPQQDBANoADBlAjEAhtyXbjYqxVBT4KonoZcYciftQkRt+0DxBnPmRZ52
|
||||
d67SbyA9LP/7XDTg8qw++aPyAjAFYTG7tu/EGBqWfvSCjEo0aK9ZS/eS5HZoTfs7
|
||||
dzuXqOBuBj1L+HpiiBobsDhL63c=
|
||||
-----END CERTIFICATE-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_key_sha512_brainpoolP512r1 = `-----BEGIN EC PRIVATE KEY-----
|
||||
MIHaAgEBBEBsh1A9ArliqvxSQg7Z4u9XszaGEJTw9qPD52QSVG9qWN7zfnl4xWmD
|
||||
m7ZCM00Lc2it0orK3FjymVEPr7GOcLgPoAsGCSskAwMCCAEBDaGBhQOBggAEjJkR
|
||||
N4I/rAdmNOyUfmz/xAZ8rhLQlKYk8qwdQg3XrW0r9VbXTRkdnJxZLo8m/PH9AlFL
|
||||
qHdloVKLJp+JkITdYWuLbDn+Y6wGUCsFLCfJR1YRByP5L0+gT4LcFlotLDmRm46B
|
||||
44q5Et+aQIimslTS9KAK6VlSSswSEaG2LqzSAD0=
|
||||
-----END EC PRIVATE KEY-----
|
||||
`;
|
||||
|
||||
export const mock_dsc_sha512_brainpoolP512r1 = `-----BEGIN CERTIFICATE-----
|
||||
MIICYzCCAcigAwIBAgIUAwDW2UZPk3oy12xQCOrtAi4J8dswCgYIKoZIzj0EAwQw
|
||||
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
|
||||
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEyMzAxNDUyMTdaFw0yNTEyMzAx
|
||||
NDUyMTdaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
|
||||
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwgZswFAYHKoZIzj0CAQYJKyQD
|
||||
AwIIAQENA4GCAASMmRE3gj+sB2Y07JR+bP/EBnyuEtCUpiTyrB1CDdetbSv1VtdN
|
||||
GR2cnFkujyb88f0CUUuod2WhUosmn4mQhN1ha4tsOf5jrAZQKwUsJ8lHVhEHI/kv
|
||||
T6BPgtwWWi0sOZGbjoHjirkS35pAiKayVNL0oArpWVJKzBIRobYurNIAPaNTMFEw
|
||||
HQYDVR0OBBYEFGNz0nQzf/S2dvSrGKeczYkAapabMB8GA1UdIwQYMBaAFGNz0nQz
|
||||
f/S2dvSrGKeczYkAapabMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwQDgYgA
|
||||
MIGEAkBvgsKebJL2PQOXy3KWDvb50ygqXAXItDbbqLqxE+7h7zswDiqQz/tDtDeG
|
||||
tGGbBQIiYYwa1WlqaTJA+AjUpsZCAkBW+Z7PiQJE4DNms8za0bzom7u5kaHGaOGU
|
||||
fRSx8q4PN04hIQfS8Rm4/1Zg8VmHIQ4kdnYC4WLQgXOmshSS8LTi
|
||||
-----END CERTIFICATE-----
|
||||
`;
|
||||
|
||||
|
||||
@@ -40,12 +40,31 @@ import {
|
||||
mock_dsc_sha256_rsapss_65537_3072,
|
||||
mock_dsc_key_rsapss_65537_4096,
|
||||
mock_dsc_sha256_rsapss_65537_4096,
|
||||
mock_dsc_key_sha384_brainpoolP384r1,
|
||||
mock_dsc_sha384_brainpoolP384r1,
|
||||
mock_dsc_key_sha256_secp384r1,
|
||||
mock_dsc_sha256_secp384r1,
|
||||
mock_dsc_key_sha384_brainpoolP256r1,
|
||||
mock_dsc_sha384_brainpoolP256r1,
|
||||
mock_dsc_key_sha512_brainpoolP256r1,
|
||||
mock_dsc_sha512_brainpoolP256r1,
|
||||
mock_dsc_key_sha512_brainpoolP384r1,
|
||||
mock_dsc_sha512_brainpoolP384r1,
|
||||
mock_dsc_key_sha1_brainpoolP224r1,
|
||||
mock_dsc_sha1_brainpoolP224r1,
|
||||
mock_dsc_key_sha256_brainpoolP224r1,
|
||||
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
|
||||
@@ -159,10 +178,22 @@ export function genMockPassportData(
|
||||
privateKeyPem = mock_dsc_key_sha384_ecdsa;
|
||||
dsc = mock_dsc_sha384_ecdsa;
|
||||
break;
|
||||
case 'ecdsa_sha256_secp384r1_384':
|
||||
privateKeyPem = mock_dsc_key_sha256_secp384r1;
|
||||
dsc = mock_dsc_sha256_secp384r1;
|
||||
break;
|
||||
case 'ecdsa_sha256_brainpoolP256r1_256':
|
||||
privateKeyPem = mock_dsc_key_sha256_brainpoolP256r1;
|
||||
dsc = mock_dsc_sha256_brainpoolP256r1;
|
||||
break;
|
||||
case 'ecdsa_sha384_brainpoolP256r1_256':
|
||||
privateKeyPem = mock_dsc_key_sha384_brainpoolP256r1;
|
||||
dsc = mock_dsc_sha384_brainpoolP256r1;
|
||||
break;
|
||||
case 'ecdsa_sha512_brainpoolP256r1_256':
|
||||
privateKeyPem = mock_dsc_key_sha512_brainpoolP256r1;
|
||||
dsc = mock_dsc_sha512_brainpoolP256r1;
|
||||
break;
|
||||
case 'rsa_sha256_3_2048':
|
||||
privateKeyPem = mock_dsc_key_sha256_rsa_3_2048;
|
||||
dsc = mock_dsc_sha256_rsa_3_2048;
|
||||
@@ -179,6 +210,30 @@ export function genMockPassportData(
|
||||
privateKeyPem = mock_dsc_key_rsapss_65537_4096;
|
||||
dsc = mock_dsc_sha256_rsapss_65537_4096;
|
||||
break;
|
||||
case 'ecdsa_sha384_brainpoolP384r1_384':
|
||||
privateKeyPem = mock_dsc_key_sha384_brainpoolP384r1;
|
||||
dsc = mock_dsc_sha384_brainpoolP384r1;
|
||||
break;
|
||||
case 'ecdsa_sha512_brainpoolP384r1_384':
|
||||
privateKeyPem = mock_dsc_key_sha512_brainpoolP384r1;
|
||||
dsc = mock_dsc_sha512_brainpoolP384r1;
|
||||
break;
|
||||
case 'ecdsa_sha1_brainpoolP224r1_224':
|
||||
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;
|
||||
break;
|
||||
case 'ecdsa_sha512_brainpoolP512r1_512':
|
||||
privateKeyPem = mock_dsc_key_sha512_brainpoolP512r1;
|
||||
dsc = mock_dsc_sha512_brainpoolP512r1;
|
||||
break;
|
||||
}
|
||||
|
||||
// Generate MRZ hash first
|
||||
@@ -236,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);
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
MAX_PADDED_ECONTENT_LEN,
|
||||
MAX_PADDED_SIGNED_ATTR_LEN,
|
||||
} from '../constants/constants';
|
||||
import { assert, shaPad } from './shaPad';
|
||||
import { assert, sha384_512Pad, shaPad } from './shaPad';
|
||||
import { PassportData, SignatureAlgorithm } from './types';
|
||||
import {
|
||||
bytesToBigDecimal,
|
||||
@@ -221,13 +221,25 @@ export function generateCircuitInputsProve(
|
||||
);
|
||||
}
|
||||
|
||||
console.log('signatureAlgorithmFullName', signatureAlgorithmFullName);
|
||||
const [eContentPadded, eContentLen] = shaPad(
|
||||
const dg1PaddingFunction =
|
||||
passportMetadata.dg1HashFunction === 'sha1' ||
|
||||
passportMetadata.dg1HashFunction === 'sha224' ||
|
||||
passportMetadata.dg1HashFunction === 'sha256'
|
||||
? shaPad
|
||||
: sha384_512Pad;
|
||||
|
||||
const [eContentPadded, eContentLen] = dg1PaddingFunction(
|
||||
new Uint8Array(eContent),
|
||||
MAX_PADDED_ECONTENT_LEN[passportMetadata.dg1HashFunction]
|
||||
);
|
||||
|
||||
const [signedAttrPadded, signedAttrPaddedLen] = shaPad(
|
||||
const eContentPaddingFunction =
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -23,12 +23,21 @@ export type SignatureAlgorithm =
|
||||
| 'ecdsa_sha256_secp256r1_256'
|
||||
| 'ecdsa_sha1_secp256r1_256'
|
||||
| 'ecdsa_sha384_secp384r1_384'
|
||||
| 'ecdsa_sha256_secp384r1_384'
|
||||
| 'ecdsa_sha384_brainpoolP256r1_256'
|
||||
| 'ecdsa_sha512_brainpoolP256r1_256'
|
||||
| 'ecdsa_sha256_brainpoolP256r1_256'
|
||||
| 'rsa_sha256_3_2048'
|
||||
| 'rsa_sha256_65537_3072'
|
||||
| 'rsa_sha256_65537_4096'
|
||||
| 'rsa_sha512_65537_4096'
|
||||
| 'rsapss_sha256_65537_3072'
|
||||
| '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';
|
||||
|
||||
export type Proof = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
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_256 } from 'js-sha512';
|
||||
import { sha384, sha512 } from 'js-sha512';
|
||||
import { SMT } from '@openpassport/zk-kit-smt';
|
||||
import forge from 'node-forge';
|
||||
import {
|
||||
@@ -37,7 +37,19 @@ export function getNAndK(sigAlg: SignatureAlgorithm) {
|
||||
}
|
||||
|
||||
if (sigAlg.startsWith('ecdsa_')) {
|
||||
return { n: n_dsc_ecdsa, k: k_dsc_ecdsa }; // 256/32 = 8
|
||||
if (sigAlg.endsWith('224')) {
|
||||
return { n: 32, k: 7 };
|
||||
} else if (sigAlg.endsWith('256')) {
|
||||
return { n: n_dsc_ecdsa, k: 4 };
|
||||
} else if (sigAlg.endsWith('384')) {
|
||||
return { n: n_dsc_ecdsa, k: 6 };
|
||||
} else if (sigAlg.endsWith('512')) {
|
||||
return { n: n_dsc_ecdsa, k: 8 };
|
||||
} else if (sigAlg.endsWith('521')) {
|
||||
return { n: n_dsc_ecdsa, k: 16 };
|
||||
} else {
|
||||
throw new Error('invalid key size');
|
||||
}
|
||||
}
|
||||
|
||||
if (sigAlg.startsWith('rsapss_')) {
|
||||
@@ -236,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;
|
||||
@@ -243,7 +258,7 @@ export function hash(hashFunction: string, bytesArray: number[]): number[] {
|
||||
hashResult = sha384(unsignedBytesArray);
|
||||
break;
|
||||
case 'sha512':
|
||||
hashResult = sha512_256(unsignedBytesArray);
|
||||
hashResult = sha512(unsignedBytesArray);
|
||||
break;
|
||||
default:
|
||||
console.log('\x1b[31m%s\x1b[0m', `${hashFunction} not found in hash`); // Log in red
|
||||
@@ -311,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