Skip to content

Commit da4004c

Browse files
committed
tag some byte arrays with maxbits
1 parent cf3865d commit da4004c

12 files changed

+527
-88
lines changed

circuit/templates/helpers/base64url/Base64UrlDecode.circom

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ template Base64UrlDecode(N) {
3434
// (We implement this as: \floor{(4*N + 2) / 3}.)
3535
var M = (4*N + 2) \ 3;
3636
signal input in[M];
37-
signal output out[N];
37+
signal output {maxbits} out[N];
38+
// TODO(Soundness): Make sure this is actually enforced by this template.
39+
out.maxbits = 8;
3840

3941
component bits_in[M \ 4][4];
4042
component bits_out[M \ 4][3];

circuit/templates/helpers/hashtofield/HashBytesToFieldWithLen.circom

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,13 @@ include "HashElemsToField.circom";
1414
* We hash the length `len` of the input as well to prevent collisions.
1515
*
1616
* Currently, does not work for inputs larger than $64 \times 31 = 1984$ bytes.
17-
* TODO(Comment): Why?
18-
*
19-
* TODO(Buses): If `in` is `Bytes(MAX_LEN)` bus, then we can remove the `AssertIsBytes`
20-
* constraint here, since it may be unnecessarily repeated if this gets called for the
21-
* same byte sub-sequence repeatedly.
17+
* because `HashElemsToField` only handles <= 64 field elements (but can be extended).
2218
*
2319
* Parameters:
24-
* NUM_BYTES the max number of bytes this can handle; is > 0 and <= 1984 (64 * 31)
20+
* NUM_BYTES the max number of bytes this can handle; is > 0 and <= 1984 (64 * 31)
2521
*
2622
* Input signals:
27-
* in[NUM_BYTES] array to be hashed, although only in[0], in[1], ..., in[len-1];
28-
* constrained to ensure elements are actually bytes
29-
* are actually hashed
23+
* in[NUM_BYTES] array to be hashed, but only in[0], in[1], ..., in[len-1] prefix is actually hashed
3024
* len the number of bytes that will be actually hashed;
3125
* bytes `in[len], in[len+1]..., in[NUM_BYTES-1]` are ignored
3226
*
@@ -35,15 +29,15 @@ include "HashElemsToField.circom";
3529
*
3630
* Notes:
3731
* There is no way to meaningfully ensure that `len` is the actual length of the bytes in `in`.
38-
* TODO(Buses): Some type-safety via a `Bytes(MAX_LEN)` bus may be useful here?
3932
*/
4033
template HashBytesToFieldWithLen(NUM_BYTES) {
4134
assert(NUM_BYTES > 0);
42-
signal input in[NUM_BYTES];
35+
assert(NUM_BYTES <= 1984);
36+
signal input {maxbits} in[NUM_BYTES];
4337
signal input len;
4438
signal output hash;
4539

46-
AssertIsBytes(NUM_BYTES)(in);
40+
assert(in.maxbits <= 8);
4741

4842
var NUM_ELEMS = NUM_BYTES % 31 == 0 ? NUM_BYTES\31 : NUM_BYTES\31 + 1;
4943

@@ -54,14 +48,13 @@ template HashBytesToFieldWithLen(NUM_BYTES) {
5448
8 // bitsPerChunk
5549
)(in);
5650

57-
// TODO(Cleanup): Can't we use a var here? We are simply re-assigning signals, it seems.
58-
signal input_with_len[NUM_ELEMS + 1];
51+
var elems[NUM_ELEMS + 1];
5952
for (var i = 0; i < NUM_ELEMS; i++) {
60-
input_with_len[i] <== input_packed[i];
53+
elems[i] = input_packed[i];
6154
}
62-
input_with_len[NUM_ELEMS] <== len;
55+
elems[NUM_ELEMS] = len;
6356

64-
PoseidonBN254Hash() poseidonHash <== HashElemsToField(NUM_ELEMS + 1)(input_with_len);
57+
PoseidonBN254Hash() poseidonHash <== HashElemsToField(NUM_ELEMS + 1)(elems);
6558

6659
hash <== poseidonHash.value;
6760
}

circuit/templates/helpers/jwt/ParseEmailVerifiedField.circom

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ include "circomlib/circuits/gates.circom";
2424
// This template exists specifically for the email_verified JWT field, as some providers
2525
// do not follow the OIDC spec and instead enclose the value of this field in quotes
2626
template ParseEmailVerifiedField(MAX_KV_PAIR_LEN, MAX_NAME_LEN, MAX_VALUE_LEN) {
27-
signal input field[MAX_KV_PAIR_LEN]; // ASCII
28-
signal input name[MAX_NAME_LEN];
29-
signal input value[MAX_VALUE_LEN];
27+
signal input {maxbits} field[MAX_KV_PAIR_LEN]; // ASCII
28+
signal input {maxbits} name[MAX_NAME_LEN];
29+
signal input {maxbits} value[MAX_VALUE_LEN];
3030
signal input field_len; // ASCII
3131
signal input name_len;
3232
signal input value_index; // index of value within `field`

circuit/templates/helpers/jwt/ParseJWTFieldSharedLogic.circom

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ include "circomlib/circuits/gates.circom";
2323
// Note that this template is NOT secure on its own, but must be called from
2424
// `ParseJWTFieldWithQuotedValue` or `ParseJWTFieldWithUnquotedValue`
2525
template ParseJWTFieldSharedLogic(MAX_KV_PAIR_LEN, MAX_NAME_LEN, MAX_VALUE_LEN) {
26-
signal input field[MAX_KV_PAIR_LEN]; // ASCII
27-
signal input name[MAX_NAME_LEN]; // ASCII
28-
signal input value[MAX_VALUE_LEN]; // ASCII
26+
signal input {maxbits} field[MAX_KV_PAIR_LEN]; // ASCII
27+
signal input {maxbits} name[MAX_NAME_LEN]; // ASCII
28+
signal input {maxbits} value[MAX_VALUE_LEN]; // ASCII
2929
signal input field_len;
3030
signal input name_len;
3131
signal input value_index; // index of value within `field`
@@ -68,4 +68,4 @@ template ParseJWTFieldSharedLogic(MAX_KV_PAIR_LEN, MAX_NAME_LEN, MAX_VALUE_LEN)
6868
signal checks_pass <== MultiAND(9)(checks);
6969
signal success <== OR()(checks_pass, skip_checks);
7070
success === 1;
71-
}
71+
}

circuit/templates/helpers/jwt/ParseJWTFieldWithQuotedValue.circom

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ include "circomlib/circuits/gates.circom";
2222
// checks enforced by this template will be skipped, and it will function as
2323
// a no-op. If it is set to 0, failing one check will fail proof generation
2424
template ParseJWTFieldWithQuotedValue(MAX_KV_PAIR_LEN, MAX_NAME_LEN, MAX_VALUE_LEN) {
25-
signal input field[MAX_KV_PAIR_LEN]; // ASCII
26-
signal input name[MAX_NAME_LEN]; // ASCII
27-
signal input value[MAX_VALUE_LEN]; // ASCII
25+
signal input {maxbits} field[MAX_KV_PAIR_LEN]; // ASCII
26+
signal input {maxbits} name[MAX_NAME_LEN]; // ASCII
27+
signal input {maxbits} value[MAX_VALUE_LEN]; // ASCII
2828
signal input field_string_bodies[MAX_KV_PAIR_LEN];
2929
signal input field_len;
3030
signal input name_len;
@@ -70,4 +70,4 @@ template ParseJWTFieldWithQuotedValue(MAX_KV_PAIR_LEN, MAX_NAME_LEN, MAX_VALUE_L
7070
signal checks_pass <== MultiAND(3)(checks);
7171
signal succeed <== OR()(checks_pass, skip_checks);
7272
succeed === 1;
73-
}
73+
}

circuit/templates/helpers/jwt/ParseJWTFieldWithUnquotedValue.circom

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ include "circomlib/circuits/gates.circom";
2222
// checks enforced by this template will be skipped, and it will function as
2323
// a no-op. If it is set to 0, failing one check will fail proof generation
2424
template ParseJWTFieldWithUnquotedValue(MAX_KV_PAIR_LEN, MAX_NAME_LEN, MAX_VALUE_LEN) {
25-
signal input field[MAX_KV_PAIR_LEN]; // ASCII
26-
signal input name[MAX_NAME_LEN];
27-
signal input value[MAX_VALUE_LEN];
25+
signal input {maxbits} field[MAX_KV_PAIR_LEN]; // ASCII
26+
signal input {maxbits} name[MAX_NAME_LEN];
27+
signal input {maxbits} value[MAX_VALUE_LEN];
2828
signal input field_len; // ASCII
2929
signal input name_len;
3030
signal input value_index; // index of value within `field`
@@ -65,4 +65,4 @@ template ParseJWTFieldWithUnquotedValue(MAX_KV_PAIR_LEN, MAX_NAME_LEN, MAX_VALUE
6565
signal checks_pass <== AND()(checks[0], checks[1]);
6666
signal success <== OR()(checks_pass, skip_checks);
6767
success === 1;
68-
}
68+
}

circuit/templates/helpers/sha/SHA2_256_PaddingVerify.circom

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,20 @@ include "circomlib/circuits/bitify.circom";
99

1010
// Verifies SHA2_256 input padding according to https://www.rfc-editor.org/rfc/rfc4634.html#section-4.1
1111
template SHA2_256_PaddingVerify(MAX_INPUT_LEN) {
12-
signal input in[MAX_INPUT_LEN]; // byte array
12+
signal input {maxbits} in[MAX_INPUT_LEN]; // byte array
1313
signal input num_blocks; // Number of 512-bit blocks in `in` including sha padding
1414
signal input padding_start; // equivalent to L/8, where L is the length of the unpadded message in bits as specified in RFC4634
15-
signal input L_byte_encoded[8]; // 64-bit encoding of L
16-
signal input padding_without_len[64]; // padding_without_len[0] = 1, followed by K 0s. Length K+1, max length 512 bits. Does not include the 64-bit encoding of L
15+
signal input {maxbits} L_byte_encoded[8]; // byte-array; 64-bit encoding of L
16+
signal input {maxbits} padding_without_len[64]; // byte-array; padding_without_len[0] = 1, followed by K 0s. Length K+1, max length 512 bits. Does not include the 64-bit encoding of L
1717

1818
var len_bits = num_blocks * 512;
1919
var padding_start_bits = padding_start * 8;
2020
var K = len_bits - padding_start_bits - 1 - 64;
2121

22+
assert(in.maxbits == 8);
23+
assert(L_byte_encoded.maxbits == 8);
24+
assert(padding_without_len.maxbits == 8);
25+
2226
// Ensure K is 9-bits (i.e., < 2^9 = 512)
2327
_ <== Num2Bits(9)(K);
2428

circuit/templates/helpers/strings/IsSubstring.circom

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,15 @@ template IsSubstring(MAX_STR_LEN, MAX_SUBSTR_LEN) {
4040
// length
4141
assert(MAX_SUBSTR_LEN <= MAX_STR_LEN);
4242

43-
signal input str[MAX_STR_LEN];
43+
signal input {maxbits} str[MAX_STR_LEN];
4444
signal input str_hash;
4545

46-
signal input substr[MAX_SUBSTR_LEN];
46+
signal input {maxbits} substr[MAX_SUBSTR_LEN];
4747
signal input substr_len;
4848

49+
assert(str.maxbits <= 8);
50+
assert(substr.maxbits <= 8);
51+
4952
// The index of `substr` in `str`:
5053
//
5154
// str[start_index] = substr[0]
@@ -126,9 +129,9 @@ template IsSubstring(MAX_STR_LEN, MAX_SUBSTR_LEN) {
126129
// Enforces that:
127130
// - `str[start_index:substr_len]` = `substr[0:substr_len]`
128131
template AssertIsSubstring(MAX_STR_LEN, MAX_SUBSTR_LEN) {
129-
signal input str[MAX_STR_LEN];
132+
signal input {maxbits} str[MAX_STR_LEN];
130133
signal input str_hash;
131-
signal input substr[MAX_SUBSTR_LEN];
134+
signal input {maxbits} substr[MAX_SUBSTR_LEN];
132135
signal input substr_len;
133136
signal input start_index;
134137

0 commit comments

Comments
 (0)