mirror of
https://github.com/selfxyz/self.git
synced 2026-04-27 03:01:15 -04:00
Merge pull request #301 from zk-passport/feat/rsapss-zkemail-tests
Feat/rsapss zkemail tests
This commit is contained in:
@@ -2,4 +2,4 @@ pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(256, 256, 8, 64, 4, 448, 128, 20);
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(256, 256, 8, 64, 4, 448, 128, 20);
|
||||
|
||||
@@ -2,4 +2,4 @@ pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(384, 384, 9, 64, 6, 640, 256, 20);
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(384, 384, 9, 64, 6, 640, 256, 20);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma circom 2.1.9;
|
||||
include "../../../utils/circomlib/signature/rsapss/rsapss3.circom";
|
||||
|
||||
template VerifyRsaPss3Sig_tester() {
|
||||
signal input modulus[35];
|
||||
signal input signature[35];
|
||||
signal input message[256];
|
||||
|
||||
VerifyRsaPss3Sig(120, 35, 32, 256, 2048)(modulus,signature,message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPss3Sig_tester();
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma circom 2.1.9;
|
||||
include "../../../utils/circomlib/signature/rsapss/rsapss3.circom";
|
||||
|
||||
template VerifyRsaPss3Sig_tester() {
|
||||
signal input modulus[35];
|
||||
signal input signature[35];
|
||||
signal input message[256];
|
||||
|
||||
VerifyRsaPss3Sig(120, 35, 32, 256, 3072)(modulus,signature,message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPss3Sig_tester();
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma circom 2.1.9;
|
||||
include "../../../utils/circomlib/signature/rsapss/rsapss3.circom";
|
||||
|
||||
template VerifyRsaPss3Sig_tester() {
|
||||
signal input modulus[35];
|
||||
signal input signature[35];
|
||||
signal input message[256];
|
||||
|
||||
VerifyRsaPss3Sig(120, 35, 32, 256, 4096)(modulus,signature,message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPss3Sig_tester();
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma circom 2.1.9;
|
||||
include "../../../utils/circomlib/signature/rsapss/rsapss65537.circom";
|
||||
|
||||
template VerifyRsaPss65537Sig_tester() {
|
||||
signal input modulus[35];
|
||||
signal input signature[35];
|
||||
signal input message[256];
|
||||
|
||||
VerifyRsaPss65537Sig(120, 35, 32, 256, 2048)(modulus,signature,message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPss65537Sig_tester();
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma circom 2.1.9;
|
||||
include "../../../utils/circomlib/signature/rsapss/rsapss65537.circom";
|
||||
|
||||
template VerifyRsaPss65537Sig_tester() {
|
||||
signal input modulus[35];
|
||||
signal input signature[35];
|
||||
signal input message[256];
|
||||
|
||||
VerifyRsaPss65537Sig(120, 35, 32, 256, 3072)(modulus,signature,message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPss65537Sig_tester();
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma circom 2.1.9;
|
||||
include "../../../utils/circomlib/signature/rsapss/rsapss65537.circom";
|
||||
|
||||
template VerifyRsaPss65537Sig_tester() {
|
||||
signal input modulus[35];
|
||||
signal input signature[35];
|
||||
signal input message[256];
|
||||
|
||||
VerifyRsaPss65537Sig(120, 35, 32, 256, 4096)(modulus,signature,message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPss65537Sig_tester();
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma circom 2.1.9;
|
||||
include "../../../utils/circomlib/signature/rsapss/rsapss3.circom";
|
||||
|
||||
template VerifyRsaPss3Sig_tester() {
|
||||
signal input modulus[35];
|
||||
signal input signature[35];
|
||||
signal input message[384];
|
||||
|
||||
VerifyRsaPss3Sig(120, 35, 48, 384, 3072)(modulus,signature,message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPss3Sig_tester();
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma circom 2.1.9;
|
||||
include "../../../utils/circomlib/signature/rsapss/rsapss3.circom";
|
||||
|
||||
template VerifyRsaPss3Sig_tester() {
|
||||
signal input modulus[35];
|
||||
signal input signature[35];
|
||||
signal input message[384];
|
||||
|
||||
VerifyRsaPss3Sig(120, 35, 48, 384, 4096)(modulus,signature,message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPss3Sig_tester();
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma circom 2.1.9;
|
||||
include "../../../utils/circomlib/signature/rsapss/rsapss65537.circom";
|
||||
|
||||
template VerifyRsaPss65537Sig_tester() {
|
||||
signal input modulus[35];
|
||||
signal input signature[35];
|
||||
signal input message[384];
|
||||
|
||||
VerifyRsaPss65537Sig(120, 35, 48, 384, 3072)(modulus,signature,message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPss65537Sig_tester();
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma circom 2.1.9;
|
||||
include "../../../utils/circomlib/signature/rsapss/rsapss65537.circom";
|
||||
|
||||
template VerifyRsaPss65537Sig_tester() {
|
||||
signal input modulus[35];
|
||||
signal input signature[35];
|
||||
signal input message[384];
|
||||
|
||||
VerifyRsaPss65537Sig(120, 35, 48, 384, 4096)(modulus,signature,message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPss65537Sig_tester();
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma circom 2.1.9;
|
||||
include "../../../utils/circomlib/signature/rsapss/rsapss3.circom";
|
||||
|
||||
template VerifyRsaPss65537Sig_tester() {
|
||||
signal input modulus[35];
|
||||
signal input signature[35];
|
||||
signal input message[512];
|
||||
|
||||
VerifyRsaPss3Sig(120, 35, 64, 512, 2048)(modulus,signature,message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPss65537Sig_tester();
|
||||
@@ -0,0 +1,12 @@
|
||||
pragma circom 2.1.9;
|
||||
include "../../../utils/circomlib/signature/rsapss/rsapss3.circom";
|
||||
|
||||
template VerifyRsaPss65537Sig_tester() {
|
||||
signal input modulus[35];
|
||||
signal input signature[35];
|
||||
signal input message[512];
|
||||
|
||||
VerifyRsaPss3Sig(120, 35, 64, 512, 4096)(modulus,signature,message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPss65537Sig_tester();
|
||||
83
circuits/circuits/utils/circomlib/signature/FpPowMod.circom
Normal file
83
circuits/circuits/utils/circomlib/signature/FpPowMod.circom
Normal file
@@ -0,0 +1,83 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "@zk-email/circuits/lib/fp.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
|
||||
/// @title FpPow3Mod
|
||||
/// @notice Computes base^3 mod modulus
|
||||
/// @dev Does not necessarily reduce fully mod modulus (the answer could be too big by a multiple of modulus)
|
||||
/// @param n Number of bits per chunk the modulus is split into.
|
||||
/// @param k Number of chunks the modulus is split into.
|
||||
/// @input base The base to exponentiate; assumes to consist of `k` chunks, each of which must fit in `n` bits
|
||||
/// @input modulus The modulus; assumes to consist of `k` chunks, each of which must fit in `n` bits
|
||||
/// @output out The result of the exponentiation.
|
||||
template FpPow3Mod(n, k) {
|
||||
signal input base[k];
|
||||
signal input modulus[k];
|
||||
|
||||
signal output out[k];
|
||||
|
||||
component doublers = FpMul(n, k);
|
||||
component adder = FpMul(n, k);
|
||||
|
||||
for (var j = 0; j < k; j++) {
|
||||
adder.p[j] <== modulus[j];
|
||||
doublers.p[j] <== modulus[j];
|
||||
}
|
||||
for (var j = 0; j < k; j++) {
|
||||
doublers.a[j] <== base[j];
|
||||
doublers.b[j] <== base[j];
|
||||
}
|
||||
for (var j = 0; j < k; j++) {
|
||||
adder.a[j] <== base[j];
|
||||
adder.b[j] <== doublers.out[j];
|
||||
}
|
||||
for (var j = 0; j < k; j++) {
|
||||
out[j] <== adder.out[j];
|
||||
}
|
||||
}
|
||||
|
||||
/// @title FpPow65537Mod
|
||||
/// @notice Computes base^65537 mod modulus
|
||||
/// @dev Does not necessarily reduce fully mod modulus (the answer could be too big by a multiple of modulus)
|
||||
/// @param n Number of bits per chunk the modulus is split into.
|
||||
/// @param k Number of chunks the modulus is split into.
|
||||
/// @input base The base to exponentiate; assumes to consist of `k` chunks, each of which must fit in `n` bits
|
||||
/// @input modulus The modulus; assumes to consist of `k` chunks, each of which must fit in `n` bits
|
||||
/// @output out The result of the exponentiation.
|
||||
template FpPow65537Mod(n, k) {
|
||||
signal input base[k];
|
||||
signal input modulus[k];
|
||||
|
||||
signal output out[k];
|
||||
|
||||
component doublers[16];
|
||||
component adder = FpMul(n, k);
|
||||
for (var i = 0; i < 16; i++) {
|
||||
doublers[i] = FpMul(n, k);
|
||||
}
|
||||
|
||||
for (var j = 0; j < k; j++) {
|
||||
adder.p[j] <== modulus[j];
|
||||
for (var i = 0; i < 16; i++) {
|
||||
doublers[i].p[j] <== modulus[j];
|
||||
}
|
||||
}
|
||||
for (var j = 0; j < k; j++) {
|
||||
doublers[0].a[j] <== base[j];
|
||||
doublers[0].b[j] <== base[j];
|
||||
}
|
||||
for (var i = 0; i + 1 < 16; i++) {
|
||||
for (var j = 0; j < k; j++) {
|
||||
doublers[i + 1].a[j] <== doublers[i].out[j];
|
||||
doublers[i + 1].b[j] <== doublers[i].out[j];
|
||||
}
|
||||
}
|
||||
for (var j = 0; j < k; j++) {
|
||||
adder.a[j] <== base[j];
|
||||
adder.b[j] <== doublers[15].out[j];
|
||||
}
|
||||
for (var j = 0; j < k; j++) {
|
||||
out[j] <== adder.out[j];
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ pragma circom 2.1.9;
|
||||
|
||||
include "@zk-email/circuits/lib/fp.circom";
|
||||
include "./pkcs1v1_5Padding.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
include "../FpPowMod.circom";
|
||||
|
||||
// For 2048bits RSA, CHUNK_SIZE = 64, CHUNK_NUMBER = 32
|
||||
// For 3072bits RSA, CHUNK_SIZE = 64, CHUNK_NUMBER = 48
|
||||
@@ -46,37 +46,3 @@ template VerifyRsa3Pkcs1v1_5(CHUNK_SIZE, CHUNK_NUMBER, HASH_SIZE) {
|
||||
bigPow.out[i] === padder.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// @title FpPow3Mod
|
||||
/// @notice Computes base^3 mod modulus
|
||||
/// @dev Does not necessarily reduce fully mod modulus (the answer could be too big by a multiple of modulus)
|
||||
/// @param n Number of bits per chunk the modulus is split into.
|
||||
/// @param k Number of chunks the modulus is split into.
|
||||
/// @input base The base to exponentiate; assumes to consist of `k` chunks, each of which must fit in `n` bits
|
||||
/// @input modulus The modulus; assumes to consist of `k` chunks, each of which must fit in `n` bits
|
||||
/// @output out The result of the exponentiation.
|
||||
template FpPow3Mod(n, k) {
|
||||
signal input base[k];
|
||||
signal input modulus[k];
|
||||
|
||||
signal output out[k];
|
||||
|
||||
component doublers = FpMul(n, k);
|
||||
component adder = FpMul(n, k);
|
||||
|
||||
for (var j = 0; j < k; j++) {
|
||||
adder.p[j] <== modulus[j];
|
||||
doublers.p[j] <== modulus[j];
|
||||
}
|
||||
for (var j = 0; j < k; j++) {
|
||||
doublers.a[j] <== base[j];
|
||||
doublers.b[j] <== base[j];
|
||||
}
|
||||
for (var j = 0; j < k; j++) {
|
||||
adder.a[j] <== base[j];
|
||||
adder.b[j] <== doublers.out[j];
|
||||
}
|
||||
for (var j = 0; j < k; j++) {
|
||||
out[j] <== adder.out[j];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ pragma circom 2.1.9;
|
||||
|
||||
include "@zk-email/circuits/lib/fp.circom";
|
||||
include "./pkcs1v1_5Padding.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
include "../FpPowMod.circom";
|
||||
|
||||
// For 2048bits RSA, CHUNK_SIZE = 64, CHUNK_NUMBER = 32
|
||||
// For 3072bits RSA, CHUNK_SIZE = 64, CHUNK_NUMBER = 48
|
||||
@@ -46,48 +46,3 @@ template VerifyRsa65537Pkcs1v1_5(CHUNK_SIZE, CHUNK_NUMBER, HASH_SIZE) {
|
||||
bigPow.out[i] === padder.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// @title FpPow65537Mod
|
||||
/// @notice Computes base^65537 mod modulus
|
||||
/// @dev Does not necessarily reduce fully mod modulus (the answer could be too big by a multiple of modulus)
|
||||
/// @param n Number of bits per chunk the modulus is split into.
|
||||
/// @param k Number of chunks the modulus is split into.
|
||||
/// @input base The base to exponentiate; assumes to consist of `k` chunks, each of which must fit in `n` bits
|
||||
/// @input modulus The modulus; assumes to consist of `k` chunks, each of which must fit in `n` bits
|
||||
/// @output out The result of the exponentiation.
|
||||
template FpPow65537Mod(n, k) {
|
||||
signal input base[k];
|
||||
signal input modulus[k];
|
||||
|
||||
signal output out[k];
|
||||
|
||||
component doublers[16];
|
||||
component adder = FpMul(n, k);
|
||||
for (var i = 0; i < 16; i++) {
|
||||
doublers[i] = FpMul(n, k);
|
||||
}
|
||||
|
||||
for (var j = 0; j < k; j++) {
|
||||
adder.p[j] <== modulus[j];
|
||||
for (var i = 0; i < 16; i++) {
|
||||
doublers[i].p[j] <== modulus[j];
|
||||
}
|
||||
}
|
||||
for (var j = 0; j < k; j++) {
|
||||
doublers[0].a[j] <== base[j];
|
||||
doublers[0].b[j] <== base[j];
|
||||
}
|
||||
for (var i = 0; i + 1 < 16; i++) {
|
||||
for (var j = 0; j < k; j++) {
|
||||
doublers[i + 1].a[j] <== doublers[i].out[j];
|
||||
doublers[i + 1].b[j] <== doublers[i].out[j];
|
||||
}
|
||||
}
|
||||
for (var j = 0; j < k; j++) {
|
||||
adder.a[j] <== base[j];
|
||||
adder.b[j] <== doublers[15].out[j];
|
||||
}
|
||||
for (var j = 0; j < k; j++) {
|
||||
out[j] <== adder.out[j];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,55 @@ pragma circom 2.1.6;
|
||||
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
|
||||
template Mgf1Sha512(seedLen, maskLen) { //in bytes
|
||||
var seedLenBits = seedLen * 8;
|
||||
var maskLenBits = maskLen * 8;
|
||||
var hashLen = 64; //output len of sha function in bytes
|
||||
var hashLenBits = hashLen * 8;//output len of sha function in bits
|
||||
|
||||
signal input seed[seedLenBits]; //each represents a bit
|
||||
signal output out[maskLenBits];
|
||||
|
||||
assert(maskLen <= 0xffffffff * hashLen );
|
||||
var iterations = (maskLen \ hashLen) + 1; //adding 1, in-case maskLen \ hashLen is 0
|
||||
component sha512[iterations];
|
||||
component num2Bits[iterations];
|
||||
|
||||
for (var i = 0; i < iterations; i++) {
|
||||
//512 + 32 bits for counter
|
||||
sha512[i] = ShaHashBits(544, 512);
|
||||
|
||||
num2Bits[i] = Num2Bits(32);
|
||||
}
|
||||
|
||||
var concated[hashLenBits + 32]; //seed + 32 bits(4 Bytes) for counter
|
||||
signal hashed[hashLenBits * (iterations)];
|
||||
|
||||
for (var i = 0; i < seedLenBits; i++) {
|
||||
concated[i] = seed[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < iterations; i++) {
|
||||
num2Bits[i].in <== i; //convert counter to bits
|
||||
|
||||
for (var j = 0; j < 32; j++) {
|
||||
//concat seed and counter
|
||||
concated[seedLenBits + j] = num2Bits[i].out[31-j];
|
||||
}
|
||||
|
||||
//hashing value
|
||||
sha512[i].in <== concated;
|
||||
|
||||
for (var j = 0; j < hashLenBits; j++) {
|
||||
hashed[i * hashLenBits + j] <== sha512[i].out[j];
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < maskLenBits; i++) {
|
||||
out[i] <== hashed[i];
|
||||
}
|
||||
}
|
||||
|
||||
template Mgf1Sha384(SEED_LEN, MASK_LEN) { //in bytes
|
||||
var SEED_LEN_BITS = SEED_LEN * 8;
|
||||
var MASK_LEN_BITS = MASK_LEN * 8;
|
||||
@@ -21,7 +70,7 @@ template Mgf1Sha384(SEED_LEN, MASK_LEN) { //in bytes
|
||||
component num2Bits[ITERATIONS];
|
||||
|
||||
for (var i = 0; i < ITERATIONS; i++) {
|
||||
sha384[i] = ShaHashChunks(1 , 384); //32 bits for counter
|
||||
sha384[i] = ShaHashBits(416, 384); //32 bits for counter
|
||||
|
||||
num2Bits[i] = Num2Bits(32);
|
||||
}
|
||||
@@ -41,25 +90,10 @@ template Mgf1Sha384(SEED_LEN, MASK_LEN) { //in bytes
|
||||
concated[SEED_LEN_BITS + j] = num2Bits[i].out[31-j];
|
||||
}
|
||||
|
||||
//adding padding (len = 416 = 110100000)
|
||||
for (var j = 417; j < 1015; j++) {
|
||||
concated[j] = 0;
|
||||
for (var k =0; k < 416; k++) {
|
||||
sha384[i].in[k] <== concated[k];
|
||||
}
|
||||
|
||||
concated[416] = 1;
|
||||
concated[1023] = 0;
|
||||
concated[1022] = 0;
|
||||
concated[1021] = 0;
|
||||
concated[1020] = 0;
|
||||
concated[1019] = 0;
|
||||
concated[1018] = 1;
|
||||
concated[1017] = 0;
|
||||
concated[1016] = 1;
|
||||
concated[1015] = 1;
|
||||
|
||||
//hashing value
|
||||
sha384[i].in <== concated;
|
||||
|
||||
for (var j = 0; j < HASH_LEN_BITS; j++) {
|
||||
hashed[i * HASH_LEN_BITS + j] <== sha384[i].out[j];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,470 @@
|
||||
pragma circom 2.1.6;
|
||||
|
||||
include "../../bigInt/bigInt.circom";
|
||||
include "./mgf1.circom";
|
||||
include "../../bitify/gates.circom";
|
||||
include "../../hasher/hash.circom";
|
||||
include "../FpPowMod.circom";
|
||||
|
||||
/*
|
||||
* Verification for RSAPSS signature.
|
||||
* hashed is hashed message of hash_type algo, hash_type is algo hash algo for mgf1 mask generation.
|
||||
* There is no assert for CHUNK_SIZE == 64 and it may work with other chunking, but this one wasn`t tested,
|
||||
* so better use 64 signature and pubkey - chunked numbers (CHUNK_SIZE, CHUNK_NUMBER).
|
||||
* default exp = 65537
|
||||
* SALT_LEN is salt lenght in bytes! (NOT IN BITES LIKE HASH_TYPE!).
|
||||
* This is because salt len can`t be % 8 != 0 so we use bytes len (8 bites).
|
||||
* For now, only HASH_TYPE == 384 && SALT_LEN == 48, HASH_TYPE == 256 && SALT_LEN == 64, HASH_TYPE == 256 && SALT_LEN == 32 cases supported.
|
||||
* Use this for CHUNK_NUMBER == 2**n, otherwise error will occur.
|
||||
*/
|
||||
template VerifyRsaPss3Sig(CHUNK_SIZE, CHUNK_NUMBER, SALT_LEN, HASH_TYPE, KEY_LENGTH) {
|
||||
assert((HASH_TYPE == 512 && SALT_LEN == 64) || (HASH_TYPE == 384 && SALT_LEN == 48) || (HASH_TYPE == 256 && SALT_LEN == 64) || (HASH_TYPE == 256 && SALT_LEN == 32));
|
||||
|
||||
signal input pubkey[CHUNK_NUMBER];
|
||||
signal input signature[CHUNK_NUMBER];
|
||||
signal input hashed[HASH_TYPE];
|
||||
|
||||
|
||||
var EM_LEN = KEY_LENGTH \ 8;
|
||||
var HASH_LEN = HASH_TYPE \ 8;
|
||||
var SALT_LEN_BITS = SALT_LEN * 8;
|
||||
var EM_LEN_BITS = KEY_LENGTH;
|
||||
|
||||
signal eM[EM_LEN];
|
||||
signal eMsgInBits[EM_LEN_BITS];
|
||||
|
||||
//computing encoded message
|
||||
component bigPow = FpPow3Mod(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++) {
|
||||
bigPow.base[i] <== signature[i];
|
||||
bigPow.modulus[i] <== pubkey[i];
|
||||
}
|
||||
|
||||
signal encoded[CHUNK_NUMBER];
|
||||
encoded <== bigPow.out;
|
||||
|
||||
component num2Bits[CHUNK_NUMBER];
|
||||
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++) {
|
||||
num2Bits[i] = Num2Bits(CHUNK_SIZE);
|
||||
num2Bits[i].in <== encoded[CHUNK_NUMBER - 1 - i];
|
||||
|
||||
for (var j = 0; j < CHUNK_SIZE; j++) {
|
||||
var sourcePos = i * CHUNK_SIZE + j;
|
||||
var targetPos = sourcePos - (CHUNK_NUMBER * CHUNK_SIZE - EM_LEN_BITS);
|
||||
if (targetPos >= 0 && targetPos < EM_LEN_BITS) {
|
||||
eMsgInBits[targetPos] <== num2Bits[i].out[CHUNK_SIZE - j - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component bits2Num[EM_LEN];
|
||||
|
||||
for (var i = 0; i < EM_LEN; i++) {
|
||||
bits2Num[i] = Bits2Num(8);
|
||||
|
||||
for (var j = 0; j < 8; j++) {
|
||||
bits2Num[i].in[7 - j] <== eMsgInBits[i * 8 + j];
|
||||
}
|
||||
|
||||
eM[EM_LEN - i - 1] <== bits2Num[i].out;
|
||||
}
|
||||
|
||||
//should be more than HLEN + SLEN + 2
|
||||
assert(EM_LEN >= HASH_LEN + SALT_LEN + 2);
|
||||
|
||||
//should end with 0xBC (188 in decimal)
|
||||
eM[0] === 188;
|
||||
|
||||
var DB_MASK_LEN = EM_LEN - HASH_LEN - 1;
|
||||
|
||||
signal dbMask[DB_MASK_LEN * 8];
|
||||
signal db[DB_MASK_LEN * 8];
|
||||
signal salt[SALT_LEN * 8];
|
||||
signal maskedDB[(EM_LEN - HASH_LEN - 1) * 8];
|
||||
|
||||
for (var i = 0; i < (EM_LEN - HASH_LEN - 1) * 8; i++) {
|
||||
maskedDB[i] <== eMsgInBits[i];
|
||||
}
|
||||
|
||||
signal hash[HASH_LEN * 8];
|
||||
|
||||
//inserting hash
|
||||
for (var i = 0; i < HASH_TYPE; i++) {
|
||||
hash[i] <== eMsgInBits[(EM_LEN_BITS) - HASH_TYPE - 8 + i];
|
||||
}
|
||||
|
||||
//getting mask
|
||||
if (HASH_TYPE == 256) {
|
||||
component MGF1_256 = Mgf1Sha256(HASH_LEN, DB_MASK_LEN);
|
||||
|
||||
for (var i = 0; i < (HASH_TYPE); i++) {
|
||||
MGF1_256.seed[i] <== hash[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
dbMask[i] <== MGF1_256.out[i];
|
||||
}
|
||||
}
|
||||
if (HASH_TYPE == 384) {
|
||||
component MGF1_384 = Mgf1Sha384(HASH_LEN, DB_MASK_LEN);
|
||||
|
||||
for (var i = 0; i < (HASH_TYPE); i++) {
|
||||
MGF1_384.seed[i] <== hash[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
dbMask[i] <== MGF1_384.out[i];
|
||||
}
|
||||
}
|
||||
if (HASH_TYPE == 512) {
|
||||
component MGF1_512 = Mgf1Sha512(HASH_LEN, DB_MASK_LEN);
|
||||
|
||||
for (var i = 0; i < (HASH_TYPE); i++) {
|
||||
MGF1_512.seed[i] <== hash[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
dbMask[i] <== MGF1_512.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
component xor = Xor2(DB_MASK_LEN * 8);
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
xor.in1[i] <== maskedDB[i];
|
||||
xor.in2[i] <== dbMask[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
//setting the first leftmost byte to 0
|
||||
if (i == 0) {
|
||||
db[i] <== 0;
|
||||
} else {
|
||||
db[i] <== xor.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
//inserting salt
|
||||
for (var i = 0; i < SALT_LEN_BITS; i++) {
|
||||
salt[SALT_LEN_BITS - 1 - i] <== db[(DB_MASK_LEN * 8) - 1 - i];
|
||||
}
|
||||
|
||||
signal mDash[2048];
|
||||
//adding 0s
|
||||
for (var i = 0; i < 64; i++) {
|
||||
mDash[i] <== 0;
|
||||
}
|
||||
|
||||
//adding message hash
|
||||
for (var i = 0; i < HASH_LEN * 8; i++) {
|
||||
mDash[64 + i] <== hashed[i];
|
||||
}
|
||||
|
||||
//adding salt
|
||||
for (var i = 0; i < SALT_LEN * 8; i++) {
|
||||
mDash[64 + HASH_LEN * 8 + i] <== salt[i];
|
||||
}
|
||||
|
||||
if (HASH_TYPE == 256 && SALT_LEN == 32) {
|
||||
//adding padding
|
||||
//len = 64+512 = 576 = 1001000000
|
||||
for (var i = 577; i < 1014; i++) {
|
||||
mDash[i] <== 0;
|
||||
}
|
||||
|
||||
mDash[576] <== 1;
|
||||
mDash[1023] <== 0;
|
||||
mDash[1022] <== 0;
|
||||
mDash[1021] <== 0;
|
||||
mDash[1020] <== 0;
|
||||
mDash[1019] <== 0;
|
||||
mDash[1018] <== 0;
|
||||
mDash[1017] <== 1;
|
||||
mDash[1016] <== 0;
|
||||
mDash[1015] <== 0;
|
||||
mDash[1014] <== 1;
|
||||
|
||||
signal mDash256[1024];
|
||||
for (var i = 0; i < 1024; i++){
|
||||
mDash256[i] <== mDash[i];
|
||||
}
|
||||
|
||||
//hashing
|
||||
component hDash256 = ShaHashChunks(2, HASH_TYPE);
|
||||
hDash256.in <== mDash256;
|
||||
|
||||
hDash256.out === hash;
|
||||
}
|
||||
|
||||
if (HASH_TYPE == 256 && SALT_LEN == 64) {
|
||||
for (var i = 833; i < 1014; i++) {
|
||||
mDash[i] <== 0;
|
||||
}
|
||||
|
||||
mDash[832] <== 1;
|
||||
mDash[1023] <== 0;
|
||||
mDash[1022] <== 0;
|
||||
mDash[1021] <== 0;
|
||||
mDash[1020] <== 0;
|
||||
mDash[1019] <== 0;
|
||||
mDash[1018] <== 0;
|
||||
mDash[1017] <== 1;
|
||||
mDash[1016] <== 0;
|
||||
mDash[1015] <== 1;
|
||||
mDash[1014] <== 1;
|
||||
|
||||
signal mDash256[1024];
|
||||
for (var i = 0; i < 1024; i++){
|
||||
mDash256[i] <== mDash[i];
|
||||
}
|
||||
|
||||
component hDash256 = ShaHashChunks(2, HASH_TYPE);
|
||||
hDash256.in <== mDash256;
|
||||
|
||||
hDash256.out === hash;
|
||||
}
|
||||
|
||||
if (HASH_TYPE == 384 && SALT_LEN == 48) {
|
||||
//padding
|
||||
//len = 64+(48*8)+384 = 832 = 1101000000
|
||||
|
||||
component hDash384 = ShaHashBits(64 + SALT_LEN_BITS + HASH_LEN * 8, 384);
|
||||
for (var i = 0; i < 832; i++) {
|
||||
hDash384.in[i] <== mDash[i];
|
||||
}
|
||||
|
||||
hDash384.out === hash;
|
||||
}
|
||||
if (HASH_TYPE == 512 && SALT_LEN == 64) {
|
||||
// 64 + 512 + 512 = 1088
|
||||
component hDash512 = ShaHashBits(64 + SALT_LEN_BITS + HASH_LEN * 8, 512);
|
||||
// hDash512.dummy <== dummy;
|
||||
|
||||
for (var i = 0; i < 1088; i++) {
|
||||
hDash512.in[i] <== mDash[i];
|
||||
}
|
||||
|
||||
hDash512.out === hash;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verification for RSAPSS signature.
|
||||
* hashed is hashed message of hash_type algo, hash_type is algo hash algo for mgf1 mask generation.
|
||||
* There is no assert for CHUNK_SIZE == 64 and it may work with other chunking, but this one wasn`t tested,
|
||||
* so better use 64 signature and pubkey - chunked numbers (CHUNK_SIZE, CHUNK_NUMBER).
|
||||
* e_bits - Len of bit representation of exponent with 1 highest and lowest bits, other are 0 (2^(e_bits - 1) + 1).
|
||||
* default exp = 65537 (e_bits = 17)
|
||||
* SALT_LEN is salt lenght in bytes! (NOT IN BITES LIKE HASH_TYPE!)
|
||||
* This is because salt len can`t be % 8 != 0 so we use bytes len (8 bites).
|
||||
* For now, only HASH_TYPE == 384 && SALT_LEN == 48, HASH_TYPE == 256 && SALT_LEN == 64, HASH_TYPE == 256 && SALT_LEN == 32 cases supported.
|
||||
* Use this for CHUNK_NUMBER != 2**n, otherwise use previous template.
|
||||
*/
|
||||
template VerifyRsaPss3SigNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, SALT_LEN, EXP, HASH_TYPE) {
|
||||
assert((HASH_TYPE == 384 && SALT_LEN == 48) || (HASH_TYPE == 256 && SALT_LEN == 64) || (HASH_TYPE == 256 && SALT_LEN == 32));
|
||||
|
||||
signal input pubkey[CHUNK_NUMBER];
|
||||
signal input signature[CHUNK_NUMBER];
|
||||
signal input hashed[HASH_TYPE];
|
||||
|
||||
|
||||
var EM_LEN = (CHUNK_SIZE * CHUNK_NUMBER) \ 8;
|
||||
var HASH_LEN = HASH_TYPE \ 8;
|
||||
var SALT_LEN_BITS = SALT_LEN * 8;
|
||||
var EM_LEN_BITS = CHUNK_SIZE * CHUNK_NUMBER;
|
||||
|
||||
signal eM[EM_LEN];
|
||||
signal eMsgInBits[EM_LEN_BITS];
|
||||
|
||||
//computing encoded message
|
||||
component powerMod;
|
||||
powerMod = PowerModNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, EXP);
|
||||
powerMod.base <== signature;
|
||||
powerMod.modulus <== pubkey;
|
||||
|
||||
signal encoded[CHUNK_NUMBER];
|
||||
encoded <== powerMod.out;
|
||||
|
||||
component num2Bits[CHUNK_NUMBER];
|
||||
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++) {
|
||||
num2Bits[i] = Num2Bits(CHUNK_SIZE);
|
||||
num2Bits[i].in <== encoded[CHUNK_NUMBER - 1 - i];
|
||||
|
||||
for (var j = 0; j < CHUNK_SIZE; j++) {
|
||||
eMsgInBits[i * CHUNK_SIZE + j] <== num2Bits[i].out[CHUNK_SIZE - j - 1];
|
||||
}
|
||||
}
|
||||
|
||||
component bits2Num[EM_LEN];
|
||||
|
||||
for (var i = 0; i < EM_LEN; i++) {
|
||||
bits2Num[i] = Bits2Num(8);
|
||||
|
||||
for (var j = 0; j < 8; j++) {
|
||||
bits2Num[i].in[7 - j] <== eMsgInBits[i * 8 + j];
|
||||
}
|
||||
|
||||
eM[EM_LEN - i - 1] <== bits2Num[i].out;
|
||||
}
|
||||
|
||||
//should be more than HLEN + SLEN + 2
|
||||
assert(EM_LEN >= HASH_LEN + SALT_LEN + 2);
|
||||
|
||||
//should end with 0xBC (188 in decimal)
|
||||
assert(eM[0] == 188);
|
||||
|
||||
var DB_MASK_LEN = EM_LEN - HASH_LEN - 1;
|
||||
signal dbMask[DB_MASK_LEN * 8];
|
||||
signal db[DB_MASK_LEN * 8];
|
||||
signal salt[SALT_LEN * 8];
|
||||
signal maskedDB[(EM_LEN - HASH_LEN - 1) * 8];
|
||||
|
||||
for (var i = 0; i < (EM_LEN - HASH_LEN - 1) * 8; i++) {
|
||||
maskedDB[i] <== eMsgInBits[i];
|
||||
}
|
||||
|
||||
signal hash[HASH_LEN * 8];
|
||||
|
||||
//inserting hash
|
||||
for (var i = 0; i < HASH_TYPE; i++) {
|
||||
hash[i] <== eMsgInBits[(EM_LEN_BITS) - HASH_TYPE - 8 + i];
|
||||
}
|
||||
|
||||
//getting mask
|
||||
if (HASH_TYPE == 256) {
|
||||
component MGF1_256 = Mgf1Sha256(HASH_LEN, DB_MASK_LEN);
|
||||
|
||||
for (var i = 0; i < (HASH_TYPE); i++) {
|
||||
MGF1_256.seed[i] <== hash[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
dbMask[i] <== MGF1_256.out[i];
|
||||
}
|
||||
}
|
||||
if (HASH_TYPE == 384) {
|
||||
component MGF1_384 = Mgf1Sha384(HASH_LEN, DB_MASK_LEN);
|
||||
|
||||
for (var i = 0; i < (HASH_TYPE); i++) {
|
||||
MGF1_384.seed[i] <== hash[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
dbMask[i] <== MGF1_384.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
component xor = Xor2(DB_MASK_LEN * 8);
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
xor.in1[i] <== maskedDB[i];
|
||||
xor.in2[i] <== dbMask[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
//setting the first leftmost byte to 0
|
||||
if (i == 0) {
|
||||
db[i] <== 0;
|
||||
} else {
|
||||
db[i] <== xor.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
//inserting salt
|
||||
for (var i = 0; i < SALT_LEN_BITS; i++) {
|
||||
salt[SALT_LEN_BITS - 1 - i] <== db[(DB_MASK_LEN * 8) - 1 - i];
|
||||
}
|
||||
|
||||
signal mDash[1024];
|
||||
//adding 0s
|
||||
for (var i = 0; i < 64; i++) {
|
||||
mDash[i] <== 0;
|
||||
}
|
||||
|
||||
//adding message hash
|
||||
for (var i = 0; i < HASH_LEN * 8; i++) {
|
||||
mDash[64 + i] <== hashed[i];
|
||||
|
||||
}
|
||||
|
||||
//adding salt
|
||||
for (var i = 0; i < SALT_LEN * 8; i++) {
|
||||
mDash[64 + HASH_LEN * 8 + i] <== salt[i];
|
||||
}
|
||||
|
||||
if (HASH_TYPE == 256 && SALT_LEN == 32) {
|
||||
//adding padding
|
||||
//len = 64+512 = 576 = 1001000000
|
||||
for (var i = 577; i < 1014; i++) {
|
||||
mDash[i] <== 0;
|
||||
}
|
||||
|
||||
mDash[576] <== 1;
|
||||
mDash[1023] <== 0;
|
||||
mDash[1022] <== 0;
|
||||
mDash[1021] <== 0;
|
||||
mDash[1020] <== 0;
|
||||
mDash[1019] <== 0;
|
||||
mDash[1018] <== 0;
|
||||
mDash[1017] <== 1;
|
||||
mDash[1016] <== 0;
|
||||
mDash[1015] <== 0;
|
||||
mDash[1014] <== 1;
|
||||
|
||||
//hashing
|
||||
component hDash256 = ShaHashChunks(2, HASH_TYPE);
|
||||
hDash256.in <== mDash;
|
||||
|
||||
hDash256.out === hash;
|
||||
}
|
||||
if (HASH_TYPE == 256 && SALT_LEN == 64) {
|
||||
for (var i = 833; i < 1014; i++) {
|
||||
mDash[i] <== 0;
|
||||
}
|
||||
|
||||
mDash[832] <== 1;
|
||||
mDash[1023] <== 0;
|
||||
mDash[1022] <== 0;
|
||||
mDash[1021] <== 0;
|
||||
mDash[1020] <== 0;
|
||||
mDash[1019] <== 0;
|
||||
mDash[1018] <== 0;
|
||||
mDash[1017] <== 1;
|
||||
mDash[1016] <== 0;
|
||||
mDash[1015] <== 1;
|
||||
mDash[1014] <== 1;
|
||||
|
||||
component hDash256 = ShaHashChunks(2, HASH_TYPE);
|
||||
hDash256.in <== mDash;
|
||||
|
||||
hDash256.out === hash;
|
||||
}
|
||||
|
||||
if (HASH_TYPE == 384 && SALT_LEN == 48) {
|
||||
//padding
|
||||
//len = 64+48*16 = 832 = 1101000000
|
||||
for (var i = 833; i < 1014; i++) {
|
||||
mDash[i] <== 0;
|
||||
}
|
||||
|
||||
mDash[832] <== 1;
|
||||
mDash[1023] <== 0;
|
||||
mDash[1022] <== 0;
|
||||
mDash[1021] <== 0;
|
||||
mDash[1020] <== 0;
|
||||
mDash[1019] <== 0;
|
||||
mDash[1018] <== 0;
|
||||
mDash[1017] <== 1;
|
||||
mDash[1016] <== 0;
|
||||
mDash[1015] <== 1;
|
||||
mDash[1014] <== 1;
|
||||
|
||||
//hashing mDash
|
||||
component hDash384 = ShaHashChunks(1, HASH_TYPE);
|
||||
hDash384.in <== mDash;
|
||||
|
||||
hDash384.out === hash;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,473 @@
|
||||
pragma circom 2.1.6;
|
||||
|
||||
include "../../bigInt/bigInt.circom";
|
||||
include "./mgf1.circom";
|
||||
include "../../bitify/gates.circom";
|
||||
include "../../hasher/hash.circom";
|
||||
include "../FpPowMod.circom";
|
||||
|
||||
/*
|
||||
* Verification for RSAPSS signature.
|
||||
* hashed is hashed message of hash_type algo, hash_type is algo hash algo for mgf1 mask generation.
|
||||
* There is no assert for CHUNK_SIZE == 64 and it may work with other chunking, but this one wasn`t tested,
|
||||
* so better use 64 signature and pubkey - chunked numbers (CHUNK_SIZE, CHUNK_NUMBER).
|
||||
* default exp = 65537
|
||||
* SALT_LEN is salt lenght in bytes! (NOT IN BITES LIKE HASH_TYPE!).
|
||||
* This is because salt len can`t be % 8 != 0 so we use bytes len (8 bites).
|
||||
* For now, only HASH_TYPE == 384 && SALT_LEN == 48, HASH_TYPE == 256 && SALT_LEN == 64, HASH_TYPE == 256 && SALT_LEN == 32 cases supported.
|
||||
* Use this for CHUNK_NUMBER == 2**n, otherwise error will occur.
|
||||
|
||||
* Singature length will not exceed the modulus length of the public key (which is the keylength), because the signature is
|
||||
* calculated as mod Modulus_of_pubkey .
|
||||
*/
|
||||
template VerifyRsaPss65537Sig(CHUNK_SIZE, CHUNK_NUMBER, SALT_LEN, HASH_TYPE, KEY_LENGTH) {
|
||||
assert((HASH_TYPE == 384 && SALT_LEN == 48) || (HASH_TYPE == 256 && SALT_LEN == 64) || (HASH_TYPE == 256 && SALT_LEN == 32));
|
||||
|
||||
signal input pubkey[CHUNK_NUMBER];
|
||||
signal input signature[CHUNK_NUMBER];
|
||||
signal input hashed[HASH_TYPE];
|
||||
|
||||
|
||||
var EM_LEN = KEY_LENGTH \ 8;
|
||||
|
||||
var HASH_LEN = HASH_TYPE \ 8;
|
||||
var SALT_LEN_BITS = SALT_LEN * 8;
|
||||
var EM_LEN_BITS = KEY_LENGTH;
|
||||
|
||||
signal eM[EM_LEN];
|
||||
signal eMsgInBits[EM_LEN_BITS];
|
||||
|
||||
//computing encoded message
|
||||
component bigPow = FpPow65537Mod(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++) {
|
||||
bigPow.base[i] <== signature[i];
|
||||
bigPow.modulus[i] <== pubkey[i];
|
||||
}
|
||||
|
||||
signal encoded[CHUNK_NUMBER];
|
||||
encoded <== bigPow.out;
|
||||
|
||||
component num2Bits[CHUNK_NUMBER];
|
||||
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++) {
|
||||
num2Bits[i] = Num2Bits(CHUNK_SIZE);
|
||||
num2Bits[i].in <== encoded[CHUNK_NUMBER - 1 - i];
|
||||
|
||||
for (var j = 0; j < CHUNK_SIZE; j++) {
|
||||
var sourcePos = i * CHUNK_SIZE + j;
|
||||
var targetPos = sourcePos - (CHUNK_NUMBER * CHUNK_SIZE - EM_LEN_BITS);
|
||||
if (targetPos >= 0 && targetPos < EM_LEN_BITS) {
|
||||
eMsgInBits[targetPos] <== num2Bits[i].out[CHUNK_SIZE - j - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component bits2Num[EM_LEN];
|
||||
|
||||
for (var i = 0; i < EM_LEN; i++) {
|
||||
bits2Num[i] = Bits2Num(8);
|
||||
|
||||
for (var j = 0; j < 8; j++) {
|
||||
bits2Num[i].in[7 - j] <== eMsgInBits[i * 8 + j];
|
||||
}
|
||||
|
||||
eM[EM_LEN - i - 1] <== bits2Num[i].out;
|
||||
}
|
||||
|
||||
//should be more than HLEN + SLEN + 2
|
||||
assert(EM_LEN >= HASH_LEN + SALT_LEN + 2);
|
||||
|
||||
//should end with 0xBC (188 in decimal)
|
||||
assert(eM[0] == 188);
|
||||
|
||||
var DB_MASK_LEN = EM_LEN - HASH_LEN - 1;
|
||||
|
||||
signal dbMask[DB_MASK_LEN * 8];
|
||||
signal db[DB_MASK_LEN * 8];
|
||||
signal salt[SALT_LEN * 8];
|
||||
signal maskedDB[(EM_LEN - HASH_LEN - 1) * 8];
|
||||
|
||||
for (var i = 0; i < (EM_LEN - HASH_LEN - 1) * 8; i++) {
|
||||
maskedDB[i] <== eMsgInBits[i];
|
||||
}
|
||||
|
||||
signal hash[HASH_LEN * 8];
|
||||
|
||||
//inserting hash
|
||||
for (var i = 0; i < HASH_TYPE; i++) {
|
||||
hash[i] <== eMsgInBits[(EM_LEN_BITS) - HASH_TYPE - 8 + i];
|
||||
}
|
||||
|
||||
//getting mask
|
||||
if (HASH_TYPE == 256) {
|
||||
component MGF1_256 = Mgf1Sha256(HASH_LEN, DB_MASK_LEN);
|
||||
|
||||
for (var i = 0; i < (HASH_TYPE); i++) {
|
||||
MGF1_256.seed[i] <== hash[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
dbMask[i] <== MGF1_256.out[i];
|
||||
}
|
||||
}
|
||||
if (HASH_TYPE == 384) {
|
||||
component MGF1_384 = Mgf1Sha384(HASH_LEN, DB_MASK_LEN);
|
||||
|
||||
for (var i = 0; i < (HASH_TYPE); i++) {
|
||||
MGF1_384.seed[i] <== hash[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
dbMask[i] <== MGF1_384.out[i];
|
||||
}
|
||||
}
|
||||
if (HASH_TYPE == 512) {
|
||||
component MGF1_512 = Mgf1Sha512(HASH_LEN, DB_MASK_LEN);
|
||||
|
||||
for (var i = 0; i < (HASH_TYPE); i++) {
|
||||
MGF1_512.seed[i] <== hash[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
dbMask[i] <== MGF1_512.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
component xor = Xor2(DB_MASK_LEN * 8);
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
xor.in1[i] <== maskedDB[i];
|
||||
xor.in2[i] <== dbMask[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
//setting the first leftmost byte to 0
|
||||
if (i == 0) {
|
||||
db[i] <== 0;
|
||||
} else {
|
||||
db[i] <== xor.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
//inserting salt
|
||||
for (var i = 0; i < SALT_LEN_BITS; i++) {
|
||||
salt[SALT_LEN_BITS - 1 - i] <== db[(DB_MASK_LEN * 8) - 1 - i];
|
||||
}
|
||||
|
||||
signal mDash[2048];
|
||||
//adding 0s
|
||||
for (var i = 0; i < 64; i++) {
|
||||
mDash[i] <== 0;
|
||||
}
|
||||
|
||||
//adding message hash
|
||||
for (var i = 0; i < HASH_LEN * 8; i++) {
|
||||
mDash[64 + i] <== hashed[i];
|
||||
}
|
||||
|
||||
//adding salt
|
||||
for (var i = 0; i < SALT_LEN * 8; i++) {
|
||||
mDash[64 + HASH_LEN * 8 + i] <== salt[i];
|
||||
}
|
||||
|
||||
if (HASH_TYPE == 256 && SALT_LEN == 32) {
|
||||
//adding padding
|
||||
//len = 64+512 = 576 = 1001000000
|
||||
for (var i = 577; i < 1014; i++) {
|
||||
mDash[i] <== 0;
|
||||
}
|
||||
|
||||
mDash[576] <== 1;
|
||||
mDash[1023] <== 0;
|
||||
mDash[1022] <== 0;
|
||||
mDash[1021] <== 0;
|
||||
mDash[1020] <== 0;
|
||||
mDash[1019] <== 0;
|
||||
mDash[1018] <== 0;
|
||||
mDash[1017] <== 1;
|
||||
mDash[1016] <== 0;
|
||||
mDash[1015] <== 0;
|
||||
mDash[1014] <== 1;
|
||||
|
||||
signal mDash256[1024];
|
||||
for (var i = 0; i < 1024; i++){
|
||||
mDash256[i] <== mDash[i];
|
||||
}
|
||||
|
||||
//hashing
|
||||
component hDash256 = ShaHashChunks(2, HASH_TYPE);
|
||||
hDash256.in <== mDash256;
|
||||
|
||||
hDash256.out === hash;
|
||||
}
|
||||
|
||||
if (HASH_TYPE == 256 && SALT_LEN == 64) {
|
||||
for (var i = 833; i < 1014; i++) {
|
||||
mDash[i] <== 0;
|
||||
}
|
||||
|
||||
mDash[832] <== 1;
|
||||
mDash[1023] <== 0;
|
||||
mDash[1022] <== 0;
|
||||
mDash[1021] <== 0;
|
||||
mDash[1020] <== 0;
|
||||
mDash[1019] <== 0;
|
||||
mDash[1018] <== 0;
|
||||
mDash[1017] <== 1;
|
||||
mDash[1016] <== 0;
|
||||
mDash[1015] <== 1;
|
||||
mDash[1014] <== 1;
|
||||
|
||||
signal mDash256[1024];
|
||||
for (var i = 0; i < 1024; i++){
|
||||
mDash256[i] <== mDash[i];
|
||||
}
|
||||
|
||||
component hDash256 = ShaHashChunks(2, HASH_TYPE);
|
||||
hDash256.in <== mDash256;
|
||||
|
||||
hDash256.out === hash;
|
||||
}
|
||||
|
||||
if (HASH_TYPE == 384 && SALT_LEN == 48) {
|
||||
//padding
|
||||
//len = 64+(48*8)+384 = 832 = 1101000000
|
||||
|
||||
component hDash384 = ShaHashBits(64 + SALT_LEN_BITS + HASH_LEN * 8, 384);
|
||||
for (var i = 0; i < 832; i++) {
|
||||
hDash384.in[i] <== mDash[i];
|
||||
}
|
||||
|
||||
hDash384.out === hash;
|
||||
}
|
||||
if (HASH_TYPE == 512 && SALT_LEN == 64) {
|
||||
// 64 + 512 + 512 = 1088
|
||||
component hDash512 = ShaHashBits(64 + SALT_LEN_BITS + HASH_LEN * 8, 512);
|
||||
|
||||
for (var i = 0; i < 1088; i++) {
|
||||
hDash512.in[i] <== mDash[i];
|
||||
}
|
||||
|
||||
hDash512.out === hash;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verification for RSAPSS signature.
|
||||
* hashed is hashed message of hash_type algo, hash_type is algo hash algo for mgf1 mask generation.
|
||||
* There is no assert for CHUNK_SIZE == 64 and it may work with other chunking, but this one wasn`t tested,
|
||||
* so better use 64 signature and pubkey - chunked numbers (CHUNK_SIZE, CHUNK_NUMBER).
|
||||
* e_bits - Len of bit representation of exponent with 1 highest and lowest bits, other are 0 (2^(e_bits - 1) + 1).
|
||||
* default exp = 65537 (e_bits = 17)
|
||||
* SALT_LEN is salt lenght in bytes! (NOT IN BITES LIKE HASH_TYPE!)
|
||||
* This is because salt len can`t be % 8 != 0 so we use bytes len (8 bites).
|
||||
* For now, only HASH_TYPE == 384 && SALT_LEN == 48, HASH_TYPE == 256 && SALT_LEN == 64, HASH_TYPE == 256 && SALT_LEN == 32 cases supported.
|
||||
* Use this for CHUNK_NUMBER != 2**n, otherwise use previous template.
|
||||
*/
|
||||
template VerifyRsaPss65537SigNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, SALT_LEN, EXP, HASH_TYPE) {
|
||||
assert((HASH_TYPE == 384 && SALT_LEN == 48) || (HASH_TYPE == 256 && SALT_LEN == 64) || (HASH_TYPE == 256 && SALT_LEN == 32));
|
||||
|
||||
signal input pubkey[CHUNK_NUMBER];
|
||||
signal input signature[CHUNK_NUMBER];
|
||||
signal input hashed[HASH_TYPE];
|
||||
|
||||
|
||||
var EM_LEN = (CHUNK_SIZE * CHUNK_NUMBER) \ 8;
|
||||
var HASH_LEN = HASH_TYPE \ 8;
|
||||
var SALT_LEN_BITS = SALT_LEN * 8;
|
||||
var EM_LEN_BITS = CHUNK_SIZE * CHUNK_NUMBER;
|
||||
|
||||
signal eM[EM_LEN];
|
||||
signal eMsgInBits[EM_LEN_BITS];
|
||||
|
||||
//computing encoded message
|
||||
component powerMod;
|
||||
powerMod = PowerModNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, EXP);
|
||||
powerMod.base <== signature;
|
||||
powerMod.modulus <== pubkey;
|
||||
|
||||
signal encoded[CHUNK_NUMBER];
|
||||
encoded <== powerMod.out;
|
||||
|
||||
component num2Bits[CHUNK_NUMBER];
|
||||
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++) {
|
||||
num2Bits[i] = Num2Bits(CHUNK_SIZE);
|
||||
num2Bits[i].in <== encoded[CHUNK_NUMBER - 1 - i];
|
||||
|
||||
for (var j = 0; j < CHUNK_SIZE; j++) {
|
||||
eMsgInBits[i * CHUNK_SIZE + j] <== num2Bits[i].out[CHUNK_SIZE - j - 1];
|
||||
}
|
||||
}
|
||||
|
||||
component bits2Num[EM_LEN];
|
||||
|
||||
for (var i = 0; i < EM_LEN; i++) {
|
||||
bits2Num[i] = Bits2Num(8);
|
||||
|
||||
for (var j = 0; j < 8; j++) {
|
||||
bits2Num[i].in[7 - j] <== eMsgInBits[i * 8 + j];
|
||||
}
|
||||
|
||||
eM[EM_LEN - i - 1] <== bits2Num[i].out;
|
||||
}
|
||||
|
||||
//should be more than HLEN + SLEN + 2
|
||||
assert(EM_LEN >= HASH_LEN + SALT_LEN + 2);
|
||||
|
||||
//should end with 0xBC (188 in decimal)
|
||||
assert(eM[0] == 188);
|
||||
|
||||
var DB_MASK_LEN = EM_LEN - HASH_LEN - 1;
|
||||
signal dbMask[DB_MASK_LEN * 8];
|
||||
signal db[DB_MASK_LEN * 8];
|
||||
signal salt[SALT_LEN * 8];
|
||||
signal maskedDB[(EM_LEN - HASH_LEN - 1) * 8];
|
||||
|
||||
for (var i = 0; i < (EM_LEN - HASH_LEN - 1) * 8; i++) {
|
||||
maskedDB[i] <== eMsgInBits[i];
|
||||
}
|
||||
|
||||
signal hash[HASH_LEN * 8];
|
||||
|
||||
//inserting hash
|
||||
for (var i = 0; i < HASH_TYPE; i++) {
|
||||
hash[i] <== eMsgInBits[(EM_LEN_BITS) - HASH_TYPE - 8 + i];
|
||||
}
|
||||
|
||||
//getting mask
|
||||
if (HASH_TYPE == 256) {
|
||||
component MGF1_256 = Mgf1Sha256(HASH_LEN, DB_MASK_LEN);
|
||||
|
||||
for (var i = 0; i < (HASH_TYPE); i++) {
|
||||
MGF1_256.seed[i] <== hash[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
dbMask[i] <== MGF1_256.out[i];
|
||||
}
|
||||
}
|
||||
if (HASH_TYPE == 384) {
|
||||
component MGF1_384 = Mgf1Sha384(HASH_LEN, DB_MASK_LEN);
|
||||
|
||||
for (var i = 0; i < (HASH_TYPE); i++) {
|
||||
MGF1_384.seed[i] <== hash[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
dbMask[i] <== MGF1_384.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
component xor = Xor2(DB_MASK_LEN * 8);
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
xor.in1[i] <== maskedDB[i];
|
||||
xor.in2[i] <== dbMask[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < DB_MASK_LEN * 8; i++) {
|
||||
//setting the first leftmost byte to 0
|
||||
if (i == 0) {
|
||||
db[i] <== 0;
|
||||
} else {
|
||||
db[i] <== xor.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
//inserting salt
|
||||
for (var i = 0; i < SALT_LEN_BITS; i++) {
|
||||
salt[SALT_LEN_BITS - 1 - i] <== db[(DB_MASK_LEN * 8) - 1 - i];
|
||||
}
|
||||
|
||||
signal mDash[1024];
|
||||
//adding 0s
|
||||
for (var i = 0; i < 64; i++) {
|
||||
mDash[i] <== 0;
|
||||
}
|
||||
|
||||
//adding message hash
|
||||
for (var i = 0; i < HASH_LEN * 8; i++) {
|
||||
mDash[64 + i] <== hashed[i];
|
||||
|
||||
}
|
||||
|
||||
//adding salt
|
||||
for (var i = 0; i < SALT_LEN * 8; i++) {
|
||||
mDash[64 + HASH_LEN * 8 + i] <== salt[i];
|
||||
}
|
||||
|
||||
if (HASH_TYPE == 256 && SALT_LEN == 32) {
|
||||
//adding padding
|
||||
//len = 64+512 = 576 = 1001000000
|
||||
for (var i = 577; i < 1014; i++) {
|
||||
mDash[i] <== 0;
|
||||
}
|
||||
|
||||
mDash[576] <== 1;
|
||||
mDash[1023] <== 0;
|
||||
mDash[1022] <== 0;
|
||||
mDash[1021] <== 0;
|
||||
mDash[1020] <== 0;
|
||||
mDash[1019] <== 0;
|
||||
mDash[1018] <== 0;
|
||||
mDash[1017] <== 1;
|
||||
mDash[1016] <== 0;
|
||||
mDash[1015] <== 0;
|
||||
mDash[1014] <== 1;
|
||||
|
||||
//hashing
|
||||
component hDash256 = ShaHashChunks(2, HASH_TYPE);
|
||||
hDash256.in <== mDash;
|
||||
|
||||
hDash256.out === hash;
|
||||
}
|
||||
if (HASH_TYPE == 256 && SALT_LEN == 64) {
|
||||
for (var i = 833; i < 1014; i++) {
|
||||
mDash[i] <== 0;
|
||||
}
|
||||
|
||||
mDash[832] <== 1;
|
||||
mDash[1023] <== 0;
|
||||
mDash[1022] <== 0;
|
||||
mDash[1021] <== 0;
|
||||
mDash[1020] <== 0;
|
||||
mDash[1019] <== 0;
|
||||
mDash[1018] <== 0;
|
||||
mDash[1017] <== 1;
|
||||
mDash[1016] <== 0;
|
||||
mDash[1015] <== 1;
|
||||
mDash[1014] <== 1;
|
||||
|
||||
component hDash256 = ShaHashChunks(2, HASH_TYPE);
|
||||
hDash256.in <== mDash;
|
||||
|
||||
hDash256.out === hash;
|
||||
}
|
||||
|
||||
if (HASH_TYPE == 384 && SALT_LEN == 48) {
|
||||
//padding
|
||||
//len = 64+48*16 = 832 = 1101000000
|
||||
for (var i = 833; i < 1014; i++) {
|
||||
mDash[i] <== 0;
|
||||
}
|
||||
|
||||
mDash[832] <== 1;
|
||||
mDash[1023] <== 0;
|
||||
mDash[1022] <== 0;
|
||||
mDash[1021] <== 0;
|
||||
mDash[1020] <== 0;
|
||||
mDash[1019] <== 0;
|
||||
mDash[1018] <== 0;
|
||||
mDash[1017] <== 1;
|
||||
mDash[1016] <== 0;
|
||||
mDash[1015] <== 1;
|
||||
mDash[1014] <== 1;
|
||||
|
||||
//hashing mDash
|
||||
component hDash384 = ShaHashChunks(1, HASH_TYPE);
|
||||
hDash384.in <== mDash;
|
||||
|
||||
hDash384.out === hash;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../circomlib/signature/rsapss/rsapss.circom";
|
||||
include "../circomlib/signature/rsapss/rsapss3.circom";
|
||||
include "../circomlib/signature/rsapss/rsapss65537.circom";
|
||||
include "ecdsaVerifier.circom";
|
||||
include "../circomlib/signature/rsa/verifyRsa3Pkcs1v1_5.circom";
|
||||
include "../circomlib/signature/rsa/verifyRsa65537Pkcs1v1_5.circom";
|
||||
@@ -47,30 +48,35 @@ template SignatureVerifier(signatureAlgorithm, n, k) {
|
||||
|
||||
if (
|
||||
signatureAlgorithm == 4
|
||||
|| signatureAlgorithm == 12
|
||||
|| signatureAlgorithm == 16
|
||||
|| signatureAlgorithm == 17
|
||||
|| signatureAlgorithm == 12
|
||||
|| signatureAlgorithm == 18
|
||||
|| signatureAlgorithm == 19
|
||||
) {
|
||||
var pubKeyBitsLength = getKeyLength(signatureAlgorithm);
|
||||
var SALT_LEN = HASH_LEN_BITS / 8;
|
||||
var E_BITS = getExponentBits(signatureAlgorithm);
|
||||
var EXP;
|
||||
if (E_BITS == 17) {
|
||||
EXP = 65537;
|
||||
} else {
|
||||
EXP = 3;
|
||||
}
|
||||
|
||||
component rsaPssShaVerification = VerifyRsaPssSig(n, k, SALT_LEN, EXP, HASH_LEN_BITS);
|
||||
rsaPssShaVerification.pubkey <== pubKey;
|
||||
rsaPssShaVerification.signature <== signature;
|
||||
rsaPssShaVerification.hashed <== hash; // send the raw hash
|
||||
component rsaPss65537ShaVerification = VerifyRsaPss65537Sig(n, k, SALT_LEN, HASH_LEN_BITS, pubKeyBitsLength);
|
||||
rsaPss65537ShaVerification.pubkey <== pubKey;
|
||||
rsaPss65537ShaVerification.signature <== signature;
|
||||
rsaPss65537ShaVerification.hashed <== hash; // send the raw hash
|
||||
|
||||
}
|
||||
if (
|
||||
signatureAlgorithm == 7
|
||||
signatureAlgorithm == 16
|
||||
|| signatureAlgorithm == 17
|
||||
) {
|
||||
var pubKeyBitsLength = getKeyLength(signatureAlgorithm);
|
||||
var SALT_LEN = HASH_LEN_BITS / 8;
|
||||
var E_BITS = getExponentBits(signatureAlgorithm);
|
||||
|
||||
component rsaPss3ShaVerification = VerifyRsaPss3Sig(n, k, SALT_LEN, HASH_LEN_BITS, pubKeyBitsLength);
|
||||
rsaPss3ShaVerification.pubkey <== pubKey;
|
||||
rsaPss3ShaVerification.signature <== signature;
|
||||
rsaPss3ShaVerification.hashed <== hash; // send the raw hash
|
||||
|
||||
}
|
||||
if (signatureAlgorithm == 9
|
||||
|| signatureAlgorithm == 7
|
||||
|| signatureAlgorithm == 8
|
||||
|| signatureAlgorithm == 9
|
||||
|| signatureAlgorithm == 21
|
||||
@@ -107,6 +113,7 @@ template SignatureVerifier(signatureAlgorithm, n, k) {
|
||||
}
|
||||
rsa.modulus <== pubKey;
|
||||
rsa.signature <== signature;
|
||||
|
||||
}
|
||||
if (signatureAlgorithm == 12) {
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"test-dsc": "yarn ts-mocha --max-old-space-size=8192 'tests/dsc.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",
|
||||
"test-rsa-pss": "yarn ts-mocha --max-old-space-size=8192 'tests/utils/rsapss.test.ts' --exit",
|
||||
"install-circuits": "cd ../common && yarn && cd ../circuits && yarn",
|
||||
"format": "prettier --write .",
|
||||
"lint": "prettier --check ."
|
||||
|
||||
@@ -238,7 +238,6 @@ const fullSigAlgs = [
|
||||
];
|
||||
|
||||
const testSuite = process.env.FULL_TEST_SUITE === 'true' ? fullSigAlgs : sigAlgs;
|
||||
// const testSuite = fullSigAlgs;
|
||||
|
||||
testSuite.forEach(
|
||||
({
|
||||
|
||||
95
circuits/tests/utils/generateMockInputsRsaPss.ts
Normal file
95
circuits/tests/utils/generateMockInputsRsaPss.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import * as forge from 'node-forge';
|
||||
import {
|
||||
splitToWords,
|
||||
hexToDecimal,
|
||||
bytesToBigDecimal,
|
||||
getNAndK,
|
||||
} from '../../../common/src/utils/utils';
|
||||
import { SignatureAlgorithm } from '../../../common/src/utils/types';
|
||||
|
||||
export const generateMockRsaPssInputs = (signatureAlgorithm: SignatureAlgorithm) => {
|
||||
let saltLength: number;
|
||||
|
||||
const [sigAlg, hashAlgorithm, exponent, modulusLength] = signatureAlgorithm.split('_');
|
||||
|
||||
switch (signatureAlgorithm) {
|
||||
case 'rsapss_sha256_65537_4096':
|
||||
saltLength = 32;
|
||||
break;
|
||||
case 'rsapss_sha256_65537_3072':
|
||||
saltLength = 32;
|
||||
break;
|
||||
case 'rsapss_sha256_65537_2048':
|
||||
saltLength = 32;
|
||||
break;
|
||||
case 'rsapss_sha256_3_4096':
|
||||
saltLength = 32;
|
||||
break;
|
||||
case 'rsapss_sha256_3_3072':
|
||||
saltLength = 32;
|
||||
break;
|
||||
case 'rsapss_sha256_3_2048':
|
||||
saltLength = 32;
|
||||
break;
|
||||
case 'rsapss_sha512_3_4096':
|
||||
saltLength = 64;
|
||||
break;
|
||||
case 'rsapss_sha512_3_2048':
|
||||
saltLength = 64;
|
||||
break;
|
||||
case 'rsapss_sha384_65537_4096':
|
||||
saltLength = 48;
|
||||
break;
|
||||
case 'rsapss_sha384_65537_3072':
|
||||
saltLength = 48;
|
||||
break;
|
||||
case 'rsapss_sha384_3_4096':
|
||||
saltLength = 48;
|
||||
break;
|
||||
case 'rsapss_sha384_3_3072':
|
||||
saltLength = 48;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`Unsupported signature algorithm: ${signatureAlgorithm}`);
|
||||
}
|
||||
|
||||
// Generate RSA key pair
|
||||
const keypair = forge.pki.rsa.generateKeyPair({
|
||||
bits: parseInt(modulusLength),
|
||||
e: parseInt(exponent),
|
||||
});
|
||||
const message = 'helloworld';
|
||||
|
||||
// Create message hash
|
||||
const md = forge.md[hashAlgorithm].create();
|
||||
md.update(forge.util.binary.raw.encode(Buffer.from(message)));
|
||||
const messageHash = md.digest().bytes();
|
||||
const messageBits = Array.from(messageHash)
|
||||
.map((char: string) => {
|
||||
const byte = char.charCodeAt(0);
|
||||
return Array.from({ length: 8 }, (_, i) => (byte >> (7 - i)) & 1);
|
||||
})
|
||||
.flat();
|
||||
|
||||
// Create PSS signature
|
||||
const pss = forge.pss.create({
|
||||
md: forge.md[hashAlgorithm].create(),
|
||||
mgf: forge.mgf.mgf1.create(forge.md[hashAlgorithm].create()),
|
||||
saltLength,
|
||||
});
|
||||
const signatureBytes = keypair.privateKey.sign(md, pss);
|
||||
const signature = Array.from(signatureBytes, (c: string) => c.charCodeAt(0));
|
||||
|
||||
// Get modulus from public key
|
||||
const modulus = keypair.publicKey.n.toString(16);
|
||||
|
||||
const { n, k } = getNAndK(signatureAlgorithm);
|
||||
|
||||
return {
|
||||
signature: splitToWords(BigInt(bytesToBigDecimal(signature)), n, k),
|
||||
modulus: splitToWords(BigInt(hexToDecimal(modulus)), n, k),
|
||||
message: messageBits,
|
||||
saltLength: saltLength,
|
||||
};
|
||||
};
|
||||
54
circuits/tests/utils/rsapss.test.ts
Normal file
54
circuits/tests/utils/rsapss.test.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { wasm as wasmTester } from 'circom_tester';
|
||||
import { describe, it } from 'mocha';
|
||||
import path from 'path';
|
||||
import { SignatureAlgorithm } from '../../../common/src/utils/types';
|
||||
import { generateMockRsaPssInputs } from './generateMockInputsRsaPss';
|
||||
|
||||
describe('VerifyRsapss Circuit Test', function () {
|
||||
this.timeout(0);
|
||||
const rsaAlgorithms: SignatureAlgorithm[] = [
|
||||
'rsapss_sha256_65537_4096',
|
||||
'rsapss_sha256_65537_3072',
|
||||
'rsapss_sha256_65537_2048',
|
||||
'rsapss_sha256_3_4096',
|
||||
'rsapss_sha256_3_3072',
|
||||
'rsapss_sha256_3_2048',
|
||||
'rsapss_sha512_3_4096',
|
||||
'rsapss_sha512_3_2048',
|
||||
'rsapss_sha384_65537_4096',
|
||||
'rsapss_sha384_65537_3072',
|
||||
'rsapss_sha384_3_4096',
|
||||
'rsapss_sha384_3_3072',
|
||||
];
|
||||
|
||||
rsaAlgorithms.forEach((algorithm) => {
|
||||
it(`should verify RSA signature using the circuit for ${algorithm}`, async function () {
|
||||
this.timeout(0);
|
||||
// Generate inputs using the utility function
|
||||
const { signature, modulus, message, saltLength } = generateMockRsaPssInputs(algorithm);
|
||||
|
||||
// Run circuit with inputs
|
||||
const circuit = await wasmTester(
|
||||
path.join(
|
||||
__dirname,
|
||||
`../../circuits/tests/utils/rsapss/test_${algorithm}_${saltLength}.circom`
|
||||
),
|
||||
{
|
||||
include: ['node_modules', './node_modules/@zk-kit/binary-merkle-root.circom/src'],
|
||||
}
|
||||
);
|
||||
|
||||
// Log the inputs for debugging
|
||||
console.log(`Testing algorithm: ${algorithm}`);
|
||||
|
||||
const witness = await circuit.calculateWitness({
|
||||
signature,
|
||||
modulus,
|
||||
message,
|
||||
});
|
||||
|
||||
// Check constraints
|
||||
await circuit.checkConstraints(witness);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -13,32 +13,37 @@ export type PassportData = {
|
||||
|
||||
// Define the signature algorithm in "algorithm_hashfunction_domainPapameter_keyLength"
|
||||
export type SignatureAlgorithm =
|
||||
| 'rsa_sha1_65537_2048'
|
||||
| 'rsa_sha256_65537_2048'
|
||||
| 'rsapss_sha256_65537_2048'
|
||||
| 'rsapss_sha256_3_4096'
|
||||
| 'rsapss_sha256_3_3072'
|
||||
| 'rsapss_sha384_65537_3072'
|
||||
| 'rsapss_sha384_65537_4096'
|
||||
| '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';
|
||||
| 'rsa_sha1_65537_2048'
|
||||
| 'rsa_sha256_65537_2048'
|
||||
| 'rsapss_sha256_65537_2048'
|
||||
| 'rsapss_sha256_3_4096'
|
||||
| 'rsapss_sha256_3_3072'
|
||||
| 'rsapss_sha384_65537_3072'
|
||||
| 'rsapss_sha384_65537_4096'
|
||||
| 'ecdsa_sha256_secp256r1_256'
|
||||
| 'ecdsa_sha1_secp256r1_256'
|
||||
| 'ecdsa_sha384_secp384r1_384'
|
||||
| 'ecdsa_sha256_brainpoolP256r1_256'
|
||||
| 'rsa_sha256_3_2048'
|
||||
| 'rsa_sha256_65537_3072'
|
||||
| 'rsa_sha256_65537_4096'
|
||||
| 'rsa_sha512_65537_4096'
|
||||
| 'rsapss_sha256_65537_3072'
|
||||
| 'rsapss_sha256_65537_4096'
|
||||
| 'rsapss_sha256_3_2048'
|
||||
| 'rsapss_sha512_3_4096'
|
||||
| 'rsapss_sha512_3_2048'
|
||||
| 'rsapss_sha384_3_4096'
|
||||
| 'rsapss_sha384_3_3072'
|
||||
| 'ecdsa_sha256_secp384r1_384'
|
||||
| 'ecdsa_sha384_brainpoolP256r1_256'
|
||||
| 'ecdsa_sha512_brainpoolP256r1_256'
|
||||
| 'ecdsa_sha384_brainpoolP384r1_384'
|
||||
| 'ecdsa_sha512_brainpoolP384r1_384'
|
||||
| 'ecdsa_sha1_brainpoolP224r1_224'
|
||||
| 'ecdsa_sha224_brainpoolP224r1_224'
|
||||
| 'ecdsa_sha256_brainpoolP224r1_224'
|
||||
| 'ecdsa_sha512_brainpoolP512r1_512'
|
||||
|
||||
export type Proof = {
|
||||
proof: {
|
||||
|
||||
Reference in New Issue
Block a user