mirror of
https://github.com/logos-storage/logos-storage-proofs-circuits.git
synced 2026-05-20 19:09:27 +00:00
Merge pull request #5 from codex-storage/review
Code review of the circom circuit
This commit is contained in:
commit
2a4a71acf6
@ -3,8 +3,9 @@ pragma circom 2.0.0;
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
//
|
//
|
||||||
// given two numbers in `n`-bit binary decomposition (little-endian), we compute
|
// given two numbers in `n`-bit binary decomposition
|
||||||
//
|
// (least significant bit first), we compute
|
||||||
|
//
|
||||||
// / -1 if A < B
|
// / -1 if A < B
|
||||||
// out := { 0 if A == B
|
// out := { 0 if A == B
|
||||||
// \ +1 if A > B
|
// \ +1 if A > B
|
||||||
@ -12,7 +13,7 @@ pragma circom 2.0.0;
|
|||||||
// NOTE: we don't check that the digits are indeed binary;
|
// NOTE: we don't check that the digits are indeed binary;
|
||||||
// that's the responsibility of the caller!
|
// that's the responsibility of the caller!
|
||||||
//
|
//
|
||||||
// This version uses `(3*n-1)` nonlinear constraints.
|
// This version uses `(3*n-1)` nonlinear constraints.
|
||||||
// Question: can we do better? (note that this has to work with n >= 254 digits too!)
|
// Question: can we do better? (note that this has to work with n >= 254 digits too!)
|
||||||
//
|
//
|
||||||
|
|
||||||
@ -42,11 +43,11 @@ template BinaryCompare(n) {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
//
|
//
|
||||||
// given two numbers in `n`-bit binary decomposition (little-endian), we compute
|
// given two numbers in `n`-bit binary decomposition (little-endian), we compute
|
||||||
//
|
//
|
||||||
// out := (A <= B) ? 1 : 0
|
// out := (A <= B) ? 1 : 0
|
||||||
//
|
//
|
||||||
// NOTE: we don't check that the digits are indeed binary;
|
// NOTE: we don't check that the digits are indeed binary;
|
||||||
// that's the responsibility of the caller!
|
// that's the responsibility of the caller!
|
||||||
//
|
//
|
||||||
|
|
||||||
@ -69,11 +70,11 @@ template BinaryLessOrEqual(n) {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
//
|
//
|
||||||
// given two numbers in `n`-bit binary decomposition (little-endian), we compute
|
// given two numbers in `n`-bit binary decomposition (little-endian), we compute
|
||||||
//
|
//
|
||||||
// out := (A >= B) ? 1 : 0
|
// out := (A >= B) ? 1 : 0
|
||||||
//
|
//
|
||||||
// NOTE: we don't check that the digits are indeed binary;
|
// NOTE: we don't check that the digits are indeed binary;
|
||||||
// that's the responsibility of the caller!
|
// that's the responsibility of the caller!
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|||||||
@ -5,12 +5,12 @@ include "misc.circom";
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
//
|
//
|
||||||
// extract the lowest `n` bits from a field element.
|
// extract the lowest `n` bits from a field element.
|
||||||
//
|
//
|
||||||
// NOTE: this is rather nontrivial, as everything is computed modulo `r`,
|
// NOTE: this is rather nontrivial, as everything is computed modulo `r`,
|
||||||
// so naive bit decomposition does not work (there are multiple solutions).
|
// so naive bit decomposition does not work (there are multiple solutions).
|
||||||
//
|
//
|
||||||
// TODO: optimize this
|
// TODO: optimize this
|
||||||
//
|
//
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ template ExtractLowerBits(n) {
|
|||||||
component tb = ToBits(254); // note: 2^253 < r < 2^254
|
component tb = ToBits(254); // note: 2^253 < r < 2^254
|
||||||
tb.inp <== inp;
|
tb.inp <== inp;
|
||||||
|
|
||||||
// bits of field prime `r` in little-endian order
|
// bits of field prime `r`, least significant bit first
|
||||||
var primeBits[254] = [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,1,0,0,1,1,0,1,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,0,1,0,1,0,0,0,1,0,0,1,0,0,0,0,1,1,1,0,1,0,0,1,1,1,0,1,1,0,0,1,1,1,1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,0,0,0,0,0,1,0,1,0,0,1,0,1,1,1,0,1,0,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,1,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,1,1,1,0,1,1,0,0,1,0,1,0,0,0,0,0,0,0,1,0,1,1,0,0,0,1,1,0,0,1,0,0,0,0,1,1,1,0,1,0,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,1,1];
|
var primeBits[254] = [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,1,0,0,1,1,0,1,0,1,1,1,1,1,0,0,0,0,1,1,1,1,1,0,0,0,0,1,0,1,0,0,0,1,0,0,1,0,0,0,0,1,1,1,0,1,0,0,1,1,1,0,1,1,0,0,1,1,1,1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,0,0,0,0,0,1,0,1,0,0,1,0,1,1,1,0,1,0,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,1,1,0,1,1,0,1,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,1,1,1,0,1,1,0,0,1,0,1,0,0,0,0,0,0,0,1,0,1,1,0,0,0,1,1,0,0,1,0,0,0,0,1,1,1,0,1,0,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,1,1];
|
||||||
|
|
||||||
// enforce that the binary representation is < r
|
// enforce that the binary representation is < r
|
||||||
@ -33,7 +33,7 @@ template ExtractLowerBits(n) {
|
|||||||
le.out === -1; // enforce `A < B`, that is, `bits < prime`
|
le.out === -1; // enforce `A < B`, that is, `bits < prime`
|
||||||
|
|
||||||
// extract the lowest `n` bits
|
// extract the lowest `n` bits
|
||||||
for(var i=0; i<n; i++) {
|
for(var i=0; i<n; i++) {
|
||||||
tb.out[i] ==> out[i];
|
tb.out[i] ==> out[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ template ExtractLowerBits_testfield65537(n) {
|
|||||||
component tb = ToBits(18); // note: 2^16 < r < 2^18
|
component tb = ToBits(18); // note: 2^16 < r < 2^18
|
||||||
tb.inp <== inp;
|
tb.inp <== inp;
|
||||||
|
|
||||||
// bits of field prime `r` in little-endian order
|
// bits of field prime `r`, least significant bit first
|
||||||
var primeBits[18] = [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0];
|
var primeBits[18] = [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0];
|
||||||
|
|
||||||
// enforce that the binary representation is < r
|
// enforce that the binary representation is < r
|
||||||
@ -66,7 +66,7 @@ template ExtractLowerBits_testfield65537(n) {
|
|||||||
le.out === -1; // enforce `A < B`, that is, `bits < prime`
|
le.out === -1; // enforce `A < B`, that is, `bits < prime`
|
||||||
|
|
||||||
// extract the lowest `n` bits
|
// extract the lowest `n` bits
|
||||||
for(var i=0; i<n; i++) {
|
for(var i=0; i<n; i++) {
|
||||||
tb.out[i] ==> out[i];
|
tb.out[i] ==> out[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ pragma circom 2.0.0;
|
|||||||
include "misc.circom";
|
include "misc.circom";
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// given an input `inp`, this template checks that inp == 2^out
|
// given an input `inp`, this template checks that inp == 2^out
|
||||||
// with 0 < out <= n
|
// with 0 < out <= n
|
||||||
//
|
//
|
||||||
@ -13,14 +13,14 @@ include "misc.circom";
|
|||||||
template Log2(n) {
|
template Log2(n) {
|
||||||
|
|
||||||
signal input inp;
|
signal input inp;
|
||||||
signal output out;
|
signal output out;
|
||||||
signal output mask[n+1];
|
signal output mask[n+1];
|
||||||
|
|
||||||
// mask will be a vector [1,1,1,...1,0,...,0,0]
|
// mask will be a vector [1,1,1,...1,0,...,0,0]
|
||||||
// which can change only where inp == 2^out
|
// which can change only where index == out
|
||||||
|
|
||||||
var log2 = -1;
|
var log2 = -1;
|
||||||
for(var i=0; i<=n; i++) {
|
for(var i=0; i<=n; i++) {
|
||||||
mask[i] <-- ((2**i) < inp) ? 1 : 0;
|
mask[i] <-- ((2**i) < inp) ? 1 : 0;
|
||||||
if (2**i == inp) { log2 = i; }
|
if (2**i == inp) { log2 = i; }
|
||||||
}
|
}
|
||||||
@ -31,19 +31,19 @@ template Log2(n) {
|
|||||||
mask[n] === 0;
|
mask[n] === 0;
|
||||||
|
|
||||||
var sum = 0;
|
var sum = 0;
|
||||||
for(var i=0; i<n; i++) {
|
for(var i=0; i<n; i++) {
|
||||||
sum += (2**(i+1)) * (mask[i] - mask[i+1]);
|
sum += (2**(i+1)) * (mask[i] - mask[i+1]);
|
||||||
0 === (mask[i] - mask[i+1]) * (i + 1 - out);
|
0 === (mask[i] - mask[i+1]) * (i + 1 - out);
|
||||||
}
|
}
|
||||||
|
|
||||||
inp === sum;
|
inp === sum;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// given an input `inp`, this template computes `out := k` such that 2^k <= inp < 2^{k+1}
|
// given an input `inp`, this template computes `out := k` such that 2^k <= inp < 2^{k+1}
|
||||||
// it also returns the binary decomposition of `inp-1`, and the binary deocmpositiom
|
// it also returns the binary decomposition of `inp-1`, and the binary decomposition
|
||||||
// of the mask `(2^k-1)`
|
// of the mask `(2^k-1)`
|
||||||
//
|
//
|
||||||
// we also output a mask vector which is 1 for i=0..k-1, and 0 elsewhere
|
// we also output a mask vector which is 1 for i=0..k-1, and 0 elsewhere
|
||||||
@ -54,12 +54,12 @@ template Log2(n) {
|
|||||||
template CeilingLog2(n) {
|
template CeilingLog2(n) {
|
||||||
|
|
||||||
signal input inp;
|
signal input inp;
|
||||||
signal output out;
|
signal output out;
|
||||||
signal output bits[n];
|
signal output bits[n];
|
||||||
signal output mask[n+1];
|
signal output mask[n+1];
|
||||||
|
|
||||||
component tb = ToBits(n);
|
component tb = ToBits(n);
|
||||||
tb.inp <== inp - 1;
|
tb.inp <== inp - 1;
|
||||||
tb.out ==> bits;
|
tb.out ==> bits;
|
||||||
|
|
||||||
signal aux[n+1];
|
signal aux[n+1];
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
pragma circom 2.0.0;
|
pragma circom 2.0.0;
|
||||||
|
|
||||||
include "poseidon2_perm.circom";
|
include "poseidon2_perm.circom";
|
||||||
include "poseidon2_hash.circom";
|
|
||||||
|
|
||||||
include "misc.circom";
|
include "misc.circom";
|
||||||
|
|
||||||
@ -15,7 +14,7 @@ include "misc.circom";
|
|||||||
//
|
//
|
||||||
// inputs and outputs:
|
// inputs and outputs:
|
||||||
// - leaf: the leaf hash
|
// - leaf: the leaf hash
|
||||||
// - pathBits: the linear index of the leaf, in binary decomposition (little-endian)
|
// - pathBits: the linear index of the leaf, in binary decomposition (least significant bit first)
|
||||||
// - lastBits: the index of the last leaf (= nLeaves-1), in binary decomposition
|
// - lastBits: the index of the last leaf (= nLeaves-1), in binary decomposition
|
||||||
// - maskBits: the bits of the the mask `2^ceilingLog2(size) - 1`
|
// - maskBits: the bits of the the mask `2^ceilingLog2(size) - 1`
|
||||||
// - merklePath: the Merkle inclusion proof (required hashes, starting from the leaf and ending near the root)
|
// - merklePath: the Merkle inclusion proof (required hashes, starting from the leaf and ending near the root)
|
||||||
@ -26,7 +25,7 @@ include "misc.circom";
|
|||||||
//
|
//
|
||||||
|
|
||||||
template RootFromMerklePath( maxDepth ) {
|
template RootFromMerklePath( maxDepth ) {
|
||||||
|
|
||||||
signal input leaf;
|
signal input leaf;
|
||||||
signal input pathBits[ maxDepth ]; // bits of the linear index
|
signal input pathBits[ maxDepth ]; // bits of the linear index
|
||||||
signal input lastBits[ maxDepth ]; // bits of the last linear index `= size-1`
|
signal input lastBits[ maxDepth ]; // bits of the last linear index `= size-1`
|
||||||
@ -38,14 +37,17 @@ template RootFromMerklePath( maxDepth ) {
|
|||||||
signal aux[ maxDepth+1 ];
|
signal aux[ maxDepth+1 ];
|
||||||
aux[0] <== leaf;
|
aux[0] <== leaf;
|
||||||
|
|
||||||
// compute which prefixes (in big-endian) of the index is
|
// Determine whether nodes from the path are last in their row and are odd,
|
||||||
// the same as the corresponding prefix of the last index
|
// by computing which binary prefixes of the index are the same as the
|
||||||
|
// corresponding prefix of the last index.
|
||||||
|
// This is done in reverse bit order, because pathBits and lastBits have the
|
||||||
|
// least significant bit first.
|
||||||
component eq[ maxDepth ];
|
component eq[ maxDepth ];
|
||||||
signal isLast[ maxDepth+1 ];
|
signal isLast[ maxDepth+1 ];
|
||||||
isLast[ maxDepth ] <== 1;
|
isLast[ maxDepth ] <== 1;
|
||||||
for(var i=maxDepth-1; i>=0; i--) {
|
for(var i=maxDepth-1; i>=0; i--) {
|
||||||
eq[i] = IsEqual();
|
eq[i] = IsEqual();
|
||||||
eq[i].A <== pathBits[i];
|
eq[i].A <== pathBits[i];
|
||||||
eq[i].B <== lastBits[i];
|
eq[i].B <== lastBits[i];
|
||||||
isLast[i] <== isLast[i+1] * eq[i].out;
|
isLast[i] <== isLast[i+1] * eq[i].out;
|
||||||
}
|
}
|
||||||
@ -64,7 +66,7 @@ template RootFromMerklePath( maxDepth ) {
|
|||||||
var R = merklePath[i];
|
var R = merklePath[i];
|
||||||
|
|
||||||
// based on pathBits[i], we switch or not
|
// based on pathBits[i], we switch or not
|
||||||
|
|
||||||
switch[i] <== (R-L) * pathBits[i];
|
switch[i] <== (R-L) * pathBits[i];
|
||||||
comp[i].key <== bottom + 2*odd;
|
comp[i].key <== bottom + 2*odd;
|
||||||
comp[i].inp[0] <== L + switch[i];
|
comp[i].inp[0] <== L + switch[i];
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
pragma circom 2.0.0;
|
pragma circom 2.0.0;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// compute (compile time) the log2 of a number
|
|
||||||
|
|
||||||
function FloorLog2(n) {
|
function FloorLog2(n) {
|
||||||
return (n==0) ? -1 : (1 + FloorLog2(n>>1));
|
return (n==0) ? -1 : (1 + FloorLog2(n>>1));
|
||||||
@ -12,7 +11,7 @@ function CeilLog2(n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// decompose an n-bit number into bits
|
// decompose an n-bit number into bits (least significant bit first)
|
||||||
|
|
||||||
template ToBits(n) {
|
template ToBits(n) {
|
||||||
signal input inp;
|
signal input inp;
|
||||||
@ -44,11 +43,11 @@ template IsZero() {
|
|||||||
out <== 1 - inp * inv;
|
out <== 1 - inp * inv;
|
||||||
|
|
||||||
// enfore that either `inp` or `out` must be zero
|
// enfore that either `inp` or `out` must be zero
|
||||||
inp*out === 0;
|
inp*out === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// check equality of two field elements; that is, computes `(A==B) ? 1 : 0`
|
// check equality of two field elements; that is, computes `(A==B) ? 1 : 0`
|
||||||
|
|
||||||
template IsEqual() {
|
template IsEqual() {
|
||||||
signal input A,B;
|
signal input A,B;
|
||||||
|
|||||||
@ -2,20 +2,6 @@ pragma circom 2.0.0;
|
|||||||
|
|
||||||
include "poseidon2_sponge.circom";
|
include "poseidon2_sponge.circom";
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
// Hash `n` field elements into 1, with approximately 127-254 bits of preimage security
|
|
||||||
// Note that the output size must be at least twice than the desired security level (?)
|
|
||||||
// (assuming bn128 scalar field. We use capacity=2, rate=1, t=3).
|
|
||||||
|
|
||||||
template Poseidon2_hash_rate1(n) {
|
|
||||||
signal input inp[n];
|
|
||||||
signal output out;
|
|
||||||
|
|
||||||
component sponge = PoseidonSponge(3,2,n,1);
|
|
||||||
sponge.inp <== inp;
|
|
||||||
sponge.out[0] ==> out;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Hash `n` field elements into 1, with approximately 127 bits of preimage security
|
// Hash `n` field elements into 1, with approximately 127 bits of preimage security
|
||||||
// (assuming bn128 scalar field. We use capacity=1, rate=2, t=3).
|
// (assuming bn128 scalar field. We use capacity=1, rate=2, t=3).
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
pragma circom 2.0.0;
|
pragma circom 2.0.0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// The Poseidon2 permutation for bn128 and t=3
|
// The Poseidon2 permutation for bn128 and t=3
|
||||||
//
|
//
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -24,7 +24,7 @@ template InternalRound(i) {
|
|||||||
signal input inp[3];
|
signal input inp[3];
|
||||||
signal output out[3];
|
signal output out[3];
|
||||||
|
|
||||||
var round_consts[56] =
|
var round_consts[56] =
|
||||||
[ 0x15ce7e5ae220e8623a40b3a3b22d441eff0c9be1ae1d32f1b777af84eea7e38c
|
[ 0x15ce7e5ae220e8623a40b3a3b22d441eff0c9be1ae1d32f1b777af84eea7e38c
|
||||||
, 0x1bf60ac8bfff0f631983c93e218ca0d4a4059c254b4299b1d9984a07edccfaf0
|
, 0x1bf60ac8bfff0f631983c93e218ca0d4a4059c254b4299b1d9984a07edccfaf0
|
||||||
, 0x0fab0c9387cb2bec9dc11b2951088b9e1e1d2978542fc131f74a8f8fdac95b40
|
, 0x0fab0c9387cb2bec9dc11b2951088b9e1e1d2978542fc131f74a8f8fdac95b40
|
||||||
@ -99,11 +99,11 @@ template ExternalRound(i) {
|
|||||||
signal input inp[3];
|
signal input inp[3];
|
||||||
signal output out[3];
|
signal output out[3];
|
||||||
|
|
||||||
var round_consts[8][3] =
|
var round_consts[8][3] =
|
||||||
|
|
||||||
[ [ 0x2c4c51fd1bb9567c27e99f5712b49e0574178b41b6f0a476cddc41d242cf2b43
|
[ [ 0x2c4c51fd1bb9567c27e99f5712b49e0574178b41b6f0a476cddc41d242cf2b43
|
||||||
, 0x1c5f8d18acb9c61ec6fcbfcda5356f1b3fdee7dc22c99a5b73a2750e5b054104
|
, 0x1c5f8d18acb9c61ec6fcbfcda5356f1b3fdee7dc22c99a5b73a2750e5b054104
|
||||||
, 0x2d3c1988b4541e4c045595b8d574e98a7c2820314a82e67a4e380f1c4541ba90
|
, 0x2d3c1988b4541e4c045595b8d574e98a7c2820314a82e67a4e380f1c4541ba90
|
||||||
]
|
]
|
||||||
, [ 0x052547dc9e6d936cab6680372f1734c39f490d0cb970e2077c82f7e4172943d3
|
, [ 0x052547dc9e6d936cab6680372f1734c39f490d0cb970e2077c82f7e4172943d3
|
||||||
, 0x29d967f4002adcbb5a6037d644d36db91f591b088f69d9b4257694f5f9456bc2
|
, 0x29d967f4002adcbb5a6037d644d36db91f591b088f69d9b4257694f5f9456bc2
|
||||||
@ -120,19 +120,19 @@ template ExternalRound(i) {
|
|||||||
, [ 0x25672a14b5d085e31a30a7e1d5675ebfab034fb04dc2ec5e544887523f98dede
|
, [ 0x25672a14b5d085e31a30a7e1d5675ebfab034fb04dc2ec5e544887523f98dede
|
||||||
, 0x0cf702434b891e1b2f1d71883506d68cdb1be36fa125674a3019647b3a98accd
|
, 0x0cf702434b891e1b2f1d71883506d68cdb1be36fa125674a3019647b3a98accd
|
||||||
, 0x1837e75235ff5d112a5eddf7a4939448748339e7b5f2de683cf0c0ae98bdfbb3
|
, 0x1837e75235ff5d112a5eddf7a4939448748339e7b5f2de683cf0c0ae98bdfbb3
|
||||||
]
|
]
|
||||||
, [ 0x1cd8a14cff3a61f04197a083c6485581a7d836941f6832704837a24b2d15613a
|
, [ 0x1cd8a14cff3a61f04197a083c6485581a7d836941f6832704837a24b2d15613a
|
||||||
, 0x266f6d85be0cef2ece525ba6a54b647ff789785069882772e6cac8131eecc1e4
|
, 0x266f6d85be0cef2ece525ba6a54b647ff789785069882772e6cac8131eecc1e4
|
||||||
, 0x0538fde2183c3f5833ecd9e07edf30fe977d28dd6f246d7960889d9928b506b3
|
, 0x0538fde2183c3f5833ecd9e07edf30fe977d28dd6f246d7960889d9928b506b3
|
||||||
]
|
]
|
||||||
, [ 0x07a0693ff41476abb4664f3442596aa8399fdccf245d65882fce9a37c268aa04
|
, [ 0x07a0693ff41476abb4664f3442596aa8399fdccf245d65882fce9a37c268aa04
|
||||||
, 0x11eb49b07d33de2bd60ea68e7f652beda15644ed7855ee5a45763b576d216e8e
|
, 0x11eb49b07d33de2bd60ea68e7f652beda15644ed7855ee5a45763b576d216e8e
|
||||||
, 0x08f8887da6ce51a8c06041f64e22697895f34bacb8c0a39ec12bf597f7c67cfc
|
, 0x08f8887da6ce51a8c06041f64e22697895f34bacb8c0a39ec12bf597f7c67cfc
|
||||||
]
|
]
|
||||||
, [ 0x2a912ec610191eb7662f86a52cc64c0122bd5ba762e1db8da79b5949fdd38092
|
, [ 0x2a912ec610191eb7662f86a52cc64c0122bd5ba762e1db8da79b5949fdd38092
|
||||||
, 0x2031d7fd91b80857aa1fef64e23cfad9a9ba8fe8c8d09de92b1edb592a44c290
|
, 0x2031d7fd91b80857aa1fef64e23cfad9a9ba8fe8c8d09de92b1edb592a44c290
|
||||||
, 0x0f81ebce43c47711751fa64d6c007221016d485641c28c507d04fd3dc7fba1d2
|
, 0x0f81ebce43c47711751fa64d6c007221016d485641c28c507d04fd3dc7fba1d2
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
component sb[3];
|
component sb[3];
|
||||||
@ -154,7 +154,7 @@ template LinearLayer() {
|
|||||||
signal output out[3];
|
signal output out[3];
|
||||||
out[0] <== 2*inp[0] + inp[1] + inp[2];
|
out[0] <== 2*inp[0] + inp[1] + inp[2];
|
||||||
out[1] <== inp[0] + 2*inp[1] + inp[2];
|
out[1] <== inp[0] + 2*inp[1] + inp[2];
|
||||||
out[2] <== inp[0] + inp[1] + 2*inp[2];
|
out[2] <== inp[0] + inp[1] + 2*inp[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -172,7 +172,7 @@ template Permutation() {
|
|||||||
|
|
||||||
component ext[8];
|
component ext[8];
|
||||||
for(var k=0; k<8; k++) { ext[k] = ExternalRound(k); }
|
for(var k=0; k<8; k++) { ext[k] = ExternalRound(k); }
|
||||||
|
|
||||||
component int[56];
|
component int[56];
|
||||||
for(var k=0; k<56; k++) { int[k] = InternalRound(k); }
|
for(var k=0; k<56; k++) { int[k] = InternalRound(k); }
|
||||||
|
|
||||||
@ -201,20 +201,6 @@ template Permutation() {
|
|||||||
// the "compression function" takes 2 field elements as input and produces
|
// the "compression function" takes 2 field elements as input and produces
|
||||||
// 1 field element as output. It is a trivial application of the permutation.
|
// 1 field element as output. It is a trivial application of the permutation.
|
||||||
|
|
||||||
template Compression() {
|
|
||||||
signal input inp[2];
|
|
||||||
signal output out;
|
|
||||||
|
|
||||||
component perm = Permutation();
|
|
||||||
perm.inp[0] <== inp[0];
|
|
||||||
perm.inp[1] <== inp[1];
|
|
||||||
perm.inp[2] <== 0;
|
|
||||||
|
|
||||||
perm.out[0] ==> out;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------
|
|
||||||
|
|
||||||
template KeyedCompression() {
|
template KeyedCompression() {
|
||||||
signal input key;
|
signal input key;
|
||||||
signal input inp[2];
|
signal input inp[2];
|
||||||
|
|||||||
@ -17,10 +17,10 @@ function min(a,b) {
|
|||||||
// c = capacity (1 or 2)
|
// c = capacity (1 or 2)
|
||||||
// r = rate = t - c
|
// r = rate = t - c
|
||||||
//
|
//
|
||||||
// everything is measured in number of field elements
|
// everything is measured in number of field elements
|
||||||
//
|
//
|
||||||
// we use the padding `10*` from the original Poseidon paper,
|
// we use the padding `10*` from the original Poseidon paper,
|
||||||
// and initial state constant zero. Note that this is different
|
// and initial state constant zero. Note that this is different
|
||||||
// from the "SAFE padding" recommended in the Poseidon2 paper
|
// from the "SAFE padding" recommended in the Poseidon2 paper
|
||||||
// (which uses `0*` padding and a nontrivial initial state)
|
// (which uses `0*` padding and a nontrivial initial state)
|
||||||
//
|
//
|
||||||
@ -47,7 +47,7 @@ template PoseidonSponge(t, capacity, input_len, output_len) {
|
|||||||
signal padded[padded_len];
|
signal padded[padded_len];
|
||||||
for(var i=0; i<input_len; i++) { padded[i] <== inp[i]; }
|
for(var i=0; i<input_len; i++) { padded[i] <== inp[i]; }
|
||||||
padded[input_len ] <== 1;
|
padded[input_len ] <== 1;
|
||||||
for(var i=input_len+1; i<padded_len; i++) { padded[i] <== 0; }
|
for(var i=input_len+1; i<padded_len; i++) { padded[i] <== 0; }
|
||||||
|
|
||||||
signal state [nblocks+nout][t ];
|
signal state [nblocks+nout][t ];
|
||||||
signal sorbed[nblocks ][rate];
|
signal sorbed[nblocks ][rate];
|
||||||
@ -58,7 +58,7 @@ template PoseidonSponge(t, capacity, input_len, output_len) {
|
|||||||
|
|
||||||
// initialize state
|
// initialize state
|
||||||
for(var i=0; i<t-1; i++) { state[0][i] <== 0; }
|
for(var i=0; i<t-1; i++) { state[0][i] <== 0; }
|
||||||
state[0][t-1] <== civ;
|
state[0][t-1] <== civ;
|
||||||
|
|
||||||
component absorb [nblocks];
|
component absorb [nblocks];
|
||||||
component squeeze[nout-1];
|
component squeeze[nout-1];
|
||||||
@ -70,7 +70,7 @@ template PoseidonSponge(t, capacity, input_len, output_len) {
|
|||||||
var b = padded[m*rate+i];
|
var b = padded[m*rate+i];
|
||||||
sorbed[m][i] <== a + b;
|
sorbed[m][i] <== a + b;
|
||||||
}
|
}
|
||||||
|
|
||||||
absorb[m] = Permutation();
|
absorb[m] = Permutation();
|
||||||
for(var j=0 ; j<rate; j++) { absorb[m].inp[j] <== sorbed[m][j]; }
|
for(var j=0 ; j<rate; j++) { absorb[m].inp[j] <== sorbed[m][j]; }
|
||||||
for(var j=rate; j<t ; j++) { absorb[m].inp[j] <== state [m][j]; }
|
for(var j=rate; j<t ; j++) { absorb[m].inp[j] <== state [m][j]; }
|
||||||
|
|||||||
@ -21,16 +21,16 @@ include "misc.circom";
|
|||||||
//
|
//
|
||||||
|
|
||||||
template CalculateCellIndexBits( maxLog2N ) {
|
template CalculateCellIndexBits( maxLog2N ) {
|
||||||
|
|
||||||
signal input entropy;
|
signal input entropy;
|
||||||
signal input slotRoot;
|
signal input slotRoot;
|
||||||
signal input counter;
|
signal input counter;
|
||||||
signal input cellIndexBitMask[maxLog2N]; // bit mask for the cell index range
|
signal input cellIndexBitMask[maxLog2N]; // bit mask for the cell index range
|
||||||
|
|
||||||
signal output indexBits[maxLog2N];
|
signal output indexBits[maxLog2N];
|
||||||
|
|
||||||
// calculate the hash
|
// calculate the hash
|
||||||
component pos = Poseidon2_hash_rate2( 3 ); // input is 3 field elements
|
component pos = Poseidon2_hash_rate2( 3 ); // input is 3 field elements
|
||||||
signal hash;
|
signal hash;
|
||||||
pos.inp[0] <== entropy;
|
pos.inp[0] <== entropy;
|
||||||
pos.inp[1] <== slotRoot;
|
pos.inp[1] <== slotRoot;
|
||||||
@ -49,7 +49,7 @@ template CalculateCellIndexBits( maxLog2N ) {
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
//
|
//
|
||||||
// sample `nSamples` number of cells; calculate their hashes;
|
// sample `nSamples` number of cells; calculate their hashes;
|
||||||
// reconstruct the slot root using the Merkle paths, then
|
// reconstruct the slot root using the Merkle paths, then
|
||||||
// the dataset root too, and checks if everything is consistent.
|
// the dataset root too, and checks if everything is consistent.
|
||||||
@ -76,7 +76,7 @@ template SampleAndProve( maxDepth, maxLog2NSlots, blockTreeDepth, nFieldElemsPer
|
|||||||
|
|
||||||
// -------------------------------------------------------
|
// -------------------------------------------------------
|
||||||
//
|
//
|
||||||
// first we prove the inclusion of the slot root in the dataset-level
|
// first we prove the inclusion of the slot root in the dataset-level
|
||||||
// (small) Merkle tree
|
// (small) Merkle tree
|
||||||
|
|
||||||
component tbtp = ToBits( maxLog2NSlots );
|
component tbtp = ToBits( maxLog2NSlots );
|
||||||
@ -94,17 +94,15 @@ template SampleAndProve( maxDepth, maxLog2NSlots, blockTreeDepth, nFieldElemsPer
|
|||||||
log("top root check = ", mtop.recRoot == dataSetRoot);
|
log("top root check = ", mtop.recRoot == dataSetRoot);
|
||||||
|
|
||||||
mtop.recRoot === dataSetRoot;
|
mtop.recRoot === dataSetRoot;
|
||||||
|
|
||||||
// -------------------------------------------------------
|
// -------------------------------------------------------
|
||||||
//
|
//
|
||||||
// then we prove the individual sampled cells
|
// then we prove the individual sampled cells
|
||||||
|
|
||||||
signal log2N;
|
|
||||||
component lg = Log2(maxDepth); // we allow at most 2^32 cells per slot
|
component lg = Log2(maxDepth); // we allow at most 2^32 cells per slot
|
||||||
lg.inp <== nCellsPerSlot;
|
lg.inp <== nCellsPerSlot;
|
||||||
lg.out ==> log2N;
|
|
||||||
|
|
||||||
// NOTE: in general we need the for Merkle prover the binary decomposition
|
// NOTE: in general we need for the Merkle prover the binary decomposition
|
||||||
// of `nLeaves - 1`. But currently this is in fact a power of two, so we
|
// of `nLeaves - 1`. But currently this is in fact a power of two, so we
|
||||||
// can reuse the binary mask for this. Later we may change this?
|
// can reuse the binary mask for this. Later we may change this?
|
||||||
//
|
//
|
||||||
@ -118,7 +116,7 @@ log("top root check = ", mtop.recRoot == dataSetRoot);
|
|||||||
|
|
||||||
calci[cnt] = CalculateCellIndexBits( maxDepth );
|
calci[cnt] = CalculateCellIndexBits( maxDepth );
|
||||||
prove[cnt] = ProveSingleCell( nFieldElemsPerCell, blockTreeDepth, maxDepth );
|
prove[cnt] = ProveSingleCell( nFieldElemsPerCell, blockTreeDepth, maxDepth );
|
||||||
|
|
||||||
// calci[cnt].cellIndexBitMask <== lg.mask;
|
// calci[cnt].cellIndexBitMask <== lg.mask;
|
||||||
for(var i=0; i<maxDepth; i++) { calci[cnt].cellIndexBitMask[i] <== lg.mask[i]; }
|
for(var i=0; i<maxDepth; i++) { calci[cnt].cellIndexBitMask[i] <== lg.mask[i]; }
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
pragma circom 2.0.0;
|
pragma circom 2.0.0;
|
||||||
|
|
||||||
include "poseidon2_perm.circom";
|
|
||||||
include "poseidon2_hash.circom";
|
include "poseidon2_hash.circom";
|
||||||
|
|
||||||
include "merkle.circom";
|
include "merkle.circom";
|
||||||
include "misc.circom";
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user