Skip to content

Commit

Permalink
Added basic dvm circuit. (#367)
Browse files Browse the repository at this point in the history
* Added basic zkevm circuit.

* Bytecode circuit constraints added #364 (#375)

Co-authored-by: e.tatuzova <e.tatuzova@nil.foundation>

* Added real opcode numbers assignment.

* Added the new tests to the flake.

* Allocated_rows increased according to enable_selector #389

* Multiprecision changes.

* Updated crypto3 in fix attempt.

* Changed crypto3 to see other tests.

* Fixes for multiprecision update.

* Added missing test.

* Fixed test reporting not running if some tests failed.

* Fixed path in verifier test.

---------

Co-authored-by: e.tatuzova <e.tatuzova@nil.foundation>
  • Loading branch information
Iluvmagick and ETatuzova authored Jun 10, 2024
1 parent 8a3c405 commit 1f43078
Show file tree
Hide file tree
Showing 34 changed files with 3,817 additions and 55 deletions.
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use flake
2 changes: 1 addition & 1 deletion .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
${{ github.workspace }}/**
!${{ github.workspace }}/
!${{ github.workspace }}/**/.git/**
# nix is taken from the cloud-init template, no need to install it.
- name: Build and run tests
env:
Expand Down
76 changes: 66 additions & 10 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 22 additions & 4 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
description = "Nix flake for zkllvm-blueprint";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
nil_crypto3 = {
url =
"git+https://github.com/NilFoundation/crypto3?submodules=1&rev=66096ae733cabc99a763e00e803d710493318563";
"git+https://github.com/NilFoundation/crypto3?submodules=1&rev=1cf64acec2f4022224cb19673854250e08a6d7c3";
inputs.nixpkgs.follows = "nixpkgs";
};
flake-utils.url = "github:numtide/flake-utils";
Expand Down Expand Up @@ -107,6 +107,15 @@
"blueprint_verifiers_flexible_multiplications_test"
"blueprint_verifiers_flexible_poseidon_test"
"blueprint_verifiers_flexible_constant_pow_test"
"blueprint_verifiers_placeholder_verifier_test"
"blueprint_zkevm_zkevm_word_test"
"blueprint_zkevm_bytecode_test"
"blueprint_zkevm_state_selector_test"
"blueprint_zkevm_state_transition_test"
"blueprint_zkevm_opcodes_iszero_test"
"blueprint_zkevm_opcodes_add_sub_test"
"blueprint_zkevm_opcodes_mul_test"
"blueprint_zkevm_opcodes_div_test"
];

checks = {
Expand Down Expand Up @@ -137,14 +146,14 @@
"-DCMAKE_CXX_COMPILER=clang++"
];

ninjaFlags = pkgs.lib.strings.concatStringsSep " " testList;
ninjaFlags = pkgs.lib.strings.concatStringsSep " " (["-k 0"] ++ testList);

doCheck = true;

checkPhase = ''
# JUNIT file without explicit file name is generated after the name of the master test suite inside `CMAKE_CURRENT_SOURCE_DIR` (/build/source)
export BOOST_TEST_LOGGER=JUNIT:HRF
ctest --verbose -j $NIX_BUILD_CORES --output-on-failure -R "${nixpkgs.lib.concatStringsSep "|" testList}"
ctest --verbose -j $NIX_BUILD_CORES --output-on-failure -R "${nixpkgs.lib.concatStringsSep "|" testList}" || true
mkdir -p ${placeholder "out"}/test-logs
find .. -type f -name '*_test.xml' -exec cp {} ${placeholder "out"}/test-logs \;
Expand All @@ -166,6 +175,15 @@
];

shellHook = ''
export NO_AT_BRIDGE="1"
function nil_test_runner() {
clear
filename=$(cat Makefile | grep "$2" | awk 'NR==1{print $NF}')
make -j$(nproc) "$filename" && ./test/$filename
}
function ctcmp() {
nil_test_runner blueprint $1
}
echo "zkllvm-blueprint dev environment activated"
'';
};
Expand Down
5 changes: 2 additions & 3 deletions include/nil/blueprint/blueprint/plonk/assignment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,8 @@ namespace nil {
using value_type = typename BlueprintFieldType::value_type;
using column_type = typename crypto3::zk::snark::plonk_column<BlueprintFieldType>;
using shared_container_type = typename std::array<column_type, 1>;

using constant_set_compare_type = detail::constant_batch_ref_compare<BlueprintFieldType>;

std::size_t next_selector_index = 0;
std::uint32_t assignment_allocated_rows = 0;
std::vector<value_type> assignment_private_storage;
// for variables used in component batching
Expand Down Expand Up @@ -366,6 +364,7 @@ namespace nil {
virtual void enable_selector(const std::size_t selector_index, const std::size_t row_index) {

selector(selector_index, row_index) = BlueprintFieldType::value_type::one();
assignment_allocated_rows = std::uint32_t(std::max(std::size_t(assignment_allocated_rows), row_index + 1));
}

virtual void enable_selector(const std::size_t selector_index,
Expand All @@ -374,9 +373,9 @@ namespace nil {
const std::size_t index_step = 1) {

for (std::size_t row_index = begin_row_index; row_index <= end_row_index; row_index += index_step) {

enable_selector(selector_index, row_index);
}
assignment_allocated_rows = std::uint32_t(std::max(std::size_t(assignment_allocated_rows), end_row_index));
}

void fill_selector(std::uint32_t index, const column_type& column) override {
Expand Down
7 changes: 7 additions & 0 deletions include/nil/blueprint/blueprint/plonk/circuit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,13 @@ namespace nil {
LOOKUP_GATE_ADDER_MACRO(lookup_selector_map, _lookup_gates);
}

// Sometimes existing gate is already on existing selector
// and we are sure that lookup and usual part are always together
virtual std::size_t add_lookup_gate(std::size_t selector_id, const std::vector<lookup_constraint_type> &args) {
this->_lookup_gates.push_back({selector_id, args});
return selector_id;
}

virtual const typename ArithmetizationType::lookup_table_type &lookup_table(std::size_t table_id) const {
return ArithmetizationType::lookup_table(table_id);
}
Expand Down
6 changes: 6 additions & 0 deletions include/nil/blueprint/component_stretcher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ namespace nil {
case var::column_type::selector:
BOOST_ASSERT_MSG(false, "Selectors should be moved while moving gates.");
break;
case var::column_type::uninitialized:
BOOST_ASSERT_MSG(false, "Uninitialized variable should not be moved.");
break;
}
return new_var;
}
Expand Down Expand Up @@ -330,6 +333,9 @@ namespace nil {
case var::column_type::selector:
BOOST_ASSERT_MSG(false, "Selector columns should not be inside gates.");
break;
case var::column_type::uninitialized:
BOOST_ASSERT_MSG(false, "Uninitialized variable should not be moved.");
break;
}
return new_var;
}
Expand Down
10 changes: 8 additions & 2 deletions include/nil/blueprint/gate_id.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ namespace nil {

std::array<std::array<std::vector<value_type>, 3>, 2> witnesses;
std::array<std::array<std::vector<value_type>, 3>, 2> constants;
std::array<std::array<std::vector<value_type>, 3>, 2> selectors;
// Used to separate constraints from each other in ids.
std::vector<value_type> constraint_mults;
// Used to separate lookup variables from each other in ids.
Expand Down Expand Up @@ -124,6 +125,10 @@ namespace nil {
return get_value_helper(constants, point, index, rotation);
}

value_type get_selector(std::size_t point, std::size_t index, std::size_t rotation) {
return get_value_helper(selectors, point, index, rotation);
}

value_type get_power(std::size_t index) {
return get_power_helper(constraint_mults, index);
}
Expand All @@ -144,9 +149,10 @@ namespace nil {
return this->get_witness(point, var.index, var.rotation);
case var::column_type::constant:
return this->get_constant(point, var.index, var.rotation);
case var::column_type::public_input:
case var::column_type::selector:
BOOST_ASSERT_MSG(false, "Public input/selectors should not be in a gate.");
return this->get_selector(point, var.index, var.rotation);
case var::column_type::public_input:
BOOST_ASSERT_MSG(false, "Public input variables should not be in a gate.");
case var::column_type::uninitialized:
BOOST_ASSERT_MSG(false, "Uninitialized variable should not be inside a gate.");
}
Expand Down
88 changes: 87 additions & 1 deletion include/nil/blueprint/lookup_library.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,73 @@ namespace nil {
using lookup_table_definition = typename nil::crypto3::zk::snark::lookup_table_definition<BlueprintFieldType>;
using filled_lookup_table_definition = typename nil::crypto3::zk::snark::filled_lookup_table_definition<BlueprintFieldType>;

class byte_range_table_type: public lookup_table_definition{
public:
byte_range_table_type(): lookup_table_definition("byte_range_table"){
this->subtables["full"] = {{0}, 0, 255};
}
virtual void generate(){
this->_table.push_back({});
for( std::size_t i = 0; i < 256; i++){
this->_table[0].push_back({i});
}
}
virtual std::size_t get_columns_number(){ return 1; }
virtual std::size_t get_rows_number(){ return 256; }
};

class zkevm_opcode_table: public lookup_table_definition{
public:
static constexpr std::size_t opcodes_num = 149;

zkevm_opcode_table(): lookup_table_definition("zkevm_opcodes"){
this->subtables["full"] = {{0, 1, 2}, 0, opcodes_num};
this->subtables["opcodes_only"] = {{0}, 0, opcodes_num};
}
virtual void generate(){
// opcodes
this->_table.push_back({
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, //12
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, //14
0x20, //1
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, //16
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, //11
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, //16
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, //16
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, //16
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, //16
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, //16
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, //5
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xfa, 0xfd, 0xfe, 0xff //10
});
// push_size
this->_table.push_back({
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, //12
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, //14
0x0, //1
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, //16
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, //11
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, //16
0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, //16
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, //16
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, //16
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, //16
0x0, 0x0, 0x0, 0x0, 0x0, //5
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 //10
});

this->_table.push_back({});
for( std::size_t i = 0; i < opcodes_num; i++) this->_table[2].push_back(1);

// unselected rows virtualization
this->_table[0].push_back(0);
this->_table[1].push_back(0);
this->_table[2].push_back(0);
}
virtual std::size_t get_columns_number(){ return 1; }
virtual std::size_t get_rows_number(){ return 256; }
};

class binary_xor_table_type : public lookup_table_definition{
public:
binary_xor_table_type(): lookup_table_definition("binary_xor_table"){
Expand Down Expand Up @@ -244,14 +311,31 @@ namespace nil {
virtual std::size_t get_columns_number(){return 2;}
virtual std::size_t get_rows_number(){return 5764801;}
};

class chunk_16_bits_table: public lookup_table_definition{
public:
chunk_16_bits_table(): lookup_table_definition("chunk_16_bits"){
this->subtables["full"] = {{0}, 0, 65535};
};
virtual void generate(){
this->_table.resize(1);
for (std::size_t i = 0; i < 65536; i++) {
this->_table[0].push_back(i);
}
}

virtual std::size_t get_columns_number(){return 1;}
virtual std::size_t get_rows_number(){return 65536;}
};
public:
using bimap_type = boost::bimap<boost::bimaps::set_of<std::string>, boost::bimaps::set_of<std::size_t>>;
using left_reserved_type = typename bimap_type::left_map;
using right_reserved_type = typename bimap_type::right_map;

lookup_library(){
lookup_library() {
tables = {};
reserved_all = false;
tables["chunk_16_bits"] = std::shared_ptr<lookup_table_definition>(new chunk_16_bits_table());
tables["binary_xor_table"] = std::shared_ptr<lookup_table_definition>(new binary_xor_table_type());
tables["binary_and_table"] = std::shared_ptr<lookup_table_definition>(new binary_and_table_type());
tables["sha256_sparse_base4"] = std::shared_ptr<lookup_table_definition>(new sparse_values_base4_table());
Expand All @@ -260,6 +344,8 @@ namespace nil {
tables["sha256_reverse_sparse_base7"] = std::shared_ptr<lookup_table_definition>(new reverse_sparse_sigmas_base7_table());
tables["sha256_maj"] = std::shared_ptr<lookup_table_definition>(new maj_function_table());
tables["sha256_ch"] = std::shared_ptr<lookup_table_definition>(new ch_function_table());
tables["byte_range_table"] = std::shared_ptr<lookup_table_definition>(new byte_range_table_type());
tables["zkevm_opcodes"] = std::shared_ptr<lookup_table_definition>(new zkevm_opcode_table);
}

void register_lookup_table(std::shared_ptr<lookup_table_definition> table){
Expand Down
Loading

0 comments on commit 1f43078

Please sign in to comment.