From 8141647fe63fed3df439acae3477499c6e7c47bc Mon Sep 17 00:00:00 2001 From: Martun Karapetyan Date: Thu, 22 Aug 2024 11:33:28 +0400 Subject: [PATCH 1/5] Added marshalling for preprocessed public data, LPC commitment state, polys_evaluator. --- .../libs/algebra/crypto3.algebra.podspec.json | 2 +- crypto3/libs/block/crypto3.block.podspec.json | 2 +- crypto3/libs/block/test/CMakeLists.txt | 2 +- .../nil/blueprint/basic_non_native_policy.hpp | 4 +- crypto3/libs/codec/crypto3.codec.podspec.json | 2 +- crypto3/libs/codec/test/CMakeLists.txt | 2 +- .../nil/crypto3/container/merkle/tree.hpp | 5 +- crypto3/libs/hash/crypto3.hash.podspec.json | 2 +- crypto3/libs/kdf/crypto3.kdf.podspec.json | 2 +- crypto3/libs/mac/crypto3.mac.podspec.json | 2 +- .../algebra/types/field_element.hpp | 21 +- crypto3/libs/marshalling/core/CMakeLists.txt | 4 + .../core/include/nil/marshalling/options.hpp | 10 + .../adapter/sequence_size_field_prefix.hpp | 2 +- .../nil/marshalling/types/array_list.hpp | 76 ++ .../nil/marshalling/types/integral.hpp | 13 + .../containers/types/merkle_node.hpp | 228 ++++++ .../containers/types/merkle_proof.hpp | 180 +---- .../containers/types/merkle_tree.hpp | 87 +++ .../marshalling/math/types/polynomial.hpp | 175 +++++ .../types/commitments/commitment_params.hpp | 22 +- .../zk/types/commitments/eval_storage.hpp | 12 +- .../marshalling/zk/types/commitments/fri.hpp | 45 +- .../marshalling/zk/types/commitments/lpc.hpp | 229 +++++- .../zk/types/commitments/polys_evaluator.hpp | 207 ++++++ .../zk/types/placeholder/common_data.hpp | 3 - .../placeholder/preprocessed_public_data.hpp | 114 +++ .../zk/types/placeholder/proof.hpp | 4 +- .../zk/types/plonk/assignment_table.hpp | 58 +- .../plonk_public_polynomial_dfs_table.hpp | 91 +++ .../libs/marshalling/zk/test/CMakeLists.txt | 3 + .../marshalling/zk/test/fri_commitment.cpp | 264 +------ .../marshalling/zk/test/lpc_commitment.cpp | 358 +-------- .../libs/marshalling/zk/test/merkle_tree.cpp | 151 ++++ .../placeholder_preprocessed_public_data.cpp | 677 ++++++++++++++++++ .../marshalling/zk/test/placeholder_proof.cpp | 7 +- .../zk/test/plonk_assignment_table.cpp | 39 + .../marshalling/zk/test/polys_evaluator.cpp | 182 +++++ .../zk/test/random_test_data_generation.hpp | 330 +++++++++ crypto3/libs/math/crypto3.math.podspec.json | 2 +- .../algorithms/make_evaluation_domain.hpp | 61 +- .../math/domains/basic_radix2_domain.hpp | 2 + .../math/domains/extended_radix2_domain.hpp | 2 + .../include/nil/crypto3/math/type_traits.hpp | 65 +- crypto3/libs/modes/crypto3.modes.podspec.json | 2 +- crypto3/libs/multiprecision/test/test_gcd.cpp | 2 +- .../passhash/crypto3.passhash.podspec.json | 2 +- crypto3/libs/pbkdf/crypto3.pbkdf.podspec.json | 2 +- crypto3/libs/pkpad/crypto3.pkpad.podspec.json | 2 +- .../libs/stream/crypto3.stream.podspec.json | 2 +- .../threshold/crypto3.threshold.podspec.json | 2 +- crypto3/libs/vdf/crypto3.vdf.podspec.json | 2 +- crypto3/libs/zk/CMakeLists.txt | 1 + crypto3/libs/zk/crypto3.zk.podspec.json | 2 +- .../zk/commitments/batched_commitment.hpp | 80 ++- .../basic_batched_fri_compile_time_size.hpp | 6 +- .../basic_batched_fri_runtime_size.hpp | 3 +- .../detail/polynomial/basic_fri.hpp | 80 +-- .../detail/polynomial/eval_storage.hpp | 4 +- .../crypto3/zk/commitments/polynomial/kzg.hpp | 8 +- .../zk/commitments/polynomial/kzg_v2.hpp | 8 +- .../crypto3/zk/commitments/polynomial/lpc.hpp | 69 +- .../plonk/table_description.hpp | 4 + .../systems/plonk/placeholder/verifier.hpp | 57 +- crypto3/libs/zk/test/CMakeLists.txt | 4 +- crypto3/libs/zk/test/commitment/fri.cpp | 12 +- crypto3/libs/zk/test/commitment/lpc.cpp | 75 +- .../zk/test/commitment/lpc_performance.cpp | 54 +- .../placeholder/placeholder_test_runner.hpp | 5 +- 69 files changed, 3154 insertions(+), 1083 deletions(-) create mode 100644 crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_node.hpp create mode 100644 crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_tree.hpp create mode 100644 crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/math/types/polynomial.hpp create mode 100644 crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/polys_evaluator.hpp create mode 100644 crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/preprocessed_public_data.hpp create mode 100644 crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/plonk/plonk_public_polynomial_dfs_table.hpp create mode 100644 crypto3/libs/marshalling/zk/test/merkle_tree.cpp create mode 100644 crypto3/libs/marshalling/zk/test/placeholder_preprocessed_public_data.cpp create mode 100644 crypto3/libs/marshalling/zk/test/polys_evaluator.cpp create mode 100644 crypto3/libs/marshalling/zk/test/random_test_data_generation.hpp diff --git a/crypto3/libs/algebra/crypto3.algebra.podspec.json b/crypto3/libs/algebra/crypto3.algebra.podspec.json index 19ebdf03cb..f45d4d26c1 100644 --- a/crypto3/libs/algebra/crypto3.algebra.podspec.json +++ b/crypto3/libs/algebra/crypto3.algebra.podspec.json @@ -18,7 +18,7 @@ "branch": "master" }, "xcconfig": { - "CLANG_CXX_LANGUAGE_STANDARD": "c++14", + "CLANG_CXX_LANGUAGE_STANDARD": "c++17", "CLANG_CXX_LIBRARY": "libc++", "HEADER_SEARCH_PATHS": "\"${PODS_ROOT}/include/\"" }, diff --git a/crypto3/libs/block/crypto3.block.podspec.json b/crypto3/libs/block/crypto3.block.podspec.json index fd27d0e36e..8bfc7839e2 100644 --- a/crypto3/libs/block/crypto3.block.podspec.json +++ b/crypto3/libs/block/crypto3.block.podspec.json @@ -17,7 +17,7 @@ "branch": "master" }, "xcconfig": { - "CLANG_CXX_LANGUAGE_STANDARD": "c++14", + "CLANG_CXX_LANGUAGE_STANDARD": "c++17", "CLANG_CXX_LIBRARY": "libc++", "HEADER_SEARCH_PATHS": "\"${PODS_ROOT}/include/\"" }, diff --git a/crypto3/libs/block/test/CMakeLists.txt b/crypto3/libs/block/test/CMakeLists.txt index 96bd9918f0..25b9948d43 100644 --- a/crypto3/libs/block/test/CMakeLists.txt +++ b/crypto3/libs/block/test/CMakeLists.txt @@ -21,7 +21,7 @@ macro(define_block_cipher_test name) ${Boost_INCLUDE_DIRS}) if(NOT CMAKE_CXX_STANDARD) - set_target_properties(${test_name} PROPERTIES CXX_STANDARD 14) + set_target_properties(${test_name} PROPERTIES CXX_STANDARD 17) endif() string(CONCAT TEST_DATA ${CMAKE_CURRENT_SOURCE_DIR} "/data/" "${name}" ".json") diff --git a/crypto3/libs/blueprint/include/nil/blueprint/basic_non_native_policy.hpp b/crypto3/libs/blueprint/include/nil/blueprint/basic_non_native_policy.hpp index a2d2ee643d..f53e192f27 100644 --- a/crypto3/libs/blueprint/include/nil/blueprint/basic_non_native_policy.hpp +++ b/crypto3/libs/blueprint/include/nil/blueprint/basic_non_native_policy.hpp @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include @@ -251,8 +253,6 @@ namespace nil { typedef std::array non_native_var_type; }; - - /* * Native element type. */ diff --git a/crypto3/libs/codec/crypto3.codec.podspec.json b/crypto3/libs/codec/crypto3.codec.podspec.json index b68d0be018..1bdc8f1e81 100644 --- a/crypto3/libs/codec/crypto3.codec.podspec.json +++ b/crypto3/libs/codec/crypto3.codec.podspec.json @@ -17,7 +17,7 @@ "branch": "master" }, "xcconfig": { - "CLANG_CXX_LANGUAGE_STANDARD": "c++14", + "CLANG_CXX_LANGUAGE_STANDARD": "c++17", "CLANG_CXX_LIBRARY": "libc++", "HEADER_SEARCH_PATHS": "\"${PODS_ROOT}/include/\"" }, diff --git a/crypto3/libs/codec/test/CMakeLists.txt b/crypto3/libs/codec/test/CMakeLists.txt index 75b67e0d61..6548c365ed 100644 --- a/crypto3/libs/codec/test/CMakeLists.txt +++ b/crypto3/libs/codec/test/CMakeLists.txt @@ -24,7 +24,7 @@ macro(define_codec_test name) if(NOT CMAKE_CXX_STANDARD) set_target_properties(codec_${name}_test PROPERTIES - CXX_STANDARD 14 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED TRUE) endif() diff --git a/crypto3/libs/containers/include/nil/crypto3/container/merkle/tree.hpp b/crypto3/libs/containers/include/nil/crypto3/container/merkle/tree.hpp index 534c70e428..145802635c 100644 --- a/crypto3/libs/containers/include/nil/crypto3/container/merkle/tree.hpp +++ b/crypto3/libs/containers/include/nil/crypto3/container/merkle/tree.hpp @@ -175,6 +175,7 @@ namespace nil { typedef typename node_type::value_type value_type; constexpr static const std::size_t value_bits = node_type::value_bits; + constexpr static const std::size_t arity = Arity; typedef std::vector container_type; @@ -253,7 +254,7 @@ namespace nil { } bool operator==(const merkle_tree_impl &rhs) const { - return _hashes == rhs.val; + return _hashes == rhs._hashes; } bool operator!=(const merkle_tree_impl &rhs) const { @@ -261,7 +262,7 @@ namespace nil { } allocator_type get_allocator() const BOOST_NOEXCEPT { - return this->val.__alloc(); + return this->_hashes.__alloc(); } iterator begin() BOOST_NOEXCEPT { diff --git a/crypto3/libs/hash/crypto3.hash.podspec.json b/crypto3/libs/hash/crypto3.hash.podspec.json index 902d97c550..23c94a4bcc 100644 --- a/crypto3/libs/hash/crypto3.hash.podspec.json +++ b/crypto3/libs/hash/crypto3.hash.podspec.json @@ -17,7 +17,7 @@ "branch": "master" }, "xcconfig": { - "CLANG_CXX_LANGUAGE_STANDARD": "c++14", + "CLANG_CXX_LANGUAGE_STANDARD": "c++17", "CLANG_CXX_LIBRARY": "libc++", "HEADER_SEARCH_PATHS": "\"${PODS_ROOT}/include/\"" }, diff --git a/crypto3/libs/kdf/crypto3.kdf.podspec.json b/crypto3/libs/kdf/crypto3.kdf.podspec.json index a923b4ba74..1d62957b84 100644 --- a/crypto3/libs/kdf/crypto3.kdf.podspec.json +++ b/crypto3/libs/kdf/crypto3.kdf.podspec.json @@ -17,7 +17,7 @@ "branch": "master" }, "xcconfig": { - "CLANG_CXX_LANGUAGE_STANDARD": "c++14", + "CLANG_CXX_LANGUAGE_STANDARD": "c++17", "CLANG_CXX_LIBRARY": "libc++", "HEADER_SEARCH_PATHS": "\"${PODS_ROOT}/include/\"" }, diff --git a/crypto3/libs/mac/crypto3.mac.podspec.json b/crypto3/libs/mac/crypto3.mac.podspec.json index 7199197cb4..48e8499cb5 100644 --- a/crypto3/libs/mac/crypto3.mac.podspec.json +++ b/crypto3/libs/mac/crypto3.mac.podspec.json @@ -17,7 +17,7 @@ "branch": "master" }, "xcconfig": { - "CLANG_CXX_LANGUAGE_STANDARD": "c++14", + "CLANG_CXX_LANGUAGE_STANDARD": "c++17", "CLANG_CXX_LIBRARY": "libc++", "HEADER_SEARCH_PATHS": "\"${PODS_ROOT}/include/\"" }, diff --git a/crypto3/libs/marshalling/algebra/include/nil/crypto3/marshalling/algebra/types/field_element.hpp b/crypto3/libs/marshalling/algebra/include/nil/crypto3/marshalling/algebra/types/field_element.hpp index c23fcd2d0e..8efabeb6a9 100644 --- a/crypto3/libs/marshalling/algebra/include/nil/crypto3/marshalling/algebra/types/field_element.hpp +++ b/crypto3/libs/marshalling/algebra/include/nil/crypto3/marshalling/algebra/types/field_element.hpp @@ -686,12 +686,16 @@ namespace nil { // return field; // } - template - nil::marshalling::types::array_list< - nil::marshalling::field_type, - field_element, FieldValueType>, + + template + using field_element_vector = nil::marshalling::types::array_list< + TTypeBase, + field_element, nil::marshalling::option::sequence_size_field_prefix< - nil::marshalling::types::integral, std::size_t>>> + nil::marshalling::types::integral>>; + + template + field_element_vector> fill_field_element_vector(const std::vector &field_elem_vector) { using TTypeBase = nil::marshalling::field_type; @@ -711,12 +715,7 @@ namespace nil { template std::vector make_field_element_vector( - const nil::marshalling::types::array_list< - nil::marshalling::field_type, - field_element, FieldValueType>, - nil::marshalling::option::sequence_size_field_prefix< - nil::marshalling::types::integral, std::size_t>>> - &field_elem_vector) { + const field_element_vector>& field_elem_vector) { std::vector result; result.reserve(field_elem_vector.value().size()); diff --git a/crypto3/libs/marshalling/core/CMakeLists.txt b/crypto3/libs/marshalling/core/CMakeLists.txt index 2d51db92a6..92ca677ceb 100644 --- a/crypto3/libs/marshalling/core/CMakeLists.txt +++ b/crypto3/libs/marshalling/core/CMakeLists.txt @@ -19,6 +19,10 @@ if(CRYPTO3_MARSHALLING_THROWS) add_definitions(-DCRYPTO3_MARSHALLING_THROWS) endif() +if(NOT CMAKE_CXX_STANDARD) + set_target_properties(${test_name} PROPERTIES CXX_STANDARD 17) +endif() + cm_setup_version(VERSION 0.1.0 PREFIX ${CMAKE_WORKSPACE_NAME}_${CURRENT_PROJECT_NAME}) add_library(${CMAKE_WORKSPACE_NAME}_${CURRENT_PROJECT_NAME} INTERFACE) diff --git a/crypto3/libs/marshalling/core/include/nil/marshalling/options.hpp b/crypto3/libs/marshalling/core/include/nil/marshalling/options.hpp index 49f67d0fbb..132ce9af7a 100644 --- a/crypto3/libs/marshalling/core/include/nil/marshalling/options.hpp +++ b/crypto3/libs/marshalling/core/include/nil/marshalling/options.hpp @@ -43,6 +43,12 @@ namespace nil { namespace marshalling { + namespace types { + // We cannot include integral.hpp, it includes this file. So just declare the class. + template + class integral; + } + namespace option { namespace detail { @@ -286,6 +292,10 @@ namespace nil { template struct sequence_size_field_prefix { }; + template + using size_t_sequence_size_field_prefix = sequence_size_field_prefix< + nil::marshalling::types::integral>; + /// @brief Option that modifies the default behaviour of collection fields to /// prepend the serialized data with number of @b bytes information. /// @details Similar to @ref sequence_size_field_prefix, but instead of diff --git a/crypto3/libs/marshalling/core/include/nil/marshalling/types/adapter/sequence_size_field_prefix.hpp b/crypto3/libs/marshalling/core/include/nil/marshalling/types/adapter/sequence_size_field_prefix.hpp index dec4d29686..9caa6459b7 100644 --- a/crypto3/libs/marshalling/core/include/nil/marshalling/types/adapter/sequence_size_field_prefix.hpp +++ b/crypto3/libs/marshalling/core/include/nil/marshalling/types/adapter/sequence_size_field_prefix.hpp @@ -32,6 +32,7 @@ namespace nil { namespace marshalling { namespace types { + namespace adapter { template @@ -129,7 +130,6 @@ namespace nil { base_impl_type::write_no_status(iter); } }; - } // namespace adapter } // namespace types } // namespace marshalling diff --git a/crypto3/libs/marshalling/core/include/nil/marshalling/types/array_list.hpp b/crypto3/libs/marshalling/core/include/nil/marshalling/types/array_list.hpp index 350214e01c..e675cb2c51 100644 --- a/crypto3/libs/marshalling/core/include/nil/marshalling/types/array_list.hpp +++ b/crypto3/libs/marshalling/core/include/nil/marshalling/types/array_list.hpp @@ -26,13 +26,16 @@ #ifndef MARSHALLING_ARRAY_LIST_HPP #define MARSHALLING_ARRAY_LIST_HPP +#include #include +#include #include #include #include #include +#include namespace nil { namespace marshalling { @@ -404,6 +407,79 @@ namespace nil { return field; } + // We use this type of array_list waay too often, so this is a shortcut, not to copy-paste it all the time. + template + using standard_array_list = array_list< + TFieldBase, + TElement, + nil::marshalling::option::size_t_sequence_size_field_prefix>; + + // Very often we just need an array list of std::size_t, so here's another shortcut. + template + using standard_size_t_array_list = array_list< + TFieldBase, + nil::marshalling::types::integral, + nil::marshalling::option::size_t_sequence_size_field_prefix>; + + // Helper functions to convert to/from an arraylist. + template + typename std::enable_if< + nil::detail::is_range::value, + standard_array_list>::type + fill_standard_array_list( + const Range& input_range, + std::function element_marshalling) { + standard_array_list result; + for (const auto& v: input_range) { + result.value().push_back(element_marshalling(v)); + } + return result; + } + + template + std::vector make_standard_array_list( + const standard_array_list& filled_array, + std::function element_de_marshalling) { + std::vector result; + for (const auto& v: filled_array.value()) { + result.push_back(element_de_marshalling(v)); + } + return result; + } + + // Helper functions to marshall an std::map. + // We keep TKey, TValue at the end, because they can be decuded from the map type, but the other 3 + // arguments must be provided explicitly. + template + std::pair, standard_array_list> + fill_std_map( + const std::map& input_map, + std::function key_marshalling, + std::function value_marshalling) { + standard_array_list result_keys; + standard_array_list result_values; + for (const auto& [k, v]: input_map) { + result_keys.value().push_back(key_marshalling(k)); + result_values.value().push_back(value_marshalling(v)); + } + return {result_keys, result_values}; + } + + template + std::map make_std_map( + const standard_array_list& filled_keys, + const standard_array_list& filled_values, + std::function key_de_marshalling, + std::function value_de_marshalling) { + assert(filled_keys.value().size() == filled_values.value().size()); + + std::map result; + for (std::size_t i = 0; i < filled_keys.value().size(); ++i) { + result[key_de_marshalling(filled_keys.value()[i])] = value_de_marshalling(filled_values.value()[i]); + } + return result; + } + } // namespace types } // namespace marshalling } // namespace nil diff --git a/crypto3/libs/marshalling/core/include/nil/marshalling/types/integral.hpp b/crypto3/libs/marshalling/core/include/nil/marshalling/types/integral.hpp index b991d9e70a..a38e72808c 100644 --- a/crypto3/libs/marshalling/core/include/nil/marshalling/types/integral.hpp +++ b/crypto3/libs/marshalling/core/include/nil/marshalling/types/integral.hpp @@ -439,6 +439,19 @@ namespace nil { return field; } + // This is a helper, frequently used to convert size_t. It just shortens our code. + template + integral fill_size_t(const std::size_t& v) { + integral result; + result.value() = v; + return result; + } + + template + std::size_t make_size_t(const integral& v) { + return v.value(); + } + } // namespace types } // namespace marshalling } // namespace nil diff --git a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_node.hpp b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_node.hpp new file mode 100644 index 0000000000..77ad27e04d --- /dev/null +++ b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_node.hpp @@ -0,0 +1,228 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2021 Mikhail Komarov +// Copyright (c) 2021 Nikita Kaskov +// Copyright (c) 2021 Ilias Khairullin +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_MARSHALLING_MERKLE_NODE_HPP +#define CRYPTO3_MARSHALLING_MERKLE_NODE_HPP + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace nil { + namespace crypto3 { + namespace marshalling { + namespace types { + template + struct merkle_node_value; + + // For sha and similar hashes merkle tree node will contain a byte array. + template + struct merkle_node_value< + TTypeBase, + ValueType, + typename std::enable_if::value_type>::value>::type> { + using type = nil::marshalling::types::array_list< + TTypeBase, + nil::marshalling::types::integral, + nil::marshalling::option::sequence_size_field_prefix< + nil::marshalling::types::integral>>; + }; + + // For Poseidon, Merkle node will contain a Group Element, not a vector of bytes. + template + struct merkle_node_value< + TTypeBase, + GroupElementType, + typename std::enable_if::value>::type + > { + using type = field_element; + }; + + template + struct merkle_node_value< + TTypeBase, + MerkleProof, + typename std::enable_if< + std::is_same>::value>::type> { + using type = typename merkle_node_value::type; + }; + + template + struct merkle_node_value>::value>::type> { + using type = typename merkle_node_value::type; + }; + + template< + typename ValueType, + typename Endianness, + typename std::enable_if< + std::is_same::value_type>::value, + bool>::type = true> + typename merkle_node_value, ValueType>::type + fill_merkle_node_value(const ValueType &node_value) { + + using TTypeBase = nil::marshalling::field_type; + using octet_marshalling_type = nil::marshalling::types::integral; + + typename merkle_node_value, ValueType>::type + filled_node_value; + for (const auto c : node_value) { + filled_node_value.value().push_back(octet_marshalling_type(c)); + } + return filled_node_value; + } + + template< + typename GroupElementType, + typename Endianness, + typename std::enable_if::value, bool>::type = true> + typename merkle_node_value< + nil::marshalling::field_type, + GroupElementType + >::type + fill_merkle_node_value(const GroupElementType &node_value) { + + using TTypeBase = nil::marshalling::field_type; + + typename merkle_node_value, GroupElementType>::type filled_node_value = + field_element(node_value); + return filled_node_value; + } + + template>::value, + bool>::type = true> + typename merkle_node_value, MerkleProof>::type + fill_merkle_node_value(const typename MerkleProof::value_type &node_value) { + return fill_merkle_node_value(node_value); + } + + template>::value, + bool>::type = true> + typename merkle_node_value, MerkleTree>::type + fill_merkle_node_value(const typename MerkleTree::value_type &node_value) { + return fill_merkle_node_value(node_value); + } + + template< + typename ValueType, + typename Endianness, + typename std::enable_if< + std::is_same::value_type>::value, + bool>::type = true> + ValueType + make_merkle_node_value(const typename merkle_node_value, + ValueType>::type &filled_node_value) { + ValueType node_value; + BOOST_ASSERT(node_value.size() == filled_node_value.value().size()); + for (std::size_t i = 0; i < filled_node_value.value().size(); ++i) { + node_value.at(i) = filled_node_value.value().at(i).value(); + } + return node_value; + } + + template< + typename GroupElementType, + typename Endianness, + typename std::enable_if::value, bool>::type = true> + GroupElementType make_merkle_node_value(const typename merkle_node_value< + nil::marshalling::field_type, GroupElementType>::type &filled_node_value) { + return filled_node_value.value(); + } + + template>::value, + bool>::type = true> + typename MerkleProof::value_type + make_merkle_node_value(const typename merkle_node_value, + MerkleProof>::type &filled_node_value) { + return make_merkle_node_value(filled_node_value); + } + template>::value, + bool>::type = true> + typename MerkleTree::value_type + make_merkle_node_value(const typename merkle_node_value, + MerkleTree>::type &filled_node_value) { + return make_merkle_node_value(filled_node_value); + } + + } // namespace types + } // namespace marshalling + } // namespace crypto3 +} // namespace nil + +#endif // CRYPTO3_MARSHALLING_MERKLE_NODE_HPP diff --git a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_proof.hpp b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_proof.hpp index 058ed69159..f58653d8d1 100644 --- a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_proof.hpp +++ b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_proof.hpp @@ -33,7 +33,10 @@ #include #include + #include +#include + #include #include #include @@ -48,66 +51,14 @@ namespace nil { namespace crypto3 { namespace marshalling { namespace types { - template - struct merkle_node_value; - - template - struct merkle_node_value< - TTypeBase, - ValueType, - typename std::enable_if::value_type>::value>::type> { - // TODO: use option::fixed_size_storage instead of option::sequence_size_field_prefix - using type = nil::marshalling::types::array_list< - TTypeBase, - nil::marshalling::types::integral, - nil::marshalling::option::sequence_size_field_prefix< - nil::marshalling::types::integral>>; - }; - - // For Poseidon, Merkle node will contain a Group Element, not a vector of bytes. - template - struct merkle_node_value< - TTypeBase, - GroupElementType, - typename std::enable_if::value>::type - > { - using type = field_element; - }; - - template - struct merkle_node_value< - TTypeBase, - MerkleProof, - typename std::enable_if< - std::is_same>::value>::type> { - using type = typename merkle_node_value::type; - }; - - template - struct merkle_node_value>::value>::type> { - using type = typename merkle_node_value::type; - }; - template struct merkle_proof_path_element { - using type = - nil::marshalling::types::bundle, - // value_type _hash - typename merkle_node_value::type>>; + using type = nil::marshalling::types::bundle, + // value_type _hash + typename merkle_node_value::type>>; }; template @@ -139,110 +90,15 @@ namespace nil { MerkleProof::arity>>::value, bool>::type, typename... TOptions> - using merkle_proof = - nil::marshalling::types::bundle, - // value_type _root - typename merkle_node_value::type, - // path_type _path - typename merkle_proof_path::type>>; - - template< - typename ValueType, - typename Endianness, - typename std::enable_if< - std::is_same::value_type>::value, - bool>::type = true> - typename merkle_node_value, ValueType>::type - fill_merkle_node_value(const ValueType &node_value) { - - using TTypeBase = nil::marshalling::field_type; - using octet_marshalling_type = nil::marshalling::types::integral; - - typename merkle_node_value, ValueType>::type - filled_node_value; - for (const auto c : node_value) { - filled_node_value.value().push_back(octet_marshalling_type(c)); - } - return filled_node_value; - } - - template< - typename GroupElementType, - typename Endianness, - typename std::enable_if::value, bool>::type = true> - typename merkle_node_value< - nil::marshalling::field_type, - GroupElementType - >::type - fill_merkle_node_value(const GroupElementType &node_value) { - - using TTypeBase = nil::marshalling::field_type; - - typename merkle_node_value, GroupElementType>::type filled_node_value = - field_element(node_value); - return filled_node_value; - } - - template>::value, - bool>::type = true> - typename merkle_node_value, MerkleProof>::type - fill_merkle_node_value(const typename MerkleProof::value_type &node_value) { - return fill_merkle_node_value(node_value); - } - - template< - typename ValueType, - typename Endianness, - typename std::enable_if< - std::is_same::value_type>::value, - bool>::type = true> - ValueType - make_merkle_node_value(const typename merkle_node_value, - ValueType>::type &filled_node_value) { - ValueType node_value; - BOOST_ASSERT(node_value.size() == filled_node_value.value().size()); - for (std::size_t i = 0; i < filled_node_value.value().size(); ++i) { - node_value.at(i) = filled_node_value.value().at(i).value(); - } - return node_value; - } - - template< - typename GroupElementType, - typename Endianness, - typename std::enable_if::value, bool>::type = true> - GroupElementType make_merkle_node_value(const typename merkle_node_value< - nil::marshalling::field_type, GroupElementType - >::type &filled_node_value) { - return filled_node_value.value(); - } - - template>::value, - bool>::type = true> - typename MerkleProof::value_type - make_merkle_node_value(const typename merkle_node_value, - MerkleProof>::type &filled_node_value) { - return make_merkle_node_value(filled_node_value); - } + using merkle_proof = nil::marshalling::types::bundle< + TTypeBase, + std::tuple< + // std::size_t _li + nil::marshalling::types::integral, + // value_type _root + typename merkle_node_value::type, + // path_type _path + typename merkle_proof_path::type>>; template typename merkle_proof_path_element, MerkleProof>::type diff --git a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_tree.hpp b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_tree.hpp new file mode 100644 index 0000000000..7c4f813459 --- /dev/null +++ b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_tree.hpp @@ -0,0 +1,87 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2024 Martun Karapetyan +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_MARSHALLING_MERKLE_TREE_HPP +#define CRYPTO3_MARSHALLING_MERKLE_TREE_HPP + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +namespace nil { + namespace crypto3 { + namespace marshalling { + namespace types { + template + using merkle_tree = nil::marshalling::types::array_list< + TTypeBase, + typename merkle_node_value::type, + nil::marshalling::option::sequence_size_field_prefix< + nil::marshalling::types::integral>>; + + template + merkle_tree, MerkleTree> + fill_merkle_tree(const MerkleTree& tree) { + + using TTypeBase = nil::marshalling::field_type; + + merkle_tree filled_tree; + for (const auto &hash_value : tree) { + filled_tree.value().push_back( + fill_merkle_node_value(hash_value)); + } + return filled_tree; + } + + template + MerkleTree make_merkle_tree(const merkle_tree< + nil::marshalling::field_type, MerkleTree> &filled_merkle_tree) { + typename MerkleTree::container_type hashes; + for (std::size_t i = 0; i < filled_merkle_tree.value().size(); ++i) { + hashes.push_back( + make_merkle_node_value(filled_merkle_tree.value().at(i))); + } + return MerkleTree(hashes.begin(), hashes.end()); + } + } // namespace types + } // namespace marshalling + } // namespace crypto3 +} // namespace nil + +#endif // CRYPTO3_MARSHALLING_MERKLE_TREE_HPP diff --git a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/math/types/polynomial.hpp b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/math/types/polynomial.hpp new file mode 100644 index 0000000000..80859a38fb --- /dev/null +++ b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/math/types/polynomial.hpp @@ -0,0 +1,175 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2024 Martun Karapetyan +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_MARSHALLING_POLYNOMIAL_HPP +#define CRYPTO3_MARSHALLING_POLYNOMIAL_HPP + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +namespace nil { + namespace crypto3 { + namespace marshalling { + namespace types { + + /////////////////////////////////////////////// + // math::polynomial marshalling. + /////////////////////////////////////////////// + template + struct polynomial; + + template + struct polynomial::value>> { + using type = field_element_vector; + }; + + template + typename polynomial, PolynomialType, std::enable_if_t< + nil::crypto3::math::is_polynomial::value>>::type + fill_polynomial(const PolynomialType &f) { + using TTypeBase = nil::marshalling::field_type; + + std::vector val; + for( auto it=f.begin(); it != f.end(); it++){ val.push_back(*it); } + + return nil::crypto3::marshalling::types::fill_field_element_vector< + typename PolynomialType::value_type, Endianness>(val); + } + + template + PolynomialType + make_polynomial( + const typename polynomial< + nil::marshalling::field_type, + PolynomialType, + std::enable_if_t::value>>::type &filled_polynomial) { + auto val = nil::crypto3::marshalling::types::make_field_element_vector< + typename PolynomialType::value_type, + Endianness + >(filled_polynomial); + + return PolynomialType(val.begin(), val.end()); + } + + /////////////////////////////////////////////// + // math::polynomial_dfs marshalling. + /////////////////////////////////////////////// + template + struct polynomial::value>> { + using type = nil::marshalling::types::bundle< + TTypeBase, + std::tuple< + // degree + nil::marshalling::types::integral, + // values + field_element_vector + > + >; + }; + + template + typename polynomial, PolynomialDFSType, std::enable_if_t< + nil::crypto3::math::is_polynomial_dfs::value>>::type + fill_polynomial(const PolynomialDFSType &f) { + using TTypeBase = nil::marshalling::field_type; + using result_type = typename polynomial, PolynomialDFSType>::type; + + std::vector val; + for( auto it=f.begin(); it != f.end(); it++){ val.push_back(*it); } + + return result_type(std::make_tuple( + nil::marshalling::types::integral(f.degree()), + nil::crypto3::marshalling::types::fill_field_element_vector< + typename PolynomialDFSType::value_type, + Endianness + >(val) + )); + } + + template + PolynomialDFSType + make_polynomial(const typename polynomial< + nil::marshalling::field_type, + PolynomialDFSType, + std::enable_if_t::value + >>::type &filled_polynomial) { + auto val = nil::crypto3::marshalling::types::make_field_element_vector< + typename PolynomialDFSType::value_type, + Endianness>(std::get<1>(filled_polynomial.value())); + + return PolynomialDFSType(std::get<0>(filled_polynomial.value()).value(), val.begin(), val.end()); + } + + /////////////////////////////////////////////// + // Polynomial vector marshalling, regardless of the form of the polynomial. + /////////////////////////////////////////////// + template + using polynomial_vector = nil::marshalling::types::standard_array_list< + TTypeBase, + typename polynomial::type + >; + + template + polynomial_vector, PolynomialType> + fill_polynomial_vector(const std::vector &f) { + polynomial_vector, PolynomialType> result; + for (auto it=f.begin(); it != f.end(); it++) { + result.value().push_back(fill_polynomial(*it)); + } + return result; + } + + template + std::vector make_polynomial_vector( + const polynomial_vector, PolynomialType> &filled_polynomial_vector) { + std::vector result; + result.reserve(filled_polynomial_vector.value().size()); + for (std::size_t i = 0; i < filled_polynomial_vector.value().size(); i++) { + result.push_back(make_polynomial( + filled_polynomial_vector.value()[i])); + } + + return result; + } + + } // namespace types + } // namespace marshalling + } // namespace crypto3 +} // namespace nil + +#endif // CRYPTO3_MARSHALLING_POLYNOMIAL_HPP diff --git a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/commitment_params.hpp b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/commitment_params.hpp index db3dfa1b8f..d83108b5b2 100644 --- a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/commitment_params.hpp +++ b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/commitment_params.hpp @@ -137,7 +137,7 @@ namespace nil { integral_type, // constexpr static std::size_t m; integral_type, -// constexpr static std::uint32_t grinding_type::mask; If use_grinding==false, this will be 0. +// constexpr static std::uint32_t grinding_parameters; If use_grinding==false, this will be 0. integral_type, // const std::size_t max_degree; integral_type, @@ -188,21 +188,25 @@ namespace nil { make_commitment_params(const typename commitment_params, CommitmentSchemeType, std::enable_if_t>>::type &filled_params) { using CommitmentParamsType = typename CommitmentSchemeType::params_type; - auto step_list = make_integer_vector(std::get<5>(filled_params.value())); std::size_t lambda = std::get<0>(filled_params.value()).value(); - std::size_t r = std::accumulate(step_list.begin(), step_list.end(), 0); + // We skip value #1 which is 'm'. It's a static value, cannot be set from a marshalling. + // We still need to include it when converting to a marshalling structure, to include it + // in the transcript value intialization. + std::size_t grinding_parameter = std::get<2>(filled_params.value()).value(); std::size_t max_degree = std::get<3>(filled_params.value()).value(); + std::size_t degree_log = std::ceil(std::log2(max_degree)); + + // We skip value #4, which is unity roots. They will be generated again. + + auto step_list = make_integer_vector(std::get<5>(filled_params.value())); std::size_t expand_factor = std::get<6>(filled_params.value()).value(); - std::size_t grinding_parameter = std::get<2>(filled_params.value()).value(); - auto D = math::calculate_domain_set(r + expand_factor + 1, r); - // TODO: check generators correctness + std::size_t r = std::accumulate(step_list.begin(), step_list.end(), 0); return CommitmentParamsType( - max_degree, - D, step_list, - expand_factor, + degree_log, lambda, + expand_factor, (grinding_parameter != 0), grinding_parameter ); diff --git a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/eval_storage.hpp b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/eval_storage.hpp index 919d5c39bb..5b446cb540 100644 --- a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/eval_storage.hpp +++ b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/eval_storage.hpp @@ -46,19 +46,19 @@ namespace nil { namespace marshalling { namespace types { - // Default commitment marshalling typetype. - template + // Default commitment marshalling type. + template struct commitment; - // Default commitment marshalling typetype. - template + // Default commitment marshalling type. + template struct commitment_preprocessed_data; // Default commitment scheme proof marshalling type in fact it'll be one of tuple's elements for LPC and KZG - template + template struct eval_proof; - template < typename TTypeBase, typename EvalStorage > + template using eval_storage = nil::marshalling::types::bundle< TTypeBase, std::tuple< diff --git a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/fri.hpp b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/fri.hpp index 25fb591204..7dbaa92763 100644 --- a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/fri.hpp +++ b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/fri.hpp @@ -42,48 +42,12 @@ #include #include +#include namespace nil { namespace crypto3 { namespace marshalling { namespace types { - template - using field_element_vector_type = nil::marshalling::types::array_list< - TTypeBase, - field_element, - nil::marshalling::option::sequence_size_field_prefix> - >; - - /////////////////////////////////////////////// - // math::polynomial marshalling - /////////////////////////////////////////////// - template - using fri_math_polynomial = field_element_vector_type; - - template - fri_math_polynomial, PolynomialType> - fill_fri_math_polynomial(const Range &f){ - std::vector val; - for( auto it=f.begin(); it != f.end(); it++){ val.push_back(*it); } - - return nil::crypto3::marshalling::types::fill_field_element_vector< - typename PolynomialType::value_type, - Endianness - >(val); - } - - template - PolynomialType - make_fri_math_polynomial( const fri_math_polynomial, PolynomialType> &filled_polynomial){ - auto val = nil::crypto3::marshalling::types::make_field_element_vector< - typename PolynomialType::value_type, - Endianness - >(filled_polynomial); - - return PolynomialType(val); - } - - /////////////////////////////////////////////////// // fri::merkle_proofs marshalling @@ -182,8 +146,7 @@ namespace nil { // std::select_container final_polynomials // May be different size, because real degree may be less than before. So put int in the end - fri_math_polynomial, - + typename polynomial::type, // proof of work. TODO: how to do it optional? nil::marshalling::types::integral //proof of work*/ @@ -290,7 +253,7 @@ namespace nil { } } - auto filled_final_polynomial = fill_fri_math_polynomial( + auto filled_final_polynomial = fill_polynomial( proof.final_polynomial ); @@ -380,7 +343,7 @@ namespace nil { } // final_polynomial - proof.final_polynomial = make_fri_math_polynomial( + proof.final_polynomial = make_polynomial( std::get<6>(filled_proof.value()) ); // proof_of_work diff --git a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/lpc.hpp b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/lpc.hpp index e2564a91cd..d0ee08b67e 100644 --- a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/lpc.hpp +++ b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/lpc.hpp @@ -3,6 +3,7 @@ // Copyright (c) 2021-2022 Nikita Kaskov // Copyright (c) 2021-2022 Ilias Khairullin // Copyright (c) 2022-2023 Elena Tatuzova +// Copyright (c) 2024 Martun Karapetyan // // MIT License // @@ -42,9 +43,13 @@ #include #include +#include +#include + #include #include -#include +#include +#include #include @@ -57,7 +62,7 @@ namespace nil { // * LPCScheme is like lpc_commitment_scheme template struct commitment>> { - using type = typename merkle_node_value< TTypeBase, typename LPCScheme::commitment_type>::type; + using type = typename merkle_node_value::type; }; template @@ -65,7 +70,7 @@ namespace nil { nil::marshalling::field_type, LPCScheme, std::enable_if_t> >::type - fill_commitment(typename LPCScheme::commitment_type commitment){ + fill_commitment(typename LPCScheme::commitment_type commitment) { return fill_merkle_node_value( commitment ); } @@ -74,8 +79,7 @@ namespace nil { make_commitment(typename commitment< nil::marshalling::field_type, LPCScheme, std::enable_if_t> - >::type const& filled_commitment - ){ + >::type const& filled_commitment) { return make_merkle_node_value( filled_commitment ); } @@ -109,7 +113,7 @@ namespace nil { nil::marshalling::field_type, LPCScheme, std::enable_if_t> >::type - fill_commitment_preprocessed_data(const typename LPCScheme::preprocessed_data_type lpc_data){ + fill_commitment_preprocessed_data(const typename LPCScheme::preprocessed_data_type& lpc_data){ using TTypeBase = nil::marshalling::field_type; using field_marshalling_type = field_element; @@ -132,13 +136,14 @@ namespace nil { nil::marshalling::option::sequence_size_field_prefix> > filled_values; - for(const auto&[k, v]:lpc_data){ + for (const auto&[k, v]: lpc_data) { filled_map_ids.value().push_back(nil::marshalling::types::integral(k)); filled_sizes.value().push_back(nil::marshalling::types::integral(v.size())); - for(std::size_t i = 0; i < v.size(); i++){ + for (std::size_t i = 0; i < v.size(); i++) { filled_values.value().push_back(field_marshalling_type((v[i]))); } } + return result_type( std::make_tuple( filled_map_ids, @@ -151,10 +156,10 @@ namespace nil { template typename LPCScheme::preprocessed_data_type make_commitment_preprocessed_data(typename commitment_preprocessed_data< - nil::marshalling::field_type, LPCScheme, - std::enable_if_t> - >::type const& filled_commitment_preprocessed_data - ){ + nil::marshalling::field_type, LPCScheme, + std::enable_if_t> + >::type const& filled_commitment_preprocessed_data + ) { using TTypeBase = nil::marshalling::field_type; typename LPCScheme::preprocessed_data_type result; @@ -206,16 +211,208 @@ namespace nil { template typename LPCScheme::proof_type make_eval_proof( - const typename eval_proof, LPCScheme, std::enable_if_t>>::type &filled_proof - ){ + const typename eval_proof< + nil::marshalling::field_type, + LPCScheme, + std::enable_if_t> + >::type &filled_proof + ) { typename LPCScheme::proof_type proof; - proof.z = make_eval_storage(std::get<0>(filled_proof.value())); + proof.z = make_eval_storage( + std::get<0>(filled_proof.value())); + auto batch_info = proof.z.get_batch_info(); - proof.fri_proof = make_fri_proof(std::get<1>(filled_proof.value()), batch_info); + proof.fri_proof = make_fri_proof( + std::get<1>(filled_proof.value()), batch_info); return proof; } + + template + struct precommitment_type; + + // Will be used to store precommitment type of a commitment scheme. It's useful only for LPC for now, + // and in practive precommitment contains a merkle tree. The following check checks that statement, + // that the precommitment is a merkle tree. + template + struct precommitment_type && + std::is_same< + typename LPCScheme::precommitment_type, + nil::crypto3::containers::merkle_tree< + typename LPCScheme::precommitment_type::hash_type, + LPCScheme::precommitment_type::arity + > + >::value>> { + using type = merkle_tree; + }; + + template + struct commitment_scheme_state; + + // We need the ability to save the whole state of a commitment scheme, every sinlge field, + // so we can resume our program's execution from where it was stopped. + // This will allow us to separate the preprocessor from prover, because LPC has a preprocess step, which + // changes the state of the 'lpc_commitment_scheme' class. + template + struct commitment_scheme_state> > { + using type = nil::marshalling::types::bundle< + TTypeBase, + std::tuple< + // std::map _trees; + nil::marshalling::types::array_list< + TTypeBase, + nil::marshalling::types::integral, + nil::marshalling::option::sequence_size_field_prefix< + nil::marshalling::types::integral> + >, + nil::marshalling::types::array_list< + TTypeBase, + typename precommitment_type::type, + nil::marshalling::option::sequence_size_field_prefix< + nil::marshalling::types::integral> + >, + // typename fri_type::params_type _fri_params; + typename commitment_params::type, + + // value_type _etha; + field_element, + + //std::map _batch_fixed; + nil::marshalling::types::array_list< + TTypeBase, + nil::marshalling::types::integral, + nil::marshalling::option::sequence_size_field_prefix< + nil::marshalling::types::integral> + >, + // Next value was supposed to be a vector of bool, but our marshalling core + // does not allow us to create an array_list of bools. + nil::marshalling::types::array_list< + TTypeBase, + nil::marshalling::types::integral, + nil::marshalling::option::sequence_size_field_prefix< + nil::marshalling::types::integral> + >, + // preprocessed_data_type _fixed_polys_values; + typename commitment_preprocessed_data< + TTypeBase, LPCScheme, + std::enable_if_t> + >::type, + // LPC derives from polys_evaluator, so we need to marshall that as well. + polys_evaluator + > + >; + }; + + template + typename commitment_scheme_state, LPCScheme, + std::enable_if_t>>::type + fill_commitment_scheme(const LPCScheme &scheme) { + using TTypeBase = nil::marshalling::field_type; + using result_type = typename commitment_scheme_state, LPCScheme>::type; + + // std::map _trees; + nil::marshalling::types::array_list< + TTypeBase, + nil::marshalling::types::integral, + nil::marshalling::option::sequence_size_field_prefix< + nil::marshalling::types::integral> + > filled_trees_keys; + nil::marshalling::types::array_list< + TTypeBase, + typename precommitment_type::type, + nil::marshalling::option::sequence_size_field_prefix< + nil::marshalling::types::integral> + > filled_trees_values; + for (const auto&[key, value]: scheme.get_trees()) { + filled_trees_keys.value().push_back(nil::marshalling::types::integral(key)); + // Precommitment for LPC is a merkle tree. We may want to abstract away this part into a separate + // fill_precommitment function. + filled_trees_values.value().push_back( + fill_merkle_tree(value)); + } + + //std::map _batch_fixed; + nil::marshalling::types::array_list< + TTypeBase, + nil::marshalling::types::integral, + nil::marshalling::option::sequence_size_field_prefix< + nil::marshalling::types::integral> + > filled_batch_fixed_keys; + nil::marshalling::types::array_list< + TTypeBase, + nil::marshalling::types::integral, + nil::marshalling::option::sequence_size_field_prefix< + nil::marshalling::types::integral> + > filled_batch_fixed_values; + for (const auto&[key, value]: scheme.get_batch_fixed()) { + filled_batch_fixed_keys.value().push_back( + nil::marshalling::types::integral(key)); + // Here we convert the value, that is a 'bool' into size_t, which is not good. + filled_batch_fixed_values.value().push_back( + nil::marshalling::types::integral(value)); + } + + return result_type(std::make_tuple( + filled_trees_keys, + filled_trees_values, + fill_commitment_params(scheme.get_fri_params()), + field_element(scheme.get_etha()), + filled_batch_fixed_keys, + filled_batch_fixed_values, + fill_commitment_preprocessed_data(scheme.get_fixed_polys_values()), + fill_polys_evaluator( + static_cast(scheme)) + )); + } + + template + LPCScheme make_commitment_scheme( + typename commitment_scheme_state< + nil::marshalling::field_type, LPCScheme, + std::enable_if_t>>::type& filled_commitment_scheme + ) { + using TTypeBase = typename nil::marshalling::field_type; + + std::map trees; + // TODO(martun): this check must be made in release mode as well, maybe we need to start returning statuses + // from make_ functions. + const auto& filled_tree_keys = std::get<0>(filled_commitment_scheme.value()).value(); + const auto& filled_tree_values = std::get<1>(filled_commitment_scheme.value()).value(); + BOOST_ASSERT(filled_tree_keys.size() == filled_tree_values.size()); + + for (std::size_t i = 0; i < filled_tree_keys.size(); i++) { + trees[std::size_t(filled_tree_keys[i].value())] = + make_merkle_tree( + filled_tree_values[i]); + } + + typename LPCScheme::fri_type::params_type fri_params = make_commitment_params( + std::get<2>(filled_commitment_scheme.value())); + typename LPCScheme::value_type etha = std::get<3>(filled_commitment_scheme.value()).value(); + + std::map batch_fixed; + const auto& batch_fixed_keys = std::get<4>(filled_commitment_scheme.value()).value(); + const auto& batch_fixed_values = std::get<5>(filled_commitment_scheme.value()).value(); + BOOST_ASSERT(batch_fixed_keys.size() == batch_fixed_values.size()); + + for (std::size_t i = 0; i < batch_fixed_keys.size(); i++) { + // Here we convert the value from type size_t back into a 'bool', which is not good. + batch_fixed[std::size_t(batch_fixed_keys[i].value())] = bool(batch_fixed_values[i].value()); + } + + typename LPCScheme::preprocessed_data_type fixed_polys_values = + make_commitment_preprocessed_data( + std::get<6>(filled_commitment_scheme.value())); + + typename LPCScheme::polys_evaluator_type evaluator = make_polys_evaluator< + Endianness, typename LPCScheme::polys_evaluator_type>( + std::get<7>(filled_commitment_scheme.value()) + ); + + return LPCScheme(evaluator, trees, fri_params, etha, batch_fixed, fixed_polys_values); + } } // namespace types } // namespace marshalling } // namespace crypto3 diff --git a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/polys_evaluator.hpp b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/polys_evaluator.hpp new file mode 100644 index 0000000000..924971e588 --- /dev/null +++ b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/polys_evaluator.hpp @@ -0,0 +1,207 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2024 Martun Karapetyan +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_MARSHALLING_POLYS_EVALUATOR_HPP +#define CRYPTO3_MARSHALLING_POLYS_EVALUATOR_HPP + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +namespace nil { + namespace crypto3 { + namespace marshalling { + namespace types { + + // * PolysEvaluator is like lpc_commitment_scheme + template + using polys_evaluator = nil::marshalling::types::bundle< + TTypeBase, + std::tuple< + // std::map> _polys; + nil::marshalling::types::standard_size_t_array_list, + nil::marshalling::types::standard_array_list< + TTypeBase, + polynomial_vector + >, + // std::map _locked; + nil::marshalling::types::standard_size_t_array_list, + nil::marshalling::types::standard_size_t_array_list, + // std::map>> _points; + nil::marshalling::types::standard_size_t_array_list, + // Next structure is a vector of vector of vector of field values. + nil::marshalling::types::standard_array_list< + TTypeBase, + nil::marshalling::types::standard_array_list< + TTypeBase, + field_element_vector + > + >, + // eval_storage _z; + eval_storage + > // This one closes the tuple + >; // this one closes the bundle + + template + polys_evaluator, PolysEvaluator> + fill_polys_evaluator(const PolysEvaluator& evaluator) { + + using nil::marshalling::types::fill_size_t; + using nil::marshalling::types::fill_std_map; + using nil::marshalling::types::standard_array_list; + using nil::marshalling::types::fill_standard_array_list; + + using TTypeBase = nil::marshalling::field_type; + using polynomial_type = typename PolysEvaluator::polynomial_type; + using value_type = typename polynomial_type::value_type; + + using size_t_marshalling_type = nil::marshalling::types::integral; + using polynomial_vector_marshalling_type = polynomial_vector; + + using field_element_vector_type = field_element_vector>; + using array_of_field_element_vector_type = standard_array_list; + + using result_type = polys_evaluator, PolysEvaluator>; + + auto [filled_polys_keys, filled_polys_values] = fill_std_map< + TTypeBase, + size_t_marshalling_type, + polynomial_vector_marshalling_type, + std::size_t, + std::vector>( + evaluator._polys, fill_size_t, fill_polynomial_vector); + + // Note that we marshall a bool value as an std::size_t. + auto [filled_locked_keys, filled_locked_values] = fill_std_map< + TTypeBase, + size_t_marshalling_type, + size_t_marshalling_type, + std::size_t, + bool>( + evaluator._locked, fill_size_t, fill_size_t); + + auto [filled_points_keys, filled_points_values] = fill_std_map< + TTypeBase, + size_t_marshalling_type, + array_of_field_element_vector_type, + std::size_t, + std::vector>>( + evaluator._points, + fill_size_t, + [](const std::vector>& points) -> array_of_field_element_vector_type { + return fill_standard_array_list( + points, fill_field_element_vector); + }); + + auto filled_eval_storage = fill_eval_storage( + evaluator._z); + + return result_type( + std::make_tuple( + filled_polys_keys, + filled_polys_values, + filled_locked_keys, + filled_locked_values, + filled_points_keys, + filled_points_values, + filled_eval_storage + ) + ); + } + + template + PolysEvaluator make_polys_evaluator( + const polys_evaluator, PolysEvaluator>& filled_polys_evaluator + ) { + using nil::marshalling::types::make_size_t; + using nil::marshalling::types::make_std_map; + using nil::marshalling::types::standard_array_list; + using nil::marshalling::types::make_standard_array_list; + + using TTypeBase = nil::marshalling::field_type; + using polynomial_type = typename PolysEvaluator::polynomial_type; + using value_type = typename polynomial_type::value_type; + + using size_t_marshalling_type = nil::marshalling::types::integral; + using polynomial_vector_marshalling_type = polynomial_vector; + + using field_element_vector_type = field_element_vector>; + using array_of_field_element_vector_type = standard_array_list; + + + using TTypeBase = nil::marshalling::field_type; + using polynomial_type = typename PolysEvaluator::polynomial_type; + using value_type = typename polynomial_type::value_type; + + PolysEvaluator result; + result._polys = make_std_map, size_t_marshalling_type, polynomial_vector_marshalling_type>( + std::get<0>(filled_polys_evaluator.value()), + std::get<1>(filled_polys_evaluator.value()), + make_size_t, + make_polynomial_vector); + + result._locked = make_std_map( + std::get<2>(filled_polys_evaluator.value()), + std::get<3>(filled_polys_evaluator.value()), + make_size_t, + make_size_t); + + result._points = make_std_map>, size_t_marshalling_type, array_of_field_element_vector_type>( + std::get<4>(filled_polys_evaluator.value()), + std::get<5>(filled_polys_evaluator.value()), + make_size_t, + [](const array_of_field_element_vector_type& points) -> std::vector> { + return make_standard_array_list, field_element_vector_type>( + points, make_field_element_vector); + }); + + result._z = make_eval_storage( + std::get<6>(filled_polys_evaluator.value())); + + // We need to build _points_map, which duplicates the data in _points but as a map. + result.build_points_map(); + + return result; + } + + } // namespace types + } // namespace marshalling + } // namespace crypto3 +} // namespace nil + +#endif // CRYPTO3_MARSHALLING_POLYS_EVALUATOR_HPP diff --git a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/common_data.hpp b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/common_data.hpp index 0eea373570..f4ab6e9979 100644 --- a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/common_data.hpp +++ b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/common_data.hpp @@ -115,8 +115,6 @@ namespace nil { using TTypeBase = typename nil::marshalling::field_type; using result_type = placeholder_common_data; - result_type result; - using array_int_marshalling_type = nil::marshalling::types::array_list , nil::marshalling::option::sequence_size_field_prefix> @@ -200,7 +198,6 @@ namespace nil { filled_commitment_params, // 14 filled_commitment_preprocessed_data // 15 )); - return result; } template diff --git a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/preprocessed_public_data.hpp b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/preprocessed_public_data.hpp new file mode 100644 index 0000000000..5c46a807f3 --- /dev/null +++ b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/preprocessed_public_data.hpp @@ -0,0 +1,114 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2024 Martun Karapetyan +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_MARSHALLING_PREPROCESSED_PUBLIC_DATA_HPP +#define CRYPTO3_MARSHALLING_PREPROCESSED_PUBLIC_DATA_HPP + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +namespace nil { + namespace crypto3 { + namespace marshalling { + namespace types { + // ******************* placeholder preprocessed public data ********************************* // + template + using placeholder_preprocessed_public_data = nil::marshalling::types::bundle< + TTypeBase, + std::tuple< + // plonk_public_polynomial_dfs_table public_polynomial_table; + plonk_public_polynomial_table, + // std::vector permutation_polynomials + polynomial_vector, + + // std::vector identity_polynomials; + polynomial_vector, + + // polynomial_dfs_type q_last; + typename polynomial::type, + // polynomial_dfs_type q_blind; + typename polynomial::type, + + // common_data_type common_data; + placeholder_common_data + > + >; + + template + placeholder_preprocessed_public_data, PreprocessedPublicDataType> + fill_placeholder_preprocessed_public_data(const PreprocessedPublicDataType& preprocessed_public_data) { + using TTypeBase = typename nil::marshalling::field_type; + using PolynomialDFSType = typename PreprocessedPublicDataType::polynomial_dfs_type; + using result_type = placeholder_preprocessed_public_data< + nil::marshalling::field_type, PreprocessedPublicDataType>; + + return result_type(std::make_tuple( + fill_plonk_public_table( + preprocessed_public_data.public_polynomial_table), + fill_polynomial_vector(preprocessed_public_data.permutation_polynomials), + fill_polynomial_vector(preprocessed_public_data.identity_polynomials), + fill_polynomial(preprocessed_public_data.q_last), + fill_polynomial(preprocessed_public_data.q_blind), + fill_placeholder_common_data( + preprocessed_public_data.common_data) + )); + } + + template + PreprocessedPublicDataType make_placeholder_preprocessed_public_data(const + placeholder_preprocessed_public_data, PreprocessedPublicDataType> &filled_preprocessed_public_data + ) { + using TTypeBase = typename nil::marshalling::field_type; + using PolynomialDFSType = typename PreprocessedPublicDataType::polynomial_dfs_type; + + return PreprocessedPublicDataType({ + make_plonk_public_table( + std::get<0>(filled_preprocessed_public_data.value())), + make_polynomial_vector(std::get<1>(filled_preprocessed_public_data.value())), + make_polynomial_vector(std::get<2>(filled_preprocessed_public_data.value())), + make_polynomial(std::get<3>(filled_preprocessed_public_data.value())), + make_polynomial(std::get<4>(filled_preprocessed_public_data.value())), + make_placeholder_common_data( + std::get<5>(filled_preprocessed_public_data.value())) + }); + } + } // namespace types + } // namespace marshalling + } // namespace crypto3 +} // namespace nil + +#endif // CRYPTO3_MARSHALLING_PREPROCESSED_PUBLIC_DATA_HPP diff --git a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/proof.hpp b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/proof.hpp index de79fa02f5..d7a228b1de 100644 --- a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/proof.hpp +++ b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/proof.hpp @@ -67,10 +67,10 @@ namespace nil { using TTypeBase = nil::marshalling::field_type; - using field_marhsalling_type = field_element; + using field_marshalling_type = field_element; // typename FieldType::value_type challenge - field_marhsalling_type filled_challenge = field_marhsalling_type(proof.challenge); + field_marshalling_type filled_challenge = field_marshalling_type(proof.challenge); // typename commitment_scheme_type::proof_type eval_proof; auto filled_eval_proof = diff --git a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/plonk/assignment_table.hpp b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/plonk/assignment_table.hpp index 2621c90c87..d963248321 100644 --- a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/plonk/assignment_table.hpp +++ b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/plonk/assignment_table.hpp @@ -43,6 +43,60 @@ namespace nil { namespace marshalling { namespace types { + ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + ///////// Marshalling the assignment table description. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + + // TODO(we may consider to use this construct when marshalling the assignment table.) + template + using plonk_assignment_table_description = nil::marshalling::types::bundle< + TTypeBase, std::tuple< + nil::marshalling::types::integral, // witness_amount + nil::marshalling::types::integral, // public_input_amount + nil::marshalling::types::integral, // constant_amount + nil::marshalling::types::integral, // selector_amount + + nil::marshalling::types::integral, // usable_rows + nil::marshalling::types::integral // rows_amount + > + >; + + template + plonk_assignment_table_description> fill_assignment_table_description( + const zk::snark::plonk_table_description& desc + ) { + using TTypeBase = nil::marshalling::field_type; + using result_type = plonk_assignment_table_description>; + using value_type = typename FieldType::value_type; + + return result_type(std::move(std::make_tuple( + nil::marshalling::types::integral(desc.witness_columns), + nil::marshalling::types::integral(desc.public_input_columns), + nil::marshalling::types::integral(desc.constant_columns), + nil::marshalling::types::integral(desc.selector_columns), + nil::marshalling::types::integral(desc.usable_rows_amount), + nil::marshalling::types::integral(desc.rows_amount)))); + } + + template + zk::snark::plonk_table_description make_assignment_table_description( + const plonk_assignment_table_description> &filled_description) { + + zk::snark::plonk_table_description desc( + std::get<0>(filled_description.value()).value(), + std::get<1>(filled_description.value()).value(), + std::get<2>(filled_description.value()).value(), + std::get<3>(filled_description.value()).value(), + std::get<4>(filled_description.value()).value(), + std::get<5>(filled_description.value()).value() + ); + return desc; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + ///////// Marshalling the assignment table. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////// + template using plonk_assignment_table = nil::marshalling::types::bundle< TTypeBase, std::tuple< @@ -143,7 +197,7 @@ namespace nil { plonk_assignment_table, PlonkTable> fill_assignment_table( std::size_t usable_rows, const PlonkTable &assignments - ){ + ) { using TTypeBase = nil::marshalling::field_type; using result_type = plonk_assignment_table, PlonkTable>; using value_type = typename PlonkTable::field_type::value_type; @@ -228,6 +282,8 @@ namespace nil { typename PlonkTable::public_table_type(public_inputs, constants, selectors) )); } + + } //namespace types } // namespace marshalling } // namespace crypto3 diff --git a/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/plonk/plonk_public_polynomial_dfs_table.hpp b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/plonk/plonk_public_polynomial_dfs_table.hpp new file mode 100644 index 0000000000..61aaceb9db --- /dev/null +++ b/crypto3/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/plonk/plonk_public_polynomial_dfs_table.hpp @@ -0,0 +1,91 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2024 Martun Karapetyan +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_MARSHALLING_ZK_PLONK_PUBLIC_POLYNOMIAL_TABLE_HPP +#define CRYPTO3_MARSHALLING_ZK_PLONK_PUBLIC_POLYNOMIAL_TABLE_HPP + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace nil { + namespace crypto3 { + namespace marshalling { + namespace types { + + template + using plonk_public_polynomial_table = nil::marshalling::types::bundle< + TTypeBase, std::tuple< + // public_inputs + polynomial_vector, + // constants + polynomial_vector, + // selectors + polynomial_vector + > + >; + + template + plonk_public_polynomial_table, PlonkPublicTable> fill_plonk_public_table( + const PlonkPublicTable &public_table + ) { + using TTypeBase = nil::marshalling::field_type; + using PolynomialType = typename PlonkPublicTable::column_type; + using result_type = plonk_public_polynomial_table, PlonkPublicTable>; + return result_type(std::make_tuple( + fill_polynomial_vector(public_table.public_inputs()), + fill_polynomial_vector(public_table.constants()), + fill_polynomial_vector(public_table.selectors()) + )); + } + + template + PlonkPublicTable make_plonk_public_table( + const plonk_public_polynomial_table, PlonkPublicTable> &filled_public_table) { + using TTypeBase = nil::marshalling::field_type; + using PolynomialType = typename PlonkPublicTable::column_type; + + return PlonkPublicTable( + make_polynomial_vector(std::get<0>(filled_public_table.value())), + make_polynomial_vector(std::get<1>(filled_public_table.value())), + make_polynomial_vector(std::get<2>(filled_public_table.value())) + ); + } + + } //namespace types + } // namespace marshalling + } // namespace crypto3 +} // namespace nil + +#endif diff --git a/crypto3/libs/marshalling/zk/test/CMakeLists.txt b/crypto3/libs/marshalling/zk/test/CMakeLists.txt index 41a0f48eaa..fba9aa60d3 100644 --- a/crypto3/libs/marshalling/zk/test/CMakeLists.txt +++ b/crypto3/libs/marshalling/zk/test/CMakeLists.txt @@ -52,6 +52,7 @@ endmacro() # r1cs tests are failing compilation, turning them off for now. set(TESTS_NAMES "merkle_proof" + "merkle_tree" "accumulation_vector" "sparse_vector" # "r1cs_gg_ppzksnark_primary_input" @@ -61,8 +62,10 @@ set(TESTS_NAMES "kzg_commitment" "fri_commitment" "lpc_commitment" + "polys_evaluator" "placeholder_proof" "placeholder_common_data" + "placeholder_preprocessed_public_data" "plonk_gates" "plonk_constraint_system" "plonk_assignment_table" diff --git a/crypto3/libs/marshalling/zk/test/fri_commitment.cpp b/crypto3/libs/marshalling/zk/test/fri_commitment.cpp index a9070c6d77..027f3100b8 100644 --- a/crypto3/libs/marshalling/zk/test/fri_commitment.cpp +++ b/crypto3/libs/marshalling/zk/test/fri_commitment.cpp @@ -70,213 +70,9 @@ #include #include -using namespace nil::crypto3; - -/* -template -void print_byteblob(std::ostream &os, TIter iter_begin, TIter iter_end) { - for (TIter it = iter_begin; it != iter_end; it++) { - os << std::hex << int(*it) << std::endl; - } -} - -template -void print_field_element(std::ostream &os, - const typename nil::crypto3::algebra::fields::detail::element_fp &e) { - os << e.data << std::endl; -} - -template -void print_field_element(std::ostream &os, - const typename nil::crypto3::algebra::fields::detail::element_fp2 &e) { - os << "[" << e.data[0].data << "," << e.data[1].data << "]" << std::endl; -} -*/ -template -typename std::enable_if::value, std::vector>>::type -generate_random_data(std::size_t leaf_number, boost::random::mt11213b &rnd) { - std::vector> v; - for (std::size_t i = 0; i < leaf_number; ++i) { - std::array leaf; - std::generate(std::begin(leaf), std::end(leaf), - [&]() { return rnd() % (std::numeric_limits::max() + 1); }); - v.emplace_back(leaf); - } - return v; -} - -std::vector> -generate_random_data_for_merkle_tree(size_t leafs_number, size_t leaf_bytes, boost::random::mt11213b &rnd) { - std::vector> rdata(leafs_number, std::vector(leaf_bytes)); - - for (std::size_t i = 0; i < leafs_number; ++i) { - std::vector leaf(leaf_bytes); - for (size_t i = 0; i < leaf_bytes; i++) { - leaf[i] = rnd() % (std::numeric_limits::max() + 1); - } - rdata.emplace_back(leaf); - } - return rdata; -} - -template -typename FRI::merkle_proof_type generate_random_merkle_proof(std::size_t tree_depth, boost::random::mt11213b &rnd) { - std::size_t leafs_number = 1 << tree_depth; - std::size_t leaf_size = 32; - - auto rdata1 = generate_random_data_for_merkle_tree(leafs_number, leaf_size, rnd); - auto tree1 = containers::make_merkle_tree(rdata1.begin(), - rdata1.end()); - std::size_t idx1 = rnd() % leafs_number; - typename FRI::merkle_proof_type mp1(tree1, idx1); - return mp1; -} - -inline std::vector -generate_random_step_list(const std::size_t r, const std::size_t max_step, boost::random::mt11213b &rnd) { - using dist_type = std::uniform_int_distribution; - - std::vector step_list; - std::size_t steps_sum = 0; - while (steps_sum != r) { - if (r - steps_sum <= max_step) { - while (r - steps_sum != 1) { - step_list.emplace_back(r - steps_sum - 1); - steps_sum += step_list.back(); - } - step_list.emplace_back(1); - steps_sum += step_list.back(); - } else { - step_list.emplace_back(dist_type(1, max_step)(rnd)); - steps_sum += step_list.back(); - } - } - - return step_list; -} - - -template -typename FRI::polynomial_values_type generate_random_polynomial_values( - size_t step, - nil::crypto3::random::algebraic_engine &alg_rnd -) { - typename FRI::polynomial_values_type values; - - std::size_t coset_size = 1 << (step - 1); - values.resize(coset_size); - for (size_t i = 0; i < coset_size; i++) { - for (size_t j = 0; j < FRI::m; j++) { - values[i][j] = alg_rnd(); - values[i][j] = alg_rnd(); - } - } - return values; -} +#include "random_test_data_generation.hpp" -template -math::polynomial generate_random_polynomial( - size_t degree, - nil::crypto3::random::algebraic_engine &d -) { - math::polynomial poly; - poly.resize(degree); - - for (std::size_t i = 0; i < degree; ++i) { - poly[i] = d(); - } - return poly; -} - -template -typename FRI::round_proof_type generate_random_fri_round_proof( - std::size_t r_i, - nil::crypto3::random::algebraic_engine &alg_rnd, - boost::random::mt11213b &rnd -) { - typename FRI::round_proof_type res; - res.p = generate_random_merkle_proof(3, rnd); - res.y = generate_random_polynomial_values(r_i, alg_rnd); - - return res; -} - -template -typename FRI::initial_proof_type generate_random_fri_initial_proof( - std::size_t polynomial_number, - std::size_t r0, - nil::crypto3::random::algebraic_engine &alg_rnd, - boost::random::mt11213b &rnd -) { - typename FRI::initial_proof_type res; - - std::size_t coset_size = 1 << r0; - res.p = generate_random_merkle_proof(3, rnd); - res.values.resize(polynomial_number); - for (std::size_t i = 0; i < polynomial_number; i++) { - res.values[i].resize(coset_size / FRI::m); - for (std::size_t j = 0; j < coset_size / FRI::m; j++) { - res.values[i][j][0] = alg_rnd(); - res.values[i][j][1] = alg_rnd(); - } - } - - return res; -} - -template -typename FRI::query_proof_type generate_random_fri_query_proof( - std::size_t max_batch_size, - std::vector step_list, - nil::crypto3::marshalling::types::batch_info_type batch_info, - nil::crypto3::random::algebraic_engine &alg_rnd, - boost::random::mt11213b &rnd -) { - typename FRI::query_proof_type res; - - for (const auto &it : batch_info) { - res.initial_proof[it.first] = generate_random_fri_initial_proof(it.second, step_list[0], alg_rnd, rnd); - } - res.round_proofs.resize(step_list.size()); - for (std::size_t i = 1; i < step_list.size(); i++) { - res.round_proofs[i-1] = generate_random_fri_round_proof( - step_list[i], alg_rnd, rnd - ); - } - res.round_proofs[step_list.size()-1] = generate_random_fri_round_proof( - 1, alg_rnd, rnd - ); - return res; -} - -template -typename FRI::proof_type generate_random_fri_proof( - std::size_t d, //final polynomial degree - std::size_t max_batch_size, - std::vector step_list, - std::size_t lambda, - bool use_grinding, - nil::crypto3::marshalling::types::batch_info_type batch_info, - nil::crypto3::random::algebraic_engine &alg_rnd, - boost::random::mt11213b &rnd -) { - typename FRI::proof_type res; - res.query_proofs.resize(lambda); - for (std::size_t k = 0; k < lambda; k++) { - res.query_proofs[k] = generate_random_fri_query_proof(max_batch_size, step_list, batch_info, alg_rnd, rnd); - } - res.fri_roots.resize(step_list.size()); - for (std::size_t k = 0; k < step_list.size(); k++) { - res.fri_roots[k] = nil::crypto3::hash( - generate_random_data(1, rnd).at(0) - ); - } - if (use_grinding){ - res.proof_of_work = rnd(); - } - res.final_polynomial = generate_random_polynomial(d, alg_rnd); - return res; -} +using namespace nil::crypto3; template void test_fri_proof(typename FRI::proof_type &proof, typename nil::crypto3::marshalling::types::batch_info_type batch_info, @@ -332,15 +128,15 @@ BOOST_FIXTURE_TEST_SUITE(marshalling_fri_proof_elements, zk::test_tools::random_ BOOST_AUTO_TEST_CASE(polynomial_test) { using polynomial_type = math::polynomial; polynomial_type f = {{1u, 3u, 4u, 1u, 5u, 6u, 7u, 2u, 8u, 7u, 5u, 6u, 1u, 2u, 1u, 1u}}; - auto filled_polynomial = nil::crypto3::marshalling::types::fill_fri_math_polynomial(f); + auto filled_polynomial = nil::crypto3::marshalling::types::fill_polynomial(f); - auto _f = nil::crypto3::marshalling::types::make_fri_math_polynomial(filled_polynomial); + auto _f = nil::crypto3::marshalling::types::make_polynomial(filled_polynomial); BOOST_CHECK(f == _f); f = generate_random_polynomial(2048, alg_random_engines.template get_alg_engine()); - filled_polynomial = nil::crypto3::marshalling::types::fill_fri_math_polynomial(f); + filled_polynomial = nil::crypto3::marshalling::types::fill_polynomial(f); - _f = nil::crypto3::marshalling::types::make_fri_math_polynomial(filled_polynomial); + _f = nil::crypto3::marshalling::types::make_polynomial(filled_polynomial); BOOST_CHECK(f == _f); } @@ -380,8 +176,11 @@ BOOST_FIXTURE_TEST_SUITE(marshalling_fri_proof_elements, zk::test_tools::random_ batch_info[3] = 6; batch_info[4] = 3; - typename FRI::params_type fri_params ( - 1, 11, lambda, 4 + typename FRI::params_type fri_params( + 1, // max_step + 11, // degree_log + lambda, + 4 // expand_factor ); auto proof = generate_random_fri_proof( @@ -396,7 +195,7 @@ BOOST_FIXTURE_TEST_SUITE(marshalling_fri_proof_elements, zk::test_tools::random_ test_fri_proof(proof, batch_info, fri_params); } - BOOST_AUTO_TEST_CASE(fri_grinding_proof_test){ + BOOST_AUTO_TEST_CASE(fri_grinding_proof_test) { nil::crypto3::marshalling::types::batch_info_type batch_info; batch_info[0] = 1; batch_info[1] = 5; @@ -444,42 +243,33 @@ BOOST_AUTO_TEST_CASE(marshalling_fri_basic_test) { typedef typename fri_type::proof_type proof_type; typedef typename fri_type::params_type params_type; - std::size_t extended_log = boost::static_log2::value; - std::vector>> D = - math::calculate_domain_set(extended_log, r); - - params_type params( - d - 1, // max_degree - D, - generate_random_step_list(r, 3, generic_random_engine), - 2, //expand_factor - lambda - ); - - BOOST_CHECK(D[1]->m == D[0]->m / 2); - BOOST_CHECK(D[1]->get_domain_element(1) == D[0]->get_domain_element(1).squared()); + // Setup params + std::size_t degree_log = std::ceil(std::log2(d - 1)); + typename fri_type::params_type fri_params( + 3, /*max_step*/ + degree_log, + lambda, + 2 //expand_factor + ); // commit - math::polynomial f = {{1u, 3u, 4u, 1u, 5u, 6u, 7u, 2u, 8u, 7u, 5u, 6u, 1u, 2u, 1u, 1u}}; + math::polynomial f = {{ + 1u, 3u, 4u, 1u, 5u, 6u, 7u, 2u, 8u, 7u, 5u, 6u, 1u, 2u, 1u, 1u}}; std::array>, 1> fs; fs[0].resize(1); fs[0][0] = f; - typename fri_type::merkle_tree_type tree = zk::algorithms::precommit(fs[0], params.D[0], - params.step_list[0]); + typename fri_type::merkle_tree_type tree = zk::algorithms::precommit( + fs[0], fri_params.D[0], fri_params.step_list[0]); auto root = zk::algorithms::commit(tree); // eval std::vector init_blob{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; zk::transcript::fiat_shamir_heuristic_sequential transcript(init_blob); - proof_type proof = zk::algorithms::proof_eval(f, tree, params, transcript); + proof_type proof = zk::algorithms::proof_eval(f, tree, fri_params, transcript); nil::crypto3::marshalling::types::batch_info_type batch_info; batch_info[0] = 1; - test_fri_proof(proof, batch_info, params); - - // verify - //zk::transcript::fiat_shamir_heuristic_sequential transcript_verifier(init_blob); - - //BOOST_CHECK(zk::algorithms::verify_eval(proof, root, params, transcript_verifier)); + test_fri_proof(proof, batch_info, fri_params); } + BOOST_AUTO_TEST_SUITE_END() diff --git a/crypto3/libs/marshalling/zk/test/lpc_commitment.cpp b/crypto3/libs/marshalling/zk/test/lpc_commitment.cpp index 26e433fa74..413b479d4d 100644 --- a/crypto3/libs/marshalling/zk/test/lpc_commitment.cpp +++ b/crypto3/libs/marshalling/zk/test/lpc_commitment.cpp @@ -30,9 +30,6 @@ #include #include -#include -#include - #include #include #include @@ -42,10 +39,6 @@ #include #include -#include -#include - -#include #include #include #include @@ -70,309 +63,24 @@ #include #include -#include -#include - #include #include -#include +#include "random_test_data_generation.hpp" using namespace nil::crypto3; -/******************************************************************************* - * Printing functions - *******************************************************************************/ -template -void print_hex_byteblob(std::ostream &os, TIter iter_begin, TIter iter_end, bool endl) { - os << std::hex; - for (TIter it = iter_begin; it != iter_end; it++) { - os << std::setfill('0') << std::setw(2) << std::right << int(*it); - } - os << std::dec; - if (endl) { - os << std::endl; - } -} - -template -void print_hex_byteblob_to_file(ProofIterator proof_begin, ProofIterator proof_end, bool endl, std::string name) { - std::ofstream out; - out.open(name); - print_hex_byteblob(out, proof_begin, proof_end, endl); -} - -//******************************************************************************* -//* Fill data structures with random data -//******************************************************************************* -template -typename std::enable_if::value, std::vector>>::type -generate_random_data(std::size_t leaf_number, boost::random::mt11213b &rnd) { - std::vector> v; - for (std::size_t i = 0; i < leaf_number; ++i) { - std::array leaf; - std::generate(std::begin(leaf), std::end(leaf), - [&]() { return rnd() % (std::numeric_limits::max() + 1); }); - v.emplace_back(leaf); - } - return v; -} - -std::vector> -generate_random_data_for_merkle_tree(size_t leafs_number, size_t leaf_bytes, boost::random::mt11213b &rnd) { - std::vector> rdata(leafs_number, std::vector(leaf_bytes)); - - for (std::size_t i = 0; i < leafs_number; ++i) { - std::vector leaf(leaf_bytes); - for (size_t i = 0; i < leaf_bytes; i++) { - leaf[i] = rnd() % (std::numeric_limits::max() + 1); - } - rdata.emplace_back(leaf); - } - return rdata; -} - -template -typename FRI::merkle_proof_type generate_random_merkle_proof(std::size_t tree_depth, boost::random::mt11213b &rnd) { - std::size_t leafs_number = 1 << tree_depth; - std::size_t leaf_size = 32; - - auto rdata1 = generate_random_data_for_merkle_tree(leafs_number, leaf_size, rnd); - auto tree1 = containers::make_merkle_tree(rdata1.begin(), - rdata1.end()); - std::size_t idx1 = rnd() % leafs_number; - typename FRI::merkle_proof_type mp1(tree1, idx1); - return mp1; -} - -inline std::vector -generate_random_step_list(const std::size_t r, const std::size_t max_step, boost::random::mt11213b &rnd) { - using dist_type = std::uniform_int_distribution; - - std::vector step_list; - std::size_t steps_sum = 0; - while (steps_sum != r) { - if (r - steps_sum <= max_step) { - while (r - steps_sum != 1) { - step_list.emplace_back(r - steps_sum - 1); - steps_sum += step_list.back(); - } - step_list.emplace_back(1); - steps_sum += step_list.back(); - } else { - step_list.emplace_back(dist_type(1, max_step)(rnd)); - steps_sum += step_list.back(); - } - } - - return step_list; -} - -template -typename FRI::polynomial_values_type generate_random_polynomial_values( - size_t step, - nil::crypto3::random::algebraic_engine &alg_rnd -) { - typename FRI::polynomial_values_type values; - - std::size_t coset_size = 1 << (step - 1); - values.resize(coset_size); - for (size_t i = 0; i < coset_size; i++) { - for (size_t j = 0; j < FRI::m; j++) { - values[i][j] = alg_rnd(); - values[i][j] = alg_rnd(); - } - } - return values; -} - -template -math::polynomial generate_random_polynomial( - size_t degree, - nil::crypto3::random::algebraic_engine &d -) { - math::polynomial poly; - poly.resize(degree); - - for (std::size_t i = 0; i < degree; ++i) { - poly[i] = d(); - } - return poly; -} - -template -typename FRI::round_proof_type generate_random_fri_round_proof( - std::size_t r_i, - nil::crypto3::random::algebraic_engine &alg_rnd, - boost::random::mt11213b &rnd -) { - typename FRI::round_proof_type res; - res.p = generate_random_merkle_proof(3, rnd); - res.y = generate_random_polynomial_values(r_i, alg_rnd); - - return res; -} - -template -typename FRI::initial_proof_type generate_random_fri_initial_proof( - std::size_t polynomial_number, - std::size_t r0, - nil::crypto3::random::algebraic_engine &alg_rnd, - boost::random::mt11213b &rnd -) { - typename FRI::initial_proof_type res; - - std::size_t coset_size = 1 << r0; - res.p = generate_random_merkle_proof(3, rnd); - res.values.resize(polynomial_number); - for (std::size_t i = 0; i < polynomial_number; i++) { - res.values[i].resize(coset_size / FRI::m); - for (std::size_t j = 0; j < coset_size / FRI::m; j++) { - res.values[i][j][0] = alg_rnd(); - res.values[i][j][1] = alg_rnd(); - } - } - - return res; -} - -template -typename FRI::query_proof_type generate_random_fri_query_proof( - std::size_t max_batch_size, - std::vector step_list, - nil::crypto3::marshalling::types::batch_info_type batch_info, - nil::crypto3::random::algebraic_engine &alg_rnd, - boost::random::mt11213b &rnd -) { - typename FRI::query_proof_type res; - - for (const auto &it : batch_info) { - res.initial_proof[it.first] = generate_random_fri_initial_proof(it.second, step_list[0], alg_rnd, rnd); - } - res.round_proofs.resize(step_list.size()); - for (std::size_t i = 1; i < step_list.size(); i++) { - res.round_proofs[i-1] = generate_random_fri_round_proof( - step_list[i], alg_rnd, rnd - ); - } - res.round_proofs[step_list.size()-1] = generate_random_fri_round_proof( - 1, alg_rnd, rnd - ); - return res; -} - -template -typename FRI::proof_type generate_random_fri_proof( - std::size_t d, //final polynomial degree - std::size_t max_batch_size, - std::vector step_list, - std::size_t lambda, - bool use_grinding, - nil::crypto3::marshalling::types::batch_info_type batch_info, - nil::crypto3::random::algebraic_engine &alg_rnd, - boost::random::mt11213b &rnd -) { - typename FRI::proof_type res; - res.query_proofs.resize(lambda); - for (std::size_t k = 0; k < lambda; k++) { - res.query_proofs[k] = generate_random_fri_query_proof(max_batch_size, step_list, batch_info, alg_rnd, rnd); - } - res.fri_roots.resize(step_list.size()); - for (std::size_t k = 0; k < step_list.size(); k++) { - res.fri_roots[k] = nil::crypto3::hash( - generate_random_data(1, rnd).at(0) - ); - } - if (use_grinding){ - res.proof_of_work = rnd(); - } - res.final_polynomial = generate_random_polynomial(d, alg_rnd); - return res; -} - - -template -typename LPC::proof_type generate_random_lpc_proof( - std::size_t d, //final polynomial degree - std::size_t max_batch_size, - std::vector step_list, - std::size_t lambda, - std::size_t use_grinding, - nil::crypto3::random::algebraic_engine &alg_rnd, - boost::random::mt11213b &rnd -) { - typename LPC::proof_type res; - - nil::crypto3::marshalling::types::batch_info_type batch_info; - for( std::size_t i = 0; i < 6; i++ ){ - batch_info[rnd()%6] = rnd()%9 + 1; - } - for( const auto&it: batch_info){ - res.z.set_batch_size(it.first, it.second); - for( std::size_t i = 0; i < it.second; i++){ - res.z.set_poly_points_number(it.first, i, rnd()%3 + 1); - for( std::size_t j = 0; j < res.z.get_poly_points_number(it.first, i); j++){ - res.z.set(it.first, i, j, alg_rnd()); - } - } - } - res.fri_proof = generate_random_fri_proof(d, max_batch_size, step_list, lambda, use_grinding, batch_info, alg_rnd, rnd); - return res; -} - - -template -math::polynomial_dfs -generate_random_polynomial_dfs(std::size_t degree, nil::crypto3::random::algebraic_engine &rnd) { - math::polynomial data = generate_random_polynomial(degree, rnd); - math::polynomial_dfs result; - result.from_coefficients(data); - return result; -} - -template -std::vector> generate_random_polynomial_batch( - std::size_t batch_size, - std::size_t degree, - nil::crypto3::random::algebraic_engine &rnd -) { - std::vector> result; - - for (std::size_t i = 0; i < batch_size; i++) { - result.push_back(generate_random_polynomial(degree, rnd)); - } - return result; -} - -template -std::vector> -generate_random_polynomial_dfs_batch(std::size_t batch_size, - std::size_t degree, - nil::crypto3::random::algebraic_engine &rnd) { - auto data = generate_random_polynomial_batch(batch_size, degree, rnd); - std::vector> result; - - for (std::size_t i = 0; i < data.size(); i++) { - math::polynomial_dfs dfs; - dfs.from_coefficients(data[i]); - result.push_back(dfs); - } - return result; -} - // ******************************************************************************* // * Test marshalling function // ******************************************************************************* / - - template -void test_lpc_proof(typename LPC::proof_type &proof, typename LPC::fri_type::params_type fri_params, std::string filename = "") { +void test_lpc_proof(typename LPC::proof_type &proof, typename LPC::fri_type::params_type fri_params) { using TTypeBase = nil::marshalling::field_type; auto filled_proof = nil::crypto3::marshalling::types::fill_eval_proof(proof, fri_params); auto _proof = nil::crypto3::marshalling::types::make_eval_proof(filled_proof); BOOST_CHECK(proof == _proof); -/* + std::vector cv; cv.resize(filled_proof.length(), 0x00); auto write_iter = cv.begin(); @@ -386,10 +94,30 @@ void test_lpc_proof(typename LPC::proof_type &proof, typename LPC::fri_type::par typename LPC::proof_type constructed_val_read = nil::crypto3::marshalling::types::make_eval_proof(test_val_read); BOOST_CHECK(proof == constructed_val_read); +} - if (filename != "") { - print_hex_byteblob_to_file(cv.begin(), cv.end(), false, filename + ".data"); - }*/ +// This function will test saving and restoring LPC commitment scheme state to a file/buffer. +template +void test_lpc_state_recovery(const LPC& lpc_commitment_scheme) { + using TTypeBase = nil::marshalling::field_type; + + auto filled_lpc_scheme = nil::crypto3::marshalling::types::fill_commitment_scheme(lpc_commitment_scheme); + auto _lpc_commitment_scheme = nil::crypto3::marshalling::types::make_commitment_scheme(filled_lpc_scheme); + BOOST_CHECK(lpc_commitment_scheme == _lpc_commitment_scheme); + + std::vector cv; + cv.resize(filled_lpc_scheme.length(), 0x00); + auto write_iter = cv.begin(); + auto status = filled_lpc_scheme.write(write_iter, cv.size()); + BOOST_CHECK(status == nil::marshalling::status_type::success); + + typename nil::crypto3::marshalling::types::commitment_scheme_state::type test_val_read; + auto read_iter = cv.begin(); + test_val_read.read(read_iter, cv.size()); + BOOST_CHECK(status == nil::marshalling::status_type::success); + LPC constructed_val_read = + nil::crypto3::marshalling::types::make_commitment_scheme(test_val_read); + BOOST_CHECK(lpc_commitment_scheme == constructed_val_read); } BOOST_AUTO_TEST_SUITE(marshalling_random) @@ -464,23 +192,18 @@ BOOST_FIXTURE_TEST_CASE(batches_num_3_test, zk::test_tools::random_test_initiali static_assert(!zk::is_commitment::value); static_assert(!zk::is_commitment::value); - constexpr static const std::size_t d_extended = d; - std::size_t extended_log = boost::static_log2::value; - std::vector>> D = - math::calculate_domain_set(extended_log, r); + std::size_t degree_log = boost::static_log2::value; // Setup params typename fri_type::params_type fri_params( - d - 1, // max_degree - D, - generate_random_step_list(r, 1, generic_random_engine), - 2, //expand_factor - lambda + 1, /*max_step*/ + degree_log, + lambda, + 2 /*expand_factor*/ ); using lpc_scheme_type = nil::crypto3::zk::commitments::lpc_commitment_scheme>; lpc_scheme_type lpc_scheme_prover(fri_params); - lpc_scheme_type lpc_scheme_verifier(fri_params); // Generate polynomials lpc_scheme_prover.append_to_batch(0, {1u, 13u, 4u, 1u, 5u, 6u, 7u, 2u, 8u, 7u, 5u, 6u, 1u, 2u, 1u, 1u}); @@ -513,22 +236,7 @@ BOOST_FIXTURE_TEST_CASE(batches_num_3_test, zk::test_tools::random_test_initiali auto proof = lpc_scheme_prover.proof_eval(transcript); test_lpc_proof(proof, fri_params); - - // Verify -/* zk::transcript::fiat_shamir_heuristic_sequential transcript_verifier(x_data); - - lpc_scheme_verifier.set_batch_size(0, proof.z.get_batch_size(0)); - lpc_scheme_verifier.set_batch_size(2, proof.z.get_batch_size(2)); - lpc_scheme_verifier.set_batch_size(3, proof.z.get_batch_size(3)); - - lpc_scheme_verifier.append_eval_point(0, point); - lpc_scheme_verifier.append_eval_point(2, point); - lpc_scheme_verifier.append_eval_point(3, point); - BOOST_CHECK(lpc_scheme_verifier.verify_eval(proof, commitments, transcript_verifier)); - - // Check transcript state - typename field_type::value_type verifier_next_challenge = transcript_verifier.template challenge(); - typename field_type::value_type prover_next_challenge = transcript.template challenge(); - BOOST_CHECK(verifier_next_challenge == prover_next_challenge);*/ + test_lpc_state_recovery(lpc_scheme_prover); } + BOOST_AUTO_TEST_SUITE_END() diff --git a/crypto3/libs/marshalling/zk/test/merkle_tree.cpp b/crypto3/libs/marshalling/zk/test/merkle_tree.cpp new file mode 100644 index 0000000000..8b66c67f47 --- /dev/null +++ b/crypto3/libs/marshalling/zk/test/merkle_tree.cpp @@ -0,0 +1,151 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2024 Martun Karapetyan +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#define BOOST_TEST_MODULE crypto3_marshalling_merkle_tree_test + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +template +typename std::enable_if::value, std::vector>>::type +generate_random_data(std::size_t leaf_number) { + std::vector> v; + for (std::size_t i = 0; i < leaf_number; ++i) { + std::array leaf; + std::generate(std::begin(leaf), std::end(leaf), + [&]() { return std::rand() % (std::numeric_limits::max() + 1); }); + v.emplace_back(leaf); + } + return v; +} + +template +void test_merkle_tree_marshalling(std::size_t tree_depth) { + + using namespace nil::crypto3::marshalling; + using merkle_tree_type = nil::crypto3::containers::merkle_tree; + using merkle_tree_marshalling_type = + types::merkle_tree, merkle_tree_type>; + + std::size_t leafs_number = std::pow(Arity, tree_depth); + // You can also lazy convert byte stream to field elements stream using + auto data = generate_random_data(leafs_number); + merkle_tree_type tree; + + if constexpr (nil::crypto3::algebra::is_field_element::value) { + // Populate the vector with wrappers, one for each block + std::vector< + nil::crypto3::hashes::block_to_field_elements_wrapper< + typename Hash::word_type::field_type, + std::array + > + > wrappers; + for (const auto& inner_containers : data) { + wrappers.emplace_back(inner_containers); + } + tree = nil::crypto3::containers::make_merkle_tree(wrappers.begin(), wrappers.end()); + } else { + tree = nil::crypto3::containers::make_merkle_tree(data.begin(), data.end()); + } + + auto filled_merkle_tree = types::fill_merkle_tree(tree); + merkle_tree_type _tree = types::make_merkle_tree(filled_merkle_tree); + BOOST_CHECK(tree == _tree); + + std::vector cv; + cv.resize(filled_merkle_tree.length(), 0x00); + auto write_iter = cv.begin(); + nil::marshalling::status_type status = filled_merkle_tree.write(write_iter, cv.size()); + BOOST_CHECK(status == nil::marshalling::status_type::success); + // print_merkle_tree(cv.cbegin(), cv.cend(), data[tree_idx].cbegin(), data[tree_idx].cend(), true); + + merkle_tree_marshalling_type test_val_read; + auto read_iter = cv.begin(); + status = test_val_read.read(read_iter, cv.size()); + BOOST_CHECK(status == nil::marshalling::status_type::success); + merkle_tree_type constructed_val_read = types::make_merkle_tree(test_val_read); + BOOST_CHECK(tree == constructed_val_read); +} + +BOOST_AUTO_TEST_SUITE(marshalling_merkle_tree_test_suite) + +using curve_type = nil::crypto3::algebra::curves::pallas; +using field_type = typename curve_type::base_field_type; + +using HashTypes = boost::mpl::list< + nil::crypto3::hashes::sha2<256>, + nil::crypto3::hashes::keccak_1600<512>, + nil::crypto3::hashes::poseidon> + >; + + +BOOST_AUTO_TEST_CASE_TEMPLATE(marshalling_merkle_tree_arity_2_test, HashType, HashTypes) { + std::srand(std::time(0)); + test_merkle_tree_marshalling(2); + test_merkle_tree_marshalling(4); + test_merkle_tree_marshalling(8); +} + +// Poseidon hash function supports only Arity 2. +using BlockHashTypes = boost::mpl::list< + nil::crypto3::hashes::sha2<256>, + nil::crypto3::hashes::keccak_1600<512> + >; + +BOOST_AUTO_TEST_CASE_TEMPLATE(marshalling_merkle_tree_arity_3_test, HashType, BlockHashTypes) { + test_merkle_tree_marshalling(2); + test_merkle_tree_marshalling(4); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(marshalling_merkle_tree_arity_4_test, HashType, BlockHashTypes) { + test_merkle_tree_marshalling(2); + test_merkle_tree_marshalling(4); +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(marshalling_merkle_tree_arity_5_test, HashType, BlockHashTypes) { + test_merkle_tree_marshalling(2); + test_merkle_tree_marshalling(4); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/crypto3/libs/marshalling/zk/test/placeholder_preprocessed_public_data.cpp b/crypto3/libs/marshalling/zk/test/placeholder_preprocessed_public_data.cpp new file mode 100644 index 0000000000..11ea97d8c8 --- /dev/null +++ b/crypto3/libs/marshalling/zk/test/placeholder_preprocessed_public_data.cpp @@ -0,0 +1,677 @@ +#define BOOST_TEST_MODULE crypto3_marshalling_placeholder_preprocessed_public_data_test + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include "./detail/circuits.hpp" +#include "random_test_data_generation.hpp" + + +using namespace nil::crypto3; +using namespace nil::crypto3::zk; +using namespace nil::crypto3::zk::snark; + + +template +void test_placeholder_public_preprocessed_data_marshalling( + PreprocessedPublicDataType preprocessed_data) { + using Endianness = nil::marshalling::option::big_endian; + using TTypeBase = nil::marshalling::field_type; + + auto filled_preprocessed_data = nil::crypto3::marshalling::types::fill_placeholder_preprocessed_public_data(preprocessed_data); +// auto _preprocessed_data = nil::crypto3::marshalling::types::make_placeholder_preprocessed_public_data(filled_preprocessed_data); +// BOOST_CHECK(preprocessed_data == _preprocessed_data); +// +// std::vector cv; +// cv.resize(filled_preprocessed_data.length(), 0x00); +// auto write_iter = cv.begin(); +// auto status = filled_preprocessed_data.write(write_iter, cv.size()); +// BOOST_CHECK(status == nil::marshalling::status_type::success); +// +// nil::crypto3::marshalling::types::placeholder_preprocessed_public_data test_val_read; +// auto read_iter = cv.begin(); +// test_val_read.read(read_iter, cv.size()); +// BOOST_CHECK(status == nil::marshalling::status_type::success); +// auto constructed_val_read = nil::crypto3::marshalling::types::make_placeholder_preprocessed_public_data( +// test_val_read +// ); +// BOOST_CHECK(preprocessed_data == constructed_val_read); +} + +BOOST_AUTO_TEST_SUITE(placeholder_circuit1_poseidon) + using Endianness = nil::marshalling::option::big_endian; + using TTypeBase = nil::marshalling::field_type; + + using curve_type = algebra::curves::pallas; + using field_type = typename curve_type::base_field_type; + using poseidon_type = hashes::poseidon>; + using merkle_hash_type = poseidon_type; + using transcript_hash_type = poseidon_type; + + struct placeholder_test_params { + constexpr static const std::size_t witness_columns = witness_columns_1; + constexpr static const std::size_t public_input_columns = public_columns_1; + constexpr static const std::size_t constant_columns = constant_columns_1; + constexpr static const std::size_t selector_columns = selector_columns_1; + + constexpr static const std::size_t lambda = 40; + constexpr static const std::size_t m = 2; + }; + typedef placeholder_circuit_params circuit_params; + using transcript_type = typename transcript::fiat_shamir_heuristic_sequential; + + using lpc_params_type = commitments::list_polynomial_commitment_params< + merkle_hash_type, + transcript_hash_type, + placeholder_test_params::m + >; + + using lpc_type = commitments::list_polynomial_commitment; + using lpc_scheme_type = typename commitments::lpc_commitment_scheme; + using lpc_placeholder_params_type = nil::crypto3::zk::snark::placeholder_params; + using policy_type = zk::snark::detail::placeholder_policy; + +BOOST_AUTO_TEST_CASE(prover_test) { + auto circuit = circuit_test_1(); + + plonk_table_description desc( + placeholder_test_params::witness_columns, + placeholder_test_params::public_input_columns, + placeholder_test_params::constant_columns, + placeholder_test_params::selector_columns + ); + + desc.rows_amount = circuit.table_rows; + desc.usable_rows_amount = circuit.usable_rows; + std::size_t table_rows_log = std::ceil(std::log2(circuit.table_rows)); + + typename policy_type::constraint_system_type constraint_system(circuit.gates, circuit.copy_constraints, circuit.lookup_gates); + typename policy_type::variable_assignment_type assignments = circuit.table; + + std::vector columns_with_copy_constraints = {0, 1, 2, 3}; + + + typename lpc_type::fri_type::params_type fri_params( + 1, table_rows_log, placeholder_test_params::lambda, 4, true + ); + lpc_scheme_type lpc_scheme(fri_params); + + typename placeholder_public_preprocessor::preprocessed_data_type + lpc_preprocessed_public_data = placeholder_public_preprocessor::process( + constraint_system, assignments.public_table(), desc, lpc_scheme, columns_with_copy_constraints.size() + ); + + using preprocessed_data_type = placeholder_public_preprocessor::preprocessed_data_type; + test_placeholder_public_preprocessed_data_marshalling(lpc_preprocessed_public_data); +} +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(placeholder_circuit1) + using Endianness = nil::marshalling::option::big_endian; + using TTypeBase = nil::marshalling::field_type; + + using curve_type = algebra::curves::pallas; + using field_type = typename curve_type::base_field_type; + using merkle_hash_type = hashes::keccak_1600<512>; + using transcript_hash_type = hashes::keccak_1600<512>; + + struct placeholder_test_params { + constexpr static const std::size_t witness_columns = witness_columns_1; + constexpr static const std::size_t public_input_columns = public_columns_1; + constexpr static const std::size_t constant_columns = constant_columns_1; + constexpr static const std::size_t selector_columns = selector_columns_1; + + constexpr static const std::size_t lambda = 40; + constexpr static const std::size_t m = 2; + }; + typedef placeholder_circuit_params circuit_params; + using transcript_type = typename transcript::fiat_shamir_heuristic_sequential; + + using lpc_params_type = commitments::list_polynomial_commitment_params< + merkle_hash_type, + transcript_hash_type, + placeholder_test_params::m + >; + + using lpc_type = commitments::list_polynomial_commitment; + using lpc_scheme_type = typename commitments::lpc_commitment_scheme; + using lpc_placeholder_params_type = nil::crypto3::zk::snark::placeholder_params; + using policy_type = zk::snark::detail::placeholder_policy; + +BOOST_AUTO_TEST_CASE(prover_test) { + auto circuit = circuit_test_1(); + + plonk_table_description desc( + placeholder_test_params::witness_columns, + placeholder_test_params::public_input_columns, + placeholder_test_params::constant_columns, + placeholder_test_params::selector_columns + ); + + desc.rows_amount = circuit.table_rows; + desc.usable_rows_amount = circuit.usable_rows; + std::size_t table_rows_log = std::ceil(std::log2(circuit.table_rows)); + + typename policy_type::constraint_system_type constraint_system(circuit.gates, circuit.copy_constraints, circuit.lookup_gates); + typename policy_type::variable_assignment_type assignments = circuit.table; + + std::vector columns_with_copy_constraints = {0, 1, 2, 3}; + + typename lpc_type::fri_type::params_type fri_params( + 1, table_rows_log, placeholder_test_params::lambda, 4, true + ); + lpc_scheme_type lpc_scheme(fri_params); + + typename placeholder_public_preprocessor::preprocessed_data_type + lpc_preprocessed_public_data = placeholder_public_preprocessor::process( + constraint_system, assignments.public_table(), desc, lpc_scheme, columns_with_copy_constraints.size() + ); + + using preprocessed_data_type = placeholder_public_preprocessor::preprocessed_data_type; + test_placeholder_public_preprocessed_data_marshalling(lpc_preprocessed_public_data); +} + +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(placeholder_circuit2) + using Endianness = nil::marshalling::option::big_endian; + using TTypeBase = nil::marshalling::field_type; + + using curve_type = algebra::curves::bls12<381>; + using field_type = typename curve_type::scalar_field_type; + + struct placeholder_test_params { + using merkle_hash_type = hashes::keccak_1600<512>; + using transcript_hash_type = hashes::keccak_1600<512>; + + constexpr static const std::size_t witness_columns = 3; + constexpr static const std::size_t public_input_columns = 1; + constexpr static const std::size_t constant_columns = 0; + constexpr static const std::size_t selector_columns = 2; + + constexpr static const std::size_t lambda = 1; + constexpr static const std::size_t m = 2; + }; + using circuit_t_params = placeholder_circuit_params; + + using transcript_type = typename transcript::fiat_shamir_heuristic_sequential; + + using lpc_params_type = commitments::list_polynomial_commitment_params< + typename placeholder_test_params::merkle_hash_type, + typename placeholder_test_params::transcript_hash_type, + placeholder_test_params::m + >; + + using lpc_type = commitments::list_polynomial_commitment; + using lpc_scheme_type = typename commitments::lpc_commitment_scheme; + using lpc_placeholder_params_type = nil::crypto3::zk::snark::placeholder_params; + + using policy_type = zk::snark::detail::placeholder_policy; + +BOOST_FIXTURE_TEST_CASE(preprocessed_data_marshalling_test, test_tools::random_test_initializer) { + auto pi0 = nil::crypto3::algebra::random_element(); + auto circuit = circuit_test_t( + pi0, + alg_random_engines.template get_alg_engine(), + generic_random_engine + ); + + plonk_table_description desc( + placeholder_test_params::witness_columns, + placeholder_test_params::public_input_columns, + placeholder_test_params::constant_columns, + placeholder_test_params::selector_columns + ); + desc.rows_amount = circuit.table_rows; + desc.usable_rows_amount = circuit.usable_rows; + std::size_t table_rows_log = std::ceil(std::log2(circuit.table_rows)); + + typename policy_type::constraint_system_type constraint_system(circuit.gates, circuit.copy_constraints, circuit.lookup_gates); + typename policy_type::variable_assignment_type assignments = circuit.table; + + std::vector columns_with_copy_constraints = {0, 1, 2, 3}; + + // LPC commitment scheme + typename lpc_type::fri_type::params_type fri_params( + 1, table_rows_log, placeholder_test_params::lambda, 4 + ); + lpc_scheme_type lpc_scheme(fri_params); + + typename placeholder_public_preprocessor::preprocessed_data_type + lpc_preprocessed_public_data = placeholder_public_preprocessor::process( + constraint_system, assignments.public_table(), desc, lpc_scheme, columns_with_copy_constraints.size() + ); + + using preprocessed_data_type = placeholder_public_preprocessor::preprocessed_data_type; + test_placeholder_public_preprocessed_data_marshalling(lpc_preprocessed_public_data); +} + +BOOST_AUTO_TEST_SUITE_END() + + +BOOST_AUTO_TEST_SUITE(placeholder_circuit3) + using Endianness = nil::marshalling::option::big_endian; + using TTypeBase = nil::marshalling::field_type; + using curve_type = algebra::curves::pallas; + using field_type = typename curve_type::base_field_type; + + struct placeholder_test_params { + using merkle_hash_type = hashes::keccak_1600<512>; + using transcript_hash_type = hashes::keccak_1600<512>; + + constexpr static const std::size_t witness_columns = witness_columns_3; + constexpr static const std::size_t public_input_columns = public_columns_3; + constexpr static const std::size_t constant_columns = constant_columns_3; + constexpr static const std::size_t selector_columns = selector_columns_3; + + constexpr static const std::size_t lambda = 40; + constexpr static const std::size_t m = 2; + }; + + using circuit_params = placeholder_circuit_params; + using transcript_type = typename transcript::fiat_shamir_heuristic_sequential; + using lpc_params_type = commitments::list_polynomial_commitment_params< + typename placeholder_test_params::merkle_hash_type, + typename placeholder_test_params::transcript_hash_type, + placeholder_test_params::m + >; + + using lpc_type = commitments::list_polynomial_commitment; + using lpc_scheme_type = typename commitments::lpc_commitment_scheme; + using lpc_placeholder_params_type = nil::crypto3::zk::snark::placeholder_params; + using policy_type = zk::snark::detail::placeholder_policy; + +BOOST_FIXTURE_TEST_CASE(proof_marshalling_test, test_tools::random_test_initializer) { + auto circuit = circuit_test_3( + alg_random_engines.template get_alg_engine(), + generic_random_engine + ); + + plonk_table_description desc( + placeholder_test_params::witness_columns, + placeholder_test_params::public_input_columns, + placeholder_test_params::constant_columns, + placeholder_test_params::selector_columns + ); + + desc.rows_amount = circuit.table_rows; + desc.usable_rows_amount = circuit.usable_rows; + std::size_t table_rows_log = std::ceil(std::log2(circuit.table_rows)); + + typename policy_type::constraint_system_type constraint_system( + circuit.gates, + circuit.copy_constraints, + circuit.lookup_gates, + circuit.lookup_tables + ); + typename policy_type::variable_assignment_type assignments = circuit.table; + + typename lpc_type::fri_type::params_type fri_params( + 1, table_rows_log, placeholder_test_params::lambda, 4 + ); + lpc_scheme_type lpc_scheme(fri_params); + + std::vector columns_with_copy_constraints = {0, 1, 2, 3}; + + typename placeholder_public_preprocessor::preprocessed_data_type + preprocessed_public_data = placeholder_public_preprocessor::process( + constraint_system, assignments.public_table(), desc, lpc_scheme, columns_with_copy_constraints.size()); + + using preprocessed_data_type = placeholder_public_preprocessor::preprocessed_data_type; + test_placeholder_public_preprocessed_data_marshalling(preprocessed_public_data); +} + +BOOST_AUTO_TEST_SUITE_END() + + +BOOST_AUTO_TEST_SUITE(placeholder_circuit4) + using Endianness = nil::marshalling::option::big_endian; + using TTypeBase = nil::marshalling::field_type; + using curve_type = algebra::curves::pallas; + using field_type = typename curve_type::base_field_type; + + struct placeholder_test_params { + using merkle_hash_type = hashes::keccak_1600<512>; + using transcript_hash_type = hashes::keccak_1600<512>; + + constexpr static const std::size_t witness_columns = witness_columns_4; + constexpr static const std::size_t public_input_columns = public_columns_4; + constexpr static const std::size_t constant_columns = constant_columns_4; + constexpr static const std::size_t selector_columns = selector_columns_4; + + constexpr static const std::size_t lambda = 40; + constexpr static const std::size_t m = 2; + }; + + using circuit_params = placeholder_circuit_params; + using transcript_type = typename transcript::fiat_shamir_heuristic_sequential; + using lpc_params_type = commitments::list_polynomial_commitment_params< + typename placeholder_test_params::merkle_hash_type, + typename placeholder_test_params::transcript_hash_type, + placeholder_test_params::m + >; + + using lpc_type = commitments::list_polynomial_commitment; + using lpc_scheme_type = typename commitments::lpc_commitment_scheme; + using lpc_placeholder_params_type = nil::crypto3::zk::snark::placeholder_params; + using policy_type = zk::snark::detail::placeholder_policy; + +BOOST_FIXTURE_TEST_CASE(proof_marshalling_test, test_tools::random_test_initializer) { + auto circuit = circuit_test_4( + alg_random_engines.template get_alg_engine(), + generic_random_engine + ); + + plonk_table_description desc( + placeholder_test_params::witness_columns, + placeholder_test_params::public_input_columns, + placeholder_test_params::constant_columns, + placeholder_test_params::selector_columns + ); + + desc.rows_amount = circuit.table_rows; + desc.usable_rows_amount = circuit.usable_rows; + std::size_t table_rows_log = std::ceil(std::log2(circuit.table_rows)); + + typename policy_type::constraint_system_type constraint_system( + circuit.gates, + circuit.copy_constraints, + circuit.lookup_gates, + circuit.lookup_tables + ); + typename policy_type::variable_assignment_type assignments = circuit.table; + + typename lpc_type::fri_type::params_type fri_params( + 1, table_rows_log, placeholder_test_params::lambda, 4, true + ); + lpc_scheme_type lpc_scheme(fri_params); + + std::vector columns_with_copy_constraints = {0, 1, 2, 3}; + + typename placeholder_public_preprocessor::preprocessed_data_type + preprocessed_public_data = placeholder_public_preprocessor::process( + constraint_system, assignments.public_table(), desc, lpc_scheme, columns_with_copy_constraints.size()); + + using preprocessed_data_type = placeholder_public_preprocessor::preprocessed_data_type; + test_placeholder_public_preprocessed_data_marshalling(preprocessed_public_data); +} + +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(placeholder_circuit5) + using Endianness = nil::marshalling::option::big_endian; + using TTypeBase = nil::marshalling::field_type; + + using curve_type = algebra::curves::bls12<381>; + using field_type = typename curve_type::scalar_field_type; + + struct placeholder_test_params { + using merkle_hash_type = hashes::keccak_1600<512>; + using transcript_hash_type = hashes::keccak_1600<512>; + + constexpr static const std::size_t witness_columns = witness_columns_5; + constexpr static const std::size_t public_input_columns = public_columns_5; + constexpr static const std::size_t constant_columns = constant_columns_5; + constexpr static const std::size_t selector_columns = selector_columns_5; + + constexpr static const std::size_t lambda = 1; + constexpr static const std::size_t m = 2; + }; + using circuit_t_params = placeholder_circuit_params; + + using transcript_type = typename transcript::fiat_shamir_heuristic_sequential; + + using lpc_params_type = commitments::list_polynomial_commitment_params< + typename placeholder_test_params::merkle_hash_type, + typename placeholder_test_params::transcript_hash_type, + placeholder_test_params::m + >; + + using lpc_type = commitments::list_polynomial_commitment; + using lpc_scheme_type = typename commitments::lpc_commitment_scheme; + using lpc_placeholder_params_type = nil::crypto3::zk::snark::placeholder_params; + + using policy_type = zk::snark::detail::placeholder_policy; + +BOOST_FIXTURE_TEST_CASE(preprocessed_data_marshalling_test, test_tools::random_test_initializer) { + auto pi0 = nil::crypto3::algebra::random_element(); + auto circuit = circuit_test_t( + pi0, + alg_random_engines.template get_alg_engine(), + generic_random_engine + ); + + plonk_table_description desc( + placeholder_test_params::witness_columns, + placeholder_test_params::public_input_columns, + placeholder_test_params::constant_columns, + placeholder_test_params::selector_columns + ); + desc.rows_amount = circuit.table_rows; + desc.usable_rows_amount = circuit.usable_rows; + std::size_t table_rows_log = std::ceil(std::log2(circuit.table_rows)); + + typename policy_type::constraint_system_type constraint_system(circuit.gates, circuit.copy_constraints, circuit.lookup_gates); + typename policy_type::variable_assignment_type assignments = circuit.table; + + bool verifier_res; + + // LPC commitment scheme + typename lpc_type::fri_type::params_type fri_params( + 1, table_rows_log, placeholder_test_params::lambda, 4 + ); + lpc_scheme_type lpc_scheme(fri_params); + + using preprocessed_data_type = placeholder_public_preprocessor::preprocessed_data_type; + preprocessed_data_type lpc_preprocessed_public_data = placeholder_public_preprocessor::process( + constraint_system, assignments.public_table(), desc, lpc_scheme, 10 + ); + + test_placeholder_public_preprocessed_data_marshalling(lpc_preprocessed_public_data); +} + +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(placeholder_circuit6) + using Endianness = nil::marshalling::option::big_endian; + using TTypeBase = nil::marshalling::field_type; + using curve_type = algebra::curves::pallas; + using field_type = typename curve_type::base_field_type; + + struct placeholder_test_params { + using merkle_hash_type = hashes::keccak_1600<512>; + using transcript_hash_type = hashes::keccak_1600<512>; + + constexpr static const std::size_t witness_columns = witness_columns_6; + constexpr static const std::size_t public_input_columns = public_columns_6; + constexpr static const std::size_t constant_columns = constant_columns_6; + constexpr static const std::size_t selector_columns = selector_columns_6; + + constexpr static const std::size_t lambda = 40; + constexpr static const std::size_t m = 2; + }; + + using circuit_params = placeholder_circuit_params; + using transcript_type = typename transcript::fiat_shamir_heuristic_sequential; + using lpc_params_type = commitments::list_polynomial_commitment_params< + typename placeholder_test_params::merkle_hash_type, + typename placeholder_test_params::transcript_hash_type, + placeholder_test_params::m + >; + + using lpc_type = commitments::list_polynomial_commitment; + using lpc_scheme_type = typename commitments::lpc_commitment_scheme; + using lpc_placeholder_params_type = nil::crypto3::zk::snark::placeholder_params; + using policy_type = zk::snark::detail::placeholder_policy; + +BOOST_FIXTURE_TEST_CASE(proof_marshalling_test, test_tools::random_test_initializer) { + auto circuit = circuit_test_6( + alg_random_engines.template get_alg_engine(), + generic_random_engine + ); + + plonk_table_description desc( + placeholder_test_params::witness_columns, + placeholder_test_params::public_input_columns, + placeholder_test_params::constant_columns, + placeholder_test_params::selector_columns + ); + + desc.rows_amount = circuit.table_rows; + desc.usable_rows_amount = circuit.usable_rows; + std::size_t table_rows_log = std::ceil(std::log2(circuit.table_rows)); + + typename policy_type::constraint_system_type constraint_system( + circuit.gates, + circuit.copy_constraints, + circuit.lookup_gates, + circuit.lookup_tables + ); + typename policy_type::variable_assignment_type assignments = circuit.table; + + typename lpc_type::fri_type::params_type fri_params( + 1, table_rows_log, placeholder_test_params::lambda, 4, true + ); + lpc_scheme_type lpc_scheme(fri_params); + + std::vector columns_with_copy_constraints = {0, 1, 2, 3}; + + typename placeholder_public_preprocessor::preprocessed_data_type + preprocessed_public_data = placeholder_public_preprocessor::process( + constraint_system, assignments.public_table(), desc, lpc_scheme, columns_with_copy_constraints.size()); + + using preprocessed_data_type = placeholder_public_preprocessor::preprocessed_data_type; + test_placeholder_public_preprocessed_data_marshalling(preprocessed_public_data); +} + +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(placeholder_circuit7) + using Endianness = nil::marshalling::option::big_endian; + using TTypeBase = nil::marshalling::field_type; + using curve_type = algebra::curves::pallas; + using field_type = typename curve_type::base_field_type; + + struct placeholder_test_params { + using merkle_hash_type = hashes::keccak_1600<512>; + using transcript_hash_type = hashes::keccak_1600<512>; + + constexpr static const std::size_t witness_columns = witness_columns_7; + constexpr static const std::size_t public_input_columns = public_columns_7; + constexpr static const std::size_t constant_columns = constant_columns_7; + constexpr static const std::size_t selector_columns = selector_columns_7; + + constexpr static const std::size_t lambda = 40; + constexpr static const std::size_t m = 2; + }; + + using circuit_params = placeholder_circuit_params; + using transcript_type = typename transcript::fiat_shamir_heuristic_sequential; + using lpc_params_type = commitments::list_polynomial_commitment_params< + typename placeholder_test_params::merkle_hash_type, + typename placeholder_test_params::transcript_hash_type, + placeholder_test_params::m + >; + + using lpc_type = commitments::list_polynomial_commitment; + using lpc_scheme_type = typename commitments::lpc_commitment_scheme; + using lpc_placeholder_params_type = nil::crypto3::zk::snark::placeholder_params; + using policy_type = zk::snark::detail::placeholder_policy; + +BOOST_FIXTURE_TEST_CASE(proof_marshalling_test, test_tools::random_test_initializer) { + auto circuit = circuit_test_7( + alg_random_engines.template get_alg_engine(), + generic_random_engine + ); + plonk_table_description desc( + placeholder_test_params::witness_columns, + placeholder_test_params::public_input_columns, + placeholder_test_params::constant_columns, + placeholder_test_params::selector_columns + ); + + desc.rows_amount = circuit.table_rows; + desc.usable_rows_amount = circuit.usable_rows; + std::size_t table_rows_log = std::ceil(std::log2(circuit.table_rows)); + + typename policy_type::constraint_system_type constraint_system( + circuit.gates, + circuit.copy_constraints, + circuit.lookup_gates, + circuit.lookup_tables + ); + typename policy_type::variable_assignment_type assignments = circuit.table; + + typename lpc_type::fri_type::params_type fri_params( + 1, table_rows_log, placeholder_test_params::lambda, 4, true + ); + lpc_scheme_type lpc_scheme(fri_params); + + std::vector columns_with_copy_constraints = {0, 1, 2, 3}; + + typename placeholder_public_preprocessor::preprocessed_data_type + preprocessed_public_data = placeholder_public_preprocessor::process( + constraint_system, assignments.public_table(), desc, lpc_scheme, columns_with_copy_constraints.size()); + + using preprocessed_data_type = placeholder_public_preprocessor::preprocessed_data_type; + test_placeholder_public_preprocessed_data_marshalling(preprocessed_public_data); +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/crypto3/libs/marshalling/zk/test/placeholder_proof.cpp b/crypto3/libs/marshalling/zk/test/placeholder_proof.cpp index 19bd0d9394..1613efd676 100644 --- a/crypto3/libs/marshalling/zk/test/placeholder_proof.cpp +++ b/crypto3/libs/marshalling/zk/test/placeholder_proof.cpp @@ -323,7 +323,12 @@ BOOST_FIXTURE_TEST_CASE(proof_marshalling_test, test_tools::random_test_initiali typename policy_type::variable_assignment_type assignments = circuit.table; typename lpc_type::fri_type::params_type fri_params( - 1, table_rows_log, placeholder_test_params::lambda, 4, true, 0xFFFF8000 + 1, /*max_step*/ + table_rows_log, + placeholder_test_params::lambda, + 4, // expand_factor + true, // use_grinding + 19 // grinding_parameter ); lpc_scheme_type lpc_scheme(fri_params); diff --git a/crypto3/libs/marshalling/zk/test/plonk_assignment_table.cpp b/crypto3/libs/marshalling/zk/test/plonk_assignment_table.cpp index 2d5b58ebc2..353d779b8f 100644 --- a/crypto3/libs/marshalling/zk/test/plonk_assignment_table.cpp +++ b/crypto3/libs/marshalling/zk/test/plonk_assignment_table.cpp @@ -60,6 +60,30 @@ void print_hex_byteblob(std::ostream &os, TIter iter_begin, TIter iter_end, bool } } +template +void test_assignment_table_description(const PlonkTableDescription& val) { + using TTypeBase = nil::marshalling::field_type; + using FieldType = typename PlonkTableDescription::field_type; + using value_marshalling_type = nil::crypto3::marshalling::types::plonk_assignment_table_description; + + auto filled_val = types::fill_assignment_table_description(val); + auto table_desc = types::make_assignment_table_description(filled_val); + BOOST_CHECK(val == table_desc); + + std::vector cv; + cv.resize(filled_val.length(), 0x00); + + auto write_iter = cv.begin(); + nil::marshalling::status_type status = filled_val.write(write_iter, cv.size()); + value_marshalling_type test_val_read; + auto read_iter = cv.begin(); + status = test_val_read.read(read_iter, cv.size()); + BOOST_CHECK(status == nil::marshalling::status_type::success); + table_desc = types::make_assignment_table_description(test_val_read); + + BOOST_CHECK(val == table_desc); +} + template void test_assignment_table(std::size_t usable_rows, PlonkTable val, std::string folder_name = "") { using TTypeBase = nil::marshalling::field_type; @@ -148,7 +172,10 @@ BOOST_FIXTURE_TEST_CASE(assignment_table_marshalling_test, test_tools::random_te test_assignment_table(desc.usable_rows_amount, assignments, "circuit1"); else test_assignment_table(desc.usable_rows_amount, assignments); + + test_assignment_table_description>(desc); } + BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE(placeholder_circuit2) @@ -209,6 +236,8 @@ BOOST_FIXTURE_TEST_CASE(assignment_table_marshalling_test, test_tools::random_te test_assignment_table(desc.usable_rows_amount, assignments, "circuit2"); else test_assignment_table(desc.usable_rows_amount, assignments); + + test_assignment_table_description>(desc); } BOOST_AUTO_TEST_SUITE_END() @@ -266,6 +295,8 @@ BOOST_FIXTURE_TEST_CASE(assignment_table_marshalling_test, test_tools::random_te test_assignment_table(desc.usable_rows_amount, assignments, "circuit3"); else test_assignment_table(desc.usable_rows_amount, assignments); + + test_assignment_table_description>(desc); } BOOST_AUTO_TEST_SUITE_END() @@ -325,6 +356,8 @@ BOOST_FIXTURE_TEST_CASE(assignment_table_marshalling_test, test_tools::random_te test_assignment_table(desc.usable_rows_amount, assignments, "circuit4"); else test_assignment_table(desc.usable_rows_amount, assignments); + + test_assignment_table_description>(desc); } BOOST_AUTO_TEST_SUITE_END() @@ -386,6 +419,8 @@ BOOST_FIXTURE_TEST_CASE(assignment_table_marshalling_test, test_tools::random_te test_assignment_table(desc.usable_rows_amount, assignments, "circuit5"); else test_assignment_table(desc.usable_rows_amount, assignments); + + test_assignment_table_description>(desc); } BOOST_AUTO_TEST_SUITE_END() @@ -442,6 +477,8 @@ BOOST_FIXTURE_TEST_CASE(assignment_table_marshalling_test, test_tools::random_te test_assignment_table(desc.usable_rows_amount, assignments, "circuit6"); else test_assignment_table(desc.usable_rows_amount, assignments); + + test_assignment_table_description>(desc); } BOOST_AUTO_TEST_SUITE_END() @@ -498,5 +535,7 @@ BOOST_FIXTURE_TEST_CASE(assignment_table_marshalling_test, test_tools::random_te test_assignment_table(desc.usable_rows_amount, assignments, "circuit7"); else test_assignment_table(desc.usable_rows_amount, assignments); + + test_assignment_table_description>(desc); } BOOST_AUTO_TEST_SUITE_END() diff --git a/crypto3/libs/marshalling/zk/test/polys_evaluator.cpp b/crypto3/libs/marshalling/zk/test/polys_evaluator.cpp new file mode 100644 index 0000000000..52d61f795e --- /dev/null +++ b/crypto3/libs/marshalling/zk/test/polys_evaluator.cpp @@ -0,0 +1,182 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2024 Martun Karapetyan +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#define BOOST_TEST_MODULE crypto3_marshalling_polys_evaluator_test + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include // contains class polys_evaluator +#include "random_test_data_generation.hpp" + +using namespace nil::crypto3; + +// ******************************************************************************* +// * Test marshalling function +// ******************************************************************************* / + +template +void test_polys_evaluator_marshalling(PolysEvaluator &evaluator) { + using TTypeBase = nil::marshalling::field_type; + + auto filled_evaluator = nil::crypto3::marshalling::types::fill_polys_evaluator(evaluator); + auto _evaluator = nil::crypto3::marshalling::types::make_polys_evaluator(filled_evaluator); + BOOST_CHECK(evaluator == _evaluator); + + std::vector cv; + cv.resize(filled_evaluator.length(), 0x00); + auto write_iter = cv.begin(); + auto status = filled_evaluator.write(write_iter, cv.size()); + BOOST_CHECK(status == nil::marshalling::status_type::success); + + nil::crypto3::marshalling::types::polys_evaluator test_val_read; + auto read_iter = cv.begin(); + test_val_read.read(read_iter, cv.size()); + BOOST_CHECK(status == nil::marshalling::status_type::success); + + PolysEvaluator constructed_val_read = + nil::crypto3::marshalling::types::make_polys_evaluator(test_val_read); + BOOST_CHECK(evaluator == constructed_val_read); +} + +BOOST_AUTO_TEST_SUITE(marshalling_real) + // Setup common types. + using Endianness = nil::marshalling::option::big_endian; + using curve_type = nil::crypto3::algebra::curves::vesta; + using field_type = curve_type::scalar_field_type; + using merkle_hash_type = nil::crypto3::hashes::keccak_1600<256>; + using transcript_hash_type = nil::crypto3::hashes::keccak_1600<256>; + using merkle_tree_type = typename containers::merkle_tree; + +BOOST_FIXTURE_TEST_CASE(batches_num_3_test, zk::test_tools::random_test_initializer){ + // Setup types. + constexpr static const std::size_t lambda = 40; + constexpr static const std::size_t k = 1; + + constexpr static const std::size_t d = 16; + + constexpr static const std::size_t r = boost::static_log2<(d - k)>::value; + constexpr static const std::size_t m = 2; + + typedef zk::commitments::fri fri_type; + + typedef zk::commitments:: + list_polynomial_commitment_params + lpc_params_type; + typedef zk::commitments::list_polynomial_commitment lpc_type; + + static_assert(zk::is_commitment::value); + static_assert(zk::is_commitment::value); + static_assert(!zk::is_commitment::value); + static_assert(!zk::is_commitment::value); + static_assert(!zk::is_commitment::value); + + std::size_t degree_log = boost::static_log2::value; + + // Setup params + typename fri_type::params_type fri_params( + 1, /*max_step*/ + degree_log, + lambda, + 2 /*expand_factor*/ + ); + + using lpc_scheme_type = nil::crypto3::zk::commitments::lpc_commitment_scheme< + lpc_type, math::polynomial>; + using polys_evaluator_type = typename lpc_scheme_type::polys_evaluator_type; + + lpc_scheme_type lpc_scheme_prover(fri_params); + + // Generate polynomials + lpc_scheme_prover.append_to_batch(0, {1u, 13u, 4u, 1u, 5u, 6u, 7u, 2u, 8u, 7u, 5u, 6u, 1u, 2u, 1u, 1u}); + lpc_scheme_prover.append_to_batch(2, {0u, 1u}); + lpc_scheme_prover.append_to_batch(2, {0u, 1u, 2u}); + lpc_scheme_prover.append_to_batch(2, {0u, 1u, 3u}); + lpc_scheme_prover.append_to_batch(3, {0u}); + + // Commit + std::map commitments; + commitments[0] = lpc_scheme_prover.commit(0); + commitments[2] = lpc_scheme_prover.commit(2); + commitments[3] = lpc_scheme_prover.commit(3); + + auto filled_commitment = nil::crypto3::marshalling::types::fill_commitment(commitments[0]); + auto _commitment = nil::crypto3::marshalling::types::make_commitment(filled_commitment); + + // Generate evaluation points. Generate points outside of the basic domain + // Generate evaluation points. Choose poin1ts outside the domain + auto point = algebra::fields::arithmetic_params::multiplicative_generator; + lpc_scheme_prover.append_eval_point(0, point); + lpc_scheme_prover.append_eval_point(2, point); + lpc_scheme_prover.append_eval_point(3, point); + + std::array x_data {}; + + polys_evaluator_type evaluator = static_cast(lpc_scheme_prover); + test_polys_evaluator_marshalling(evaluator); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/crypto3/libs/marshalling/zk/test/random_test_data_generation.hpp b/crypto3/libs/marshalling/zk/test/random_test_data_generation.hpp new file mode 100644 index 0000000000..ac21739f24 --- /dev/null +++ b/crypto3/libs/marshalling/zk/test/random_test_data_generation.hpp @@ -0,0 +1,330 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2024 Martun Karapetyan +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +using namespace nil::crypto3; + +//******************************************************************************* +//* Fill data structures with random data +//******************************************************************************* +template +typename std::enable_if::value, std::vector>>::type +generate_random_data(std::size_t leaf_number, boost::random::mt11213b &rnd) { + std::vector> v; + for (std::size_t i = 0; i < leaf_number; ++i) { + std::array leaf; + std::generate(std::begin(leaf), std::end(leaf), + [&]() { return rnd() % (std::numeric_limits::max() + 1); }); + v.emplace_back(leaf); + } + return v; +} + +std::vector> +generate_random_data_for_merkle_tree(size_t leafs_number, size_t leaf_bytes, boost::random::mt11213b &rnd) { + std::vector> rdata(leafs_number, std::vector(leaf_bytes)); + + for (std::size_t i = 0; i < leafs_number; ++i) { + std::vector leaf(leaf_bytes); + for (size_t i = 0; i < leaf_bytes; i++) { + leaf[i] = rnd() % (std::numeric_limits::max() + 1); + } + rdata.emplace_back(leaf); + } + return rdata; +} + +template +typename FRI::merkle_proof_type generate_random_merkle_proof(std::size_t tree_depth, boost::random::mt11213b &rnd) { + std::size_t leafs_number = 1 << tree_depth; + std::size_t leaf_size = 32; + + auto rdata1 = generate_random_data_for_merkle_tree(leafs_number, leaf_size, rnd); + auto tree1 = containers::make_merkle_tree(rdata1.begin(), + rdata1.end()); + std::size_t idx1 = rnd() % leafs_number; + typename FRI::merkle_proof_type mp1(tree1, idx1); + return mp1; +} + +inline std::vector +generate_random_step_list(const std::size_t r, const std::size_t max_step, boost::random::mt11213b &rnd) { + using dist_type = std::uniform_int_distribution; + + std::vector step_list; + std::size_t steps_sum = 0; + while (steps_sum != r) { + if (r - steps_sum <= max_step) { + while (r - steps_sum != 1) { + step_list.emplace_back(r - steps_sum - 1); + steps_sum += step_list.back(); + } + step_list.emplace_back(1); + steps_sum += step_list.back(); + } else { + step_list.emplace_back(dist_type(1, max_step)(rnd)); + steps_sum += step_list.back(); + } + } + + return step_list; +} + +template +typename FRI::polynomial_values_type generate_random_polynomial_values( + size_t step, + nil::crypto3::random::algebraic_engine &alg_rnd +) { + typename FRI::polynomial_values_type values; + + std::size_t coset_size = 1 << (step - 1); + values.resize(coset_size); + for (size_t i = 0; i < coset_size; i++) { + for (size_t j = 0; j < FRI::m; j++) { + values[i][j] = alg_rnd(); + values[i][j] = alg_rnd(); + } + } + return values; +} + +template +math::polynomial generate_random_polynomial( + size_t degree, + nil::crypto3::random::algebraic_engine &d +) { + math::polynomial poly; + poly.resize(degree); + + for (std::size_t i = 0; i < degree; ++i) { + poly[i] = d(); + } + return poly; +} + +template +typename FRI::round_proof_type generate_random_fri_round_proof( + std::size_t r_i, + nil::crypto3::random::algebraic_engine &alg_rnd, + boost::random::mt11213b &rnd +) { + typename FRI::round_proof_type res; + res.p = generate_random_merkle_proof(3, rnd); + res.y = generate_random_polynomial_values(r_i, alg_rnd); + + return res; +} + +template +typename FRI::initial_proof_type generate_random_fri_initial_proof( + std::size_t polynomial_number, + std::size_t r0, + nil::crypto3::random::algebraic_engine &alg_rnd, + boost::random::mt11213b &rnd +) { + typename FRI::initial_proof_type res; + + std::size_t coset_size = 1 << r0; + res.p = generate_random_merkle_proof(3, rnd); + res.values.resize(polynomial_number); + for (std::size_t i = 0; i < polynomial_number; i++) { + res.values[i].resize(coset_size / FRI::m); + for (std::size_t j = 0; j < coset_size / FRI::m; j++) { + res.values[i][j][0] = alg_rnd(); + res.values[i][j][1] = alg_rnd(); + } + } + + return res; +} + +template +typename FRI::query_proof_type generate_random_fri_query_proof( + std::size_t max_batch_size, + std::vector step_list, + nil::crypto3::marshalling::types::batch_info_type batch_info, + nil::crypto3::random::algebraic_engine &alg_rnd, + boost::random::mt11213b &rnd +) { + typename FRI::query_proof_type res; + + for (const auto &it : batch_info) { + res.initial_proof[it.first] = generate_random_fri_initial_proof(it.second, step_list[0], alg_rnd, rnd); + } + res.round_proofs.resize(step_list.size()); + for (std::size_t i = 1; i < step_list.size(); i++) { + res.round_proofs[i-1] = generate_random_fri_round_proof( + step_list[i], alg_rnd, rnd + ); + } + res.round_proofs[step_list.size()-1] = generate_random_fri_round_proof( + 1, alg_rnd, rnd + ); + return res; +} + +template +typename FRI::proof_type generate_random_fri_proof( + std::size_t d, //final polynomial degree + std::size_t max_batch_size, + std::vector step_list, + std::size_t lambda, + bool use_grinding, + nil::crypto3::marshalling::types::batch_info_type batch_info, + nil::crypto3::random::algebraic_engine &alg_rnd, + boost::random::mt11213b &rnd +) { + typename FRI::proof_type res; + res.query_proofs.resize(lambda); + for (std::size_t k = 0; k < lambda; k++) { + res.query_proofs[k] = generate_random_fri_query_proof(max_batch_size, step_list, batch_info, alg_rnd, rnd); + } + res.fri_roots.resize(step_list.size()); + for (std::size_t k = 0; k < step_list.size(); k++) { + res.fri_roots[k] = nil::crypto3::hash( + generate_random_data(1, rnd).at(0) + ); + } + if (use_grinding){ + res.proof_of_work = rnd(); + } + res.final_polynomial = generate_random_polynomial(d, alg_rnd); + return res; +} + + +template +typename LPC::proof_type generate_random_lpc_proof( + std::size_t d, //final polynomial degree + std::size_t max_batch_size, + std::vector step_list, + std::size_t lambda, + std::size_t use_grinding, + nil::crypto3::random::algebraic_engine &alg_rnd, + boost::random::mt11213b &rnd +) { + typename LPC::proof_type res; + + nil::crypto3::marshalling::types::batch_info_type batch_info; + for( std::size_t i = 0; i < 6; i++ ){ + batch_info[rnd()%6] = rnd()%9 + 1; + } + for( const auto&it: batch_info){ + res.z.set_batch_size(it.first, it.second); + for( std::size_t i = 0; i < it.second; i++){ + res.z.set_poly_points_number(it.first, i, rnd()%3 + 1); + for( std::size_t j = 0; j < res.z.get_poly_points_number(it.first, i); j++){ + res.z.set(it.first, i, j, alg_rnd()); + } + } + } + res.fri_proof = generate_random_fri_proof(d, max_batch_size, step_list, lambda, use_grinding, batch_info, alg_rnd, rnd); + return res; +} + + +template +math::polynomial_dfs +generate_random_polynomial_dfs(std::size_t degree, nil::crypto3::random::algebraic_engine &rnd) { + math::polynomial data = generate_random_polynomial(degree, rnd); + math::polynomial_dfs result; + result.from_coefficients(data); + return result; +} + +template +std::vector> generate_random_polynomial_batch( + std::size_t batch_size, + std::size_t degree, + nil::crypto3::random::algebraic_engine &rnd +) { + std::vector> result; + + for (std::size_t i = 0; i < batch_size; i++) { + result.push_back(generate_random_polynomial(degree, rnd)); + } + return result; +} + +template +std::vector> +generate_random_polynomial_dfs_batch(std::size_t batch_size, + std::size_t degree, + nil::crypto3::random::algebraic_engine &rnd) { + auto data = generate_random_polynomial_batch(batch_size, degree, rnd); + std::vector> result; + + for (std::size_t i = 0; i < data.size(); i++) { + math::polynomial_dfs dfs; + dfs.from_coefficients(data[i]); + result.push_back(dfs); + } + return result; +} diff --git a/crypto3/libs/math/crypto3.math.podspec.json b/crypto3/libs/math/crypto3.math.podspec.json index 1b47a8625c..dffd3cdebd 100644 --- a/crypto3/libs/math/crypto3.math.podspec.json +++ b/crypto3/libs/math/crypto3.math.podspec.json @@ -17,7 +17,7 @@ "branch": "master" }, "xcconfig": { - "CLANG_CXX_LANGUAGE_STANDARD": "c++14", + "CLANG_CXX_LANGUAGE_STANDARD": "c++17", "CLANG_CXX_LIBRARY": "libc++", "HEADER_SEARCH_PATHS": "\"${PODS_ROOT}/include/\"" }, diff --git a/crypto3/libs/math/include/nil/crypto3/math/algorithms/make_evaluation_domain.hpp b/crypto3/libs/math/include/nil/crypto3/math/algorithms/make_evaluation_domain.hpp index 44c16ee8df..393f7e97b6 100644 --- a/crypto3/libs/math/include/nil/crypto3/math/algorithms/make_evaluation_domain.hpp +++ b/crypto3/libs/math/include/nil/crypto3/math/algorithms/make_evaluation_domain.hpp @@ -26,6 +26,8 @@ #ifndef CRYPTO3_MATH_MAKE_EVALUATION_DOMAIN_HPP #define CRYPTO3_MATH_MAKE_EVALUATION_DOMAIN_HPP +#include + #include #include #include @@ -33,12 +35,67 @@ #include #include -#include - namespace nil { namespace crypto3 { namespace math { + namespace detail { + /*! + @brief + A convenience method for choosing an evaluation domain + Returns an evaluation domain object in which the domain S has size + |S| >= MinSize. + The function get_evaluation_domain is chosen from different supported domains, + depending on MinSize. + */ + using namespace nil::crypto3::algebra; + + template + bool is_basic_radix2_domain(std::size_t m) { + const std::size_t log_m = static_cast(std::ceil(std::log2(m))); + + return (m > 1) && (log_m <= fields::arithmetic_params::s) && (m == (1ul << log_m)); + } + + template + bool is_extended_radix2_domain(std::size_t m) { + const std::size_t log_m = static_cast(std::ceil(std::log2(m))); + const std::size_t small_m = m / 2; + const std::size_t log_small_m = static_cast(std::ceil(std::log2(small_m))); + + return (m > 1) && (log_m == fields::arithmetic_params::s + 1) && + (small_m == (1ul << log_small_m)) && + (log_small_m <= fields::arithmetic_params::s); + } + + template + bool is_step_radix2_domain(std::size_t m) { + const std::size_t log_m = static_cast(std::ceil(std::log2(m))); + const std::size_t shift_log_m = (1ul << log_m); + const std::size_t log_shift_log_m = static_cast(std::ceil(std::log2(shift_log_m))); + const std::size_t small_m = m - (1ul << (static_cast(std::ceil(std::log2(m))) - 1)); + const std::size_t log_small_m = static_cast(std::ceil(std::log2(small_m))); + + return (m > 1) && (small_m == (1ul << log_small_m)) && (shift_log_m == (1ul << log_shift_log_m)) && + (log_shift_log_m <= fields::arithmetic_params::s); + } + + template + bool is_geometric_sequence_domain(std::size_t m) { + return (m > 1) && + (typename FieldType::value_type(fields::arithmetic_params::geometric_generator) != + FieldType::value_type::zero()); + } + + template + bool is_arithmetic_sequence_domain(std::size_t m) { + return (m > 1) && (typename FieldType::value_type( + fields::arithmetic_params::arithmetic_generator) != + FieldType::value_type::zero()); + } + + } // namespace detail + /*! @brief A convenience method for choosing an evaluation domain diff --git a/crypto3/libs/math/include/nil/crypto3/math/domains/basic_radix2_domain.hpp b/crypto3/libs/math/include/nil/crypto3/math/domains/basic_radix2_domain.hpp index 53fe992865..96f02314e6 100755 --- a/crypto3/libs/math/include/nil/crypto3/math/domains/basic_radix2_domain.hpp +++ b/crypto3/libs/math/include/nil/crypto3/math/domains/basic_radix2_domain.hpp @@ -28,6 +28,8 @@ #include +#include + #include #include diff --git a/crypto3/libs/math/include/nil/crypto3/math/domains/extended_radix2_domain.hpp b/crypto3/libs/math/include/nil/crypto3/math/domains/extended_radix2_domain.hpp index 57d4ca95a9..de5974d4bb 100755 --- a/crypto3/libs/math/include/nil/crypto3/math/domains/extended_radix2_domain.hpp +++ b/crypto3/libs/math/include/nil/crypto3/math/domains/extended_radix2_domain.hpp @@ -28,6 +28,8 @@ #include +#include + #include #include #include diff --git a/crypto3/libs/math/include/nil/crypto3/math/type_traits.hpp b/crypto3/libs/math/include/nil/crypto3/math/type_traits.hpp index 9bcc203861..a5094230a3 100755 --- a/crypto3/libs/math/include/nil/crypto3/math/type_traits.hpp +++ b/crypto3/libs/math/include/nil/crypto3/math/type_traits.hpp @@ -36,68 +36,27 @@ #include #include +#include +#include + #include namespace nil { namespace crypto3 { namespace math { - namespace detail { - - /*! - @brief - A convenience method for choosing an evaluation domain - Returns an evaluation domain object in which the domain S has size - |S| >= MinSize. - The function get_evaluation_domain is chosen from different supported domains, - depending on MinSize. - */ - using namespace nil::crypto3::algebra; - - template - bool is_basic_radix2_domain(std::size_t m) { - const std::size_t log_m = static_cast(std::ceil(std::log2(m))); - - return (m > 1) && (log_m <= fields::arithmetic_params::s) && (m == (1ul << log_m)); - } - - template - bool is_extended_radix2_domain(std::size_t m) { - const std::size_t log_m = static_cast(std::ceil(std::log2(m))); - const std::size_t small_m = m / 2; - const std::size_t log_small_m = static_cast(std::ceil(std::log2(small_m))); - - return (m > 1) && (log_m == fields::arithmetic_params::s + 1) && - (small_m == (1ul << log_small_m)) && - (log_small_m <= fields::arithmetic_params::s); - } - - template - bool is_step_radix2_domain(std::size_t m) { - const std::size_t log_m = static_cast(std::ceil(std::log2(m))); - const std::size_t shift_log_m = (1ul << log_m); - const std::size_t log_shift_log_m = static_cast(std::ceil(std::log2(shift_log_m))); - const std::size_t small_m = m - (1ul << (static_cast(std::ceil(std::log2(m))) - 1)); - const std::size_t log_small_m = static_cast(std::ceil(std::log2(small_m))); + // Type trait to check if a given structure is math::polynomial. + template + struct is_polynomial : std::integral_constant {}; - return (m > 1) && (small_m == (1ul << log_small_m)) && (shift_log_m == (1ul << log_shift_log_m)) && - (log_shift_log_m <= fields::arithmetic_params::s); - } + template + struct is_polynomial> : std::integral_constant { }; - template - bool is_geometric_sequence_domain(std::size_t m) { - return (m > 1) && - (typename FieldType::value_type(fields::arithmetic_params::geometric_generator) != - FieldType::value_type::zero()); - } + template + struct is_polynomial_dfs : std::integral_constant {}; - template - bool is_arithmetic_sequence_domain(std::size_t m) { - return (m > 1) && (typename FieldType::value_type( - fields::arithmetic_params::arithmetic_generator) != - FieldType::value_type::zero()); - } + template + struct is_polynomial_dfs> : std::integral_constant { }; - } // namespace detail } // namespace math } // namespace crypto3 } // namespace nil diff --git a/crypto3/libs/modes/crypto3.modes.podspec.json b/crypto3/libs/modes/crypto3.modes.podspec.json index 924cd2979f..426148648d 100644 --- a/crypto3/libs/modes/crypto3.modes.podspec.json +++ b/crypto3/libs/modes/crypto3.modes.podspec.json @@ -17,7 +17,7 @@ "branch": "master" }, "xcconfig": { - "CLANG_CXX_LANGUAGE_STANDARD": "c++14", + "CLANG_CXX_LANGUAGE_STANDARD": "c++17", "CLANG_CXX_LIBRARY": "libc++", "HEADER_SEARCH_PATHS": "\"${PODS_ROOT}/include/\"" }, diff --git a/crypto3/libs/multiprecision/test/test_gcd.cpp b/crypto3/libs/multiprecision/test/test_gcd.cpp index afd07a7c5c..19e6d28c82 100644 --- a/crypto3/libs/multiprecision/test/test_gcd.cpp +++ b/crypto3/libs/multiprecision/test/test_gcd.cpp @@ -15,7 +15,7 @@ #include #include // -// clang in c++14 mode only has a problem with this file: it's an order of instantiation +// clang in c++17 mode only has a problem with this file: it's an order of instantiation // issue caused by us using cpp_int within the gcd algorithm as an error check. // Just exclude that combination from testing for now as it's purely a testing issue // and we have other compilers that cover this sanity check... diff --git a/crypto3/libs/passhash/crypto3.passhash.podspec.json b/crypto3/libs/passhash/crypto3.passhash.podspec.json index aaa36054f5..0288b17845 100644 --- a/crypto3/libs/passhash/crypto3.passhash.podspec.json +++ b/crypto3/libs/passhash/crypto3.passhash.podspec.json @@ -17,7 +17,7 @@ "branch": "master" }, "xcconfig": { - "CLANG_CXX_LANGUAGE_STANDARD": "c++14", + "CLANG_CXX_LANGUAGE_STANDARD": "c++17", "CLANG_CXX_LIBRARY": "libc++", "HEADER_SEARCH_PATHS": "\"${PODS_ROOT}/include/\"" }, diff --git a/crypto3/libs/pbkdf/crypto3.pbkdf.podspec.json b/crypto3/libs/pbkdf/crypto3.pbkdf.podspec.json index 6d1cb51121..4563144ecf 100644 --- a/crypto3/libs/pbkdf/crypto3.pbkdf.podspec.json +++ b/crypto3/libs/pbkdf/crypto3.pbkdf.podspec.json @@ -17,7 +17,7 @@ "branch": "master" }, "xcconfig": { - "CLANG_CXX_LANGUAGE_STANDARD": "c++14", + "CLANG_CXX_LANGUAGE_STANDARD": "c++17", "CLANG_CXX_LIBRARY": "libc++", "HEADER_SEARCH_PATHS": "\"${PODS_ROOT}/include/\"" }, diff --git a/crypto3/libs/pkpad/crypto3.pkpad.podspec.json b/crypto3/libs/pkpad/crypto3.pkpad.podspec.json index 2b8e1d9c3a..6ef7c83a37 100644 --- a/crypto3/libs/pkpad/crypto3.pkpad.podspec.json +++ b/crypto3/libs/pkpad/crypto3.pkpad.podspec.json @@ -17,7 +17,7 @@ "branch": "master" }, "xcconfig": { - "CLANG_CXX_LANGUAGE_STANDARD": "c++14", + "CLANG_CXX_LANGUAGE_STANDARD": "c++17", "CLANG_CXX_LIBRARY": "libc++", "HEADER_SEARCH_PATHS": "\"${PODS_ROOT}/include/\"" }, diff --git a/crypto3/libs/stream/crypto3.stream.podspec.json b/crypto3/libs/stream/crypto3.stream.podspec.json index 0c1c70ea46..264bdab0d8 100644 --- a/crypto3/libs/stream/crypto3.stream.podspec.json +++ b/crypto3/libs/stream/crypto3.stream.podspec.json @@ -17,7 +17,7 @@ "branch": "master" }, "xcconfig": { - "CLANG_CXX_LANGUAGE_STANDARD": "c++14", + "CLANG_CXX_LANGUAGE_STANDARD": "c++17", "CLANG_CXX_LIBRARY": "libc++", "HEADER_SEARCH_PATHS": "\"${PODS_ROOT}/include/\"" }, diff --git a/crypto3/libs/threshold/crypto3.threshold.podspec.json b/crypto3/libs/threshold/crypto3.threshold.podspec.json index 924cd2979f..426148648d 100644 --- a/crypto3/libs/threshold/crypto3.threshold.podspec.json +++ b/crypto3/libs/threshold/crypto3.threshold.podspec.json @@ -17,7 +17,7 @@ "branch": "master" }, "xcconfig": { - "CLANG_CXX_LANGUAGE_STANDARD": "c++14", + "CLANG_CXX_LANGUAGE_STANDARD": "c++17", "CLANG_CXX_LIBRARY": "libc++", "HEADER_SEARCH_PATHS": "\"${PODS_ROOT}/include/\"" }, diff --git a/crypto3/libs/vdf/crypto3.vdf.podspec.json b/crypto3/libs/vdf/crypto3.vdf.podspec.json index 71996bac76..d7093452f8 100644 --- a/crypto3/libs/vdf/crypto3.vdf.podspec.json +++ b/crypto3/libs/vdf/crypto3.vdf.podspec.json @@ -17,7 +17,7 @@ "branch": "master" }, "xcconfig": { - "CLANG_CXX_LANGUAGE_STANDARD": "c++14", + "CLANG_CXX_LANGUAGE_STANDARD": "c++17", "CLANG_CXX_LIBRARY": "libc++", "HEADER_SEARCH_PATHS": "\"${PODS_ROOT}/include/\"" }, diff --git a/crypto3/libs/zk/CMakeLists.txt b/crypto3/libs/zk/CMakeLists.txt index 08e64325e9..2ebcef5092 100644 --- a/crypto3/libs/zk/CMakeLists.txt +++ b/crypto3/libs/zk/CMakeLists.txt @@ -37,6 +37,7 @@ target_include_directories(${CMAKE_WORKSPACE_NAME}_${CURRENT_PROJECT_NAME} INTER target_link_libraries(${CMAKE_WORKSPACE_NAME}_${CURRENT_PROJECT_NAME} INTERFACE Boost::container + Boost::log ${CMAKE_WORKSPACE_NAME}::algebra ${CMAKE_WORKSPACE_NAME}::block diff --git a/crypto3/libs/zk/crypto3.zk.podspec.json b/crypto3/libs/zk/crypto3.zk.podspec.json index 980402d087..945ae83466 100644 --- a/crypto3/libs/zk/crypto3.zk.podspec.json +++ b/crypto3/libs/zk/crypto3.zk.podspec.json @@ -17,7 +17,7 @@ "branch": "master" }, "xcconfig": { - "CLANG_CXX_LANGUAGE_STANDARD": "c++14", + "CLANG_CXX_LANGUAGE_STANDARD": "c++17", "CLANG_CXX_LIBRARY": "libc++", "HEADER_SEARCH_PATHS": "\"${PODS_ROOT}/include/\"" }, diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/batched_commitment.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/batched_commitment.hpp index 8a39bb2308..0cb037003e 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/batched_commitment.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/batched_commitment.hpp @@ -62,15 +62,25 @@ namespace nil { using field_type = typename ParamsType::field_type; using transcript_type = TranscriptType; using polynomial_type = PolynomialType; - - eval_storage _z; + using value_type = typename field_type::value_type; + using eval_storage_type = eval_storage; polys_evaluator() = default; - protected: + // These fields are accessed from marshalling. + eval_storage_type _z; + std::map> _polys; - std::map _locked; // _locked[batch] is true after it is commited - std::map>> _points; + + // _locked[batch] is true after it is commited + std::map _locked; + + std::map>> _points; + + bool operator==(const polys_evaluator& other) const { + return _z == other._z && _polys == other._polys && + _locked == other._locked && _points == other._points; + } // We frequently search over the this->_points structure, and it's better to keep a hashmap that maps point to // it's index in vector for faster search. We need to duplicate this data for now, because the order of points matters. @@ -91,6 +101,13 @@ namespace nil { } } + // This function is called from verifier directly, without actually committing to the + // polynomials. + void state_commited(std::size_t index) { + _locked[index] = true; + _points[index].resize(_polys[index].size()); + } + protected: math::polynomial get_V( const std::vector &points) const { @@ -150,16 +167,16 @@ namespace nil { std::vector> get_unique_point_sets_list() const{ std::vector> unique_points; - for(auto const &[k, point]:_points){ - for( std::size_t i = 0; i < point.size(); i++ ){ + for (auto const &[k, point]:_points) { + for (std::size_t i = 0; i < point.size(); i++) { bool found = false; - for( std::size_t j = 0; j < unique_points.size(); j++ ){ + for (std::size_t j = 0; j < unique_points.size(); j++) { if( unique_points[j] == point[i] ){ found = true; break; } } - if( !found ){ + if (!found) { unique_points.push_back(point[i]); } } @@ -188,12 +205,6 @@ namespace nil { return eval_map; } - - void state_commited(std::size_t index){ - _locked[index] = true; - _points[index].resize(_polys[index].size()); - } - void eval_polys() { for(auto const &[k, poly] : _polys) { _z.set_batch_size(k, poly.size()); @@ -217,27 +228,39 @@ namespace nil { } void append_to_batch(std::size_t index, const polynomial_type& poly){ - if( _locked.find(index) == _locked.end() ) _locked[index] = false; - BOOST_ASSERT(!_locked[index]); // We cannot modify batch after commitment + if (_locked.find(index) == _locked.end()) + _locked[index] = false; + + // We cannot modify batch after commitment + BOOST_ASSERT(!_locked[index]); + _polys[index].push_back(poly); } template void append_to_batch(std::size_t index, const container_type& polys){ - if( _locked.find(index) == _locked.end() ) _locked[index] = false; + if (_locked.find(index) == _locked.end()) + _locked[index] = false; + BOOST_ASSERT(!_locked[index]); // We cannot modify batch after commitment _polys[index].insert(std::end(_polys[index]), std::begin(polys), std::end(polys)); } - void append_eval_point(std::size_t batch_id, typename field_type::value_type point){ - BOOST_ASSERT(_locked[batch_id]); // We can add points only after polynomails are commited. - for(std::size_t i = 0; i < _points[batch_id].size(); i++){ + void append_eval_point(std::size_t batch_id, typename field_type::value_type point) { + // We can add points only after polynomails are commited. + BOOST_ASSERT(_locked[batch_id]); + + for (std::size_t i = 0; i < _points[batch_id].size(); i++) { _points[batch_id][i].push_back(point); } } - void append_eval_point(std::size_t batch_id, std::size_t poly_id, typename field_type::value_type point){ - BOOST_ASSERT(_locked[batch_id]); // We can add points only after polynomails are commited. + void append_eval_point( + std::size_t batch_id, std::size_t poly_id, + const typename field_type::value_type& point) { + // We can add points only after polynomails are commited. + BOOST_ASSERT(_locked[batch_id]); + _points[batch_id][poly_id].push_back(point); } @@ -250,13 +273,16 @@ namespace nil { } // This function don't check evaluation points repeats - void append_eval_points(std::size_t batch_id, std::size_t poly_id, std::set points){ - BOOST_ASSERT(_locked[batch_id]); // We can add points only after polynomails are commited. + void append_eval_points(std::size_t batch_id, std::size_t poly_id, + std::set points) { + // We can add points only after polynomails are commited. + BOOST_ASSERT(_locked[batch_id]); + _points[batch_id][poly_id].insert(_points[batch_id][poly_id].end(), points.begin(), points.end()); } - void set_batch_size(std::size_t batch_id, std::size_t batch_size){ - if( _points.find(batch_id) == _points.end() ){ + void set_batch_size(std::size_t batch_id, std::size_t batch_size) { + if (_points.find(batch_id) == _points.end()) { _points[batch_id] = {}; } _points[batch_id].resize(batch_size); diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_batched_fri_compile_time_size.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_batched_fri_compile_time_size.hpp index 7497225e10..00d4590430 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_batched_fri_compile_time_size.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_batched_fri_compile_time_size.hpp @@ -66,10 +66,8 @@ namespace nil { std::size_t BatchSize = 1> struct basic_batched_fri_compile_time_size { - constexpr static const std::size_t - m = M; - constexpr static const std::size_t - leaf_size = BatchSize; + constexpr static const std::size_t m = M; + constexpr static const std::size_t leaf_size = BatchSize; typedef FieldType field_type; typedef MerkleTreeHashType merkle_tree_hash_type; diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_batched_fri_runtime_size.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_batched_fri_runtime_size.hpp index 404875df10..33ec6827f8 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_batched_fri_runtime_size.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_batched_fri_runtime_size.hpp @@ -65,8 +65,7 @@ namespace nil { std::size_t M = 2> struct basic_batched_fri_runtime_size { - constexpr static const std::size_t - m = M; + constexpr static const std::size_t m = M; typedef FieldType field_type; typedef MerkleTreeHashType merkle_tree_hash_type; diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp index 2a328871c8..4d1e0f510b 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp @@ -31,6 +31,8 @@ #ifndef CRYPTO3_ZK_COMMITMENTS_BASIC_FRI_HPP #define CRYPTO3_ZK_COMMITMENTS_BASIC_FRI_HPP +#include + #include #include #include @@ -121,10 +123,6 @@ namespace nil { // needs to be marshalled is a part of params_type. using grinding_type = GrindingType; - std::size_t lambda; - bool use_grinding; - std::size_t grinding_parameter; - constexpr static std::size_t m = M; static std::vector generate_random_step_list(const std::size_t r, const int max_step) { using dist_type = std::uniform_int_distribution; @@ -148,8 +146,6 @@ namespace nil { return step_list; } - //params_type(const params_type &other){} - // TODO when marshalling will be fine params_type( std::size_t max_step, std::size_t degree_log, @@ -162,71 +158,61 @@ namespace nil { , grinding_parameter(grinding_parameter) , max_degree((1 << degree_log) - 1) , D(math::calculate_domain_set(degree_log + expand_factor, degree_log - 1)) - , r( degree_log - 1 ) + , r(degree_log - 1) , step_list(generate_random_step_list(r, max_step)) , expand_factor(expand_factor) { } params_type( - std::vector step_list_in, + const std::vector& step_list_in, std::size_t degree_log, std::size_t lambda, std::size_t expand_factor, bool use_grinding = false, std::size_t grinding_parameter = 16 - ): lambda(lambda) + ) : lambda(lambda) , use_grinding(use_grinding) , grinding_parameter(grinding_parameter) , max_degree((1 << degree_log) - 1) - , D(math::calculate_domain_set(degree_log + expand_factor, std::accumulate(step_list_in.begin(), step_list_in.end(), 0))) + , D(math::calculate_domain_set( + degree_log + expand_factor, + std::accumulate(step_list_in.begin(), step_list_in.end(), 0))) , r(std::accumulate(step_list_in.begin(), step_list_in.end(), 0)) , step_list(step_list_in) , expand_factor(expand_factor) { } - params_type( - std::size_t max_degree, - std::vector>> D, - std::vector step_list_in, - std::size_t expand_factor, - std::size_t lambda, - bool use_grinding = false, - std::size_t grinding_parameter = 16 - ) : lambda(lambda) - , use_grinding(use_grinding) - , grinding_parameter(grinding_parameter) - , max_degree(max_degree) - , D(D) - , r(std::accumulate(step_list_in.begin(), step_list_in.end(), 0)) - , step_list(step_list_in) - , expand_factor(expand_factor) - {} - bool operator==(const params_type &rhs) const { - if( D.size() != rhs.D.size() ){ + if (D.size() != rhs.D.size()) { return false; } - for( std::size_t i = 0; i < D.size(); i++){ - if( D[i]->get_domain_element(1) != rhs.D[i]->get_domain_element(1) ){ + for (std::size_t i = 0; i < D.size(); i++) { + if (D[i]->get_domain_element(1) != rhs.D[i]->get_domain_element(1)) { return false; } } - if(use_grinding && rhs.use_grinding && grinding_parameter != rhs.grinding_parameter){ + if (use_grinding != rhs.use_grinding) { + return false; + } + if (use_grinding && grinding_parameter != rhs.grinding_parameter) { return false; } return r == rhs.r && max_degree == rhs.max_degree && step_list == rhs.step_list && expand_factor == rhs.expand_factor - && lambda == rhs.lambda - && use_grinding == rhs.use_grinding - ; + && lambda == rhs.lambda; } bool operator!=(const params_type &rhs) const { return !(rhs == *this); } + constexpr static std::size_t m = M; + + const std::size_t lambda; + const bool use_grinding; + const std::size_t grinding_parameter; const std::size_t max_degree; const std::vector>> D; @@ -249,8 +235,12 @@ namespace nil { } // For the last round it's final_polynomial's values - polynomial_values_type y; // Values for the next round. - merkle_proof_type p; // Merkle proof(values[i-1], T_i) + + // Values for the next round. + polynomial_values_type y; + + // Merkle proof(values[i-1], T_i). + merkle_proof_type p; }; struct initial_proof_type { @@ -280,6 +270,7 @@ namespace nil { struct proof_type { bool operator==(const proof_type &rhs) const { + // TODO(martun): check if the following comment can be deleted. // if( FRI::use_grinding && proof_of_work != rhs.proof_of_work ){ // return false; // } @@ -1054,7 +1045,8 @@ namespace nil { } } - if(fri_params.use_grinding && !FRI::grinding_type::verify(transcript, proof.proof_of_work, fri_params.grinding_parameter)){ + if (fri_params.use_grinding && !FRI::grinding_type::verify( + transcript, proof.proof_of_work, fri_params.grinding_parameter)){ return false; } for (std::size_t query_id = 0; query_id < fri_params.lambda; query_id++) { @@ -1084,7 +1076,8 @@ namespace nil { return false; } - detail::fri_field_element_consumer leaf_data(coset_size * query_proof.initial_proof.at(k).values.size()); + detail::fri_field_element_consumer leaf_data( + coset_size * query_proof.initial_proof.at(k).values.size()); for (std::size_t i = 0; i < query_proof.initial_proof.at(k).values.size(); i++) { for (auto [idx, pair_idx] : correct_order_idx) { @@ -1093,12 +1086,12 @@ namespace nil { } } if (!query_proof.initial_proof.at(k).p.validate(leaf_data)) { - std::cout << "Wrong initial proof" << std::endl; + BOOST_LOG_TRIVIAL(info) << "Wrong initial proof"; return false; } } - //Calculate combinedQ values + // Calculate combinedQ values typename FRI::field_type::value_type theta_acc = FRI::field_type::value_type::one(); typename FRI::polynomial_values_type y; typename FRI::polynomial_values_type combined_eval_values; @@ -1134,7 +1127,8 @@ namespace nil { typename FRI::polynomial_values_type y_next; for (std::size_t i = 0; i < fri_params.step_list.size(); i++) { coset_size = 1 << fri_params.step_list[i]; - if (query_proof.round_proofs[i].p.root() != proof.fri_roots[i]) return false; + if (query_proof.round_proofs[i].p.root() != proof.fri_roots[i]) + return false; std::tie(s, s_indices) = calculate_s(x_index, fri_params.step_list[i], fri_params.D[t]); @@ -1146,7 +1140,7 @@ namespace nil { leaf_data.consume(y[idx][1]); } if (!query_proof.round_proofs[i].p.validate(leaf_data)) { - std::cout << "Wrong round merkle proof on " << i << "-th round" << std::endl; + BOOST_LOG_TRIVIAL(info) << "Wrong round merkle proof on " << i << "-th round"; return false; } diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/eval_storage.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/eval_storage.hpp index daf6f4d43b..ee1a312a2c 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/eval_storage.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/eval_storage.hpp @@ -33,7 +33,7 @@ namespace nil { namespace zk { namespace commitments { template - class eval_storage{ + class eval_storage { private: std::map>> z; public: @@ -97,4 +97,4 @@ namespace nil { } } } -#endif \ No newline at end of file +#endif diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp index 58d02f6caa..eaa24611a1 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp @@ -725,9 +725,13 @@ namespace nil { } public: - // Interface function. Isn't useful here. + using preprocessed_data_type = bool; + + // Interface functions, not useful here. Added for compatibility with LPC. void mark_batch_as_fixed(std::size_t index) { } + void set_fixed_polys_values(const preprocessed_data_type& value) { + } kzg_commitment_scheme(params_type kzg_params) : _params(kzg_params) {} @@ -753,8 +757,6 @@ namespace nil { return result; } - using preprocessed_data_type = bool; - preprocessed_data_type preprocess(transcript_type &transcript) const { return true; } diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/kzg_v2.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/kzg_v2.hpp index d708a3128c..9888a462ba 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/kzg_v2.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/kzg_v2.hpp @@ -174,9 +174,13 @@ namespace nil { } public: - // Interface function. Isn't useful here. + using preprocessed_data_type = bool; + + // Interface functions, not useful here. Added for compatibility with LPC. void mark_batch_as_fixed(std::size_t index) { } + void set_fixed_polys_values(const preprocessed_data_type& value) { + } static params_type create_params(std::size_t d, typename CommitmentSchemeType::scalar_value_type alpha) { @@ -210,8 +214,6 @@ namespace nil { return result; } - using preprocessed_data_type = bool; - preprocessed_data_type preprocess(transcript_type &transcript) const { return true; } diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp index 999f7824ea..8b5b695d94 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp @@ -39,6 +39,7 @@ #include #include + namespace nil { namespace crypto3 { namespace zk { @@ -66,6 +67,8 @@ namespace nil { using lpc = LPCScheme; using eval_storage_type = typename LPCScheme::eval_storage_type; using preprocessed_data_type = std::map>; + using polys_evaluator_type = polys_evaluator; private: std::map _trees; @@ -75,6 +78,34 @@ namespace nil { preprocessed_data_type _fixed_polys_values; public: + // Getters for the upper fields. Used from marshalling only so far. + const std::map& get_trees() const {return _trees;} + const typename fri_type::params_type& get_fri_params() const {return _fri_params;} + const value_type& get_etha() const {return _etha;} + const std::map& get_batch_fixed() const {return _batch_fixed;} + const preprocessed_data_type& get_fixed_polys_values() const {return _fixed_polys_values;} + + // We must set it in verifier, taking this value from common data. + void set_fixed_polys_values(const preprocessed_data_type& value) {_fixed_polys_values = value;} + + // This constructor is normally used from marshalling, to recover the LPC state from a file. + // Maybe we want the move variant of this constructor. + lpc_commitment_scheme( + const polys_evaluator_type& polys_evaluator, + const std::map& trees, + const typename fri_type::params_type& fri_params, + const value_type& etha, + const std::map& batch_fixed, + const preprocessed_data_type& fixed_polys_values) + : polys_evaluator_type(polys_evaluator) + , _trees(trees) + , _fri_params(fri_params) + , _etha(etha) + , _batch_fixed(batch_fixed) + , _fixed_polys_values(fixed_polys_values) + { + } + lpc_commitment_scheme(const typename fri_type::params_type &fri_params) : _fri_params(fri_params), _etha(0u) { } @@ -84,7 +115,8 @@ namespace nil { preprocessed_data_type result; for(auto const&[index, fixed]: _batch_fixed) { - if(!fixed) continue; + if (!fixed) + continue; result[index] = {}; for (const auto& poly: this->_polys.at(index)){ result[index].push_back(poly.evaluate(etha)); @@ -153,28 +185,32 @@ namespace nil { combined_Q_normal += Q_normal; } - for(std::size_t i: this->_z.get_batches()){ - if( !_batch_fixed[i] )continue; + for (std::size_t i: this->_z.get_batches()) { + if (!_batch_fixed[i]) + continue; + math::polynomial Q_normal; auto point = _etha; V = {-point, 1u}; - for(std::size_t j = 0; j < this->_z.get_batch_size(i); j++){ + for (std::size_t j = 0; j < this->_z.get_batch_size(i); j++) { math::polynomial g_normal; - if constexpr(std::is_same, PolynomialType>::value ) { + if constexpr(std::is_same, PolynomialType>::value) { g_normal = math::polynomial(this->_polys[i][j].coefficients()); } else { g_normal = this->_polys[i][j]; } + g_normal *= theta_acc; Q_normal += g_normal; Q_normal -= _fixed_polys_values[i][j] * theta_acc; theta_acc *= theta; } + Q_normal = Q_normal / V; combined_Q_normal += Q_normal; } - if constexpr (std::is_same, PolynomialType>::value ) { + if constexpr (std::is_same, PolynomialType>::value) { combined_Q.from_coefficients(combined_Q_normal); } else { combined_Q = std::move(combined_Q_normal); @@ -213,7 +249,8 @@ namespace nil { // List of unique eval points set. [id=>points] std::size_t total_points = points.size(); - if (std::any_of(_batch_fixed.begin(), _batch_fixed.end(), [](auto i){return i.second != false;})) total_points++; + if (std::any_of(_batch_fixed.begin(), _batch_fixed.end(), [](auto i){return i.second != false;})) + total_points++; typename std::vector U(total_points); // V is product of (x - eval_point) polynomial for each eval_point @@ -238,12 +275,13 @@ namespace nil { } } - if( total_points > points.size()){ + if (total_points > points.size()) { std::size_t p = points.size(); V[p] = {-_etha, 1u}; - for(std::size_t i:this->_z.get_batches()){ - if( !_batch_fixed[i] )continue; - for(std::size_t j = 0; j < this->_z.get_batch_size(i); j++){ + for (std::size_t i:this->_z.get_batches()) { + if (!_batch_fixed[i]) + continue; + for (std::size_t j = 0; j < this->_z.get_batch_size(i); j++) { U[p] += _fixed_polys_values[i][j] * theta_acc; poly_map[p].push_back(std::make_tuple(i, j)); theta_acc *= theta; @@ -296,6 +334,14 @@ namespace nil { params.add_child("D_omegas", D_omegas_node); return params; } + + bool operator==(const lpc_commitment_scheme& other) const { + return _trees == other._trees && + _fri_params == other._fri_params && + _etha == other._etha && + _batch_fixed == other._batch_fixed && + _fixed_polys_values == other._fixed_polys_values; + } }; template struct plonk_table_description { + // Needed for marshalling. + using field_type = FieldType; + std::size_t witness_columns; std::size_t public_input_columns; std::size_t constant_columns; diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp index fbd5734026..0a46ee832e 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp @@ -28,6 +28,8 @@ #ifndef CRYPTO3_ZK_PLONK_PLACEHOLDER_VERIFIER_HPP #define CRYPTO3_ZK_PLONK_PLACEHOLDER_VERIFIER_HPP +#include + #include #include @@ -61,6 +63,8 @@ namespace nil { constexpr static const std::size_t f_parts = 8; public: + + // TODO(martun): this function is pretty similar to the one in prover, we should de-duplicate it. static void generate_evaluation_points( commitment_scheme_type &_commitment_scheme, const typename public_preprocessor_type::preprocessed_data_type::common_data_type &common_data, @@ -69,7 +73,6 @@ namespace nil { typename FieldType::value_type challenge, bool _is_lookup_enabled ) { - PROFILE_SCOPE("evaluation_points_generated_time"); const std::size_t witness_columns = table_description.witness_columns; const std::size_t public_input_columns = table_description.public_input_columns; @@ -116,7 +119,7 @@ namespace nil { std::size_t i = 0; std::size_t start_index = common_data.permuted_columns.size() * 2 + 2; - for( i = 0; i < start_index; i++){ + for( i = 0; i < start_index; i++) { _commitment_scheme.append_eval_point(FIXED_VALUES_BATCH, i, challenge); } @@ -156,11 +159,13 @@ namespace nil { numerator *= typename FieldType::value_type(table_description.rows_amount).inversed(); // If public input sizes are set, all of them should be set. - if(constraint_system.public_input_sizes_num() != 0 && constraint_system.public_input_sizes_num() != table_description.public_input_columns){ + if (constraint_system.public_input_sizes_num() != 0 && + constraint_system.public_input_sizes_num() != table_description.public_input_columns) { + BOOST_LOG_TRIVIAL(info) << "Verification failed because: If public input sizes are set, all of them should be set."; return false; } - for( std::size_t i = 0; i < public_input.size(); ++i ){ + for (std::size_t i = 0; i < public_input.size(); ++i) { typename FieldType::value_type value = FieldType::value_type::zero(); std::size_t max_size = public_input[i].size(); if (constraint_system.public_input_sizes_num() != 0) @@ -171,8 +176,9 @@ namespace nil { omega_pow = omega_pow * omega; } value *= numerator; - if( value != proof.eval_proof.eval_proof.z.get(VARIABLE_VALUES_BATCH, table_description.witness_columns + i, 0) ) + if (value != proof.eval_proof.eval_proof.z.get(VARIABLE_VALUES_BATCH, table_description.witness_columns + i, 0) ) { + BOOST_LOG_TRIVIAL(info) << "Verification failed because: evaluation proof failed."; return false; } } @@ -186,6 +192,17 @@ namespace nil { const plonk_constraint_system &constraint_system, commitment_scheme_type commitment_scheme ) { + + // We cannot add eval points unless everything is committed, so when verifying assume it's committed. + commitment_scheme.state_commited(FIXED_VALUES_BATCH); + commitment_scheme.state_commited(VARIABLE_VALUES_BATCH); + commitment_scheme.state_commited(PERMUTATION_BATCH); + commitment_scheme.state_commited(QUOTIENT_BATCH); + commitment_scheme.state_commited(LOOKUP_BATCH); + commitment_scheme.mark_batch_as_fixed(FIXED_VALUES_BATCH); + + commitment_scheme.set_fixed_polys_values(common_data.commitment_scheme_data); + const std::size_t witness_columns = table_description.witness_columns; const std::size_t public_input_columns = table_description.public_input_columns; const std::size_t constant_columns = table_description.constant_columns; @@ -204,13 +221,15 @@ namespace nil { std::vector special_selector_values(3); special_selector_values[0] = common_data.lagrange_0.evaluate(proof.eval_proof.challenge); - special_selector_values[1] = proof.eval_proof.eval_proof.z.get(FIXED_VALUES_BATCH, 2*common_data.permuted_columns.size(), 0); - special_selector_values[2] = proof.eval_proof.eval_proof.z.get(FIXED_VALUES_BATCH, 2*common_data.permuted_columns.size() + 1, 0); + special_selector_values[1] = proof.eval_proof.eval_proof.z.get( + FIXED_VALUES_BATCH, 2*common_data.permuted_columns.size(), 0); + special_selector_values[2] = proof.eval_proof.eval_proof.z.get( + FIXED_VALUES_BATCH, 2*common_data.permuted_columns.size() + 1, 0); // 4. prepare evaluaitons of the polynomials that are copy-constrained std::array F; std::size_t permutation_size = (proof.eval_proof.eval_proof.z.get_batch_size(FIXED_VALUES_BATCH) - 2 - constant_columns - selector_columns) / 2; - if( constraint_system.copy_constraints().size() > 0 ){ + if (constraint_system.copy_constraints().size() > 0) { // Permutation polys std::vector permuted_polys_global_indices = common_data.permuted_columns; std::vector f(permutation_size); @@ -360,18 +379,29 @@ namespace nil { auto challenge = transcript.template challenge(); BOOST_ASSERT(challenge == proof.eval_proof.challenge); - commitment_scheme.set_batch_size(VARIABLE_VALUES_BATCH, proof.eval_proof.eval_proof.z.get_batch_size(VARIABLE_VALUES_BATCH)); - if( is_lookup_enabled || constraint_system.copy_constraints().size()) - commitment_scheme.set_batch_size(PERMUTATION_BATCH, proof.eval_proof.eval_proof.z.get_batch_size(PERMUTATION_BATCH)); - commitment_scheme.set_batch_size(QUOTIENT_BATCH, proof.eval_proof.eval_proof.z.get_batch_size(QUOTIENT_BATCH)); + commitment_scheme.set_batch_size(VARIABLE_VALUES_BATCH, + proof.eval_proof.eval_proof.z.get_batch_size(VARIABLE_VALUES_BATCH)); + commitment_scheme.set_batch_size(FIXED_VALUES_BATCH, + proof.eval_proof.eval_proof.z.get_batch_size(FIXED_VALUES_BATCH)); + + if (is_lookup_enabled || constraint_system.copy_constraints().size()) + commitment_scheme.set_batch_size(PERMUTATION_BATCH, + proof.eval_proof.eval_proof.z.get_batch_size(PERMUTATION_BATCH)); + + commitment_scheme.set_batch_size(QUOTIENT_BATCH, + proof.eval_proof.eval_proof.z.get_batch_size(QUOTIENT_BATCH)); + if (is_lookup_enabled) - commitment_scheme.set_batch_size(LOOKUP_BATCH, proof.eval_proof.eval_proof.z.get_batch_size(LOOKUP_BATCH)); + commitment_scheme.set_batch_size(LOOKUP_BATCH, + proof.eval_proof.eval_proof.z.get_batch_size(LOOKUP_BATCH)); + generate_evaluation_points(commitment_scheme, common_data, constraint_system, table_description, challenge, is_lookup_enabled); std::map commitments = proof.commitments; commitments[FIXED_VALUES_BATCH] = common_data.commitments.fixed_values; if (!commitment_scheme.verify_eval( proof.eval_proof.eval_proof, commitments, transcript )) { + BOOST_LOG_TRIVIAL(info) << "Verification failed because: commitment scheme verification failed."; return false; } @@ -396,6 +426,7 @@ namespace nil { // Z is polynomial -1, 0 ...., 0, 1 typename FieldType::value_type Z_at_challenge = common_data.Z.evaluate(challenge); if (F_consolidated != Z_at_challenge * T_consolidated) { + BOOST_LOG_TRIVIAL(info) << "Verification failed because: F consoludated polynomial does not match."; return false; } return true; diff --git a/crypto3/libs/zk/test/CMakeLists.txt b/crypto3/libs/zk/test/CMakeLists.txt index 3f824ac4af..b5a4aff45e 100644 --- a/crypto3/libs/zk/test/CMakeLists.txt +++ b/crypto3/libs/zk/test/CMakeLists.txt @@ -15,7 +15,9 @@ target_include_directories(${CMAKE_WORKSPACE_NAME}_${CURRENT_PROJECT_NAME} INTER cm_test_link_libraries(${CMAKE_WORKSPACE_NAME}_${CURRENT_PROJECT_NAME} ${CMAKE_WORKSPACE_NAME}::random crypto3::marshalling-zk - Boost::unit_test_framework) + Boost::unit_test_framework + Boost::log + ) if(PROFILING_ENABLED) add_definitions(-DPROFILING_ENABLED) diff --git a/crypto3/libs/zk/test/commitment/fri.cpp b/crypto3/libs/zk/test/commitment/fri.cpp index 2aae7eda1e..a6064750d6 100644 --- a/crypto3/libs/zk/test/commitment/fri.cpp +++ b/crypto3/libs/zk/test/commitment/fri.cpp @@ -108,14 +108,14 @@ void fri_basic_test() std::vector>> D = math::calculate_domain_set(extended_log, r); + std::size_t degree_log = std::ceil(std::log2(d - 1)); params_type params( - d - 1, // max_degree - D, - generate_random_step_list(r, 1), - 2, //expand_factor + 1, /*max_step*/ + degree_log, lambda, - true, - 16 + 2, //expand_factor + true, // use_grinding + 16 // grinding_parameter ); BOOST_CHECK(D[1]->m == D[0]->m / 2); diff --git a/crypto3/libs/zk/test/commitment/lpc.cpp b/crypto3/libs/zk/test/commitment/lpc.cpp index a6e92d6528..d7a763ea69 100644 --- a/crypto3/libs/zk/test/commitment/lpc.cpp +++ b/crypto3/libs/zk/test/commitment/lpc.cpp @@ -203,15 +203,15 @@ BOOST_AUTO_TEST_SUITE(lpc_math_polynomial_suite); // Setup params + std::size_t degree_log = std::ceil(std::log2(d - 1)); typename fri_type::params_type fri_params( - d - 1, // max_degree - D, - generate_random_step_list(r, 1, test_global_rnd_engine), - 2, //expand_factor + 1, /*max_step*/ + degree_log, lambda, - true, - 12 - ); + 2, //expand_factor + true, // use_grinding + 12 // grinding_parameter + ); using lpc_scheme_type = nil::crypto3::zk::commitments::lpc_commitment_scheme>; lpc_scheme_type lpc_scheme_prover(fri_params); @@ -304,13 +304,13 @@ BOOST_AUTO_TEST_SUITE(lpc_math_polynomial_suite); typedef zk::commitments::fri fri_type; // Setup params + std::size_t degree_log = std::ceil(std::log2(d - 1)); typename fri_type::params_type fri_params( - d - 1, // max_degree - D, - generate_random_step_list(r, 5, test_global_rnd_engine), - 2, //expand_factor - lambda - ); + 5, /*max_step*/ + degree_log, + lambda, + 2 //expand_factor + ); using lpc_scheme_type = nil::crypto3::zk::commitments::lpc_commitment_scheme>; lpc_scheme_type lpc_scheme_prover(fri_params); @@ -396,20 +396,14 @@ BOOST_AUTO_TEST_SUITE(lpc_math_polynomial_suite); static_assert(!zk::is_commitment::value); // Setup params - constexpr static const std::size_t d_extended = d; - std::size_t extended_log = boost::static_log2::value; - std::vector>> D = - math::calculate_domain_set(extended_log, r + 1); - - // Setup params + std::size_t degree_log = std::ceil(std::log2(d - 1)); typename fri_type::params_type fri_params( - d - 1, // max_degree - D, - generate_random_step_list(r, 1, test_global_rnd_engine), - 2, //expand_factor + 1, /*max_step*/ + degree_log, lambda, - true - ); + 2, //expand_factor + true // use_grinding + ); using lpc_scheme_type = nil::crypto3::zk::commitments::lpc_commitment_scheme; lpc_scheme_type lpc_scheme_prover(fri_params); @@ -498,20 +492,16 @@ BOOST_AUTO_TEST_SUITE(lpc_params_test_suite) static_assert(!zk::is_commitment::value); static_assert(!zk::is_commitment::value); - constexpr static const std::size_t d_extended = d; - std::size_t extended_log = boost::static_log2::value; - std::vector>> D = - math::calculate_domain_set(extended_log, r); - + // Setup params + std::size_t degree_log = std::ceil(std::log2(d - 1)); typename fri_type::params_type fri_params( - d - 1, // max_degree - D, - generate_random_step_list(r, 1, test_global_rnd_engine), - 2, //expand_factor + 1, /*max_step*/ + degree_log, lambda, - true, + 2, // expand_factor + true, // use_grinding 8 - ); + ); using lpc_scheme_type = nil::crypto3::zk::commitments::lpc_commitment_scheme>; lpc_scheme_type lpc_scheme_prover(fri_params); @@ -595,13 +585,14 @@ BOOST_AUTO_TEST_SUITE(lpc_params_test_suite) std::vector>> D = math::calculate_domain_set(extended_log, r); + // Setup params + std::size_t degree_log = std::ceil(std::log2(d - 1)); typename fri_type::params_type fri_params( - d - 1, // max_degree - D, - generate_random_step_list(r, 1, test_global_rnd_engine), - 2, //expand_factor - lambda - ); + 1, /*max_step*/ + degree_log, + lambda, + 2 //expand_factor + ); using lpc_scheme_type = nil::crypto3::zk::commitments::lpc_commitment_scheme>; lpc_scheme_type lpc_scheme_prover(fri_params); diff --git a/crypto3/libs/zk/test/commitment/lpc_performance.cpp b/crypto3/libs/zk/test/commitment/lpc_performance.cpp index a9c8ef1281..2216ad4ce7 100644 --- a/crypto3/libs/zk/test/commitment/lpc_performance.cpp +++ b/crypto3/libs/zk/test/commitment/lpc_performance.cpp @@ -148,18 +148,14 @@ BOOST_AUTO_TEST_CASE(step_list_1, *boost::unit_test::disabled()) { typedef zk::commitments::list_polynomial_commitment_params lpc_params_type; typedef zk::commitments::list_polynomial_commitment lpc_type; - constexpr static const std::size_t d_extended = d; - std::size_t extended_log = boost::static_log2::value; - std::vector>> D = - math::calculate_domain_set(extended_log, r); - + // Setup params + std::size_t degree_log = std::ceil(std::log2(d - 1)); typename fri_type::params_type fri_params( - d - 1, - D, - generate_random_step_list(r, 1), - r, - lambda - ); + 1, /*max_step*/ + degree_log, + lambda, + 4, //expand_factor + ); using lpc_scheme_type = nil::crypto3::zk::commitments::lpc_commitment_scheme>; lpc_scheme_type lpc_scheme_prover(fri_params); @@ -239,18 +235,14 @@ BOOST_AUTO_TEST_CASE(step_list_3, *boost::unit_test::disabled()) { typedef zk::commitments::list_polynomial_commitment_params lpc_params_type; typedef zk::commitments::list_polynomial_commitment lpc_type; - constexpr static const std::size_t d_extended = d; - std::size_t extended_log = boost::static_log2::value; - std::vector>> D = - math::calculate_domain_set(extended_log, r); - + // Setup params + std::size_t degree_log = std::ceil(std::log2(d - 1)); typename fri_type::params_type fri_params( - d - 1, - D, - generate_random_step_list(r, 3), - r, - lambda - ); + 3, /*max_step*/ + degree_log, + lambda, + 4, //expand_factor + ); using lpc_scheme_type = nil::crypto3::zk::commitments::lpc_commitment_scheme>; lpc_scheme_type lpc_scheme_prover(fri_params); @@ -329,18 +321,14 @@ BOOST_AUTO_TEST_CASE(step_list_5, *boost::unit_test::disabled()) { typedef zk::commitments::list_polynomial_commitment_params lpc_params_type; typedef zk::commitments::list_polynomial_commitment lpc_type; - constexpr static const std::size_t d_extended = d; - std::size_t extended_log = boost::static_log2::value; - std::vector>> D = - math::calculate_domain_set(extended_log, r); - + // Setup params + std::size_t degree_log = std::ceil(std::log2(d - 1)); typename fri_type::params_type fri_params( - d - 1, - D, - generate_random_step_list(r, 5), - r, - lambda - ); + 5, /*max_step*/ + degree_log, + lambda, + 4, //expand_factor + ); using lpc_scheme_type = nil::crypto3::zk::commitments::lpc_commitment_scheme>; lpc_scheme_type lpc_scheme_prover(fri_params); diff --git a/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_test_runner.hpp b/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_test_runner.hpp index bae48452d7..b6ffe491f7 100644 --- a/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_test_runner.hpp +++ b/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_test_runner.hpp @@ -104,8 +104,11 @@ struct placeholder_test_runner { lpc_preprocessed_public_data, std::move(lpc_preprocessed_private_data), desc, constraint_system, lpc_scheme); + // We must not use the same instance of lpc_scheme. + lpc_scheme_type verifier_lpc_scheme(fri_params); + bool verifier_res = placeholder_verifier::process( - lpc_preprocessed_public_data.common_data, lpc_proof, desc, constraint_system, lpc_scheme); + lpc_preprocessed_public_data.common_data, lpc_proof, desc, constraint_system, verifier_lpc_scheme); return verifier_res; } From e500bd24a35814f8c85349cf2317aed6a7546fc1 Mon Sep 17 00:00:00 2001 From: Vasiliy Olekhov Date: Wed, 11 Sep 2024 12:04:10 +0300 Subject: [PATCH 2/5] Synchronize with parallel-crypto3 sources --- crypto3/libs/containers/CMakeLists.txt | 1 - .../marshalling/zk/test/kzg_commitment.cpp | 5 +- .../algorithms/make_evaluation_domain.hpp | 2 - .../math/domains/basic_radix2_domain.hpp | 2 - .../math/domains/extended_radix2_domain.hpp | 2 - .../math/polynomial/basic_operations.hpp | 1 - .../crypto3/math/polynomial/basis_change.hpp | 0 .../nil/crypto3/math/polynomial/evaluate.hpp | 0 .../crypto3/math/polynomial/polynomial.hpp | 130 +++--- .../math/polynomial/polynomial_dfs.hpp | 11 +- .../math/polynomial/polynomial_view.hpp | 1 - .../nil/crypto3/math/polynomial/shift.hpp | 4 +- .../nil/crypto3/math/polynomial/xgcd.hpp | 0 .../include/nil/crypto3/math/type_traits.hpp | 2 - crypto3/libs/math/test/polynomial_dfs.cpp | 11 +- crypto3/libs/zk/CMakeLists.txt | 19 +- crypto3/libs/zk/README.md | 4 +- .../detail/polynomial/basic_fri.hpp | 8 +- .../plonk/placeholder/lookup_argument.hpp | 150 ++++--- .../systems/plonk/placeholder/verifier.hpp | 5 +- crypto3/libs/zk/test/CMakeLists.txt | 2 - .../zk/test/commitment/lpc_performance.cpp | 390 ------------------ .../libs/zk/test/commitment/proof_of_work.cpp | 9 +- crypto3/libs/zk/test/math/expression.cpp | 6 +- .../placeholder/placeholder_gate_argument.cpp | 1 + 25 files changed, 199 insertions(+), 567 deletions(-) mode change 100755 => 100644 crypto3/libs/math/include/nil/crypto3/math/polynomial/basic_operations.hpp mode change 100755 => 100644 crypto3/libs/math/include/nil/crypto3/math/polynomial/basis_change.hpp mode change 100755 => 100644 crypto3/libs/math/include/nil/crypto3/math/polynomial/evaluate.hpp mode change 100755 => 100644 crypto3/libs/math/include/nil/crypto3/math/polynomial/xgcd.hpp delete mode 100644 crypto3/libs/zk/test/commitment/lpc_performance.cpp diff --git a/crypto3/libs/containers/CMakeLists.txt b/crypto3/libs/containers/CMakeLists.txt index 50947bd2cb..0fe20bf82f 100644 --- a/crypto3/libs/containers/CMakeLists.txt +++ b/crypto3/libs/containers/CMakeLists.txt @@ -57,7 +57,6 @@ target_include_directories(${CMAKE_WORKSPACE_NAME}_${CURRENT_PROJECT_NAME} INTER cm_deploy(TARGETS ${CMAKE_WORKSPACE_NAME}_${CURRENT_PROJECT_NAME} INCLUDE include NAMESPACE ${CMAKE_WORKSPACE_NAME}::) -include(CMTest) cm_add_test_subdirectory(test) if (BUILD_EXAMPLES) diff --git a/crypto3/libs/marshalling/zk/test/kzg_commitment.cpp b/crypto3/libs/marshalling/zk/test/kzg_commitment.cpp index 5c3a127ab3..b2e44ae539 100644 --- a/crypto3/libs/marshalling/zk/test/kzg_commitment.cpp +++ b/crypto3/libs/marshalling/zk/test/kzg_commitment.cpp @@ -25,7 +25,6 @@ // SOFTWARE. //---------------------------------------------------------------------------// -#include "nil/crypto3/zk/commitments/batched_commitment.hpp" #define BOOST_TEST_MODULE crypto3_marshalling_kzg_commitment_test #include @@ -53,7 +52,8 @@ #include #include -#include +#include +#include /* #include @@ -75,6 +75,7 @@ #include #include #include +#include #include #include diff --git a/crypto3/libs/math/include/nil/crypto3/math/algorithms/make_evaluation_domain.hpp b/crypto3/libs/math/include/nil/crypto3/math/algorithms/make_evaluation_domain.hpp index 393f7e97b6..e18ff409c7 100644 --- a/crypto3/libs/math/include/nil/crypto3/math/algorithms/make_evaluation_domain.hpp +++ b/crypto3/libs/math/include/nil/crypto3/math/algorithms/make_evaluation_domain.hpp @@ -26,8 +26,6 @@ #ifndef CRYPTO3_MATH_MAKE_EVALUATION_DOMAIN_HPP #define CRYPTO3_MATH_MAKE_EVALUATION_DOMAIN_HPP -#include - #include #include #include diff --git a/crypto3/libs/math/include/nil/crypto3/math/domains/basic_radix2_domain.hpp b/crypto3/libs/math/include/nil/crypto3/math/domains/basic_radix2_domain.hpp index 96f02314e6..53fe992865 100755 --- a/crypto3/libs/math/include/nil/crypto3/math/domains/basic_radix2_domain.hpp +++ b/crypto3/libs/math/include/nil/crypto3/math/domains/basic_radix2_domain.hpp @@ -28,8 +28,6 @@ #include -#include - #include #include diff --git a/crypto3/libs/math/include/nil/crypto3/math/domains/extended_radix2_domain.hpp b/crypto3/libs/math/include/nil/crypto3/math/domains/extended_radix2_domain.hpp index de5974d4bb..57d4ca95a9 100755 --- a/crypto3/libs/math/include/nil/crypto3/math/domains/extended_radix2_domain.hpp +++ b/crypto3/libs/math/include/nil/crypto3/math/domains/extended_radix2_domain.hpp @@ -28,8 +28,6 @@ #include -#include - #include #include #include diff --git a/crypto3/libs/math/include/nil/crypto3/math/polynomial/basic_operations.hpp b/crypto3/libs/math/include/nil/crypto3/math/polynomial/basic_operations.hpp old mode 100755 new mode 100644 index e9f896c648..6d1057674a --- a/crypto3/libs/math/include/nil/crypto3/math/polynomial/basic_operations.hpp +++ b/crypto3/libs/math/include/nil/crypto3/math/polynomial/basic_operations.hpp @@ -308,7 +308,6 @@ namespace nil { */ template void division(Range &q, Range &r, const Range &a, const Range &b) { - typedef typename std::iterator_traits()))>::value_type value_type; diff --git a/crypto3/libs/math/include/nil/crypto3/math/polynomial/basis_change.hpp b/crypto3/libs/math/include/nil/crypto3/math/polynomial/basis_change.hpp old mode 100755 new mode 100644 diff --git a/crypto3/libs/math/include/nil/crypto3/math/polynomial/evaluate.hpp b/crypto3/libs/math/include/nil/crypto3/math/polynomial/evaluate.hpp old mode 100755 new mode 100644 diff --git a/crypto3/libs/math/include/nil/crypto3/math/polynomial/polynomial.hpp b/crypto3/libs/math/include/nil/crypto3/math/polynomial/polynomial.hpp index 53c9917c09..80be1e775b 100644 --- a/crypto3/libs/math/include/nil/crypto3/math/polynomial/polynomial.hpp +++ b/crypto3/libs/math/include/nil/crypto3/math/polynomial/polynomial.hpp @@ -64,19 +64,19 @@ namespace nil { } } - explicit polynomial(size_type n, const allocator_type &a) : val(n, FieldValueType::zero(), a) { + explicit polynomial(size_type n, const allocator_type& a) : val(n, FieldValueType::zero(), a) { if (val.empty()) { val.push_back(FieldValueType::zero()); } } - polynomial(size_type n, const value_type &x) : val(n, x) { + polynomial(size_type n, const value_type& x) : val(n, x) { if (val.empty()) { val.push_back(FieldValueType::zero()); } } - polynomial(size_type n, const value_type &x, const allocator_type &a) : val(n, x, a) { + polynomial(size_type n, const value_type& x, const allocator_type& a) : val(n, x, a) { } template @@ -87,7 +87,7 @@ namespace nil { } template - polynomial(InputIterator first, InputIterator last, const allocator_type &a) : val(first, last, a) { + polynomial(InputIterator first, InputIterator last, const allocator_type& a) : val(first, last, a) { if (val.empty()) { val.push_back(FieldValueType::zero()); } @@ -95,73 +95,73 @@ namespace nil { ~polynomial() = default; - polynomial(const polynomial &x) : val(x.val) { + polynomial(const polynomial& x) : val(x.val) { } - polynomial(const polynomial &x, const allocator_type &a) : val(x.val, a) { + polynomial(const polynomial& x, const allocator_type& a) : val(x.val, a) { } polynomial(std::initializer_list il) : val(il) { } - polynomial(std::initializer_list il, const allocator_type &a) : val(il, a) { + polynomial(std::initializer_list il, const allocator_type& a) : val(il, a) { } - polynomial(polynomial &&x) BOOST_NOEXCEPT - (std::is_nothrow_move_constructible::value): - val(x.val) { + polynomial(polynomial&& x) BOOST_NOEXCEPT + (std::is_nothrow_move_constructible::value) : + val(std::move(x.val)) { } - polynomial(polynomial &&x, const allocator_type &a) : val(x.val, a) { + polynomial(polynomial&& x, const allocator_type& a) : val(std::move(x.val), a) { } - polynomial(const container_type &c) : val(c) { + explicit polynomial(const container_type &c) : val(c) { if (val.empty()) { val.push_back(FieldValueType::zero()); } } - polynomial(container_type &&c) : val(std::forward(c)) { + explicit polynomial(container_type &&c) : val(std::forward(c)) { if (val.empty()) { val.push_back(FieldValueType::zero()); } } - polynomial(const FieldValueType &value, std::size_t power = 0) : val(power + 1, - FieldValueType::zero()) { + polynomial(const FieldValueType& value, std::size_t power = 0) + : val(power + 1, FieldValueType::zero()) { this->operator[](power) = value; } - polynomial &operator=(const polynomial &x) { + polynomial& operator=(const polynomial& x) { val = x.val; return *this; } - polynomial &operator=(polynomial &&x) { + polynomial& operator=(polynomial&& x) { val = x.val; return *this; } - polynomial &operator=(const container_type &x) { + polynomial& operator=(const container_type& x) { val = x; return *this; } - polynomial &operator=(container_type &&x) { + polynomial& operator=(container_type&& x) { val = x; return *this; } - polynomial &operator=(std::initializer_list il) { + polynomial& operator=(std::initializer_list il) { val.assign(il.begin(), il.end()); return *this; } - bool operator==(const polynomial &rhs) const { + bool operator==(const polynomial& rhs) const { return val == rhs.val; } - bool operator!=(const polynomial &rhs) const { + bool operator!=(const polynomial& rhs) const { return !(rhs == *this); } @@ -183,7 +183,7 @@ namespace nil { return this->val.__alloc(); } - container_type &get_storage() { + container_type& get_storage() { return val; } @@ -295,11 +295,11 @@ namespace nil { return val.back(); } - value_type *data() BOOST_NOEXCEPT { + value_type* data() BOOST_NOEXCEPT { return val.data(); } - const value_type *data() const BOOST_NOEXCEPT { + const value_type* data() const BOOST_NOEXCEPT { return val.data(); } @@ -307,12 +307,12 @@ namespace nil { val.push_back(_x); } - void push_back(value_type &&_x) { + void push_back(value_type&& _x) { val.push_back(_x); } template - reference emplace_back(Args &&... _args) { + reference emplace_back(Args&&... _args) { return val.template emplace_back(_args...); } @@ -324,12 +324,12 @@ namespace nil { return val.insert(_position, _x); } - iterator insert(const_iterator _position, value_type &&_x) { + iterator insert(const_iterator _position, value_type&& _x) { return val.insert(_position, _x); } template - iterator emplace(const_iterator _position, Args &&... _args) { + iterator emplace(const_iterator _position, Args&&... _args) { return val.template emplace(_position, _args...); } @@ -366,12 +366,12 @@ namespace nil { return val.resize(_sz, _x); } - void swap(polynomial &other) { + void swap(polynomial& other) { val.swap(other.val); } template - FieldValueType evaluate(const Range &values) const { + FieldValueType evaluate(const Range& values) const { assert(values.size() + 1 == this->size()); @@ -383,7 +383,7 @@ namespace nil { return result; } - FieldValueType evaluate(const FieldValueType &value) const { + FieldValueType evaluate(const FieldValueType& value) const { FieldValueType result = FieldValueType::zero(); auto end = this->end(); while (end != this->begin()) { @@ -405,8 +405,8 @@ namespace nil { */ bool is_one() const { return (*this->begin() == FieldValueType(1)) && - std::all_of(++this->begin(), this->end(), - [](FieldValueType i) { return i == FieldValueType::zero(); }); + std::all_of(++this->begin(), this->end(), + [](FieldValueType i) { return i == FieldValueType::zero(); }); } inline static polynomial zero() { @@ -444,13 +444,13 @@ namespace nil { * Computes the standard polynomial addition, polynomial A + polynomial B, and stores result in * polynomial C. */ - polynomial operator+(const polynomial &other) const { + polynomial operator+(const polynomial& other) const { polynomial result; addition(result, *this, other); return result; } - polynomial &operator+=(const polynomial &other) { + polynomial& operator+=(const polynomial& other) { addition(*this, *this, other); return *this; } @@ -465,13 +465,13 @@ namespace nil { * Computes the standard polynomial subtraction, polynomial A - polynomial B, and stores result in * polynomial C. */ - polynomial operator-(const polynomial &other) const { + polynomial operator-(const polynomial& other) const { polynomial result; subtraction(result, *this, other); return result; } - polynomial &operator-=(const polynomial &other) { + polynomial& operator-=(const polynomial& other) { subtraction(*this, *this, other); return *this; } @@ -480,13 +480,13 @@ namespace nil { * Perform the multiplication of two polynomials, polynomial A * polynomial B, and stores result in * polynomial C. */ - polynomial operator*(const polynomial &other) const { + polynomial operator*(const polynomial& other) const { polynomial result; multiplication(result, *this, other); return result; } - polynomial &operator*=(const polynomial &other) { + polynomial& operator*=(const polynomial& other) { multiplication(*this, *this, other); return *this; } @@ -496,13 +496,13 @@ namespace nil { * Input: Polynomial A, Polynomial B, where A / B * Output: Polynomial Q, such that A = (Q * B) + R. */ - polynomial operator/(const polynomial &other) const { + polynomial operator/(const polynomial& other) const { polynomial r, q; division(q, r, *this, other); return q; } - polynomial &operator/=(const polynomial &other) { + polynomial& operator/=(const polynomial& other) { polynomial r, q; // Can't pass *this to the following function call instead of q. division(q, r, *this, other); @@ -515,13 +515,13 @@ namespace nil { * Input: Polynomial A, Polynomial B, where A / B * Output: Polynomial R, such that A = (Q * B) + R. */ - polynomial operator%(const polynomial &other) const { + polynomial operator%(const polynomial& other) const { polynomial r, q; division(q, r, *this, other); return r; } - polynomial &operator%=(const polynomial &other) { + polynomial& operator%=(const polynomial& other) { polynomial q, r; // Can't pass *this to the following function call instead of r. division(q, r, *this, other); @@ -531,33 +531,33 @@ namespace nil { }; template, - typename = typename std::enable_if::value>::type> - polynomial operator+(const polynomial &A, - const FieldValueType &B) { + typename = typename std::enable_if::value>::type> + polynomial operator+(const polynomial& A, + const FieldValueType& B) { return A + polynomial(B); } template, - typename = typename std::enable_if::value>::type> - polynomial operator+(const FieldValueType &A, - const polynomial &B) { + typename = typename std::enable_if::value>::type> + polynomial operator+(const FieldValueType& A, + const polynomial& B) { return polynomial(A) + B; } template, - typename = typename std::enable_if::value>::type> - polynomial operator-(const polynomial &A, - const FieldValueType &B) { + typename = typename std::enable_if::value>::type> + polynomial operator-(const polynomial& A, + const FieldValueType& B) { return A - polynomial(B); } template, - typename = typename std::enable_if::value>::type> - polynomial operator-(const FieldValueType &A, - const polynomial &B) { + typename = typename std::enable_if::value>::type> + polynomial operator-(const FieldValueType& A, + const polynomial& B) { return polynomial(A) - B; } @@ -567,7 +567,7 @@ namespace nil { polynomial operator*(const polynomial& A, const FieldValueType& B) { polynomial result(A); - for( auto it = result.begin(); it != result.end(); it++ ){ + for (auto it = result.begin(); it != result.end(); ++it) { *it *= B; } return result; @@ -587,16 +587,16 @@ namespace nil { const FieldValueType& B) { polynomial result(A); FieldValueType B_inversed = B.inversed(); - for( auto it = result.begin(); it != result.end(); it++ ){ + for (auto it = result.begin(); it != result.end(); ++it) { *it *= B_inversed; } return result; } template, - typename = typename std::enable_if::value>::type> - polynomial operator/(const FieldValueType &A, - const polynomial &B) { + typename = typename std::enable_if::value>::type> + polynomial operator/(const FieldValueType& A, + const polynomial& B) { return polynomial(A) / B; } @@ -604,15 +604,15 @@ namespace nil { // Used in the unit tests, so we can use BOOST_CHECK_EQUALS, and see // the values of polynomials, when the check fails. template, - typename = typename std::enable_if::value>::type> - std::ostream &operator<<(std::ostream &os, - const polynomial &poly) { + typename = typename std::enable_if::value>::type> + std::ostream& operator<<(std::ostream& os, + const polynomial& poly) { if (poly.degree() == 0) { // If all it contains is a constant, print the constant, so it's more readable. os << *poly.begin(); } else { os << "[Polynomial, size " << poly.size() << " values "; - for (auto it = poly.begin(); it != poly.end(); it++) { + for (auto it = poly.begin(); it != poly.end(); ++it) { os << "0x" << std::hex << it->data << ", "; } os << "]"; diff --git a/crypto3/libs/math/include/nil/crypto3/math/polynomial/polynomial_dfs.hpp b/crypto3/libs/math/include/nil/crypto3/math/polynomial/polynomial_dfs.hpp index 2b5a9c6e47..16c9a2c202 100644 --- a/crypto3/libs/math/include/nil/crypto3/math/polynomial/polynomial_dfs.hpp +++ b/crypto3/libs/math/include/nil/crypto3/math/polynomial/polynomial_dfs.hpp @@ -73,11 +73,11 @@ namespace nil { polynomial_dfs() : val(1, FieldValueType::zero()), _d(0) { } - explicit polynomial_dfs(size_t d, size_type n) : val(n), _d(d) { + explicit polynomial_dfs(size_t d, size_type n) : val(n, FieldValueType::zero()), _d(d) { BOOST_ASSERT_MSG(n == detail::power_of_two(n), "DFS optimal polynomial size must be a power of two"); } - explicit polynomial_dfs(size_t d, size_type n, const allocator_type& a) : val(n, a), _d(d) { + explicit polynomial_dfs(size_t d, size_type n, const allocator_type& a) : val(n, FieldValueType::zero(), a), _d(d) { BOOST_ASSERT_MSG(n == detail::power_of_two(n), "DFS optimal polynomial size must be a power of two"); } @@ -340,6 +340,7 @@ namespace nil { return; } BOOST_ASSERT_MSG(_sz >= _d, "Resizing DFS polynomial to a size less than degree is prohibited: can't restore the polynomial in the future."); + if (this->degree() == 0) { // Here we cannot write this->val.resize(_sz, this->val[0]), it will segfault. auto value = this->val[0]; @@ -436,6 +437,7 @@ namespace nil { this->resize(other.size()); } this->_d = std::max(this->_d, other._d); + if (this->size() > other.size()) { polynomial_dfs tmp(other); tmp.resize(this->size()); @@ -512,7 +514,6 @@ namespace nil { polynomial_dfs operator*(const polynomial_dfs& other) const { polynomial_dfs result = *this; result *= other; - return result; } @@ -711,7 +712,7 @@ namespace nil { polynomial_dfs operator*(const polynomial_dfs& A, const FieldValueType& B) { polynomial_dfs result(A); - for( auto it = result.begin(); it != result.end(); it++ ){ + for ( auto it = result.begin(); it != result.end(); ++it) { *it *= B; } return result; @@ -731,7 +732,7 @@ namespace nil { const FieldValueType& B) { polynomial_dfs result(A); FieldValueType B_inversed = B.inversed(); - for( auto it = result.begin(); it != result.end(); it++ ){ + for ( auto it = result.begin(); it != result.end(); ++it) { *it *= B_inversed; } return result; diff --git a/crypto3/libs/math/include/nil/crypto3/math/polynomial/polynomial_view.hpp b/crypto3/libs/math/include/nil/crypto3/math/polynomial/polynomial_view.hpp index d4bb38aea9..3b105d30e6 100644 --- a/crypto3/libs/math/include/nil/crypto3/math/polynomial/polynomial_view.hpp +++ b/crypto3/libs/math/include/nil/crypto3/math/polynomial/polynomial_view.hpp @@ -350,7 +350,6 @@ namespace nil { return *this; } -// polynomial_view operator-() const { void neg() { std::transform(this->begin(), this->end(), this->begin(), std::negate()); } diff --git a/crypto3/libs/math/include/nil/crypto3/math/polynomial/shift.hpp b/crypto3/libs/math/include/nil/crypto3/math/polynomial/shift.hpp index 1eec617f70..284640452a 100644 --- a/crypto3/libs/math/include/nil/crypto3/math/polynomial/shift.hpp +++ b/crypto3/libs/math/include/nil/crypto3/math/polynomial/shift.hpp @@ -39,7 +39,7 @@ namespace nil { polynomial f_shifted(f); FieldValueType x_power = x; for (std::size_t i = 1; i < f.size(); i++) { - f_shifted[i] = f_shifted[i] * x_power; + f_shifted[i] *= x_power; x_power *= x; } @@ -74,4 +74,4 @@ namespace nil { } // namespace crypto3 } // namespace nil -#endif // CRYPTO3_ZK_PLONK_REDSHIFT_POLYNOMIAL_SHIFT_HPP \ No newline at end of file +#endif // CRYPTO3_ZK_PLONK_REDSHIFT_POLYNOMIAL_SHIFT_HPP diff --git a/crypto3/libs/math/include/nil/crypto3/math/polynomial/xgcd.hpp b/crypto3/libs/math/include/nil/crypto3/math/polynomial/xgcd.hpp old mode 100755 new mode 100644 diff --git a/crypto3/libs/math/include/nil/crypto3/math/type_traits.hpp b/crypto3/libs/math/include/nil/crypto3/math/type_traits.hpp index a5094230a3..ff9443e538 100755 --- a/crypto3/libs/math/include/nil/crypto3/math/type_traits.hpp +++ b/crypto3/libs/math/include/nil/crypto3/math/type_traits.hpp @@ -39,8 +39,6 @@ #include #include -#include - namespace nil { namespace crypto3 { namespace math { diff --git a/crypto3/libs/math/test/polynomial_dfs.cpp b/crypto3/libs/math/test/polynomial_dfs.cpp index 6d19cf6353..2f049dbd5b 100644 --- a/crypto3/libs/math/test/polynomial_dfs.cpp +++ b/crypto3/libs/math/test/polynomial_dfs.cpp @@ -1246,7 +1246,7 @@ BOOST_AUTO_TEST_CASE(polynomial_dfs_pow_eq_test) { }}; polynomial_dfs res = a; - for (int i = 1; i < 7; ++i) + for (std::size_t i = 1; i < 7; ++i) res *= a; BOOST_CHECK_EQUAL(res, a.pow(7)); @@ -1345,7 +1345,7 @@ BOOST_AUTO_TEST_CASE(polynomial_dfs_multiplication_perf_test, *boost::unit_test: poly4[i] *= poly; } - for (int i = 1; i < poly4.size(); ++i) { + for (std::size_t i = 1; i < poly4.size(); ++i) { BOOST_CHECK(poly4[i] == poly4[0]); } @@ -1360,8 +1360,8 @@ BOOST_AUTO_TEST_CASE(polynomial_dfs_multiplication_perf_test, *boost::unit_test: BOOST_AUTO_TEST_CASE(polynomial_dfs_resize_perf_test, *boost::unit_test::disabled()) { std::vector values; - size_t size = 131072 * 16; - for (int i = 0; i < size; i++) { + std::size_t size = 131072 * 16; + for (std::size_t i = 0; i < size; i++) { values.push_back(nil::crypto3::algebra::random_element()); } @@ -1369,10 +1369,9 @@ BOOST_AUTO_TEST_CASE(polynomial_dfs_resize_perf_test, *boost::unit_test::disable size - 1, values}; auto start = std::chrono::high_resolution_clock::now(); - for (int i = 0; i < 10; ++i) { + for (std::size_t i = 0; i < 10; ++i) { auto poly2 = poly; poly2.resize(8 * size); - BOOST_CHECK(poly2.size() == 8 * size); } diff --git a/crypto3/libs/zk/CMakeLists.txt b/crypto3/libs/zk/CMakeLists.txt index 2ebcef5092..a9eb134ae1 100644 --- a/crypto3/libs/zk/CMakeLists.txt +++ b/crypto3/libs/zk/CMakeLists.txt @@ -39,15 +39,18 @@ target_link_libraries(${CMAKE_WORKSPACE_NAME}_${CURRENT_PROJECT_NAME} INTERFACE Boost::container Boost::log - ${CMAKE_WORKSPACE_NAME}::algebra - ${CMAKE_WORKSPACE_NAME}::block - ${CMAKE_WORKSPACE_NAME}::math - ${CMAKE_WORKSPACE_NAME}::hash - ${CMAKE_WORKSPACE_NAME}::multiprecision + # Containers and math implementation could be replaced with namespace change ${CMAKE_WORKSPACE_NAME}::containers - ${CMAKE_WORKSPACE_NAME}::marshalling-zk - ${CMAKE_WORKSPACE_NAME}::benchmark_tools - ) + ${CMAKE_WORKSPACE_NAME}::math + + crypto3::algebra + crypto3::block + crypto3::hash + crypto3::multiprecision + crypto3::marshalling-zk + + crypto3::benchmark_tools +) cm_deploy(TARGETS ${CMAKE_WORKSPACE_NAME}_${CURRENT_PROJECT_NAME} INCLUDE include diff --git a/crypto3/libs/zk/README.md b/crypto3/libs/zk/README.md index d72cb7908f..96ff298216 100644 --- a/crypto3/libs/zk/README.md +++ b/crypto3/libs/zk/README.md @@ -1,7 +1,7 @@ # Zero-Knowledge Cryptography Schemes for =nil; Foundation's Cryptography Suite -Zero-Knowledge cryptography schemes for =nil; Foundation's cryptography suite. -SNARK-alike schemes for now. More trivial Pedersen commitment schemes, STARKs, +Zero-Knowledge cryptography schemes for =nil; Foundation's cryptography suite. +SNARK-alike schemes for now. More trivial Pedersen commitment schemes, STARKs, IOP-based SNARKs, Bulletproofs etc in future. [![Run tests](https://github.com/NilFoundation/crypto3-zk/actions/workflows/run_tests.yml/badge.svg)](https://github.com/NilFoundation/crypto3-zk/actions/workflows/run_tests.yml) diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp index 4d1e0f510b..cdf02d4d94 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp @@ -235,7 +235,7 @@ namespace nil { } // For the last round it's final_polynomial's values - + // Values for the next round. polynomial_values_type y; @@ -441,6 +441,7 @@ namespace nil { ) { PROFILE_SCOPE("Basic FRI Precommit time"); + // Resize uses low level thread pool, so we need to use the high level one here. for (std::size_t i = 0; i < poly.size(); ++i) { if (poly[i].size() != D->size()) { poly[i].resize(D->size(), nullptr, D); @@ -743,6 +744,7 @@ namespace nil { } } } + return std::move(g_coeffs); } @@ -911,6 +913,7 @@ namespace nil { return std::move(round_proofs); } + template static std::vector query_phase( @@ -957,9 +960,11 @@ namespace nil { typename FRI::query_proof_type query_proof = {std::move(initial_proof), std::move(round_proofs)}; query_proofs[query_id] = std::move(query_proof); } + return std::move(query_proofs); } + template(fri_params)); diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/lookup_argument.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/lookup_argument.hpp index ddc6d14f55..9cfc0830c3 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/lookup_argument.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/lookup_argument.hpp @@ -5,6 +5,7 @@ // Copyright (c) 2022 Alisa Cherniaeva // Copyright (c) 2023 Elena Tatuzova // Copyright (c) 2023 Martun Karapetyan +// Copyright (c) 2024 Vasiliy Olekhov // // MIT License // @@ -124,7 +125,7 @@ namespace nil { public: struct prover_lookup_result { - std::array, argument_size> F_dfs; + std::array F_dfs; typename commitment_scheme_type::commitment_type lookup_commitment; }; @@ -155,32 +156,31 @@ namespace nil { PROFILE_SCOPE("Lookup argument prove eval time"); // Construct lookup gates - math::polynomial_dfs one_polynomial( + polynomial_dfs_type one_polynomial( 0, basic_domain->m, FieldType::value_type::one()); - math::polynomial_dfs zero_polynomial( + polynomial_dfs_type zero_polynomial( 0, basic_domain->m, FieldType::value_type::zero()); - math::polynomial_dfs mask_assignment = + polynomial_dfs_type mask_assignment = one_polynomial - preprocessed_data.q_last - preprocessed_data.q_blind; - std::unique_ptr>> lookup_value_ptr = + std::unique_ptr> lookup_value_ptr = prepare_lookup_value(mask_assignment); auto& lookup_value = *lookup_value_ptr; - std::unique_ptr>> lookup_input_ptr = + std::unique_ptr> lookup_input_ptr = prepare_lookup_input(); auto& lookup_input = *lookup_input_ptr; - // 3. Lookup_input and lookup_value are ready // Now sort them! // Reduce value and input: - auto reduced_value_ptr = std::make_unique>>(); + auto reduced_value_ptr = std::make_unique>(); auto& reduced_value = *reduced_value_ptr; for( std::size_t i = 0; i < lookup_value.size(); i++ ){ reduced_value.push_back(reduce_dfs_polynomial_domain(lookup_value[i], basic_domain->m)); } - auto reduced_input_ptr = std::make_unique>>(); + auto reduced_input_ptr = std::make_unique>(); auto& reduced_input = *reduced_input_ptr; for( std::size_t i = 0; i < lookup_input.size(); i++ ){ @@ -208,7 +208,7 @@ namespace nil { lookup_alphas.push_back(transcript.template challenge()); } - math::polynomial_dfs V_L = compute_V_L( + polynomial_dfs_type V_L = compute_V_L( sorted, reduced_input, reduced_value, beta, gamma); // We don't use reduced_input and reduced_value after this line. @@ -221,18 +221,18 @@ namespace nil { BOOST_ASSERT(std::accumulate(part_sizes.begin(), part_sizes.end(), 0) == sorted.size()); // Compute gs and hs products for each part - std::vector> gs = compute_gs( + std::vector gs = compute_gs( std::move(lookup_input_ptr), std::move(lookup_value_ptr), beta, gamma, part_sizes ); - std::vector> hs = compute_hs( + std::vector hs = compute_hs( sorted, beta, gamma, part_sizes ); - math::polynomial_dfs V_L_shifted = + polynomial_dfs_type V_L_shifted = math::polynomial_shift(V_L, 1, basic_domain->m); - std::array, argument_size> F_dfs; + std::array F_dfs; F_dfs[0] = preprocessed_data.common_data.lagrange_0 * (one_polynomial - V_L); F_dfs[1] = preprocessed_data.q_last * ( V_L * V_L - V_L ); @@ -247,16 +247,18 @@ namespace nil { g *= V_L; h *= V_L_shifted; g -= h; - h = math::polynomial_dfs(); // just clean the memory of h. + h = polynomial_dfs_type(); // just clean the memory of h. g *= (preprocessed_data.q_last + preprocessed_data.q_blind) - one_polynomial; F_dfs[2] = std::move(g); } else { - math::polynomial_dfs current_poly = V_L; - math::polynomial_dfs previous_poly = V_L; - std::vector> parts; + std::vector parts; BOOST_ASSERT(part_sizes.size() == gs.size()); BOOST_ASSERT(part_sizes.size() == hs.size()); BOOST_ASSERT(part_sizes.size() == lookup_alphas.size() + 1); + + polynomial_dfs_type current_poly = V_L; + polynomial_dfs_type previous_poly = V_L; + for( std::size_t i = 0; i < lookup_alphas.size(); i ++ ){ auto &g = gs[i]; auto &h = hs[i]; @@ -279,13 +281,20 @@ namespace nil { F_dfs[3] = zero_polynomial; - std::vector> F_dfs_3_parts(std::next(sorted.begin(), 1), sorted.end()); + std::vector alpha_challenges(sorted.size() - 1); + for (std::size_t i = 0; i < sorted.size() - 1; ++i) { + alpha_challenges[i] = transcript.template challenge(); + } + + std::vector F_dfs_3_parts(std::next(sorted.begin(), 1), sorted.end()); for (std::size_t i = 0; i < F_dfs_3_parts.size(); i++) { - typename FieldType::value_type alpha = transcript.template challenge(); - math::polynomial_dfs sorted_shifted = math::polynomial_shift(sorted[i], preprocessed_data.common_data.desc.usable_rows_amount , basic_domain->m); + polynomial_dfs_type sorted_shifted = math::polynomial_shift( + sorted[i], preprocessed_data.common_data.desc.usable_rows_amount, + basic_domain->m); F_dfs_3_parts[i] -= sorted_shifted; - F_dfs_3_parts[i] *= alpha * preprocessed_data.common_data.lagrange_0; + F_dfs_3_parts[i] *= alpha_challenges[i] * preprocessed_data.common_data.lagrange_0; } + F_dfs[3] = polynomial_sum(std::move(F_dfs_3_parts)); return { @@ -294,29 +303,31 @@ namespace nil { }; } - std::vector> compute_gs( - std::unique_ptr>> lookup_input_ptr, - std::unique_ptr>> lookup_value_ptr, + std::vector compute_gs( + std::unique_ptr> lookup_input_ptr, + std::unique_ptr> lookup_value_ptr, const typename FieldType::value_type& beta, const typename FieldType::value_type& gamma, - std::vector lookup_part_sizes + const std::vector& lookup_part_sizes ) { - std::vector> result; + PROFILE_SCOPE("Lookup argument compute_gs"); + + std::vector result; auto& lookup_value = *lookup_value_ptr; auto& lookup_input = *lookup_input_ptr; - auto g = math::polynomial_dfs::one(); + auto g = polynomial_dfs_type::one(); auto one = FieldType::value_type::one(); std::size_t current_part = 0; - std::vector> g_multipliers; + std::vector g_multipliers; for (std::size_t i = 0; i < lookup_input.size(); i++) { g_multipliers.push_back((one + beta) * (gamma + lookup_input[i])); if( g_multipliers.size() == lookup_part_sizes[current_part] ){ g *= math::polynomial_product(std::move(g_multipliers)); result.push_back(g); g_multipliers.clear(); - g = math::polynomial_dfs::one(); + g = polynomial_dfs_type::one(); current_part++; } } @@ -333,7 +344,7 @@ namespace nil { result.push_back(g); g_multipliers.clear(); g.clear(); - g = math::polynomial_dfs::one(); + g = polynomial_dfs_type::one(); current_part++; } } @@ -344,17 +355,20 @@ namespace nil { return std::move(result); } - std::vector> compute_hs( - const std::vector>& sorted, + std::vector compute_hs( + const std::vector& sorted, const typename FieldType::value_type& beta, const typename FieldType::value_type& gamma, const std::vector &lookup_part_sizes ) { + PROFILE_SCOPE("Lookup argument compute_hs"); + auto one = FieldType::value_type::one(); - std::vector> result; - std::vector> h_multipliers; - math::polynomial_dfs h = math::polynomial_dfs::one(); + std::vector result; + + std::vector h_multipliers; + polynomial_dfs_type h = polynomial_dfs_type::one(); std::size_t current_part = 0; for (std::size_t i = 0; i < sorted.size(); i++) { @@ -365,23 +379,25 @@ namespace nil { result.push_back(h); h_multipliers.clear(); h.clear(); - h = math::polynomial_dfs::one(); + h = polynomial_dfs_type::one(); current_part++; } } BOOST_ASSERT(h_multipliers.size() == 0); + return std::move(result); } - math::polynomial_dfs compute_V_L( - const std::vector>& sorted, - const std::vector>& reduced_input, - const std::vector>& reduced_value, + polynomial_dfs_type compute_V_L( + const std::vector& sorted, + const std::vector& reduced_input, + const std::vector& reduced_value, const typename FieldType::value_type& beta, const typename FieldType::value_type& gamma) { + PROFILE_SCOPE("Lookup argument compute poly V_L"); - math::polynomial_dfs V_L( - basic_domain->m-1,basic_domain->m, FieldType::value_type::zero()); + polynomial_dfs_type V_L( + basic_domain->m - 1, basic_domain->m, FieldType::value_type::zero()); V_L[0] = FieldType::value_type::one(); auto one = FieldType::value_type::one(); @@ -406,23 +422,26 @@ namespace nil { } V_L[k] *= h_tmp.inversed(); } + return V_L; } - std::unique_ptr>> prepare_lookup_value( - const math::polynomial_dfs& mask_assignment) { + std::unique_ptr> prepare_lookup_value( + const polynomial_dfs_type& mask_assignment) { + PROFILE_SCOPE("Lookup argument preparing lookup value"); + typename FieldType::value_type theta_acc; // Prepare lookup value - auto lookup_value_ptr = std::make_unique>>(); + auto lookup_value_ptr = std::make_unique>(); for (std::size_t t_id = 0; t_id < lookup_tables.size(); t_id++) { const plonk_lookup_table &l_table = lookup_tables[t_id]; - const math::polynomial_dfs &lookup_tag = plonk_columns.selector(l_table.tag_index); + const polynomial_dfs_type &lookup_tag = plonk_columns.selector(l_table.tag_index); for (std::size_t o_id = 0; o_id < l_table.lookup_options.size(); o_id++) { - math::polynomial_dfs v = (typename FieldType::value_type(t_id + 1)) * lookup_tag; + polynomial_dfs_type v = (typename FieldType::value_type(t_id + 1)) * lookup_tag; theta_acc = theta; for (std::size_t i = 0; i < l_table.columns_number; i++) { - math::polynomial_dfs c; + polynomial_dfs_type c; c = plonk_columns.get_variable_value_without_rotation(l_table.lookup_options[o_id][i]); v += theta_acc * lookup_tag * c; theta_acc *= theta; @@ -434,7 +453,8 @@ namespace nil { return std::move(lookup_value_ptr); } - std::unique_ptr>> prepare_lookup_input() { + std::unique_ptr> prepare_lookup_input() { + PROFILE_SCOPE("Lookup argument preparing lookup input"); auto value_type_to_polynomial_dfs = []( const typename VariableType::assignment_type& coeff) { @@ -447,12 +467,12 @@ namespace nil { typename FieldType::value_type theta_acc; // Prepare lookup input - auto lookup_input_ptr = std::make_unique>>(); + auto lookup_input_ptr = std::make_unique>(); for (const auto &gate : lookup_gates) { math::expression expr; - math::polynomial_dfs lookup_selector = plonk_columns.selector(gate.tag_index); + polynomial_dfs_type lookup_selector = plonk_columns.selector(gate.tag_index); for (const auto &constraint : gate.constraints) { - math::polynomial_dfs l = lookup_selector * (typename FieldType::value_type(constraint.table_id)); + polynomial_dfs_type l = lookup_selector * (typename FieldType::value_type(constraint.table_id)); theta_acc = theta; for(std::size_t k = 0; k < constraint.lookup_input.size(); k++){ expr = converter.convert(constraint.lookup_input[k]); @@ -491,11 +511,11 @@ namespace nil { private: - math::polynomial_dfs reduce_dfs_polynomial_domain( - const math::polynomial_dfs &polynomial, + polynomial_dfs_type reduce_dfs_polynomial_domain( + const polynomial_dfs_type &polynomial, const std::size_t &new_domain_size ) { - math::polynomial_dfs reduced( + polynomial_dfs_type reduced( new_domain_size - 1, new_domain_size, FieldType::value_type::zero()); BOOST_ASSERT(new_domain_size <= polynomial.size()); @@ -512,13 +532,13 @@ namespace nil { return reduced; }; - math::polynomial_dfs get_constraint_tag_from_gate_tag_column( - math::polynomial_dfs tag_column, + polynomial_dfs_type get_constraint_tag_from_gate_tag_column( + polynomial_dfs_type tag_column, std::size_t constraints_num, std::size_t constraint_id, std::size_t table_id ){ - math::polynomial_dfs result = tag_column; + polynomial_dfs_type result = tag_column; for (std::size_t i = 1; i <= constraints_num; i++) { if (i != constraint_id) { auto tmp = tag_column - typename FieldType::value_type(i); @@ -557,12 +577,14 @@ namespace nil { // similar values only with negligible probability. // So similar values in compressed lookup tables vectors repeated values may be only in one column // near each other. - std::vector> sort_polynomials( - const std::vector>& reduced_input, - const std::vector>& reduced_value, + std::vector sort_polynomials( + const std::vector& reduced_input, + const std::vector& reduced_value, std::size_t domain_size, std::size_t usable_rows_amount ) { + PROFILE_SCOPE("Sort Polynomials"); + // Build sorting map std::unordered_map sorting_map; for (std::size_t i = 0; i < reduced_value.size(); i++) { @@ -582,9 +604,9 @@ namespace nil { } } - math::polynomial_dfs zero_poly( + polynomial_dfs_type zero_poly( domain_size-1, domain_size, FieldType::value_type::zero()); - std::vector> sorted( + std::vector sorted( reduced_input.size() + reduced_value.size(), zero_poly ); std::size_t i1 = 0; diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp index 0a46ee832e..ed3ee9b5da 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp @@ -73,6 +73,7 @@ namespace nil { typename FieldType::value_type challenge, bool _is_lookup_enabled ) { + PROFILE_SCOPE("evaluation_points_generated_time"); const std::size_t witness_columns = table_description.witness_columns; const std::size_t public_input_columns = table_description.public_input_columns; @@ -119,7 +120,7 @@ namespace nil { std::size_t i = 0; std::size_t start_index = common_data.permuted_columns.size() * 2 + 2; - for( i = 0; i < start_index; i++) { + for (i = 0; i < start_index; i++) { _commitment_scheme.append_eval_point(FIXED_VALUES_BATCH, i, challenge); } @@ -426,7 +427,7 @@ namespace nil { // Z is polynomial -1, 0 ...., 0, 1 typename FieldType::value_type Z_at_challenge = common_data.Z.evaluate(challenge); if (F_consolidated != Z_at_challenge * T_consolidated) { - BOOST_LOG_TRIVIAL(info) << "Verification failed because: F consoludated polynomial does not match."; + BOOST_LOG_TRIVIAL(info) << "Verification failed because: F consolidated polynomial does not match."; return false; } return true; diff --git a/crypto3/libs/zk/test/CMakeLists.txt b/crypto3/libs/zk/test/CMakeLists.txt index b5a4aff45e..4173028d7f 100644 --- a/crypto3/libs/zk/test/CMakeLists.txt +++ b/crypto3/libs/zk/test/CMakeLists.txt @@ -107,6 +107,4 @@ foreach(TEST_NAME ${TESTS_NAMES}) define_zk_test(${TEST_NAME}) endforeach() -# string(CONCAT TEST_DATA ${CMAKE_CURRENT_SOURCE_DIR} "/systems/plonk/pickles/data/kimchi") -# target_compile_definitions(crypto3_zk_systems_plonk_pickles_kimchi_test PRIVATE TEST_DATA="${TEST_DATA}") diff --git a/crypto3/libs/zk/test/commitment/lpc_performance.cpp b/crypto3/libs/zk/test/commitment/lpc_performance.cpp deleted file mode 100644 index 2216ad4ce7..0000000000 --- a/crypto3/libs/zk/test/commitment/lpc_performance.cpp +++ /dev/null @@ -1,390 +0,0 @@ -//---------------------------------------------------------------------------// -// Copyright (c) 2021 Mikhail Komarov -// Copyright (c) 2021 Nikita Kaskov -// Copyright (c) 2022 Ilia Shirobokov -// -// MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -//---------------------------------------------------------------------------// - -#define BOOST_TEST_MODULE lpc_test - -// Do it manually for all performance tests -#define PROFILING_ENABLED - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include - -using namespace nil::crypto3; -using namespace nil::crypto3::zk::snark; - -namespace boost { - namespace test_tools { - namespace tt_detail { - template<> - struct print_log_value>>>> { - void operator()(std::ostream &, - const nil::crypto3::math::polynomial> - - >> &) { - } - }; -} // namespace tt_detail -} // namespace test_tools -} // namespace boost - -template -std::vector> generate(NumberType degree) { - typedef boost::random::independent_bits_engine - random_polynomial_generator_type; - - std::vector> res; - - boost::random::random_device rd; // Will be used to obtain a seed for the random number engine - boost::random::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd() - boost::random::uniform_int_distribution<> distrib(std::numeric_limits::min(), std::numeric_limits::max()); - - random_polynomial_generator_type polynomial_element_gen; - std::size_t height = 1; - res.reserve(height); - - for (int i = 0; i < height; i++) { - math::polynomial poly; - for (int j = 0; j < degree; j++) { - poly.push_back(typename FieldType::value_type(polynomial_element_gen())); - } - res.push_back(poly); - } - - return res; -} - -inline std::vector generate_random_step_list(const std::size_t r, const int max_step) { - using dist_type = std::uniform_int_distribution; - static std::random_device random_engine; - - std::vector step_list; - std::size_t steps_sum = 0; - while (steps_sum != r) { - if (r - steps_sum <= max_step) { - while (r - steps_sum != 1) { - step_list.emplace_back(r - steps_sum - 1); - steps_sum += step_list.back(); - } - step_list.emplace_back(1); - steps_sum += step_list.back(); - } else { - step_list.emplace_back(dist_type(1, max_step)(random_engine)); - steps_sum += step_list.back(); - } - } - return step_list; -} - -BOOST_AUTO_TEST_SUITE(lpc_performance_test_suite) - -// TODO(martun): move this to bench folder. -BOOST_AUTO_TEST_CASE(step_list_1, *boost::unit_test::disabled()) { - PROFILE_SCOPE("LPC step list 1 test"); - typedef algebra::curves::bls12<381> curve_type; - typedef typename curve_type::scalar_field_type FieldType; - - typedef hashes::keccak_1600<256> merkle_hash_type; - typedef hashes::keccak_1600<256> transcript_hash_type; - - constexpr static const std::size_t lambda = 40; - constexpr static const std::size_t k = 1; - - // It's important parameter - constexpr static const std::size_t d = 1 << 24; - constexpr static const std::size_t r = boost::static_log2<(d - k)>::value; - - constexpr static const std::size_t m = 2; - - typedef zk::commitments::fri fri_type; - typedef zk::commitments::list_polynomial_commitment_params lpc_params_type; - typedef zk::commitments::list_polynomial_commitment lpc_type; - - // Setup params - std::size_t degree_log = std::ceil(std::log2(d - 1)); - typename fri_type::params_type fri_params( - 1, /*max_step*/ - degree_log, - lambda, - 4, //expand_factor - ); - - using lpc_scheme_type = nil::crypto3::zk::commitments::lpc_commitment_scheme>; - lpc_scheme_type lpc_scheme_prover(fri_params); - lpc_scheme_type lpc_scheme_verifier(fri_params); - - typedef boost::random::independent_bits_engine< - boost::random::mt19937, FieldType::modulus_bits, - typename FieldType::value_type::integral_type - > random_polynomial_generator_type; - - std::vector> res; - - // Generate polys - boost::random::random_device rd; // Will be used to obtain a seed for the random number engine - boost::random::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd() - boost::random::uniform_int_distribution<> distrib(std::numeric_limits::min(), - std::numeric_limits::max()); - - random_polynomial_generator_type polynomial_element_gen; - std::size_t height = 1; - res.reserve(height); - - for (int i = 0; i < height; i++) { - math::polynomial poly(fri_params.max_degree + 1); - for (int j = 0; j < fri_params.max_degree + 1; j++) { - poly[i] = typename FieldType::value_type(polynomial_element_gen()); - } - - std::map commitments; - { - PROFILE_SCOPE("polynomial commitment"); - lpc_scheme_prover.append_to_batch(0, poly); - commitments[0] = lpc_scheme_prover.commit(0); - } - - - typename lpc_scheme_type::proof_type proof; - std::array x_data{}; - { - PROFILE_SCOPE("proof generation"); - lpc_scheme_prover.append_eval_point(0, - algebra::fields::arithmetic_params::multiplicative_generator); - zk::transcript::fiat_shamir_heuristic_sequential transcript(x_data); - proof = lpc_scheme_prover.proof_eval(transcript); - } - - { - PROFILE_SCOPE("verification"); - zk::transcript::fiat_shamir_heuristic_sequential transcript_verifier(x_data); - lpc_scheme_verifier.set_batch_size(0, proof.z.get_batch_size(0)); - - lpc_scheme_verifier.append_eval_point(0, - algebra::fields::arithmetic_params::multiplicative_generator); - BOOST_CHECK(lpc_scheme_verifier.verify_eval(proof, commitments, transcript_verifier)); - } - } -} - -BOOST_AUTO_TEST_CASE(step_list_3, *boost::unit_test::disabled()) { - PROFILE_SCOPE("LPC step list 3 test"); - typedef algebra::curves::bls12<381> curve_type; - typedef typename curve_type::scalar_field_type FieldType; - - typedef hashes::keccak_1600<256> merkle_hash_type; - typedef hashes::keccak_1600<256> transcript_hash_type; - - constexpr static const std::size_t lambda = 40; - constexpr static const std::size_t k = 1; - - // It's important parameter - constexpr static const std::size_t d = 1 << 24; - - constexpr static const std::size_t r = boost::static_log2<(d - k)>::value; - constexpr static const std::size_t m = 2; - - typedef zk::commitments::fri fri_type; - typedef zk::commitments::list_polynomial_commitment_params lpc_params_type; - typedef zk::commitments::list_polynomial_commitment lpc_type; - - // Setup params - std::size_t degree_log = std::ceil(std::log2(d - 1)); - typename fri_type::params_type fri_params( - 3, /*max_step*/ - degree_log, - lambda, - 4, //expand_factor - ); - - using lpc_scheme_type = nil::crypto3::zk::commitments::lpc_commitment_scheme>; - lpc_scheme_type lpc_scheme_prover(fri_params); - lpc_scheme_type lpc_scheme_verifier(fri_params); - - typedef boost::random::independent_bits_engine< - boost::random::mt19937, FieldType::modulus_bits, - typename FieldType::value_type::integral_type - > random_polynomial_generator_type; - - std::vector> res; - - // Generate polys - boost::random::random_device rd; // Will be used to obtain a seed for the random number engine - boost::random::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd() - boost::random::uniform_int_distribution<> distrib(std::numeric_limits::min(), - std::numeric_limits::max()); - - random_polynomial_generator_type polynomial_element_gen; - std::size_t height = 1; - res.reserve(height); - - for (int i = 0; i < height; i++) { - math::polynomial poly(fri_params.max_degree + 1); - for (int j = 0; j < fri_params.max_degree + 1; j++) { - poly[i] = typename FieldType::value_type(polynomial_element_gen()); - } - - std::map commitments; - { - PROFILE_SCOPE("polynomial commitment"); - lpc_scheme_prover.append_to_batch(0, poly); - commitments[0] = lpc_scheme_prover.commit(0); - } - - - typename lpc_scheme_type::proof_type proof; - std::array x_data{}; - { - PROFILE_SCOPE("proof generation"); - lpc_scheme_prover.append_eval_point(0, - algebra::fields::arithmetic_params::multiplicative_generator); - zk::transcript::fiat_shamir_heuristic_sequential transcript(x_data); - proof = lpc_scheme_prover.proof_eval(transcript); - } - - { - PROFILE_SCOPE("verification"); - zk::transcript::fiat_shamir_heuristic_sequential transcript_verifier(x_data); - lpc_scheme_verifier.set_batch_size(0, proof.z.get_batch_size(0)); - - lpc_scheme_verifier.append_eval_point(0, - algebra::fields::arithmetic_params::multiplicative_generator); - BOOST_CHECK(lpc_scheme_verifier.verify_eval(proof, commitments, transcript_verifier)); - } - } -} - -BOOST_AUTO_TEST_CASE(step_list_5, *boost::unit_test::disabled()) { - PROFILE_SCOPE("LPC step list 5 test"); - typedef algebra::curves::bls12<381> curve_type; - typedef typename curve_type::scalar_field_type FieldType; - - typedef hashes::keccak_1600<256> merkle_hash_type; - typedef hashes::keccak_1600<256> transcript_hash_type; - - constexpr static const std::size_t lambda = 40; - constexpr static const std::size_t k = 1; - - // It's important parameter - constexpr static const std::size_t d = 1 << 24; - constexpr static const std::size_t m = 2; - constexpr static const std::size_t r = boost::static_log2<(d - k)>::value; - - typedef zk::commitments::fri fri_type; - typedef zk::commitments::list_polynomial_commitment_params lpc_params_type; - typedef zk::commitments::list_polynomial_commitment lpc_type; - - // Setup params - std::size_t degree_log = std::ceil(std::log2(d - 1)); - typename fri_type::params_type fri_params( - 5, /*max_step*/ - degree_log, - lambda, - 4, //expand_factor - ); - - using lpc_scheme_type = nil::crypto3::zk::commitments::lpc_commitment_scheme>; - lpc_scheme_type lpc_scheme_prover(fri_params); - lpc_scheme_type lpc_scheme_verifier(fri_params); - - typedef boost::random::independent_bits_engine< - boost::random::mt19937, FieldType::modulus_bits, - typename FieldType::value_type::integral_type - > random_polynomial_generator_type; - - std::vector> res; - - // Generate polys - boost::random::random_device rd; // Will be used to obtain a seed for the random number engine - boost::random::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd() - boost::random::uniform_int_distribution<> distrib(std::numeric_limits::min(), - std::numeric_limits::max()); - - random_polynomial_generator_type polynomial_element_gen; - std::size_t height = 1; - res.reserve(height); - - for (int i = 0; i < height; i++) { - math::polynomial poly(fri_params.max_degree + 1); - for (int j = 0; j < fri_params.max_degree + 1; j++) { - poly[i] = typename FieldType::value_type(polynomial_element_gen()); - } - - std::map commitments; - { - PROFILE_SCOPE("polynomial commitment"); - lpc_scheme_prover.append_to_batch(0, poly); - commitments[0] = lpc_scheme_prover.commit(0); - } - - - typename lpc_scheme_type::proof_type proof; - std::array x_data{}; - { - PROFILE_SCOPE("proof generation"); - lpc_scheme_prover.append_eval_point(0, - algebra::fields::arithmetic_params::multiplicative_generator); - zk::transcript::fiat_shamir_heuristic_sequential transcript(x_data); - proof = lpc_scheme_prover.proof_eval(transcript); - } - - { - PROFILE_SCOPE("verification"); - zk::transcript::fiat_shamir_heuristic_sequential transcript_verifier(x_data); - lpc_scheme_verifier.set_batch_size(0, proof.z.get_batch_size(0)); - - lpc_scheme_verifier.append_eval_point(0, - algebra::fields::arithmetic_params::multiplicative_generator); - BOOST_CHECK(lpc_scheme_verifier.verify_eval(proof, commitments, transcript_verifier)); - } - } -} - -BOOST_AUTO_TEST_SUITE_END() diff --git a/crypto3/libs/zk/test/commitment/proof_of_work.cpp b/crypto3/libs/zk/test/commitment/proof_of_work.cpp index 66825f2a97..3c7d02df10 100644 --- a/crypto3/libs/zk/test/commitment/proof_of_work.cpp +++ b/crypto3/libs/zk/test/commitment/proof_of_work.cpp @@ -73,10 +73,10 @@ BOOST_AUTO_TEST_SUITE(proof_of_knowledge_test_suite) BOOST_AUTO_TEST_CASE(pow_basic_test) { using keccak = nil::crypto3::hashes::keccak_1600<512>; - const std::uint32_t grinding_bits = 20; - const uint64_t expected_mask = (1ULL << grinding_bits) - 1; + const std::uint64_t grinding_bits = 16; + const uint64_t expected_mask = (1ull << grinding_bits) - 1; - using pow_type = nil::crypto3::zk::commitments::proof_of_work; + using pow_type = nil::crypto3::zk::commitments::proof_of_work; nil::crypto3::zk::transcript::fiat_shamir_heuristic_sequential transcript; auto old_transcript_1 = transcript, old_transcript_2 = transcript; @@ -85,7 +85,8 @@ BOOST_AUTO_TEST_SUITE(proof_of_knowledge_test_suite) BOOST_ASSERT(pow_type::verify(old_transcript_1, result, grinding_bits)); // manually reimplement verify to ensure that changes in implementation didn't break it - old_transcript_2(pow_type::to_byte_array(result)); + auto bytes = pow_type::to_byte_array(result); + old_transcript_2(bytes); auto chal = old_transcript_2.template int_challenge(); BOOST_ASSERT( (chal & expected_mask) == 0); diff --git a/crypto3/libs/zk/test/math/expression.cpp b/crypto3/libs/zk/test/math/expression.cpp index 6d337a6860..699e87ed9a 100644 --- a/crypto3/libs/zk/test/math/expression.cpp +++ b/crypto3/libs/zk/test/math/expression.cpp @@ -81,7 +81,7 @@ BOOST_AUTO_TEST_CASE(expression_evaluation_test) { variable_type w3(6, 2, variable_type::column_type::constant); expression expr = (w0 + w1) * (w2 + w3); - + variable_type::assignment_type w0_value(1u); variable_type::assignment_type w1_value(2u); variable_type::assignment_type w2_value(3u); @@ -115,7 +115,7 @@ BOOST_AUTO_TEST_CASE(expression_max_degree_visitor_test) { variable_type w3(6, 2, variable_type::column_type::constant); expression expr = (w0 + w1) * (w2 + w3) + w0 * w1 * (w2 + w3); - + expression_max_degree_visitor visitor; BOOST_CHECK_EQUAL(visitor.compute_max_degree(expr), 3); @@ -134,7 +134,7 @@ BOOST_AUTO_TEST_CASE(expression_for_each_variable_visitor_test) { variable_type w3(6, 2, variable_type::column_type::constant); expression expr = (w0 + w1) * (w2 + w3) + w0 * w1 * (w2 + w3); - + std::set variable_indices; std::set variable_rotations; diff --git a/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_gate_argument.cpp b/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_gate_argument.cpp index f7eb1a23db..e6d00985ef 100644 --- a/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_gate_argument.cpp +++ b/crypto3/libs/zk/test/systems/plonk/placeholder/placeholder_gate_argument.cpp @@ -36,6 +36,7 @@ #include #include +#include #include #include From 8eac8219f846db6448e035881b7ef952073b3c1c Mon Sep 17 00:00:00 2001 From: Martun Karapetyan Date: Wed, 11 Sep 2024 11:48:41 +0400 Subject: [PATCH 3/5] Dividing LPC and FRI into stages and creating structures for aggregated FRI. --- .../detail/polynomial/basic_fri.hpp | 232 ++++++++++++++---- .../crypto3/zk/commitments/polynomial/lpc.hpp | 211 ++++++++++++++-- .../snark/systems/plonk/placeholder/proof.hpp | 70 +++++- .../nil/crypto3/zk/transcript/fiat_shamir.hpp | 22 ++ crypto3/libs/zk/test/commitment/fri.cpp | 3 + 5 files changed, 453 insertions(+), 85 deletions(-) diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp index cdf02d4d94..a32ef505ec 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp @@ -268,7 +268,61 @@ namespace nil { std::vector round_proofs; }; + struct commitments_part_of_proof { + bool operator==(const commitments_part_of_proof& rhs) const { + return fri_roots == rhs.fri_roots && + final_polynomial == rhs.final_polynomial; + } + + bool operator!=(const commitments_part_of_proof& rhs) const { + return !(rhs == *this); + } + + // Vector of size 'step_list.size()'. + std::vector fri_roots; + math::polynomial final_polynomial; + }; + + struct round_proofs_batch_type { + bool operator==(const round_proofs_batch_type &rhs) const { + return round_proofs == rhs.round_proofs; + } + + bool operator!=(const round_proofs_batch_type &rhs) const { + return !(rhs == *this); + } + + // Vector of size 'lambda'. + std::vector> round_proofs; + }; + + struct initial_proofs_batch_type { + bool operator==(const initial_proofs_batch_type &rhs) const { + return initial_proofs == rhs.initial_proofs; + } + + bool operator!=(const initial_proofs_batch_type &rhs) const { + return !(rhs == *this); + } + + // Vector of size 'lambda'. + std::vector> initial_proofs; + }; + struct proof_type { + proof_type() = default; + proof_type(const proof_type&) = default; + + proof_type(const round_proofs_batch_type& round_proofs, + const initial_proofs_batch_type& intial_proofs) + : fri_roots(round_proofs.fri_roots) + , final_polynomial(round_proofs.final_polynomial) { + for (std::size_t i = 0; i < intial_proofs.initial_proofs.size(); ++i) { + query_proofs.emplace_back( + {intial_proofs.initial_proofs[i], round_proofs.round_proofs[i]}); + } + } + bool operator==(const proof_type &rhs) const { // TODO(martun): check if the following comment can be deleted. // if( FRI::use_grinding && proof_of_work != rhs.proof_of_work ){ @@ -355,13 +409,13 @@ namespace nil { FRI>::value, bool>::type = true> static typename FRI::precommitment_type - precommit(math::polynomial_dfs &f, + precommit(const math::polynomial_dfs &f, std::shared_ptr> D, const std::size_t fri_step) { - if (f.size() != D->size()) { - f.resize(D->size(), nullptr, D); + throw std::runtime_error("Polynomial size does not match the domain size in FRI precommit."); } + std::size_t domain_size = D->size(); std::size_t coset_size = 1 << fri_step; std::size_t leafs_number = domain_size / coset_size; @@ -420,6 +474,10 @@ namespace nil { math::polynomial_dfs f_dfs; f_dfs.from_coefficients(f); + if (f_dfs.size() != D->size()) { + f_dfs.resize(D->size(), nullptr, D); + } + return precommit(f_dfs, D, fri_step); } @@ -660,12 +718,10 @@ namespace nil { static std::tuple< std::vector, std::vector, - std::vector, - math::polynomial + typename FRI::commitments_part_of_proof > commit_phase( const PolynomialType& combined_Q, - const std::map &precommitments, const typename FRI::precommitment_type &combined_Q_precommitment, const typename FRI::params_type &fri_params, typename FRI::transcript_type &transcript) @@ -673,8 +729,7 @@ namespace nil { PROFILE_SCOPE("Basic FRI commit phase"); std::vector fs; std::vector fri_trees; - std::vector fri_roots; - math::polynomial final_polynomial; + typename FRI::commitments_part_of_proof commitments_proof; auto f = combined_Q; auto precommitment = combined_Q_precommitment; @@ -683,7 +738,7 @@ namespace nil { for (std::size_t i = 0; i < fri_params.step_list.size(); i++) { fs.push_back(f); fri_trees.push_back(precommitment); - fri_roots.push_back(commit(precommitment)); + commitments_proof.fri_roots.push_back(commit(precommitment)); transcript(commit(precommitment)); for (std::size_t step_i = 0; step_i < fri_params.step_list[i]; ++step_i, ++t) { typename FRI::field_type::value_type alpha = transcript.template challenge(); @@ -696,17 +751,25 @@ namespace nil { f = commitments::detail::fold_polynomial(f, alpha); } } - if (i != fri_params.step_list.size() - 1) - precommitment = precommit(f, fri_params.D[t], fri_params.step_list[i + 1]); + if (i != fri_params.step_list.size() - 1) { + const auto& D = fri_params.D[t]; + if constexpr (std::is_same, + PolynomialType>::value) { + if (f.size() != D->size()) { + f.resize(D->size(), nullptr, D); + } + } + precommitment = precommit(f, D, fri_params.step_list[i + 1]); + } } fs.push_back(f); if constexpr (std::is_same, PolynomialType>::value) { - final_polynomial = math::polynomial(f.coefficients()); + commitments_proof.final_polynomial = math::polynomial(f.coefficients()); } else { - final_polynomial = f; + commitments_proof.final_polynomial = f; } - return std::make_tuple(fs, fri_trees, fri_roots, final_polynomial); + return std::make_tuple(fs, fri_trees, commitments_proof); } /** @brief Convert a set of polynomials from DFS form into coefficients form */ @@ -840,11 +903,6 @@ namespace nil { static std::vector build_round_proofs( const typename FRI::params_type &fri_params, - const std::map> &g, - const std::map< - std::size_t, - std::vector> - > &g_coeffs, const std::vector &fri_trees, const std::vector &fs, const math::polynomial &final_polynomial, @@ -915,18 +973,44 @@ namespace nil { template - static std::vector - query_phase( - const std::map &precommitments, + static typename FRI::round_proofs_batch_type query_phase_round_proofs( const typename FRI::params_type &fri_params, - typename FRI::transcript_type &transcript, - const std::map> &g, const std::vector &fri_trees, const std::vector &fs, - const math::polynomial &final_polynomial) + const math::polynomial &final_polynomial, + const std::vector& challenges) { - PROFILE_SCOPE("Basic FRI query phase"); - std::vector query_proofs(fri_params.lambda); + typename FRI::round_proofs_batch_type proof; + + for (std::size_t query_id = 0; query_id < fri_params.lambda; query_id++) { + std::size_t domain_size = fri_params.D[0]->size(); + typename FRI::field_type::value_type x = challenges[query_id]; + x = x.pow((FRI::field_type::modulus - 1) / domain_size); + + std::uint64_t x_index = 0; + + while (fri_params.D[0]->get_domain_element(x_index) != x) { + ++x_index; + } + + // Fill round proofs + std::vector round_proofs = + build_round_proofs( + fri_params, fri_trees, fs, final_polynomial, x_index); + + proof.round_proofs.emplace_back(std::move(round_proofs)); + } + return proof; + } + + template + static typename FRI::initial_proofs_batch_type query_phase_initial_proofs( + const std::map &precommitments, + const typename FRI::params_type &fri_params, + const std::map> &g, + const std::vector& challenges) + { + typename FRI::initial_proofs_batch_type proof; // If we have DFS polynomials, and we are going to resize them, better convert them to coefficients form, // and compute their values in those 2 * FRI::lambda points each, which is normally 2 * 20. @@ -937,8 +1021,8 @@ namespace nil { for (std::size_t query_id = 0; query_id < fri_params.lambda; query_id++) { std::size_t domain_size = fri_params.D[0]->size(); - typename FRI::field_type::value_type x = transcript.template challenge(); - x = x.pow((FRI::field_type::modulus - 1)/domain_size); + typename FRI::field_type::value_type x = challenges[query_id]; + x = x.pow((FRI::field_type::modulus - 1) / domain_size); std::uint64_t x_index = 0; @@ -946,34 +1030,74 @@ namespace nil { ++x_index; } - // Initial proof std::map initial_proof = build_initial_proof( precommitments, fri_params, g, g_coeffs, x_index); - // Fill round proofs - std::vector - round_proofs = build_round_proofs( - fri_params, g, g_coeffs, fri_trees, fs, final_polynomial, x_index); + proof.initial_proofs.emplace_back(std::move(initial_proof)); + } + return proof; + } + + template + static std::vector + query_phase_with_challenges( + const std::map &precommitments, + const typename FRI::params_type &fri_params, + const std::vector& challenges, + const std::map> &g, + const std::vector &fri_trees, + const std::vector &fs, + const math::polynomial &final_polynomial) + { + typename FRI::initial_proofs_batch_type initial_proofs = + query_phase_initial_proofs( + precommitments, fri_params, g, challenges); + + typename FRI::round_proofs_batch_type round_proofs = + query_phase_round_proofs( + fri_params, fri_trees, fs, final_polynomial, challenges); + + // Join intial proofs and round proofs into a structure of query proofs. + std::vector query_proofs(fri_params.lambda); - typename FRI::query_proof_type query_proof = {std::move(initial_proof), std::move(round_proofs)}; - query_proofs[query_id] = std::move(query_proof); + for (std::size_t query_id = 0; query_id < fri_params.lambda; query_id++) { + query_proofs[query_id] = {std::move(initial_proofs.initial_proofs[query_id]), + std::move(round_proofs.round_proofs[query_id])}; } + return query_proofs; + } - return std::move(query_proofs); + template + static std::vector + query_phase( + const std::map &precommitments, + const typename FRI::params_type &fri_params, + typename FRI::transcript_type &transcript, + const std::map> &g, + const std::vector &fri_trees, + const std::vector &fs, + const math::polynomial &final_polynomial) + { + PROFILE_SCOPE("Basic FRI query phase"); + std::vector challenges = + transcript.template challenges(fri_params.lambda); + + return query_phase_with_challenges( + precommitments, fri_params, challenges, g, fri_trees, fs, final_polynomial); } template, - FRI>::value, - bool>::type = true> + std::is_base_of< + commitments::detail::basic_batched_fri< + typename FRI::field_type, typename FRI::merkle_tree_hash_type, + typename FRI::transcript_hash_type, + FRI::m, typename FRI::grinding_type>, + FRI>::value, + bool>::type = true> static typename FRI::proof_type proof_eval( const std::map> &g, const PolynomialType& combined_Q, @@ -992,18 +1116,20 @@ namespace nil { // Commit phase std::vector fri_trees; - std::vector fri_roots; std::vector fs; - math::polynomial final_polynomial; + math::polynomial final_polynomial; + + // Contains fri_roots and final_polynomial. + typename FRI::commitments_part_of_proof commitments_proof; - std::tie(fs, fri_trees, fri_roots, final_polynomial) = - commit_phase( - combined_Q, precommitments, + std::tie(fs, fri_trees, commitments_proof) = + commit_phase( + combined_Q, combined_Q_precommitment, fri_params, transcript); // Grinding - if ( fri_params.use_grinding ) { + if (fri_params.use_grinding) { PROFILE_SCOPE("Basic FRI grinding phase"); proof.proof_of_work = FRI::grinding_type::generate(transcript, fri_params.grinding_parameter); } @@ -1011,10 +1137,10 @@ namespace nil { // Query phase proof.query_proofs = query_phase( precommitments, fri_params, transcript, - g, fri_trees, fs, final_polynomial); + g, fri_trees, fs, commitments_proof.final_polynomial); - proof.fri_roots = std::move(fri_roots); - proof.final_polynomial = std::move(final_polynomial); + proof.fri_roots = std::move(commitments_proof.fri_roots); + proof.final_polynomial = std::move(commitments_proof.final_polynomial); return proof; } diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp index 8b5b695d94..f93adac478 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp @@ -46,6 +46,7 @@ namespace nil { namespace commitments { // Placeholder-friendly class. + // LPCScheme is usually 'batched_list_polynomial_commitment<...>'. template> class lpc_commitment_scheme : public polys_evaluator(); preprocessed_data_type result; @@ -132,6 +136,7 @@ namespace nil { commitment_type commit(std::size_t index) { this->state_commited(index); + _trees[index] = nil::crypto3::zk::algorithms::precommit( this->_polys[index], _fri_params.D[0], _fri_params.step_list.front()); return _trees[index].root(); @@ -149,24 +154,142 @@ namespace nil { BOOST_ASSERT(this->_points.size() == this->_polys.size()); BOOST_ASSERT(this->_points.size() == this->_z.get_batches_num()); - for(auto const& it: this->_trees) { + // For each batch we have a merkle tree. + for (auto const& it: this->_trees) { transcript(it.second.root()); } // Prepare z-s and combined_Q; auto theta = transcript.template challenge(); - typename field_type::value_type theta_acc = field_type::value_type::one(); + polynomial_type combined_Q = prepare_combined_Q(theta); + + auto fri_proof = commit_and_fri_proof(combined_Q, transcript); + return proof_type({this->_z, fri_proof}); + } + + /** This function must be called for the cases where we want to skip the + * round proof for FRI. Must be called once per instance of prover for the aggregated FRI. + * \param[in] combined_Q - Polynomial combined_Q was already computed by the current + prover in the previous step of the aggregated FRI protocol. + * \param[in] transcript - This transcript is initialized from a challenge sent from the "Main" prover, + on which the round proof was created for the polynomial F(x) = Sum(combined_Q). + */ + lpc_proof_type proof_eval_lpc_proof( + const polynomial_type& combined_Q, transcript_type &transcript) { + + this->eval_polys(); + + BOOST_ASSERT(this->_points.size() == this->_polys.size()); + BOOST_ASSERT(this->_points.size() == this->_z.get_batches_num()); + + // For each batch we have a merkle tree. + for (auto const& it: this->_trees) { + transcript(it.second.root()); + } + + std::vector challenges = + transcript.template challenges(this->_fri_params.lambda); + + typename fri_type::initial_proofs_batch_type initial_proofs = + nil::crypto3::zk::algorithms::query_phase_initial_proofs( + this->_trees, this->_fri_params, this->_polys, challenges); + return {this->_z, initial_proofs}; + } + + /** This function must be called once for the aggregated FRI, to proof that polynomial + 'sum_poly' has low degree. + * \param[in] sum_poly - polynomial F(x) = Sum(combined_Q). + * \param[in] transcript - This transcript is initialized on the main prover, which has digested + challenges from all the other provers. + */ + fri_proof_type proof_eval_FRI_proof(const polynomial_type& sum_poly, transcript_type &transcript) { + // TODO(martun): this function belongs to FRI, not here, will move later. + // Precommit to sum_poly. + if (sum_poly.size() != _fri_params.D[0]->size()) { + sum_poly.resize(_fri_params.D[0]->size(), nullptr, _fri_params.D[0]); + } + precommitment_type sum_poly_precommitment = nil::crypto3::zk::algorithms::precommit( + sum_poly, + _fri_params.D[0], + _fri_params.step_list.front() + ); + + std::vector fri_trees; + std::vector fs; + math::polynomial final_polynomial; + + // Contains fri_roots and final_polynomial. + typename fri_type::commitments_part_of_proof commitments_proof; + + // Commit to sum_poly. + std::tie(fs, fri_trees, commitments_proof) = + nil::crypto3::zk::algorithms::commit_phase( + sum_poly, + sum_poly_precommitment, + _fri_params, transcript); + + std::vector challenges = + transcript.template challenges(this->_fri_params.lambda); + + fri_proof_type result; + + result.fri_round_proof = nil::crypto3::zk::algorithms::query_phase_round_proofs< + fri_type, polynomial_type>( + _fri_params, + fri_trees, + fs, + sum_poly, + challenges); + + result.fri_commitments_proof_part.fri_roots = std::move(commitments_proof.fri_roots); + result.fri_commitments_proof_part.final_polynomial = std::move(final_polynomial); + + return result; + } + + typename fri_type::proof_type commit_and_fri_proof( + const polynomial_type& combined_Q, transcript_type &transcript) { + + + precommitment_type combined_Q_precommitment = nil::crypto3::zk::algorithms::precommit( + combined_Q, + _fri_params.D[0], + _fri_params.step_list.front() + ); + + typename fri_type::proof_type fri_proof = nil::crypto3::zk::algorithms::proof_eval< + fri_type, polynomial_type>( + this->_polys, + combined_Q, + this->_trees, + combined_Q_precommitment, + this->_fri_params, + transcript + ); + return fri_proof; + } + + /** \brief + * \param theta The value of challenge. When called from aggregated FRI, this values is sent from + the "main prover" machine. + * \param starting_power When aggregated FRI is used, the value is not zero, it's the total degree of all + the polynomials in all the provers with indices lower than the current one. + */ + polynomial_type prepare_combined_Q( + const typename field_type::value_type& theta, + std::size_t starting_power = 0) { + typename field_type::value_type theta_acc = theta.pow(starting_power); polynomial_type combined_Q; math::polynomial V; auto points = this->get_unique_points(); math::polynomial combined_Q_normal; - for (auto const &point: points){ + for (auto const &point: points) { V = {-point, 1u}; math::polynomial Q_normal; - for(std::size_t i: this->_z.get_batches()){ - for(std::size_t j = 0; j < this->_z.get_batch_size(i); j++){ + for (std::size_t i: this->_z.get_batches()) { + for (std::size_t j = 0; j < this->_z.get_batch_size(i); j++) { auto it = std::find(this->_points[i][j].begin(), this->_points[i][j].end(), point); if( it == this->_points[i][j].end()) continue; math::polynomial g_normal; @@ -185,6 +308,7 @@ namespace nil { combined_Q_normal += Q_normal; } + // TODO(martun): the following code is the same as above with point = _etha, de-duplicate it. for (std::size_t i: this->_z.get_batches()) { if (!_batch_fixed[i]) continue; @@ -212,27 +336,14 @@ namespace nil { if constexpr (std::is_same, PolynomialType>::value) { combined_Q.from_coefficients(combined_Q_normal); + if (combined_Q.size() != _fri_params.D[0]->size()) { + combined_Q.resize(_fri_params.D[0]->size(), nullptr, _fri_params.D[0]); + } } else { combined_Q = std::move(combined_Q_normal); } - precommitment_type combined_Q_precommitment = nil::crypto3::zk::algorithms::precommit( - combined_Q, - _fri_params.D[0], - _fri_params.step_list.front() - ); - - typename fri_type::proof_type fri_proof = nil::crypto3::zk::algorithms::proof_eval< - fri_type, polynomial_type - >( - this->_polys, - combined_Q, - this->_trees, - combined_Q_precommitment, - this->_fri_params, - transcript - ); - return proof_type({this->_z, fri_proof}); + return combined_Q; } bool verify_eval( @@ -421,6 +532,60 @@ namespace nil { eval_storage_type z; typename basic_fri::proof_type fri_proof; }; + + // Represents an initial proof, which must be created for each of the N provers. + struct lpc_proof_type { + bool operator==(const lpc_proof_type &rhs) const { + return initial_fri_proofs == rhs.initial_fri_proofs && z == rhs.z; + } + + bool operator!=(const lpc_proof_type &rhs) const { + return !(rhs == *this); + } + + eval_storage_type z; + typename basic_fri::initial_proofs_batch_type initial_fri_proofs; + }; + + // Represents a round proof, which must be created just once on the main prover. + struct fri_proof_type { + bool operator==(const fri_proof_type &rhs) const { + return fri_round_proof == rhs.fri_round_proof && + fri_commitments_proof_part == rhs.fri_commitments_proof_part; + } + + bool operator!=(const fri_proof_type &rhs) const { + return !(rhs == *this); + } + + // We have a single round proof for checking that F(X) is a low degree polynomial. + typename basic_fri::round_proofs_batch_type fri_round_proof; + + // Contains fri_roots and final_polynomial that correspond to the polynomial F(x). + typename basic_fri::commitments_part_of_proof fri_commitments_proof_part; + }; + + // A single instance of this class will store all the LPC proofs for a group of provers + // when aggregated FRI is used. + struct aggregated_proof_type { + bool operator==(const aggregated_proof_type &rhs) const { + return fri_proof == rhs.fri_proof && + intial_proofs_per_prover == rhs.intial_proofs_per_prover && + proof_of_work == rhs.proof_of_work; + } + + bool operator!=(const proof_type &rhs) const { + return !(rhs == *this); + } + + // We have a single round proof for checking that F(X) is a low degree polynomial. + fri_proof_type fri_proof; + + // For each prover we have an initial proof. + std::vector intial_proofs_per_prover; + + typename LPCParams::grinding_type::output_type proof_of_work; + }; }; template diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp index 8c57cb86fa..c5cd9b9d35 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/proof.hpp @@ -40,6 +40,33 @@ namespace nil { constexpr std::size_t QUOTIENT_BATCH = 3; constexpr std::size_t LOOKUP_BATCH = 4; + // A part of the placeholder_proof. Used for proofs with aggregated FRI. + template + struct placeholder_partial_proof { + static constexpr std::size_t FIXED_VALUES_BATCH = 0; + static constexpr std::size_t VARIABLE_VALUES_BATCH = 1; + static constexpr std::size_t PERMUTATION_BATCH = 2; + static constexpr std::size_t QUOTIENT_BATCH = 3; + static constexpr std::size_t LOOKUP_BATCH = 4; + + typedef FieldType field_type; + typedef ParamsType params_type; + + using commitment_scheme_type = typename ParamsType::commitment_scheme_type; + using commitment_type = typename commitment_scheme_type::commitment_type; + + placeholder_partial_proof() = default; + + bool operator==(const placeholder_partial_proof &rhs) const { + return commitments == rhs.commitments; + } + bool operator!=(const placeholder_partial_proof &rhs) const { + return !(rhs == *this); + } + + std::map commitments; + }; + /** * A proof for the Placeholder scheme. * @@ -48,10 +75,10 @@ namespace nil { * about the structure for marshalling purposes. */ template - struct placeholder_proof { + struct placeholder_proof : public placeholder_partial_proof { static constexpr std::size_t FIXED_VALUES_BATCH = 0; static constexpr std::size_t VARIABLE_VALUES_BATCH = 1; - static constexpr std::size_t PERMUTATION_BATCH =2; + static constexpr std::size_t PERMUTATION_BATCH = 2; static constexpr std::size_t QUOTIENT_BATCH = 3; static constexpr std::size_t LOOKUP_BATCH = 4; @@ -76,20 +103,45 @@ namespace nil { } }; - placeholder_proof() { - } - - std::map commitments; - evaluation_proof eval_proof; + placeholder_proof() = default; bool operator==(const placeholder_proof &rhs) const { - return - commitments == rhs.commitments && + return placeholder_partial_proof::operator==(rhs) && eval_proof == rhs.eval_proof; } bool operator!=(const placeholder_proof &rhs) const { return !(rhs == *this); } + + evaluation_proof eval_proof; + }; + + /** + * An aggregated proof for the Placeholder scheme. It contains N partial proofs from N provers, with a shared + * aggregated FRI proof. + */ + template + struct placeholder_aggregated_proof { + typedef FieldType field_type; + typedef ParamsType params_type; + + using circuit_params_type = typename ParamsType::circuit_params_type; + using commitment_scheme_type = typename ParamsType::commitment_scheme_type; + using commitment_type = typename commitment_scheme_type::commitment_type; + + placeholder_aggregated_proof() = default; + + bool operator==(const placeholder_aggregated_proof &rhs) const { + return partial_proofs == rhs.partial_proofs && + aggregated_proof == rhs.aggregated_proof; + } + bool operator!=(const placeholder_aggregated_proof &rhs) const { + return !(rhs == *this); + } + + // This vector contains N partial proofs, one per prover. + std::vector> partial_proofs; + typename commitment_type::aggregated_proof_type aggregated_proof; }; } // namespace snark } // namespace zk diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/transcript/fiat_shamir.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/transcript/fiat_shamir.hpp index 8f8ce1be04..92da6d01a1 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/transcript/fiat_shamir.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/transcript/fiat_shamir.hpp @@ -230,6 +230,17 @@ namespace nil { return result; } + template + std::vector challenges(std::size_t N) { + + std::vector result; + for (std::size_t i = 0; i < N; ++i) { + result.push_back(challenge()); + } + + return result; + } + private: typename hash_type::digest_type state; }; @@ -341,6 +352,17 @@ namespace nil { return result; } + template + std::vector challenges(std::size_t N) { + + std::vector result; + for (std::size_t i = 0; i < N; ++i) { + result.push_back(challenge()); + } + + return result; + } + public: hashes::detail::poseidon_sponge_construction_custom sponge; }; diff --git a/crypto3/libs/zk/test/commitment/fri.cpp b/crypto3/libs/zk/test/commitment/fri.cpp index a6064750d6..776b3b4c58 100644 --- a/crypto3/libs/zk/test/commitment/fri.cpp +++ b/crypto3/libs/zk/test/commitment/fri.cpp @@ -130,6 +130,9 @@ void fri_basic_test() if constexpr (std::is_same, PolynomialType>::value) { f.from_coefficients(coefficients); + if (f.size() != params.D[0]->size()) { + f.resize(params.D[0]->size(), nullptr, params.D[0]); + } } else { f = PolynomialType(coefficients); } From bc2b5d54910823a016db01f1a6516a40a0ad4163 Mon Sep 17 00:00:00 2001 From: Martun Karapetyan Date: Sat, 14 Sep 2024 17:43:31 +0400 Subject: [PATCH 4/5] Use points map for faster search over the LPC points. --- .../nil/crypto3/zk/commitments/polynomial/lpc.hpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp index f93adac478..95e0d99733 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp @@ -278,6 +278,8 @@ namespace nil { polynomial_type prepare_combined_Q( const typename field_type::value_type& theta, std::size_t starting_power = 0) { + this->build_points_map(); + typename field_type::value_type theta_acc = theta.pow(starting_power); polynomial_type combined_Q; math::polynomial V; @@ -290,8 +292,10 @@ namespace nil { math::polynomial Q_normal; for (std::size_t i: this->_z.get_batches()) { for (std::size_t j = 0; j < this->_z.get_batch_size(i); j++) { - auto it = std::find(this->_points[i][j].begin(), this->_points[i][j].end(), point); - if( it == this->_points[i][j].end()) continue; + auto iter = this->_points_map[i][j].find(point); + if (iter == this->_points_map[i][j].end()) + continue; + math::polynomial g_normal; if constexpr(std::is_same, PolynomialType>::value ) { g_normal = math::polynomial(this->_polys[i][j].coefficients()); @@ -300,7 +304,7 @@ namespace nil { } g_normal *= theta_acc; Q_normal += g_normal; - Q_normal -= this->_z.get(i, j, it - this->_points[i][j].begin()) * theta_acc; + Q_normal -= this->_z.get(i, j, iter->second) * theta_acc; theta_acc *= theta; } } From a92f58289de7783d2bb0fd2e61a6f297033476de Mon Sep 17 00:00:00 2001 From: Martun Karapetyan Date: Sun, 15 Sep 2024 15:38:51 +0400 Subject: [PATCH 5/5] Fixing the tests. --- .../blueprint/test/zkevm/opcodes/iszero.cpp | 3 +- .../libs/blueprint/test/zkevm/opcodes/mul.cpp | 5 +- .../libs/containers/test/merkle/merkle.cpp | 14 +++--- crypto3/libs/hash/test/crc.cpp | 13 ++--- crypto3/libs/hash/test/tiger.cpp | 12 ++--- .../multiprecision/cpp_int_modular.hpp | 2 + .../arithmetization/plonk/assignment.hpp | 2 + .../arithmetization/plonk/constraint.hpp | 4 +- .../plonk/lookup_table_definition.hpp | 1 + .../placeholder/permutation_argument.hpp | 9 +++- .../plonk/placeholder/preprocessor.hpp | 49 ++++++++++++++----- .../systems/plonk/placeholder/prover.hpp | 40 ++++++++------- 12 files changed, 97 insertions(+), 57 deletions(-) diff --git a/crypto3/libs/blueprint/test/zkevm/opcodes/iszero.cpp b/crypto3/libs/blueprint/test/zkevm/opcodes/iszero.cpp index 2b84114ba1..8ae2fbd3ea 100644 --- a/crypto3/libs/blueprint/test/zkevm/opcodes/iszero.cpp +++ b/crypto3/libs/blueprint/test/zkevm/opcodes/iszero.cpp @@ -26,7 +26,6 @@ #include -#include #include #include @@ -35,6 +34,8 @@ #include #include "../opcode_tester.hpp" +#include + using namespace nil::blueprint; using namespace nil::crypto3::algebra; diff --git a/crypto3/libs/blueprint/test/zkevm/opcodes/mul.cpp b/crypto3/libs/blueprint/test/zkevm/opcodes/mul.cpp index 2858049a28..4f7fa4a0af 100644 --- a/crypto3/libs/blueprint/test/zkevm/opcodes/mul.cpp +++ b/crypto3/libs/blueprint/test/zkevm/opcodes/mul.cpp @@ -33,11 +33,10 @@ #include #include -#include -#include - #include "../opcode_tester.hpp" +#include + using namespace nil::blueprint; using namespace nil::crypto3::algebra; diff --git a/crypto3/libs/containers/test/merkle/merkle.cpp b/crypto3/libs/containers/test/merkle/merkle.cpp index 7db3a093f4..8eb6305539 100644 --- a/crypto3/libs/containers/test/merkle/merkle.cpp +++ b/crypto3/libs/containers/test/merkle/merkle.cpp @@ -26,12 +26,6 @@ #define BOOST_TEST_MODULE containter_merkletree_test -#include -#include -#include -#include -#include - #include #include #include @@ -41,7 +35,6 @@ #include #include #include -#include #include #include @@ -50,6 +43,13 @@ #include #include +#include +#include +#include +#include +#include +#include + using namespace nil::crypto3; using namespace nil::crypto3::containers; diff --git a/crypto3/libs/hash/test/crc.cpp b/crypto3/libs/hash/test/crc.cpp index b057e61be9..c055abd0b0 100644 --- a/crypto3/libs/hash/test/crc.cpp +++ b/crypto3/libs/hash/test/crc.cpp @@ -8,13 +8,8 @@ #define BOOST_TEST_MODULE crc_test -#include -#include -#include -#include -#include - #include + #include #include @@ -24,6 +19,12 @@ #include #include +#include +#include +#include +#include +#include + using namespace nil::crypto3; using namespace nil::crypto3::hashes; using namespace nil::crypto3::accumulators; diff --git a/crypto3/libs/hash/test/tiger.cpp b/crypto3/libs/hash/test/tiger.cpp index cbc1a69469..3f3d8b8748 100644 --- a/crypto3/libs/hash/test/tiger.cpp +++ b/crypto3/libs/hash/test/tiger.cpp @@ -25,12 +25,6 @@ #define BOOST_TEST_MODULE tiger_test -#include -#include -#include -#include -#include - #include #include @@ -45,6 +39,12 @@ #include +#include +#include +#include +#include +#include + using namespace nil::crypto3; using namespace nil::crypto3::accumulators; diff --git a/crypto3/libs/multiprecision/include/nil/crypto3/multiprecision/cpp_int_modular.hpp b/crypto3/libs/multiprecision/include/nil/crypto3/multiprecision/cpp_int_modular.hpp index 15f7bd4811..7e0f8ec4be 100644 --- a/crypto3/libs/multiprecision/include/nil/crypto3/multiprecision/cpp_int_modular.hpp +++ b/crypto3/libs/multiprecision/include/nil/crypto3/multiprecision/cpp_int_modular.hpp @@ -9,6 +9,8 @@ #ifndef CRYPTO3_CPP_INT_MODULAR_HPP #define CRYPTO3_CPP_INT_MODULAR_HPP +#include + // Suddenly, BOOST_MP_ASSERT is NOT BOOST_MP_CXX14_CONSTEXPR, and it is used in BOOST_MP_CXX14_CONSTEXPR functions throughout the boost, resulting to compilation errors on all compilers in debug mode. We need to switch assertions off inside cpp_int to make this code compile in debug mode. So we use this workaround to turn off file 'boost/multiprecision/detail/assert.hpp' which contains definition of BOOST_MP_ASSERT and BOOST_MP_ASSERT_MSG. #include // for BOOST_MP_IS_CONST_EVALUATED diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/assignment.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/assignment.hpp index e567e712e9..287ef0bede 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/assignment.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/assignment.hpp @@ -56,6 +56,7 @@ namespace nil { template class plonk_private_table { public: + using column_type = ColumnType; using witnesses_container_type = std::vector; using VariableType = plonk_variable; @@ -151,6 +152,7 @@ namespace nil { template class plonk_public_table { public: + using column_type = ColumnType; using public_input_container_type = std::vector; using constant_container_type = std::vector; using selector_container_type = std::vector; diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/constraint.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/constraint.hpp index 7a28b46c8f..63df5e2e11 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/constraint.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/constraint.hpp @@ -180,7 +180,9 @@ namespace nil { return evaluator.evaluate(); } - typename VariableType::assignment_type evaluate(detail::plonk_evaluation_map &assignments) const { + typename VariableType::assignment_type + evaluate(detail::plonk_evaluation_map &assignments) const { + math::expression_evaluator evaluator( *this, [&assignments](const VariableType &var) -> const typename VariableType::assignment_type& { diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/lookup_table_definition.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/lookup_table_definition.hpp index 6f61974afa..101a9b4ca8 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/lookup_table_definition.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/lookup_table_definition.hpp @@ -134,6 +134,7 @@ namespace nil { const std::vector &constant_columns_ids, std::size_t usable_rows ){ + // std::cout << "Packing lookup tables" << std::endl; // std::cout << "Usable rows before: " << usable_rows << std::endl; std::size_t usable_rows_after = usable_rows; diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/permutation_argument.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/permutation_argument.hpp index 56a6fe7e3d..7f8dfa4d32 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/permutation_argument.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/permutation_argument.hpp @@ -105,6 +105,7 @@ namespace nil { std::vector> h_v = S_sigma; BOOST_ASSERT(global_indices.size() == S_id.size()); BOOST_ASSERT(global_indices.size() == S_sigma.size()); + for (std::size_t i = 0; i < S_id.size(); i++) { BOOST_ASSERT(column_polynomials[global_indices[i]].size() == basic_domain->size()); BOOST_ASSERT(S_id[i].size() == basic_domain->size()); @@ -122,6 +123,7 @@ namespace nil { } V_P[0] = FieldType::value_type::one(); + for (std::size_t j = 1; j < basic_domain->size(); j++) { typename FieldType::value_type nom = FieldType::value_type::one(); typename FieldType::value_type denom = FieldType::value_type::one(); @@ -191,16 +193,19 @@ namespace nil { F_dfs[1] -= preprocessed_data.q_blind; F_dfs[1] *= V_P_shifted; } else { + PROFILE_SCOPE("PERMUTATION ARGUMENT else block"); math::polynomial_dfs previous_poly = V_P; math::polynomial_dfs current_poly = V_P; for( std::size_t i = 0; i < preprocessed_data.common_data.permutation_parts-1; i++ ){ - auto g = gs[i]; - auto h = hs[i]; + const auto& g = gs[i]; + const auto& h = hs[i]; auto reduced_g = reduce_dfs_polynomial_domain(g, basic_domain->m); auto reduced_h = reduce_dfs_polynomial_domain(h, basic_domain->m); + for(std::size_t j = 0; j < preprocessed_data.common_data.desc.usable_rows_amount; j++){ current_poly[j] = (previous_poly[j] * reduced_g[j]) * reduced_h[j].inversed(); } + commitment_scheme.append_to_batch(PERMUTATION_BATCH, current_poly); auto part = permutation_alphas[i] * (previous_poly * g - current_poly * h); F_dfs[1] += part; diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp index dc08b02eef..fd66fb36dc 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp @@ -65,10 +65,11 @@ namespace nil { template class placeholder_public_preprocessor { - typedef detail::placeholder_policy policy_type; - typedef typename plonk_constraint::variable_type variable_type; - typedef typename math::polynomial polynomial_type; - typedef typename math::polynomial_dfs polynomial_dfs_type; + using policy_type = detail::placeholder_policy; + using variable_type = typename plonk_constraint::variable_type; + using value_type = typename FieldType::value_type; + using polynomial_type = typename math::polynomial; + using polynomial_dfs_type = typename math::polynomial_dfs; using params_type = ParamsType; using commitment_scheme_type = typename params_type::commitment_scheme_type; using commitment_type = typename commitment_scheme_type::commitment_type; @@ -79,15 +80,21 @@ namespace nil { static std::size_t permutation_partitions_num( std::size_t permutation_size, std::size_t max_quotient_chunks - ){ - if( permutation_size == 0 ) return 0; - if( max_quotient_chunks == 0 ){ + ) { + if (permutation_size == 0) return 0; + if (max_quotient_chunks == 0) { return 1; } - return (permutation_size % (max_quotient_chunks - 1) == 0)? permutation_size / (max_quotient_chunks - 1) : permutation_size / (max_quotient_chunks - 1) + 1; + return (permutation_size % (max_quotient_chunks - 1) == 0) ? + permutation_size / (max_quotient_chunks - 1) : + permutation_size / (max_quotient_chunks - 1) + 1; } struct preprocessed_data_type { + // Used in marshalling. + using plonk_public_polynomial_dfs_table_type = plonk_public_polynomial_dfs_table; + using polynomial_dfs_type = typename math::polynomial_dfs; + struct public_commitments_type { commitment_type fixed_values; @@ -155,6 +162,8 @@ namespace nil { std::uint32_t permutation_parts; std::uint32_t lookup_parts; + common_data_type(const common_data_type& other) = default; + // Constructor with pregenerated domain common_data_type( std::shared_ptr> D, @@ -253,17 +262,30 @@ namespace nil { } }; - plonk_public_polynomial_dfs_table public_polynomial_table; + bool operator==(const preprocessed_data_type &rhs) const { + return public_polynomial_table == rhs.public_polynomial_table && + permutation_polynomials == rhs.permutation_polynomials && + identity_polynomials == rhs.identity_polynomials && + q_last == rhs.q_last && + q_blind == rhs.q_blind && + common_data == rhs.common_data; + } + + bool operator!=(const preprocessed_data_type &rhs) const { + return !(rhs == *this); + } + + plonk_public_polynomial_dfs_table_type public_polynomial_table; // S_sigma std::vector permutation_polynomials; // S_id std::vector identity_polynomials; - polynomial_dfs_type q_last; - polynomial_dfs_type q_blind; + polynomial_dfs_type q_last; + polynomial_dfs_type q_blind; - common_data_type common_data; + common_data_type common_data; }; private: @@ -499,7 +521,8 @@ namespace nil { commitment_scheme.append_to_batch(FIXED_VALUES_BATCH, public_table.constants()); commitment_scheme.append_to_batch(FIXED_VALUES_BATCH, public_table.selectors()); - auto result = typename preprocessed_data_type::public_commitments_type({commitment_scheme.commit(FIXED_VALUES_BATCH)}); + typename preprocessed_data_type::public_commitments_type result( + {commitment_scheme.commit(FIXED_VALUES_BATCH)}); commitment_scheme.mark_batch_as_fixed(FIXED_VALUES_BATCH); return result; } diff --git a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp index 8ec7b78d8b..f81bb2fd2b 100644 --- a/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp +++ b/crypto3/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp @@ -97,11 +97,12 @@ namespace nil { typename private_preprocessor_type::preprocessed_data_type preprocessed_private_data, const plonk_table_description &table_description, const plonk_constraint_system &constraint_system, - commitment_scheme_type commitment_scheme + commitment_scheme_type commitment_scheme, + bool skip_commitment_scheme_eval_proofs = false ) { auto prover = placeholder_prover( preprocessed_public_data, std::move(preprocessed_private_data), table_description, - constraint_system, commitment_scheme); + constraint_system, commitment_scheme, skip_commitment_scheme_eval_proofs); return prover.process(); } @@ -110,7 +111,8 @@ namespace nil { typename private_preprocessor_type::preprocessed_data_type preprocessed_private_data, const plonk_table_description &table_description, const plonk_constraint_system &constraint_system, - const commitment_scheme_type &commitment_scheme + const commitment_scheme_type &commitment_scheme, + bool skip_commitment_scheme_eval_proofs = false ) : preprocessed_public_data(preprocessed_public_data) , table_description(table_description) @@ -122,6 +124,7 @@ namespace nil { , transcript(std::vector({})) , _is_lookup_enabled(constraint_system.lookup_gates().size() > 0) , _commitment_scheme(commitment_scheme) + , _skip_commitment_scheme_eval_proofs(skip_commitment_scheme_eval_proofs) { // Initialize transcript. transcript(preprocessed_public_data.common_data.vk.constraint_system_with_params_hash); @@ -204,12 +207,11 @@ namespace nil { } transcript(_proof.commitments[QUOTIENT_BATCH]); - // 8. Run evaluation proofs - _proof.eval_proof.challenge = transcript.template challenge(); - generate_evaluation_points(); + if (!_skip_commitment_scheme_eval_proofs) { + // 8. Run evaluation proofs + _proof.eval_proof.challenge = transcript.template challenge(); + generate_evaluation_points(); - { - PROFILE_SCOPE("commitment scheme proof eval time"); _proof.eval_proof.eval_proof = _commitment_scheme.proof_eval(transcript); } @@ -218,13 +220,13 @@ namespace nil { private: std::vector quotient_polynomial_split_dfs() { + PROFILE_SCOPE("quotient_polynomial_split_dfs"); + // TODO: pass max_degree parameter placeholder std::vector T_splitted = detail::split_polynomial( quotient_polynomial(), table_description.rows_amount - 1 ); - PROFILE_SCOPE("split_polynomial_dfs_conversion_time"); - std::size_t split_polynomial_size = std::max( (preprocessed_public_data.identity_polynomials.size() + 2) * (preprocessed_public_data.common_data.desc.rows_amount -1 ), (constraint_system.lookup_poly_degree_bound() + 1) * (preprocessed_public_data.common_data.desc.rows_amount -1 )//, @@ -237,7 +239,8 @@ namespace nil { (split_polynomial_size / preprocessed_public_data.common_data.desc.rows_amount + 1): (split_polynomial_size / preprocessed_public_data.common_data.desc.rows_amount); - if( preprocessed_public_data.common_data.max_quotient_chunks != 0 && split_polynomial_size > preprocessed_public_data.common_data.max_quotient_chunks){ + if (preprocessed_public_data.common_data.max_quotient_chunks != 0 && + split_polynomial_size > preprocessed_public_data.common_data.max_quotient_chunks) { split_polynomial_size = preprocessed_public_data.common_data.max_quotient_chunks; } @@ -312,7 +315,7 @@ namespace nil { } commitment_type T_commit(const std::vector& T_splitted_dfs) { - PROFILE_SCOPE("T_splitted_precommit_time"); + PROFILE_SCOPE("T_split_precommit_time"); _commitment_scheme.append_to_batch(QUOTIENT_BATCH, T_splitted_dfs); return _commitment_scheme.commit(QUOTIENT_BATCH); } @@ -368,15 +371,16 @@ namespace nil { } } - if(_is_lookup_enabled||constraint_system.copy_constraints().size() > 0){ + if (_is_lookup_enabled||constraint_system.copy_constraints().size() > 0) { _commitment_scheme.append_eval_point(PERMUTATION_BATCH, _proof.eval_proof.challenge); } - if( constraint_system.copy_constraints().size() > 0 ) + if (constraint_system.copy_constraints().size() > 0) _commitment_scheme.append_eval_point(PERMUTATION_BATCH, 0, _proof.eval_proof.challenge * _omega); - if(_is_lookup_enabled){ - _commitment_scheme.append_eval_point(PERMUTATION_BATCH, preprocessed_public_data.common_data.permutation_parts , _proof.eval_proof.challenge * _omega); + if (_is_lookup_enabled) { + _commitment_scheme.append_eval_point(PERMUTATION_BATCH, preprocessed_public_data.common_data.permutation_parts, + _proof.eval_proof.challenge * _omega); _commitment_scheme.append_eval_point(LOOKUP_BATCH, _proof.eval_proof.challenge); _commitment_scheme.append_eval_point(LOOKUP_BATCH, _proof.eval_proof.challenge * _omega); _commitment_scheme.append_eval_point(LOOKUP_BATCH, _proof.eval_proof.challenge * @@ -385,13 +389,12 @@ namespace nil { _commitment_scheme.append_eval_point(QUOTIENT_BATCH, _proof.eval_proof.challenge); - // fixed values' rotations (table columns) std::size_t i = 0; std::size_t start_index = preprocessed_public_data.identity_polynomials.size() + preprocessed_public_data.permutation_polynomials.size() + 2; - for( i = 0; i < start_index; i++){ + for (i = 0; i < start_index; i++) { _commitment_scheme.append_eval_point(FIXED_VALUES_BATCH, i, _proof.eval_proof.challenge); } @@ -477,6 +480,7 @@ namespace nil { typename FieldType::value_type _omega; std::vector _challenge_point; commitment_scheme_type _commitment_scheme; + bool _skip_commitment_scheme_eval_proofs; }; } // namespace snark } // namespace zk