diff --git a/CMakeLists.txt b/CMakeLists.txt index 849f8b7c2..6dd98035f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,7 +53,7 @@ else() target_architecture(CMAKE_TARGET_ARCHITECTURE) endif() -find_package(Boost REQUIRED COMPONENTS container random filesystem log log_setup program_options thread system unit_test_framework timer) +find_package(Boost REQUIRED COMPONENTS container random filesystem log log_setup program_options thread system unit_test_framework timer log) add_subdirectories("${CMAKE_CURRENT_LIST_DIR}/libs/") add_subdirectories("${CMAKE_CURRENT_LIST_DIR}/libs/marshalling") diff --git a/libs/algebra/crypto3.algebra.podspec.json b/libs/algebra/crypto3.algebra.podspec.json index 19ebdf03c..f45d4d26c 100644 --- a/libs/algebra/crypto3.algebra.podspec.json +++ b/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/libs/block/crypto3.block.podspec.json b/libs/block/crypto3.block.podspec.json index fd27d0e36..8bfc7839e 100644 --- a/libs/block/crypto3.block.podspec.json +++ b/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/libs/block/test/CMakeLists.txt b/libs/block/test/CMakeLists.txt index 96bd9918f..25b9948d4 100644 --- a/libs/block/test/CMakeLists.txt +++ b/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/libs/blueprint/include/nil/blueprint/basic_non_native_policy.hpp b/libs/blueprint/include/nil/blueprint/basic_non_native_policy.hpp index a2d2ee643..f53e192f2 100644 --- a/libs/blueprint/include/nil/blueprint/basic_non_native_policy.hpp +++ b/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/libs/codec/crypto3.codec.podspec.json b/libs/codec/crypto3.codec.podspec.json index b68d0be01..1bdc8f1e8 100644 --- a/libs/codec/crypto3.codec.podspec.json +++ b/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/libs/codec/test/CMakeLists.txt b/libs/codec/test/CMakeLists.txt index 75b67e0d6..6548c365e 100644 --- a/libs/codec/test/CMakeLists.txt +++ b/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/libs/containers/include/nil/crypto3/container/merkle/tree.hpp b/libs/containers/include/nil/crypto3/container/merkle/tree.hpp index 534c70e42..145802635 100644 --- a/libs/containers/include/nil/crypto3/container/merkle/tree.hpp +++ b/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/libs/hash/crypto3.hash.podspec.json b/libs/hash/crypto3.hash.podspec.json index 902d97c55..23c94a4bc 100644 --- a/libs/hash/crypto3.hash.podspec.json +++ b/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/libs/kdf/crypto3.kdf.podspec.json b/libs/kdf/crypto3.kdf.podspec.json index a923b4ba7..1d62957b8 100644 --- a/libs/kdf/crypto3.kdf.podspec.json +++ b/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/libs/mac/crypto3.mac.podspec.json b/libs/mac/crypto3.mac.podspec.json index 7199197cb..48e8499cb 100644 --- a/libs/mac/crypto3.mac.podspec.json +++ b/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/libs/marshalling/algebra/include/nil/crypto3/marshalling/algebra/types/field_element.hpp b/libs/marshalling/algebra/include/nil/crypto3/marshalling/algebra/types/field_element.hpp index c23fcd2d0..8efabeb6a 100644 --- a/libs/marshalling/algebra/include/nil/crypto3/marshalling/algebra/types/field_element.hpp +++ b/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/libs/marshalling/core/CMakeLists.txt b/libs/marshalling/core/CMakeLists.txt index 2d51db92a..92ca677ce 100644 --- a/libs/marshalling/core/CMakeLists.txt +++ b/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/libs/marshalling/core/include/nil/marshalling/options.hpp b/libs/marshalling/core/include/nil/marshalling/options.hpp index 49f67d0fb..132ce9af7 100644 --- a/libs/marshalling/core/include/nil/marshalling/options.hpp +++ b/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/libs/marshalling/core/include/nil/marshalling/types/adapter/sequence_size_field_prefix.hpp b/libs/marshalling/core/include/nil/marshalling/types/adapter/sequence_size_field_prefix.hpp index dec4d2968..9caa6459b 100644 --- a/libs/marshalling/core/include/nil/marshalling/types/adapter/sequence_size_field_prefix.hpp +++ b/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/libs/marshalling/core/include/nil/marshalling/types/array_list.hpp b/libs/marshalling/core/include/nil/marshalling/types/array_list.hpp index 350214e01..e675cb2c5 100644 --- a/libs/marshalling/core/include/nil/marshalling/types/array_list.hpp +++ b/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/libs/marshalling/core/include/nil/marshalling/types/integral.hpp b/libs/marshalling/core/include/nil/marshalling/types/integral.hpp index b991d9e70..a38e72808 100644 --- a/libs/marshalling/core/include/nil/marshalling/types/integral.hpp +++ b/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/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_node.hpp b/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_node.hpp new file mode 100644 index 000000000..77ad27e04 --- /dev/null +++ b/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/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_proof.hpp b/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_proof.hpp index 058ed6915..f58653d8d 100644 --- a/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_proof.hpp +++ b/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/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_tree.hpp b/libs/marshalling/zk/include/nil/crypto3/marshalling/containers/types/merkle_tree.hpp new file mode 100644 index 000000000..7c4f81345 --- /dev/null +++ b/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/libs/marshalling/zk/include/nil/crypto3/marshalling/math/types/polynomial.hpp b/libs/marshalling/zk/include/nil/crypto3/marshalling/math/types/polynomial.hpp new file mode 100644 index 000000000..80859a38f --- /dev/null +++ b/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/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/commitment_params.hpp b/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/commitment_params.hpp index db3dfa1b8..d83108b5b 100644 --- a/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/commitment_params.hpp +++ b/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/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/eval_storage.hpp b/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/eval_storage.hpp index 919d5c39b..5b446cb54 100644 --- a/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/eval_storage.hpp +++ b/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/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/fri.hpp b/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/fri.hpp index 25fb59120..7dbaa9276 100644 --- a/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/fri.hpp +++ b/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/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/lpc.hpp b/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/lpc.hpp index e2564a91c..d0ee08b67 100644 --- a/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/lpc.hpp +++ b/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/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/polys_evaluator.hpp b/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/commitments/polys_evaluator.hpp new file mode 100644 index 000000000..924971e58 --- /dev/null +++ b/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/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/common_data.hpp b/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/common_data.hpp index 0eea37357..f4ab6e997 100644 --- a/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/common_data.hpp +++ b/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/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/preprocessed_public_data.hpp b/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/preprocessed_public_data.hpp new file mode 100644 index 000000000..5c46a807f --- /dev/null +++ b/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/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/proof.hpp b/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/proof.hpp index de79fa02f..d7a228b1d 100644 --- a/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/placeholder/proof.hpp +++ b/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/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/plonk/assignment_table.hpp b/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/plonk/assignment_table.hpp index 2621c90c8..d96324832 100644 --- a/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/plonk/assignment_table.hpp +++ b/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/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/plonk/plonk_public_polynomial_dfs_table.hpp b/libs/marshalling/zk/include/nil/crypto3/marshalling/zk/types/plonk/plonk_public_polynomial_dfs_table.hpp new file mode 100644 index 000000000..61aaceb9d --- /dev/null +++ b/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/libs/marshalling/zk/test/CMakeLists.txt b/libs/marshalling/zk/test/CMakeLists.txt index 41a0f48ea..fba9aa60d 100644 --- a/libs/marshalling/zk/test/CMakeLists.txt +++ b/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/libs/marshalling/zk/test/fri_commitment.cpp b/libs/marshalling/zk/test/fri_commitment.cpp index a9070c6d7..027f3100b 100644 --- a/libs/marshalling/zk/test/fri_commitment.cpp +++ b/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/libs/marshalling/zk/test/lpc_commitment.cpp b/libs/marshalling/zk/test/lpc_commitment.cpp index 26e433fa7..413b479d4 100644 --- a/libs/marshalling/zk/test/lpc_commitment.cpp +++ b/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/libs/marshalling/zk/test/merkle_tree.cpp b/libs/marshalling/zk/test/merkle_tree.cpp new file mode 100644 index 000000000..8b66c67f4 --- /dev/null +++ b/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/libs/marshalling/zk/test/placeholder_preprocessed_public_data.cpp b/libs/marshalling/zk/test/placeholder_preprocessed_public_data.cpp new file mode 100644 index 000000000..11ea97d8c --- /dev/null +++ b/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/libs/marshalling/zk/test/placeholder_proof.cpp b/libs/marshalling/zk/test/placeholder_proof.cpp index 19bd0d939..1613efd67 100644 --- a/libs/marshalling/zk/test/placeholder_proof.cpp +++ b/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/libs/marshalling/zk/test/plonk_assignment_table.cpp b/libs/marshalling/zk/test/plonk_assignment_table.cpp index 2d5b58ebc..353d779b8 100644 --- a/libs/marshalling/zk/test/plonk_assignment_table.cpp +++ b/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/libs/marshalling/zk/test/polys_evaluator.cpp b/libs/marshalling/zk/test/polys_evaluator.cpp new file mode 100644 index 000000000..52d61f795 --- /dev/null +++ b/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/libs/marshalling/zk/test/random_test_data_generation.hpp b/libs/marshalling/zk/test/random_test_data_generation.hpp new file mode 100644 index 000000000..ac21739f2 --- /dev/null +++ b/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/libs/math/crypto3.math.podspec.json b/libs/math/crypto3.math.podspec.json index 1b47a8625..dffd3cdeb 100644 --- a/libs/math/crypto3.math.podspec.json +++ b/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/libs/math/include/nil/crypto3/math/algorithms/make_evaluation_domain.hpp b/libs/math/include/nil/crypto3/math/algorithms/make_evaluation_domain.hpp index 44c16ee8d..393f7e97b 100644 --- a/libs/math/include/nil/crypto3/math/algorithms/make_evaluation_domain.hpp +++ b/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/libs/math/include/nil/crypto3/math/domains/basic_radix2_domain.hpp b/libs/math/include/nil/crypto3/math/domains/basic_radix2_domain.hpp index 53fe99286..96f02314e 100755 --- a/libs/math/include/nil/crypto3/math/domains/basic_radix2_domain.hpp +++ b/libs/math/include/nil/crypto3/math/domains/basic_radix2_domain.hpp @@ -28,6 +28,8 @@ #include +#include + #include #include diff --git a/libs/math/include/nil/crypto3/math/domains/extended_radix2_domain.hpp b/libs/math/include/nil/crypto3/math/domains/extended_radix2_domain.hpp index 57d4ca95a..de5974d4b 100755 --- a/libs/math/include/nil/crypto3/math/domains/extended_radix2_domain.hpp +++ b/libs/math/include/nil/crypto3/math/domains/extended_radix2_domain.hpp @@ -28,6 +28,8 @@ #include +#include + #include #include #include diff --git a/libs/math/include/nil/crypto3/math/type_traits.hpp b/libs/math/include/nil/crypto3/math/type_traits.hpp index 9bcc20386..a5094230a 100755 --- a/libs/math/include/nil/crypto3/math/type_traits.hpp +++ b/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/libs/modes/crypto3.modes.podspec.json b/libs/modes/crypto3.modes.podspec.json index 924cd2979..426148648 100644 --- a/libs/modes/crypto3.modes.podspec.json +++ b/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/libs/multiprecision/test/test_gcd.cpp b/libs/multiprecision/test/test_gcd.cpp index afd07a7c5..19e6d28c8 100644 --- a/libs/multiprecision/test/test_gcd.cpp +++ b/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/libs/passhash/crypto3.passhash.podspec.json b/libs/passhash/crypto3.passhash.podspec.json index aaa36054f..0288b1784 100644 --- a/libs/passhash/crypto3.passhash.podspec.json +++ b/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/libs/pbkdf/crypto3.pbkdf.podspec.json b/libs/pbkdf/crypto3.pbkdf.podspec.json index 6d1cb5112..4563144ec 100644 --- a/libs/pbkdf/crypto3.pbkdf.podspec.json +++ b/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/libs/pkpad/crypto3.pkpad.podspec.json b/libs/pkpad/crypto3.pkpad.podspec.json index 2b8e1d9c3..6ef7c83a3 100644 --- a/libs/pkpad/crypto3.pkpad.podspec.json +++ b/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/libs/stream/crypto3.stream.podspec.json b/libs/stream/crypto3.stream.podspec.json index 0c1c70ea4..264bdab0d 100644 --- a/libs/stream/crypto3.stream.podspec.json +++ b/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/libs/threshold/crypto3.threshold.podspec.json b/libs/threshold/crypto3.threshold.podspec.json index 924cd2979..426148648 100644 --- a/libs/threshold/crypto3.threshold.podspec.json +++ b/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/libs/vdf/crypto3.vdf.podspec.json b/libs/vdf/crypto3.vdf.podspec.json index 71996bac7..d7093452f 100644 --- a/libs/vdf/crypto3.vdf.podspec.json +++ b/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/libs/zk/CMakeLists.txt b/libs/zk/CMakeLists.txt index 08e64325e..2ebcef509 100644 --- a/libs/zk/CMakeLists.txt +++ b/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/libs/zk/crypto3.zk.podspec.json b/libs/zk/crypto3.zk.podspec.json index 980402d08..945ae8346 100644 --- a/libs/zk/crypto3.zk.podspec.json +++ b/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/libs/zk/include/nil/crypto3/zk/commitments/batched_commitment.hpp b/libs/zk/include/nil/crypto3/zk/commitments/batched_commitment.hpp index 8a39bb230..0cb037003 100644 --- a/libs/zk/include/nil/crypto3/zk/commitments/batched_commitment.hpp +++ b/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/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_batched_fri_compile_time_size.hpp b/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_batched_fri_compile_time_size.hpp index 7497225e1..00d459043 100644 --- a/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_batched_fri_compile_time_size.hpp +++ b/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/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_batched_fri_runtime_size.hpp b/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_batched_fri_runtime_size.hpp index 404875df1..33ec6827f 100644 --- a/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_batched_fri_runtime_size.hpp +++ b/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/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp b/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp index 2a328871c..4d1e0f510 100644 --- a/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp +++ b/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/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/eval_storage.hpp b/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/eval_storage.hpp index daf6f4d43..ee1a312a2 100644 --- a/libs/zk/include/nil/crypto3/zk/commitments/detail/polynomial/eval_storage.hpp +++ b/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/libs/zk/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp b/libs/zk/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp index 58d02f6ca..eaa24611a 100644 --- a/libs/zk/include/nil/crypto3/zk/commitments/polynomial/kzg.hpp +++ b/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/libs/zk/include/nil/crypto3/zk/commitments/polynomial/kzg_v2.hpp b/libs/zk/include/nil/crypto3/zk/commitments/polynomial/kzg_v2.hpp index d708a3128..9888a462b 100644 --- a/libs/zk/include/nil/crypto3/zk/commitments/polynomial/kzg_v2.hpp +++ b/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/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp b/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp index 999f7824e..8b5b695d9 100644 --- a/libs/zk/include/nil/crypto3/zk/commitments/polynomial/lpc.hpp +++ b/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 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/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/table_description.hpp b/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/table_description.hpp index b716482be..bda775459 100644 --- a/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/table_description.hpp +++ b/libs/zk/include/nil/crypto3/zk/snark/arithmetization/plonk/table_description.hpp @@ -36,8 +36,12 @@ namespace nil { namespace zk { namespace snark { + // TODO(martun): this class actually does not depend on the FieldType. 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/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp b/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp index dc08b02ee..91462c147 100644 --- a/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp +++ b/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/preprocessor.hpp @@ -34,6 +34,8 @@ #include #include +#include + #include #include #include @@ -65,10 +67,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 +82,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 +164,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 +264,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 +523,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/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp b/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp index 8ec7b78d8..e05a6ef97 100644 --- a/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp +++ b/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/prover.hpp @@ -375,8 +375,9 @@ namespace nil { 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 * @@ -391,7 +392,7 @@ namespace nil { 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); } diff --git a/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp b/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp index fbd573402..0a46ee832 100644 --- a/libs/zk/include/nil/crypto3/zk/snark/systems/plonk/placeholder/verifier.hpp +++ b/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/libs/zk/test/CMakeLists.txt b/libs/zk/test/CMakeLists.txt index 3f824ac4a..b5a4aff45 100644 --- a/libs/zk/test/CMakeLists.txt +++ b/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/libs/zk/test/commitment/fri.cpp b/libs/zk/test/commitment/fri.cpp index 2aae7eda1..a6064750d 100644 --- a/libs/zk/test/commitment/fri.cpp +++ b/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/libs/zk/test/commitment/lpc.cpp b/libs/zk/test/commitment/lpc.cpp index a6e92d652..d7a763ea6 100644 --- a/libs/zk/test/commitment/lpc.cpp +++ b/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/libs/zk/test/commitment/lpc_performance.cpp b/libs/zk/test/commitment/lpc_performance.cpp index a9c8ef128..2216ad4ce 100644 --- a/libs/zk/test/commitment/lpc_performance.cpp +++ b/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/libs/zk/test/systems/plonk/placeholder/placeholder_test_runner.hpp b/libs/zk/test/systems/plonk/placeholder/placeholder_test_runner.hpp index bae48452d..b6ffe491f 100644 --- a/libs/zk/test/systems/plonk/placeholder/placeholder_test_runner.hpp +++ b/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; }