From 63c04c9c2f715d63c4a54172e531f21714b84914 Mon Sep 17 00:00:00 2001 From: Stefan Nikolov Date: Thu, 22 Jun 2023 15:34:54 +0300 Subject: [PATCH 01/10] Refactor(circom): Move selector, division generic funcs to `/utils` --- .../is_valid_merkle_branch_out.circom | 5 +- .../circom/circuits/utils.circom | 52 ------------------ .../circom/circuits/utils/arrays.circom | 54 +++++++++++++++++++ .../circom/circuits/utils/bits.circom | 26 +++++++++ .../circom/circuits/utils/numerical.circom | 10 ++++ .../circom/circuits/validator_balances.circom | 37 ++----------- 6 files changed, 95 insertions(+), 89 deletions(-) delete mode 100644 beacon-light-client/circom/circuits/utils.circom create mode 100644 beacon-light-client/circom/circuits/utils/arrays.circom create mode 100644 beacon-light-client/circom/circuits/utils/bits.circom create mode 100644 beacon-light-client/circom/circuits/utils/numerical.circom diff --git a/beacon-light-client/circom/circuits/is_valid_merkle_branch_out.circom b/beacon-light-client/circom/circuits/is_valid_merkle_branch_out.circom index 52694df67..14f4943e2 100644 --- a/beacon-light-client/circom/circuits/is_valid_merkle_branch_out.circom +++ b/beacon-light-client/circom/circuits/is_valid_merkle_branch_out.circom @@ -1,8 +1,8 @@ -pragma circom 2.0.3; +pragma circom 2.1.5; include "hash_two.circom"; include "../../../node_modules/circomlib/circuits/comparators.circom"; -include "utils.circom"; +include "utils/arrays.circom"; template IsValidMerkleBranchOut(N) { signal input branch[N][256]; @@ -33,6 +33,5 @@ template IsValidMerkleBranchOut(N) { } } - out <== IsEqualArrays(256)([root, hashers[N - 1].out]); } diff --git a/beacon-light-client/circom/circuits/utils.circom b/beacon-light-client/circom/circuits/utils.circom deleted file mode 100644 index 9a0cf2d01..000000000 --- a/beacon-light-client/circom/circuits/utils.circom +++ /dev/null @@ -1,52 +0,0 @@ -pragma circom 2.1.5; - -include "../../../node_modules/circomlib/circuits/comparators.circom"; -include "../../../node_modules/circomlib/circuits/bitify.circom"; - -template LessThanBitsCheck(n) { - signal input in[2]; - signal output out; - - signal bitCheck1[n] <== Num2Bits(n)(in[0]); - - signal bitCheck2[n] <== Num2Bits(n)(in[1]); - - out <== LessThan(n)(in); -} - -template LessThanOrEqualBitsCheck(n) { - signal input in[2]; - signal output out; - - signal bitCheck1[n] <== Num2Bits(n)(in[0]); - - signal bitCheck2[n] <== Num2Bits(n)(in[1]); - - out <== LessEqThan(n)(in); -} - -template RangeCheck(n) { - signal input in[3]; - signal output out; - - signal first <== LessThanBitsCheck(64)([in[0], in[1]]); - signal second <== LessThanBitsCheck(64)([in[1], in[2]]); - - out <== first * second; -} - -template IsEqualArrays(N) { - signal input in[2][N]; - signal output out; - - signal isEqual[N]; - var counter = 0; - - for(var i = 0; i < N; i++) { - isEqual[i] <== IsEqual()([in[0][i], in[1][i]]); - - counter += isEqual[i]; - } - - out <== IsEqual()([N, counter]); -} diff --git a/beacon-light-client/circom/circuits/utils/arrays.circom b/beacon-light-client/circom/circuits/utils/arrays.circom new file mode 100644 index 000000000..c8a7f3220 --- /dev/null +++ b/beacon-light-client/circom/circuits/utils/arrays.circom @@ -0,0 +1,54 @@ +pragma circom 2.1.5; + +include "../../../../node_modules/circomlib/circuits/comparators.circom"; +include "../../../../node_modules/circomlib/circuits/bitify.circom"; + +template Selector(N) { + signal input in[N]; + signal input index; + signal output out; + + signal sums[N + 1]; + sums[0] <== 0; + + component eqs[N]; + + // For each item, check whether its index equals the input index. + for (var i = 0; i < N; i ++) { + eqs[i] = IsEqual(); + eqs[i].in[0] <== i; + eqs[i].in[1] <== index; + + // eqs[i].out is 1 if the index matches. As such, at most one input to + sums[i + 1] <== sums[i] + eqs[i].out * in[i]; + } + + // Returns 0 + 0 + ... + item + out <== sums[N]; +} + +template RangeCheck(n) { + signal input in[3]; + signal output out; + + signal first <== LessThanBitsCheck(64)([in[0], in[1]]); + signal second <== LessThanBitsCheck(64)([in[1], in[2]]); + + out <== first * second; +} + +template IsEqualArrays(N) { + signal input in[2][N]; + signal output out; + + signal isEqual[N]; + var counter = 0; + + for(var i = 0; i < N; i++) { + isEqual[i] <== IsEqual()([in[0][i], in[1][i]]); + + counter += isEqual[i]; + } + + out <== IsEqual()([N, counter]); +} diff --git a/beacon-light-client/circom/circuits/utils/bits.circom b/beacon-light-client/circom/circuits/utils/bits.circom new file mode 100644 index 000000000..e6bc7aa64 --- /dev/null +++ b/beacon-light-client/circom/circuits/utils/bits.circom @@ -0,0 +1,26 @@ +pragma circom 2.1.5; + +include "../../../../node_modules/circomlib/circuits/comparators.circom"; +include "../../../../node_modules/circomlib/circuits/bitify.circom"; + +template LessThanBitsCheck(n) { + signal input in[2]; + signal output out; + + signal bitCheck1[n] <== Num2Bits(n)(in[0]); + + signal bitCheck2[n] <== Num2Bits(n)(in[1]); + + out <== LessThan(n)(in); +} + +template LessThanOrEqualBitsCheck(n) { + signal input in[2]; + signal output out; + + signal bitCheck1[n] <== Num2Bits(n)(in[0]); + + signal bitCheck2[n] <== Num2Bits(n)(in[1]); + + out <== LessEqThan(n)(in); +} \ No newline at end of file diff --git a/beacon-light-client/circom/circuits/utils/numerical.circom b/beacon-light-client/circom/circuits/utils/numerical.circom new file mode 100644 index 000000000..8ff74d7e1 --- /dev/null +++ b/beacon-light-client/circom/circuits/utils/numerical.circom @@ -0,0 +1,10 @@ +pragma circom 2.1.5; + +template DivisionVerification() { + signal input dividend; + signal input divisor; + signal input quotient; + signal input remainder; + + dividend === divisor * quotient + remainder; +} diff --git a/beacon-light-client/circom/circuits/validator_balances.circom b/beacon-light-client/circom/circuits/validator_balances.circom index 402e542d4..0a2917236 100644 --- a/beacon-light-client/circom/circuits/validator_balances.circom +++ b/beacon-light-client/circom/circuits/validator_balances.circom @@ -1,46 +1,15 @@ pragma circom 2.1.5; include "../../../node_modules/circomlib/circuits/bitify.circom"; -include "utils.circom"; include "hash_tree_root.circom"; include "hash_two.circom"; include "validator_hash_tree_root.circom"; include "is_valid_merkle_branch_out.circom"; include "is_valid_merkle_branch.circom"; include "ssz_num.circom"; - -template DivisionVerification() { - signal input dividend; - signal input divisor; - signal input quotient; - signal input remainder; - - dividend === divisor * quotient + remainder; -} - -template Selector(N) { - signal input in[N]; - signal input index; - signal output out; - - signal sums[N + 1]; - sums[0] <== 0; - - component eqs[N]; - - // For each item, check whether its index equals the input index. - for (var i = 0; i < N; i ++) { - eqs[i] = IsEqual(); - eqs[i].in[0] <== i; - eqs[i].in[1] <== index; - - // eqs[i].out is 1 if the index matches. As such, at most one input to - sums[i + 1] <== sums[i] + eqs[i].out * in[i]; - } - - // Returns 0 + 0 + ... + item - out <== sums[N]; -} +include "./utils/arrays.circom"; +include "./utils/bits.circom"; +include "./utils/numerical.circom"; template CalculateBalancesSum(N) { signal input balances[(N \ 4) + 1][256]; From 9ef61e5d263bc272205e70a25990cdfc6085f9c2 Mon Sep 17 00:00:00 2001 From: Stefan Nikolov Date: Fri, 23 Jun 2023 15:11:45 +0300 Subject: [PATCH 02/10] feat(circom): Added Pow template --- .../circom/circuits/utils/numerical.circom | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/beacon-light-client/circom/circuits/utils/numerical.circom b/beacon-light-client/circom/circuits/utils/numerical.circom index 8ff74d7e1..b53999edb 100644 --- a/beacon-light-client/circom/circuits/utils/numerical.circom +++ b/beacon-light-client/circom/circuits/utils/numerical.circom @@ -1,5 +1,31 @@ pragma circom 2.1.5; +include "../../../../node_modules/circomlib/circuits/comparators.circom"; +include "../../../../node_modules/circomlib/circuits/bitify.circom"; +include "arrays.circom"; + +template LessThanBitsCheck(n) { + signal input in[2]; + signal output out; + + signal bitCheck1[n] <== Num2Bits(n)(in[0]); + + signal bitCheck2[n] <== Num2Bits(n)(in[1]); + + out <== LessThan(n)(in); +} + +template LessThanOrEqualBitsCheck(n) { + signal input in[2]; + signal output out; + + signal bitCheck1[n] <== Num2Bits(n)(in[0]); + + signal bitCheck2[n] <== Num2Bits(n)(in[1]); + + out <== LessEqThan(n)(in); +} + template DivisionVerification() { signal input dividend; signal input divisor; @@ -8,3 +34,26 @@ template DivisionVerification() { dividend === divisor * quotient + remainder; } + +template Pow(N){ + signal input base; + signal input power; + signal output out; + + assert(power < N); + + signal intermediary[N]; + for (var i=0; i < N; i++) { + intermediary[i] <== i == 0 ? 1 : (intermediary[i-1] * base); + } + + component selector = Selector(N); + for (var i = 0; i < N; i++) { + selector.in[i] <== intermediary[i]; + } + selector.index <== power; + + out <== selector.out; +} + +component main = Pow(256); From a7da21d7f3b6c6ba9a2e8544db78f0b228f8fa6a Mon Sep 17 00:00:00 2001 From: Stefan Nikolov Date: Fri, 23 Jun 2023 15:20:26 +0300 Subject: [PATCH 03/10] fix(circom) Add TODO for DivisionVerification constraint. --- beacon-light-client/circom/circuits/utils/numerical.circom | 1 + 1 file changed, 1 insertion(+) diff --git a/beacon-light-client/circom/circuits/utils/numerical.circom b/beacon-light-client/circom/circuits/utils/numerical.circom index b53999edb..d37c80525 100644 --- a/beacon-light-client/circom/circuits/utils/numerical.circom +++ b/beacon-light-client/circom/circuits/utils/numerical.circom @@ -32,6 +32,7 @@ template DivisionVerification() { signal input quotient; signal input remainder; + //TODO: Needs additional constraint dividend === divisor * quotient + remainder; } From 3bb8fd0237f8df57d5804cdc016c0f1d4ab08241 Mon Sep 17 00:00:00 2001 From: Stefan Nikolov Date: Fri, 23 Jun 2023 16:28:27 +0300 Subject: [PATCH 04/10] feat(circom) Add tests for pow function --- beacon-light-client/circom/test/pow/circuit.circom | 5 +++++ beacon-light-client/circom/test/pow/data/case01/input.json | 1 + beacon-light-client/circom/test/pow/data/case01/output.json | 3 +++ beacon-light-client/circom/test/pow/data/case02/input.json | 4 ++++ beacon-light-client/circom/test/pow/data/case02/output.json | 3 +++ beacon-light-client/circom/test/pow/data/case03/input.json | 4 ++++ beacon-light-client/circom/test/pow/data/case03/output.json | 3 +++ beacon-light-client/circom/test/pow/data/case04/input.json | 4 ++++ beacon-light-client/circom/test/pow/data/case04/output.json | 3 +++ 9 files changed, 30 insertions(+) create mode 100644 beacon-light-client/circom/test/pow/circuit.circom create mode 100644 beacon-light-client/circom/test/pow/data/case01/input.json create mode 100644 beacon-light-client/circom/test/pow/data/case01/output.json create mode 100644 beacon-light-client/circom/test/pow/data/case02/input.json create mode 100644 beacon-light-client/circom/test/pow/data/case02/output.json create mode 100644 beacon-light-client/circom/test/pow/data/case03/input.json create mode 100644 beacon-light-client/circom/test/pow/data/case03/output.json create mode 100644 beacon-light-client/circom/test/pow/data/case04/input.json create mode 100644 beacon-light-client/circom/test/pow/data/case04/output.json diff --git a/beacon-light-client/circom/test/pow/circuit.circom b/beacon-light-client/circom/test/pow/circuit.circom new file mode 100644 index 000000000..85a0aff57 --- /dev/null +++ b/beacon-light-client/circom/test/pow/circuit.circom @@ -0,0 +1,5 @@ +pragma circom 2.1.5; + +include "../../circuits/utils/numerical.circom"; + +component main = Pow(256); diff --git a/beacon-light-client/circom/test/pow/data/case01/input.json b/beacon-light-client/circom/test/pow/data/case01/input.json new file mode 100644 index 000000000..49a279f00 --- /dev/null +++ b/beacon-light-client/circom/test/pow/data/case01/input.json @@ -0,0 +1 @@ +{"base": "10", "power": "3"} diff --git a/beacon-light-client/circom/test/pow/data/case01/output.json b/beacon-light-client/circom/test/pow/data/case01/output.json new file mode 100644 index 000000000..7d20147b5 --- /dev/null +++ b/beacon-light-client/circom/test/pow/data/case01/output.json @@ -0,0 +1,3 @@ +{ + "out": "1000" +} diff --git a/beacon-light-client/circom/test/pow/data/case02/input.json b/beacon-light-client/circom/test/pow/data/case02/input.json new file mode 100644 index 000000000..993d63a28 --- /dev/null +++ b/beacon-light-client/circom/test/pow/data/case02/input.json @@ -0,0 +1,4 @@ +{ + "base": "2", + "power": "10" +} diff --git a/beacon-light-client/circom/test/pow/data/case02/output.json b/beacon-light-client/circom/test/pow/data/case02/output.json new file mode 100644 index 000000000..f727e391f --- /dev/null +++ b/beacon-light-client/circom/test/pow/data/case02/output.json @@ -0,0 +1,3 @@ +{ + "out": "1024" +} diff --git a/beacon-light-client/circom/test/pow/data/case03/input.json b/beacon-light-client/circom/test/pow/data/case03/input.json new file mode 100644 index 000000000..daede4e19 --- /dev/null +++ b/beacon-light-client/circom/test/pow/data/case03/input.json @@ -0,0 +1,4 @@ +{ + "base": "99", + "power": "1" +} diff --git a/beacon-light-client/circom/test/pow/data/case03/output.json b/beacon-light-client/circom/test/pow/data/case03/output.json new file mode 100644 index 000000000..891f5eea5 --- /dev/null +++ b/beacon-light-client/circom/test/pow/data/case03/output.json @@ -0,0 +1,3 @@ +{ + "out": "99" +} diff --git a/beacon-light-client/circom/test/pow/data/case04/input.json b/beacon-light-client/circom/test/pow/data/case04/input.json new file mode 100644 index 000000000..1e31fc28d --- /dev/null +++ b/beacon-light-client/circom/test/pow/data/case04/input.json @@ -0,0 +1,4 @@ +{ + "base": "1", + "power": "100" +} diff --git a/beacon-light-client/circom/test/pow/data/case04/output.json b/beacon-light-client/circom/test/pow/data/case04/output.json new file mode 100644 index 000000000..8575e58cd --- /dev/null +++ b/beacon-light-client/circom/test/pow/data/case04/output.json @@ -0,0 +1,3 @@ +{ + "out": "1" +} From 946b7fcebf3358adf0c2616bbd12c860d22f0f5a Mon Sep 17 00:00:00 2001 From: Stefan Nikolov Date: Fri, 23 Jun 2023 17:40:15 +0300 Subject: [PATCH 05/10] feat(circom) Add LessThanBitsCheck tests --- .../circom/test/less_than_bits_check/circuit.circom | 5 +++++ .../circom/test/less_than_bits_check/data/case01/input.json | 3 +++ .../circom/test/less_than_bits_check/data/case01/output.json | 3 +++ .../circom/test/less_than_bits_check/data/case02/input.json | 3 +++ .../circom/test/less_than_bits_check/data/case02/output.json | 3 +++ .../circom/test/less_than_bits_check/data/case03/input.json | 3 +++ .../circom/test/less_than_bits_check/data/case03/output.json | 3 +++ 7 files changed, 23 insertions(+) create mode 100644 beacon-light-client/circom/test/less_than_bits_check/circuit.circom create mode 100644 beacon-light-client/circom/test/less_than_bits_check/data/case01/input.json create mode 100644 beacon-light-client/circom/test/less_than_bits_check/data/case01/output.json create mode 100644 beacon-light-client/circom/test/less_than_bits_check/data/case02/input.json create mode 100644 beacon-light-client/circom/test/less_than_bits_check/data/case02/output.json create mode 100644 beacon-light-client/circom/test/less_than_bits_check/data/case03/input.json create mode 100644 beacon-light-client/circom/test/less_than_bits_check/data/case03/output.json diff --git a/beacon-light-client/circom/test/less_than_bits_check/circuit.circom b/beacon-light-client/circom/test/less_than_bits_check/circuit.circom new file mode 100644 index 000000000..7ee49b934 --- /dev/null +++ b/beacon-light-client/circom/test/less_than_bits_check/circuit.circom @@ -0,0 +1,5 @@ +pragma circom 2.1.5; + +include "../../circuits/utils/numerical.circom"; + +component main = LessThanBitsCheck(32) diff --git a/beacon-light-client/circom/test/less_than_bits_check/data/case01/input.json b/beacon-light-client/circom/test/less_than_bits_check/data/case01/input.json new file mode 100644 index 000000000..68d349081 --- /dev/null +++ b/beacon-light-client/circom/test/less_than_bits_check/data/case01/input.json @@ -0,0 +1,3 @@ +{ + "in": ["100","50"] +} diff --git a/beacon-light-client/circom/test/less_than_bits_check/data/case01/output.json b/beacon-light-client/circom/test/less_than_bits_check/data/case01/output.json new file mode 100644 index 000000000..fcf6c9a06 --- /dev/null +++ b/beacon-light-client/circom/test/less_than_bits_check/data/case01/output.json @@ -0,0 +1,3 @@ +{ + "out": "0" +} diff --git a/beacon-light-client/circom/test/less_than_bits_check/data/case02/input.json b/beacon-light-client/circom/test/less_than_bits_check/data/case02/input.json new file mode 100644 index 000000000..2a7b534b8 --- /dev/null +++ b/beacon-light-client/circom/test/less_than_bits_check/data/case02/input.json @@ -0,0 +1,3 @@ +{ + "in": ["1","2"] +} diff --git a/beacon-light-client/circom/test/less_than_bits_check/data/case02/output.json b/beacon-light-client/circom/test/less_than_bits_check/data/case02/output.json new file mode 100644 index 000000000..8575e58cd --- /dev/null +++ b/beacon-light-client/circom/test/less_than_bits_check/data/case02/output.json @@ -0,0 +1,3 @@ +{ + "out": "1" +} diff --git a/beacon-light-client/circom/test/less_than_bits_check/data/case03/input.json b/beacon-light-client/circom/test/less_than_bits_check/data/case03/input.json new file mode 100644 index 000000000..9f54db27d --- /dev/null +++ b/beacon-light-client/circom/test/less_than_bits_check/data/case03/input.json @@ -0,0 +1,3 @@ +{ + "in": ["1","1"] +} diff --git a/beacon-light-client/circom/test/less_than_bits_check/data/case03/output.json b/beacon-light-client/circom/test/less_than_bits_check/data/case03/output.json new file mode 100644 index 000000000..fcf6c9a06 --- /dev/null +++ b/beacon-light-client/circom/test/less_than_bits_check/data/case03/output.json @@ -0,0 +1,3 @@ +{ + "out": "0" +} From 0b72802b9546c4ed3f6f27e9a09d438fe4ee47bf Mon Sep 17 00:00:00 2001 From: Stefan Nikolov Date: Fri, 23 Jun 2023 17:50:11 +0300 Subject: [PATCH 06/10] feat(circom) Add tests for LessThanOrEqualBitsCheck circuit. --- .../circom/test/less_than_bits_check/circuit.circom | 2 +- .../circom/test/less_than_eq_bits_check/circuit.circom | 9 +++++++++ .../test/less_than_eq_bits_check/data/case01/input.json | 3 +++ .../test/less_than_eq_bits_check/data/case01/output.json | 3 +++ .../test/less_than_eq_bits_check/data/case02/input.json | 3 +++ .../test/less_than_eq_bits_check/data/case02/output.json | 3 +++ .../test/less_than_eq_bits_check/data/case03/input.json | 3 +++ .../test/less_than_eq_bits_check/data/case03/output.json | 3 +++ beacon-light-client/circom/test/selector/circuit.circom | 5 +++++ .../circom/test/selector/data/case01/input.json | 4 ++++ .../circom/test/selector/data/case01/output.json | 3 +++ .../circom/test/selector/data/case02/input.json | 4 ++++ .../circom/test/selector/data/case02/output.json | 3 +++ .../circom/test/selector/data/case03/input.json | 4 ++++ .../circom/test/selector/data/case03/output.json | 3 +++ 15 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 beacon-light-client/circom/test/less_than_eq_bits_check/circuit.circom create mode 100644 beacon-light-client/circom/test/less_than_eq_bits_check/data/case01/input.json create mode 100644 beacon-light-client/circom/test/less_than_eq_bits_check/data/case01/output.json create mode 100644 beacon-light-client/circom/test/less_than_eq_bits_check/data/case02/input.json create mode 100644 beacon-light-client/circom/test/less_than_eq_bits_check/data/case02/output.json create mode 100644 beacon-light-client/circom/test/less_than_eq_bits_check/data/case03/input.json create mode 100644 beacon-light-client/circom/test/less_than_eq_bits_check/data/case03/output.json create mode 100644 beacon-light-client/circom/test/selector/circuit.circom create mode 100644 beacon-light-client/circom/test/selector/data/case01/input.json create mode 100644 beacon-light-client/circom/test/selector/data/case01/output.json create mode 100644 beacon-light-client/circom/test/selector/data/case02/input.json create mode 100644 beacon-light-client/circom/test/selector/data/case02/output.json create mode 100644 beacon-light-client/circom/test/selector/data/case03/input.json create mode 100644 beacon-light-client/circom/test/selector/data/case03/output.json diff --git a/beacon-light-client/circom/test/less_than_bits_check/circuit.circom b/beacon-light-client/circom/test/less_than_bits_check/circuit.circom index 7ee49b934..e646ee633 100644 --- a/beacon-light-client/circom/test/less_than_bits_check/circuit.circom +++ b/beacon-light-client/circom/test/less_than_bits_check/circuit.circom @@ -2,4 +2,4 @@ pragma circom 2.1.5; include "../../circuits/utils/numerical.circom"; -component main = LessThanBitsCheck(32) +component main = LessThanBitsCheck(32); diff --git a/beacon-light-client/circom/test/less_than_eq_bits_check/circuit.circom b/beacon-light-client/circom/test/less_than_eq_bits_check/circuit.circom new file mode 100644 index 000000000..b4936fd3b --- /dev/null +++ b/beacon-light-client/circom/test/less_than_eq_bits_check/circuit.circom @@ -0,0 +1,9 @@ +pragma circom 2.1.5; + +include "../../circuits/utils/arrays.circom"; + +<<<<<<< HEAD +component main = LessThanOrEqualBitsCheck(32); +======= +component main = Selector(8) // N must be equal to input["in"] length +>>>>>>> 7f6ce53 (feat(circom) Add tests for Selector circuit.) diff --git a/beacon-light-client/circom/test/less_than_eq_bits_check/data/case01/input.json b/beacon-light-client/circom/test/less_than_eq_bits_check/data/case01/input.json new file mode 100644 index 000000000..68d349081 --- /dev/null +++ b/beacon-light-client/circom/test/less_than_eq_bits_check/data/case01/input.json @@ -0,0 +1,3 @@ +{ + "in": ["100","50"] +} diff --git a/beacon-light-client/circom/test/less_than_eq_bits_check/data/case01/output.json b/beacon-light-client/circom/test/less_than_eq_bits_check/data/case01/output.json new file mode 100644 index 000000000..fcf6c9a06 --- /dev/null +++ b/beacon-light-client/circom/test/less_than_eq_bits_check/data/case01/output.json @@ -0,0 +1,3 @@ +{ + "out": "0" +} diff --git a/beacon-light-client/circom/test/less_than_eq_bits_check/data/case02/input.json b/beacon-light-client/circom/test/less_than_eq_bits_check/data/case02/input.json new file mode 100644 index 000000000..2a7b534b8 --- /dev/null +++ b/beacon-light-client/circom/test/less_than_eq_bits_check/data/case02/input.json @@ -0,0 +1,3 @@ +{ + "in": ["1","2"] +} diff --git a/beacon-light-client/circom/test/less_than_eq_bits_check/data/case02/output.json b/beacon-light-client/circom/test/less_than_eq_bits_check/data/case02/output.json new file mode 100644 index 000000000..8575e58cd --- /dev/null +++ b/beacon-light-client/circom/test/less_than_eq_bits_check/data/case02/output.json @@ -0,0 +1,3 @@ +{ + "out": "1" +} diff --git a/beacon-light-client/circom/test/less_than_eq_bits_check/data/case03/input.json b/beacon-light-client/circom/test/less_than_eq_bits_check/data/case03/input.json new file mode 100644 index 000000000..9f54db27d --- /dev/null +++ b/beacon-light-client/circom/test/less_than_eq_bits_check/data/case03/input.json @@ -0,0 +1,3 @@ +{ + "in": ["1","1"] +} diff --git a/beacon-light-client/circom/test/less_than_eq_bits_check/data/case03/output.json b/beacon-light-client/circom/test/less_than_eq_bits_check/data/case03/output.json new file mode 100644 index 000000000..8575e58cd --- /dev/null +++ b/beacon-light-client/circom/test/less_than_eq_bits_check/data/case03/output.json @@ -0,0 +1,3 @@ +{ + "out": "1" +} diff --git a/beacon-light-client/circom/test/selector/circuit.circom b/beacon-light-client/circom/test/selector/circuit.circom new file mode 100644 index 000000000..ee8918502 --- /dev/null +++ b/beacon-light-client/circom/test/selector/circuit.circom @@ -0,0 +1,5 @@ +pragma circom 2.1.5; + +include "../../circuits/utils/numerical.circom"; + +component main = LessThanOrEqualBitsCheck(32) diff --git a/beacon-light-client/circom/test/selector/data/case01/input.json b/beacon-light-client/circom/test/selector/data/case01/input.json new file mode 100644 index 000000000..d0b157df3 --- /dev/null +++ b/beacon-light-client/circom/test/selector/data/case01/input.json @@ -0,0 +1,4 @@ +{ + "in": ["1","2","3","4","5","6","7","8"], + "index": "4" +} diff --git a/beacon-light-client/circom/test/selector/data/case01/output.json b/beacon-light-client/circom/test/selector/data/case01/output.json new file mode 100644 index 000000000..d84af3026 --- /dev/null +++ b/beacon-light-client/circom/test/selector/data/case01/output.json @@ -0,0 +1,3 @@ +{ + "out": "5" +} diff --git a/beacon-light-client/circom/test/selector/data/case02/input.json b/beacon-light-client/circom/test/selector/data/case02/input.json new file mode 100644 index 000000000..3bd6eea7a --- /dev/null +++ b/beacon-light-client/circom/test/selector/data/case02/input.json @@ -0,0 +1,4 @@ +{ + "in": ["123","123","123","123","123","123","123","99"], + "index": "7" +} diff --git a/beacon-light-client/circom/test/selector/data/case02/output.json b/beacon-light-client/circom/test/selector/data/case02/output.json new file mode 100644 index 000000000..891f5eea5 --- /dev/null +++ b/beacon-light-client/circom/test/selector/data/case02/output.json @@ -0,0 +1,3 @@ +{ + "out": "99" +} diff --git a/beacon-light-client/circom/test/selector/data/case03/input.json b/beacon-light-client/circom/test/selector/data/case03/input.json new file mode 100644 index 000000000..9219ace0d --- /dev/null +++ b/beacon-light-client/circom/test/selector/data/case03/input.json @@ -0,0 +1,4 @@ +{ + "in": ["99","123","123","123","123","123","123","123"], + "index": "0" +} diff --git a/beacon-light-client/circom/test/selector/data/case03/output.json b/beacon-light-client/circom/test/selector/data/case03/output.json new file mode 100644 index 000000000..891f5eea5 --- /dev/null +++ b/beacon-light-client/circom/test/selector/data/case03/output.json @@ -0,0 +1,3 @@ +{ + "out": "99" +} From 821b55a6e7dc61e83df2b72e9ed36d76858460cc Mon Sep 17 00:00:00 2001 From: Stefan Nikolov Date: Fri, 23 Jun 2023 18:17:19 +0300 Subject: [PATCH 07/10] fix(circom): Move RangeCheck circuit to numerical.circom --- .../circom/circuits/utils/arrays.circom | 10 ---------- .../circom/circuits/utils/numerical.circom | 10 ++++++++++ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/beacon-light-client/circom/circuits/utils/arrays.circom b/beacon-light-client/circom/circuits/utils/arrays.circom index c8a7f3220..475e62c95 100644 --- a/beacon-light-client/circom/circuits/utils/arrays.circom +++ b/beacon-light-client/circom/circuits/utils/arrays.circom @@ -27,16 +27,6 @@ template Selector(N) { out <== sums[N]; } -template RangeCheck(n) { - signal input in[3]; - signal output out; - - signal first <== LessThanBitsCheck(64)([in[0], in[1]]); - signal second <== LessThanBitsCheck(64)([in[1], in[2]]); - - out <== first * second; -} - template IsEqualArrays(N) { signal input in[2][N]; signal output out; diff --git a/beacon-light-client/circom/circuits/utils/numerical.circom b/beacon-light-client/circom/circuits/utils/numerical.circom index d37c80525..1a7052b2c 100644 --- a/beacon-light-client/circom/circuits/utils/numerical.circom +++ b/beacon-light-client/circom/circuits/utils/numerical.circom @@ -26,6 +26,16 @@ template LessThanOrEqualBitsCheck(n) { out <== LessEqThan(n)(in); } +template RangeCheck(n) { + signal input in[3]; + signal output out; + + signal first <== LessThanBitsCheck(64)([in[0], in[1]]); + signal second <== LessThanBitsCheck(64)([in[1], in[2]]); + + out <== first * second; +} + template DivisionVerification() { signal input dividend; signal input divisor; From a6a522eb192b0ff574ff2bf9c78830b2fc107310 Mon Sep 17 00:00:00 2001 From: Stefan Nikolov Date: Fri, 23 Jun 2023 18:29:34 +0300 Subject: [PATCH 08/10] fix(circom): Update RangeCheck to propogate numerical constraints. --- beacon-light-client/circom/circuits/utils/numerical.circom | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/beacon-light-client/circom/circuits/utils/numerical.circom b/beacon-light-client/circom/circuits/utils/numerical.circom index 1a7052b2c..20466df54 100644 --- a/beacon-light-client/circom/circuits/utils/numerical.circom +++ b/beacon-light-client/circom/circuits/utils/numerical.circom @@ -30,8 +30,8 @@ template RangeCheck(n) { signal input in[3]; signal output out; - signal first <== LessThanBitsCheck(64)([in[0], in[1]]); - signal second <== LessThanBitsCheck(64)([in[1], in[2]]); + signal first <== LessThanBitsCheck(n)([in[0], in[1]]); + signal second <== LessThanBitsCheck(n)([in[1], in[2]]); out <== first * second; } From dfb10fe0ac8adac64b65e1c282041c063a412524 Mon Sep 17 00:00:00 2001 From: Stefan Nikolov Date: Fri, 23 Jun 2023 18:41:07 +0300 Subject: [PATCH 09/10] feat(circom): Add tests for RangeCheck circuit. --- .../circom/test/less_than_eq_bits_check/circuit.circom | 4 ++++ beacon-light-client/circom/test/range_check/circuit.circom | 5 +++++ .../circom/test/range_check/data/case01/input.json | 1 + .../circom/test/range_check/data/case01/output.json | 3 +++ .../circom/test/range_check/data/case02/input.json | 1 + .../circom/test/range_check/data/case02/output.json | 3 +++ .../circom/test/range_check/data/case03/input.json | 1 + .../circom/test/range_check/data/case03/output.json | 3 +++ .../circom/test/range_check/data/case04/input.json | 1 + .../circom/test/range_check/data/case04/output.json | 3 +++ beacon-light-client/circom/test/selector/circuit.circom | 4 ++-- 11 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 beacon-light-client/circom/test/range_check/circuit.circom create mode 100644 beacon-light-client/circom/test/range_check/data/case01/input.json create mode 100644 beacon-light-client/circom/test/range_check/data/case01/output.json create mode 100644 beacon-light-client/circom/test/range_check/data/case02/input.json create mode 100644 beacon-light-client/circom/test/range_check/data/case02/output.json create mode 100644 beacon-light-client/circom/test/range_check/data/case03/input.json create mode 100644 beacon-light-client/circom/test/range_check/data/case03/output.json create mode 100644 beacon-light-client/circom/test/range_check/data/case04/input.json create mode 100644 beacon-light-client/circom/test/range_check/data/case04/output.json diff --git a/beacon-light-client/circom/test/less_than_eq_bits_check/circuit.circom b/beacon-light-client/circom/test/less_than_eq_bits_check/circuit.circom index b4936fd3b..badfa9e8d 100644 --- a/beacon-light-client/circom/test/less_than_eq_bits_check/circuit.circom +++ b/beacon-light-client/circom/test/less_than_eq_bits_check/circuit.circom @@ -2,8 +2,12 @@ pragma circom 2.1.5; include "../../circuits/utils/arrays.circom"; +<<<<<<< HEAD <<<<<<< HEAD component main = LessThanOrEqualBitsCheck(32); ======= component main = Selector(8) // N must be equal to input["in"] length >>>>>>> 7f6ce53 (feat(circom) Add tests for Selector circuit.) +======= +component main = LessThanOrEqualBitsCheck(32) +>>>>>>> 5452718 (fix(circom): Fix wrong main call for selector and less_than_eq_bits_check.) diff --git a/beacon-light-client/circom/test/range_check/circuit.circom b/beacon-light-client/circom/test/range_check/circuit.circom new file mode 100644 index 000000000..41ac857d6 --- /dev/null +++ b/beacon-light-client/circom/test/range_check/circuit.circom @@ -0,0 +1,5 @@ +pragma circom 2.1.5; + +include "../../circuits/utils/numerical.circom"; + +component main = RangeCheck(32); diff --git a/beacon-light-client/circom/test/range_check/data/case01/input.json b/beacon-light-client/circom/test/range_check/data/case01/input.json new file mode 100644 index 000000000..dbfd86aed --- /dev/null +++ b/beacon-light-client/circom/test/range_check/data/case01/input.json @@ -0,0 +1 @@ +{"in": ["1","2","3"]} diff --git a/beacon-light-client/circom/test/range_check/data/case01/output.json b/beacon-light-client/circom/test/range_check/data/case01/output.json new file mode 100644 index 000000000..8575e58cd --- /dev/null +++ b/beacon-light-client/circom/test/range_check/data/case01/output.json @@ -0,0 +1,3 @@ +{ + "out": "1" +} diff --git a/beacon-light-client/circom/test/range_check/data/case02/input.json b/beacon-light-client/circom/test/range_check/data/case02/input.json new file mode 100644 index 000000000..30acbcb2e --- /dev/null +++ b/beacon-light-client/circom/test/range_check/data/case02/input.json @@ -0,0 +1 @@ +{"in": ["3","2","1"]} diff --git a/beacon-light-client/circom/test/range_check/data/case02/output.json b/beacon-light-client/circom/test/range_check/data/case02/output.json new file mode 100644 index 000000000..fcf6c9a06 --- /dev/null +++ b/beacon-light-client/circom/test/range_check/data/case02/output.json @@ -0,0 +1,3 @@ +{ + "out": "0" +} diff --git a/beacon-light-client/circom/test/range_check/data/case03/input.json b/beacon-light-client/circom/test/range_check/data/case03/input.json new file mode 100644 index 000000000..e5f399fe0 --- /dev/null +++ b/beacon-light-client/circom/test/range_check/data/case03/input.json @@ -0,0 +1 @@ +{"in": ["2","2","3"]} diff --git a/beacon-light-client/circom/test/range_check/data/case03/output.json b/beacon-light-client/circom/test/range_check/data/case03/output.json new file mode 100644 index 000000000..fcf6c9a06 --- /dev/null +++ b/beacon-light-client/circom/test/range_check/data/case03/output.json @@ -0,0 +1,3 @@ +{ + "out": "0" +} diff --git a/beacon-light-client/circom/test/range_check/data/case04/input.json b/beacon-light-client/circom/test/range_check/data/case04/input.json new file mode 100644 index 000000000..2c8a6a40f --- /dev/null +++ b/beacon-light-client/circom/test/range_check/data/case04/input.json @@ -0,0 +1 @@ +{"in": ["1","2","2"]} diff --git a/beacon-light-client/circom/test/range_check/data/case04/output.json b/beacon-light-client/circom/test/range_check/data/case04/output.json new file mode 100644 index 000000000..fcf6c9a06 --- /dev/null +++ b/beacon-light-client/circom/test/range_check/data/case04/output.json @@ -0,0 +1,3 @@ +{ + "out": "0" +} diff --git a/beacon-light-client/circom/test/selector/circuit.circom b/beacon-light-client/circom/test/selector/circuit.circom index ee8918502..4d047b804 100644 --- a/beacon-light-client/circom/test/selector/circuit.circom +++ b/beacon-light-client/circom/test/selector/circuit.circom @@ -1,5 +1,5 @@ pragma circom 2.1.5; -include "../../circuits/utils/numerical.circom"; +include "../../circuits/utils/arrays.circom"; -component main = LessThanOrEqualBitsCheck(32) +component main = Selector(32) // N must be equal to input["in"] length From 43b2d3cd6053031d9e6f962da024ef812c334fe0 Mon Sep 17 00:00:00 2001 From: Stefan Nikolov Date: Fri, 23 Jun 2023 19:16:41 +0300 Subject: [PATCH 10/10] feat(circom): Add tests to IsEqaulArrays --- .../circom/circuits/utils/numerical.circom | 4 +--- .../circom/test/is_equal_arrays/circuit.circom | 5 +++++ .../circom/test/is_equal_arrays/data/case01/input.json | 1 + .../test/is_equal_arrays/data/case01/output.json | 1 + .../circom/test/is_equal_arrays/data/case02/input.json | 1 + .../test/is_equal_arrays/data/case02/output.json | 1 + .../circom/test/is_equal_arrays/data/case03/input.json | 1 + .../test/is_equal_arrays/data/case03/output.json | 1 + .../circom/test/less_than_eq_bits_check/circuit.circom | 10 +--------- .../circom/test/selector/circuit.circom | 2 +- 10 files changed, 14 insertions(+), 13 deletions(-) create mode 100644 beacon-light-client/circom/test/is_equal_arrays/circuit.circom create mode 100644 beacon-light-client/circom/test/is_equal_arrays/data/case01/input.json create mode 100644 beacon-light-client/circom/test/is_equal_arrays/data/case01/output.json create mode 100644 beacon-light-client/circom/test/is_equal_arrays/data/case02/input.json create mode 100644 beacon-light-client/circom/test/is_equal_arrays/data/case02/output.json create mode 100644 beacon-light-client/circom/test/is_equal_arrays/data/case03/input.json create mode 100644 beacon-light-client/circom/test/is_equal_arrays/data/case03/output.json diff --git a/beacon-light-client/circom/circuits/utils/numerical.circom b/beacon-light-client/circom/circuits/utils/numerical.circom index 20466df54..5ffee1ec6 100644 --- a/beacon-light-client/circom/circuits/utils/numerical.circom +++ b/beacon-light-client/circom/circuits/utils/numerical.circom @@ -42,7 +42,7 @@ template DivisionVerification() { signal input quotient; signal input remainder; - //TODO: Needs additional constraint + //TODO: Needs additional corebase nstraint dividend === divisor * quotient + remainder; } @@ -66,5 +66,3 @@ template Pow(N){ out <== selector.out; } - -component main = Pow(256); diff --git a/beacon-light-client/circom/test/is_equal_arrays/circuit.circom b/beacon-light-client/circom/test/is_equal_arrays/circuit.circom new file mode 100644 index 000000000..8d517930f --- /dev/null +++ b/beacon-light-client/circom/test/is_equal_arrays/circuit.circom @@ -0,0 +1,5 @@ +pragma circom 2.1.5; + +include "../../circuits/utils/arrays.circom"; + +component main = IsEqualArrays(3); // N must be equal to length in both arrays in input["in"] diff --git a/beacon-light-client/circom/test/is_equal_arrays/data/case01/input.json b/beacon-light-client/circom/test/is_equal_arrays/data/case01/input.json new file mode 100644 index 000000000..3f047d2c5 --- /dev/null +++ b/beacon-light-client/circom/test/is_equal_arrays/data/case01/input.json @@ -0,0 +1 @@ +{"in": [["1","2","2"],["1","2","2"]]} diff --git a/beacon-light-client/circom/test/is_equal_arrays/data/case01/output.json b/beacon-light-client/circom/test/is_equal_arrays/data/case01/output.json new file mode 100644 index 000000000..f4209a168 --- /dev/null +++ b/beacon-light-client/circom/test/is_equal_arrays/data/case01/output.json @@ -0,0 +1 @@ +{"out": "1"} diff --git a/beacon-light-client/circom/test/is_equal_arrays/data/case02/input.json b/beacon-light-client/circom/test/is_equal_arrays/data/case02/input.json new file mode 100644 index 000000000..23271aee5 --- /dev/null +++ b/beacon-light-client/circom/test/is_equal_arrays/data/case02/input.json @@ -0,0 +1 @@ +{"in": [["100","2","2"],["1","2","101"]]} diff --git a/beacon-light-client/circom/test/is_equal_arrays/data/case02/output.json b/beacon-light-client/circom/test/is_equal_arrays/data/case02/output.json new file mode 100644 index 000000000..8b71f4187 --- /dev/null +++ b/beacon-light-client/circom/test/is_equal_arrays/data/case02/output.json @@ -0,0 +1 @@ +{"out": "0"} diff --git a/beacon-light-client/circom/test/is_equal_arrays/data/case03/input.json b/beacon-light-client/circom/test/is_equal_arrays/data/case03/input.json new file mode 100644 index 000000000..9a6d16302 --- /dev/null +++ b/beacon-light-client/circom/test/is_equal_arrays/data/case03/input.json @@ -0,0 +1 @@ +{"in": [["10","8","7"],["7","8","10"]]} diff --git a/beacon-light-client/circom/test/is_equal_arrays/data/case03/output.json b/beacon-light-client/circom/test/is_equal_arrays/data/case03/output.json new file mode 100644 index 000000000..8b71f4187 --- /dev/null +++ b/beacon-light-client/circom/test/is_equal_arrays/data/case03/output.json @@ -0,0 +1 @@ +{"out": "0"} diff --git a/beacon-light-client/circom/test/less_than_eq_bits_check/circuit.circom b/beacon-light-client/circom/test/less_than_eq_bits_check/circuit.circom index badfa9e8d..29b65cdcc 100644 --- a/beacon-light-client/circom/test/less_than_eq_bits_check/circuit.circom +++ b/beacon-light-client/circom/test/less_than_eq_bits_check/circuit.circom @@ -1,13 +1,5 @@ pragma circom 2.1.5; -include "../../circuits/utils/arrays.circom"; +include "../../circuits/utils/numerical.circom"; -<<<<<<< HEAD -<<<<<<< HEAD component main = LessThanOrEqualBitsCheck(32); -======= -component main = Selector(8) // N must be equal to input["in"] length ->>>>>>> 7f6ce53 (feat(circom) Add tests for Selector circuit.) -======= -component main = LessThanOrEqualBitsCheck(32) ->>>>>>> 5452718 (fix(circom): Fix wrong main call for selector and less_than_eq_bits_check.) diff --git a/beacon-light-client/circom/test/selector/circuit.circom b/beacon-light-client/circom/test/selector/circuit.circom index 4d047b804..c94a2f259 100644 --- a/beacon-light-client/circom/test/selector/circuit.circom +++ b/beacon-light-client/circom/test/selector/circuit.circom @@ -2,4 +2,4 @@ pragma circom 2.1.5; include "../../circuits/utils/arrays.circom"; -component main = Selector(32) // N must be equal to input["in"] length +component main = Selector(8); // N must be equal to input["in"] length