mirror of
https://github.com/zkemail/zk-email-verify.git
synced 2026-01-09 13:38:03 -05:00
fix: computing r by hashing inputs
This commit is contained in:
@@ -2,14 +2,15 @@ pragma circom 2.1.6;
|
||||
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "circomlib/circuits/mux1.circom";
|
||||
include "../utils/hash.circom";
|
||||
|
||||
template RemoveSoftLineBreaks(maxLength) {
|
||||
signal input encoded[maxLength];
|
||||
signal input decoded[maxLength];
|
||||
signal input r;
|
||||
signal output is_valid;
|
||||
|
||||
// Helper signals
|
||||
signal r;
|
||||
signal processed[maxLength];
|
||||
signal is_equals[maxLength];
|
||||
signal is_cr[maxLength];
|
||||
@@ -26,6 +27,16 @@ template RemoveSoftLineBreaks(maxLength) {
|
||||
// Helper components
|
||||
component mux_enc[maxLength];
|
||||
|
||||
// Deriving r from Poseidon hash
|
||||
component r_hasher = PoseidonModular(2 * maxLength);
|
||||
for (var i = 0; i < maxLength; i++) {
|
||||
r_hasher.in[i] <== encoded[i];
|
||||
}
|
||||
for (var i = 0; i < maxLength; i++) {
|
||||
r_hasher.in[maxLength + i] <== decoded[i];
|
||||
}
|
||||
r <== r_hasher.out;
|
||||
|
||||
// Check for '=' (61 in ASCII)
|
||||
for (var i = 0; i < maxLength; i++) {
|
||||
is_equals[i] <== IsEqual()([encoded[i], 61]);
|
||||
|
||||
@@ -54,7 +54,6 @@ describe('RemoveSoftLineBreaks', () => {
|
||||
107,
|
||||
...Array(21).fill(0),
|
||||
],
|
||||
r: 69,
|
||||
};
|
||||
|
||||
const witness = await circuit.calculateWitness(input);
|
||||
@@ -98,10 +97,9 @@ describe('RemoveSoftLineBreaks', () => {
|
||||
114,
|
||||
101,
|
||||
97,
|
||||
108,
|
||||
108, // Changed last character
|
||||
...Array(21).fill(0),
|
||||
], // Changed last character
|
||||
r: 69,
|
||||
],
|
||||
};
|
||||
|
||||
const witness = await circuit.calculateWitness(input);
|
||||
|
||||
@@ -162,3 +162,25 @@ template AssertZeroPadding(maxArrayLen) {
|
||||
lessThans[i].out * in[i] === 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// @title Slice
|
||||
/// @notice Extract a fixed portion of an array
|
||||
/// @dev Unlike SelectSubArray, Slice uses compile-time known indices and doesn't pad the output
|
||||
/// @dev Slice is more efficient for fixed ranges, while SelectSubArray offers runtime flexibility
|
||||
/// @param n The length of the input array
|
||||
/// @param start The starting index of the slice (inclusive)
|
||||
/// @param end The ending index of the slice (exclusive)
|
||||
/// @input in The input array of length n
|
||||
/// @output out The sliced array of length (end - start)
|
||||
template Slice(n, start, end) {
|
||||
assert(n >= end);
|
||||
assert(start >= 0);
|
||||
assert(end >= start);
|
||||
|
||||
signal input in[n];
|
||||
signal output out[end - start];
|
||||
|
||||
for (var i = start; i < end; i++) {
|
||||
out[i - start] <== in[i];
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
pragma circom 2.1.6;
|
||||
|
||||
include "circomlib/circuits/poseidon.circom";
|
||||
include "./array.circom";
|
||||
|
||||
/// @title PoseidonLarge
|
||||
/// @notice Circuit to calculate Poseidon hash of inputs more than 16
|
||||
@@ -36,3 +38,45 @@ template PoseidonLarge(bitsPerChunk, chunkSize) {
|
||||
out <== Poseidon(halfChunkSize)(poseidonInput);
|
||||
}
|
||||
|
||||
/// @title PoseidonModular
|
||||
/// @notice Circuit to calculate Poseidon hash of an arbitrary number of inputs
|
||||
/// @notice Splits input into chunks of 16 elements (or less for the last chunk) and hashes them separately
|
||||
/// @notice Then combines the chunk hashes using a binary tree structure
|
||||
/// @param numElements Number of elements in the input array
|
||||
/// @input in: Array of numElements to be hashed
|
||||
/// @output out: Poseidon hash of the input array
|
||||
template PoseidonModular(numElements) {
|
||||
signal input in[numElements];
|
||||
signal output out;
|
||||
|
||||
var chunks = numElements \ 16;
|
||||
var last_chunk_size = numElements % 16;
|
||||
if (last_chunk_size != 0) {
|
||||
chunks += 1;
|
||||
}
|
||||
|
||||
var _out;
|
||||
|
||||
for (var i = 0; i < chunks; i++) {
|
||||
var start = i * 16;
|
||||
var end = start + 16;
|
||||
var chunk_hash;
|
||||
|
||||
if (end > numElements) { // last chunk
|
||||
end = numElements;
|
||||
var last_chunk[last_chunk_size] = Slice(numElements, start, end)(in);
|
||||
chunk_hash = Poseidon(last_chunk_size)(last_chunk);
|
||||
} else {
|
||||
var chunk[16] = Slice(numElements, start, end)(in);
|
||||
chunk_hash = Poseidon(16)(chunk);
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
_out = chunk_hash;
|
||||
} else {
|
||||
_out = Poseidon(2)([_out, chunk_hash]);
|
||||
}
|
||||
}
|
||||
|
||||
out <== _out;
|
||||
}
|
||||
Reference in New Issue
Block a user