Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/dsc rsapss #315

Open
wants to merge 9 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 95 additions & 14 deletions circuits/circuits/dsc/dsc.circom
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,29 @@ include "../utils/passport/signatureAlgorithm.circom";
include "../utils/passport/signatureVerifier.circom";
include "@openpassport/zk-email-circuits/utils/bytes.circom";
include "../utils/crypto/bitify/bytes.circom";
include "../utils/crypto/utils/WordToBytes.circom";

template DSC(signatureAlgorithm, n_dsc, k_dsc, n_csca, k_csca, max_cert_bytes, maxPubkeyBytesLength, nLevels) {

template DSC(signatureAlgorithm, n_dsc, k_dsc, n_csca, k_csca, max_cert_bytes, dscPubkeyBytesLength, nLevels) {
assert(n_dsc * k_dsc == maxPubkeyBytesLength * 8);

// variables verification
assert(max_cert_bytes % 64 == 0);
assert(n_csca * k_csca > max_cert_bytes);
// assert(n_csca * k_csca > max_cert_bytes);
assert(n_csca <= (255 \ 2));

var hashLength = getHashLength(signatureAlgorithm);
var kLengthFactor = getKLengthFactor(signatureAlgorithm);
var kScaled = k_csca * kLengthFactor;
var k_dsc_scaled = k_dsc * kLengthFactor;

signal input raw_dsc_cert[max_cert_bytes];
signal input raw_dsc_cert_padded_bytes;
signal input csca_pubKey[kScaled];
signal input signature[kScaled];
signal input dsc_pubKey[k_dsc];
signal input dsc_pubKey[k_dsc_scaled];
signal input dsc_pubKey_offset;
signal input dsc_pubkey_length_bytes;
signal input secret;

signal input merkle_root;
Expand All @@ -48,18 +52,95 @@ template DSC(signatureAlgorithm, n_dsc, k_dsc, n_csca, k_csca, max_cert_bytes, d

SignatureVerifier(signatureAlgorithm, n_csca, k_csca)(hashedCertificate, csca_pubKey, signature);

// verify DSC csca_pubKey
component shiftLeft = VarShiftLeft(max_cert_bytes, dscPubkeyBytesLength); // use select subarray for dscPubKey variable length
shiftLeft.in <== raw_dsc_cert;
shiftLeft.shift <== dsc_pubKey_offset;
component spbt_1 = SplitBytesToWords(dscPubkeyBytesLength, n_dsc, k_dsc);
spbt_1.in <== shiftLeft.out;
for (var i = 0; i < k_dsc; i++) {
dsc_pubKey[i] === spbt_1.out[i];
signal pubkey_extracted_2[maxPubkeyBytesLength + 1];
signal raw_dsc_cert_reversed[max_cert_bytes];
for (var i=0; i<max_cert_bytes; i++) {
raw_dsc_cert_reversed[i] <== raw_dsc_cert[max_cert_bytes - 1 - i];
}

component shiftLeft2 = VarShiftLeft(max_cert_bytes, maxPubkeyBytesLength);
shiftLeft2.in <== raw_dsc_cert_reversed;
//ecdsa
if (kLengthFactor == 2) {
signal pubkey_x_extracted[maxPubkeyBytesLength + 1];
signal pubkey_y_extracted[maxPubkeyBytesLength + 1];

shiftLeft2.shift <== max_cert_bytes - dsc_pubKey_offset - dsc_pubkey_length_bytes;
pubkey_x_extracted[maxPubkeyBytesLength] <== 0;
for (var i=0; i< maxPubkeyBytesLength; i++) {
pubkey_x_extracted[i] <== shiftLeft2.out[i];
}

component shiftLeft3 = VarShiftLeft(max_cert_bytes, maxPubkeyBytesLength);
shiftLeft3.in <== raw_dsc_cert_reversed;
shiftLeft3.shift <== max_cert_bytes - (dsc_pubKey_offset + dsc_pubkey_length_bytes) - dsc_pubkey_length_bytes;
pubkey_y_extracted[maxPubkeyBytesLength] <== 0;
for (var i=0; i< maxPubkeyBytesLength; i++) {
pubkey_y_extracted[i] <== shiftLeft3.out[i];
}

// component selectX = ByteMaskDynamic(maxPubkeyBytesLength);
// selectX.in <== pubkey_x_extracted;
// selectX.maxValidByte <== dsc_pubkey_length_bytes;
// component selectY = ByteMaskDynamic(maxPubkeyBytesLength);
// selectY.in <== pubkey_y_extracted;
// selectY.maxValidByte <== dsc_pubkey_length_bytes;

component selectX = SelectSubArray(maxPubkeyBytesLength + 1, maxPubkeyBytesLength);
component selectY = SelectSubArray(maxPubkeyBytesLength + 1, maxPubkeyBytesLength);
selectX.in <== pubkey_x_extracted;
selectY.in <== pubkey_y_extracted;
selectX.startIndex <== 0;
selectY.startIndex <== 0;
selectX.length <== dsc_pubkey_length_bytes;
selectY.length <== dsc_pubkey_length_bytes;

component wordsToBytes = WordsToBytes(n_dsc, k_dsc * 2, maxPubkeyBytesLength * 2);
wordsToBytes.words <== dsc_pubKey;
signal dsc_x_8bit[maxPubkeyBytesLength];
signal dsc_y_8bit[maxPubkeyBytesLength];

// Split the output bytes into x and y coordinates
for (var i = 0; i < maxPubkeyBytesLength; i++) {
dsc_x_8bit[i] <== wordsToBytes.bytes[i];
dsc_y_8bit[i] <== wordsToBytes.bytes[i + maxPubkeyBytesLength];
}

// Verify both coordinates match
for (var i = 0; i < maxPubkeyBytesLength; i++) {
dsc_x_8bit[i] === selectX.out[i];
dsc_y_8bit[i] === selectY.out[i];
}
} else {
// verify DSC csca_pubKey
shiftLeft2.shift <== max_cert_bytes - dsc_pubKey_offset - dsc_pubkey_length_bytes;
pubkey_extracted_2[maxPubkeyBytesLength] <== 0;
for (var i=0; i< maxPubkeyBytesLength; i++) {
pubkey_extracted_2[i] <== shiftLeft2.out[i];
}

//More constraints in ByteMaskDynamic than in SelectSubArray
// component byteMask = ByteMaskDynamic(maxPubkeyBytesLength);
// for (var i=0; i< maxPubkeyBytesLength; i++) {
// byteMask.in[i] <== pubkey_extracted_2[i];
// }
// byteMask.maxValidByte <== dsc_pubkey_length_bytes;
component selectSubArray = SelectSubArray(maxPubkeyBytesLength + 1, maxPubkeyBytesLength);
selectSubArray.in <== pubkey_extracted_2;
selectSubArray.startIndex <== 0;
selectSubArray.length <== dsc_pubkey_length_bytes;
signal extracted_pubkey[maxPubkeyBytesLength];
extracted_pubkey <== selectSubArray.out;

component wordsToBytes = WordsToBytes(n_dsc, k_dsc, maxPubkeyBytesLength);
wordsToBytes.words <== dsc_pubKey;

for (var i=0; i<maxPubkeyBytesLength; i++) {
extracted_pubkey[i] === wordsToBytes.bytes[i];
}
}

// blinded dsc commitment
signal pubkeyHash <== CustomHasher(k_dsc)(dsc_pubKey);
signal pubkeyHash <== CustomHasher(k_dsc_scaled)(dsc_pubKey);
signal output blinded_dsc_commitment <== Poseidon(2)([secret, pubkeyHash]);
}

}
5 changes: 5 additions & 0 deletions circuits/circuits/dsc/instances/dsc_rsa_sha1_3_4096.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pragma circom 2.1.9;

include "../dsc.circom";

component main { public [ merkle_root ] } = DSC(33, 120, 35, 120, 35, 1664, 525, 12);
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ pragma circom 2.1.9;

include "../dsc.circom";

component main { public [ merkle_root ] } = DSC(11, 120, 35, 120, 35, 1664, 256, 12);
component main { public [ merkle_root ] } = DSC(11, 120, 35, 120, 35, 1664, 525, 12);
5 changes: 5 additions & 0 deletions circuits/circuits/dsc/instances/dsc_rsa_sha256_3_4096.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pragma circom 2.1.9;

include "../dsc.circom";

component main { public [ merkle_root ] } = DSC(32, 120, 35, 120, 35, 1664, 525, 12);
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ pragma circom 2.1.9;

include "../dsc.circom";

component main { public [ merkle_root ] } = DSC(10, 120, 35, 120, 35, 1664, 256, 12);
component main { public [ merkle_root ] } = DSC(10, 120, 35, 120, 35, 1664, 525, 12);
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pragma circom 2.1.9;

include "../dsc.circom";

component main { public [ merkle_root ] } = DSC(34, 120, 35, 120, 35, 1664, 525, 12);
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pragma circom 2.1.9;

include "../dsc.circom";

component main { public [ merkle_root ] } = DSC(15, 120, 35, 120, 35, 1664, 525, 12);
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pragma circom 2.1.9;

include "../dsc.circom";

component main { public [ merkle_root ] } = DSC(16, 120, 35, 120, 35, 1664, 525, 12);
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pragma circom 2.1.9;

include "../dsc.circom";

component main { public [ merkle_root ] } = DSC(17, 120, 35, 120, 35, 1664, 525, 12);
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pragma circom 2.1.9;

include "../dsc.circom";

component main { public [ merkle_root ] } = DSC(4, 120, 35, 120, 35, 1664, 525, 12);
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pragma circom 2.1.9;

include "../dsc.circom";

component main { public [ merkle_root ] } = DSC(19, 120, 35, 120, 35, 1664, 525, 12);
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ pragma circom 2.1.9;

include "../dsc.circom";

component main { public [ merkle_root ] } = DSC(12, 120, 35, 120, 35, 1664, 256, 12);
component main { public [ merkle_root ] } = DSC(12, 120, 35, 120, 35, 1664, 525, 12);
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pragma circom 2.1.9;

include "../dsc.circom";

component main { public [ merkle_root ] } = DSC(18, 120, 35, 120, 35, 1664, 525, 12);
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pragma circom 2.1.9;

include "../dsc.circom";

component main { public [ merkle_root ] } = DSC(35, 120, 35, 120, 35, 1664, 525, 12);
47 changes: 47 additions & 0 deletions circuits/circuits/utils/crypto/utils/WordToBytes.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
pragma circom 2.1.9;
include "circomlib/circuits/bitify.circom";

template WordsToBytes(n_words, k_words, maxBytesLength) {
assert(n_words * k_words == maxBytesLength * 8);

signal input words[k_words];
signal output bytes[maxBytesLength];

component num2bits[k_words];
signal word_bits[k_words * n_words];

// Convert words to bits
for (var i = 0; i < k_words; i++) {
num2bits[i] = Num2Bits(n_words);
num2bits[i].in <== words[i];
}
for (var i = 0; i < k_words; i++) {
for (var j = 0; j < n_words; j++) {
word_bits[i * n_words + j] <== num2bits[i].out[j];
}
}

// Convert bits back to bytes
component bits2Num[maxBytesLength];
for (var i = 0; i < maxBytesLength; i++) {
bits2Num[i] = Bits2Num(8);
for (var j = 0; j < 8; j++) {
bits2Num[i].in[j] <== word_bits[i * 8 + j];
}
bytes[i] <== bits2Num[i].out;
}
}

template ByteMaskDynamic(maxLength) {
signal input in[maxLength];
signal input maxValidByte;
signal output out[maxLength];

component lt[maxLength];
for (var i=0; i< maxLength; i++) {
lt[i] = LessThan(32);
lt[i].in[0] <== i;
lt[i].in[1] <== maxValidByte;
out[i] <== in[i] * lt[i].out;
}
}
39 changes: 39 additions & 0 deletions circuits/circuits/utils/passport/signatureAlgorithm.circom
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ pragma circom 2.1.9;
30: ecdsa_sha224_brainpoolP224r1_224
31: rsa_sha512_65537_2048
32: rsa_sha256_3_4096
33: rsa_sha1_3_4096
34: rsa_sha384_65537_4096
35: rsapss_sha384_65537_4096
*/

function getHashLength(signatureAlgorithm) {
Expand Down Expand Up @@ -120,6 +123,15 @@ function getHashLength(signatureAlgorithm) {
if (signatureAlgorithm == 32) {
return 256;
}
if (signatureAlgorithm == 33) {
return 160;
}
if (signatureAlgorithm == 34) {
return 384;
}
if (signatureAlgorithm == 35) {
return 384;
}
return 0;
}

Expand Down Expand Up @@ -208,6 +220,15 @@ function getKeyLength(signatureAlgorithm) {
if (signatureAlgorithm == 32) {
return 4096;
}
if (signatureAlgorithm == 33) {
return 4096;
}
if (signatureAlgorithm == 34) {
return 4096;
}
if (signatureAlgorithm == 35) {
return 4096;
}
return 0;
}

Expand Down Expand Up @@ -297,6 +318,15 @@ function getKLengthFactor(signatureAlgorithm) {
if (signatureAlgorithm == 32) {
return 1;
}
if (signatureAlgorithm == 33) {
return 1;
}
if (signatureAlgorithm == 34) {
return 1;
}
if (signatureAlgorithm == 35) {
return 1;
}
return 0;

}
Expand Down Expand Up @@ -348,5 +378,14 @@ function getExponentBits(signatureAlgorithm) {
if (signatureAlgorithm == 32) {
return 2;
}
if (signatureAlgorithm == 33) {
return 2;
}
if (signatureAlgorithm == 34) {
return 17;
}
if (signatureAlgorithm == 35) {
return 17;
}
return 0;
}
3 changes: 3 additions & 0 deletions circuits/circuits/utils/passport/signatureVerifier.circom
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ template SignatureVerifier(signatureAlgorithm, n, k) {
|| signatureAlgorithm == 14
|| signatureAlgorithm == 15
|| signatureAlgorithm == 31
|| signatureAlgorithm == 34
) {
component rsa65537 = VerifyRsa65537Pkcs1v1_5(n, k, HASH_LEN_BITS);
for (var i = 0; i < msg_len; i++) {
Expand All @@ -45,6 +46,7 @@ template SignatureVerifier(signatureAlgorithm, n, k) {
if (
signatureAlgorithm == 13
|| signatureAlgorithm == 32
|| signatureAlgorithm == 33
) {
component rsa3 = VerifyRsa3Pkcs1v1_5(n, k, HASH_LEN_BITS);
for (var i = 0; i < msg_len; i++) {
Expand All @@ -61,6 +63,7 @@ template SignatureVerifier(signatureAlgorithm, n, k) {
|| signatureAlgorithm == 12
|| signatureAlgorithm == 18
|| signatureAlgorithm == 19
|| signatureAlgorithm == 35
) {
var pubKeyBitsLength = getKeyLength(signatureAlgorithm);
var SALT_LEN = HASH_LEN_BITS / 8;
Expand Down
2 changes: 1 addition & 1 deletion circuits/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"license": "MIT",
"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-dsc": "yarn ts-mocha --max-old-space-size=8192 'tests/dsc/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",
Expand Down
Loading
Loading