Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

147 keccak round bbf #148

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//---------------------------------------------------------------------------//
// Copyright (c) 2024 Elena Tatuzova <[email protected]>
//
// 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_BLUEPRINT_COMPONENTS_KECCAK_PACK_HPP
#define CRYPTO3_BLUEPRINT_COMPONENTS_KECCAK_PACK_HPP

template <typename BlueprintFieldType>
typename BlueprintFieldType::value_type pack(typename BlueprintFieldType::value_type value) {
using value_type = typename BlueprintFieldType::value_type;
using integral_type = typename BlueprintFieldType::integral_type;
integral_type value_integral = integral_type(value.data);
integral_type result_integral = 0;
integral_type power = 1;
for (int i = 0; i < 64; ++i) {
integral_type bit = value_integral & 1;
result_integral = result_integral + bit * power;
value_integral = value_integral >> 1;
power = power << 3;
}
return value_type(result_integral);
}

template<typename BlueprintFieldType>
typename BlueprintFieldType::value_type unpack(typename BlueprintFieldType::value_type value) {
using value_type = typename BlueprintFieldType::value_type;
using integral_type = typename BlueprintFieldType::integral_type;
integral_type value_integral = integral_type(value.data);
integral_type result_integral = 0;
integral_type power = 1;
while (value_integral >= 1) {
integral_type bit = value_integral & 1;
result_integral = result_integral + bit * power;
value_integral = value_integral >> 3;
power = power << 1;
}
return value_type(result_integral);
}

template <typename BlueprintFieldType>
typename BlueprintFieldType::value_type calculateRLC(
std::vector<std::uint8_t> data,
typename BlueprintFieldType::value_type factor
){
typename BlueprintFieldType::value_type RLC = data.size();
for( std::size_t i = 0; i < data.size(); i++ ){
RLC *= factor;
RLC += typename BlueprintFieldType::value_type(data[i]);
}
return RLC;
}

template <typename BlueprintFieldType>
std::array<typename BlueprintFieldType::value_type,4> sparsed_64bits_to_4_chunks(typename BlueprintFieldType::value_type num){
using integral_type = typename BlueprintFieldType::integral_type;
using value_type = typename BlueprintFieldType::value_type;
integral_type n(num.data);
integral_type mask = (integral_type(1) << 48) - 1;

std::array<typename BlueprintFieldType::value_type,4> result;
result[3] = value_type(n & mask); n >>= 48;
result[2] = value_type(n & mask); n >>= 48;
result[1] = value_type(n & mask); n >>= 48;
result[0] = value_type(n & mask);

return result;
}

// For 16-bit numbers placed into field element
template <typename BlueprintFieldType>
typename BlueprintFieldType::value_type swap_bytes( typename BlueprintFieldType::value_type i ){
typename BlueprintFieldType::integral_type n(i.data);
assert( n < 65536 );

return ((n & 0xFF) << 8) + ((n & 0xFF00) >> 8);
}
#endif
229 changes: 228 additions & 1 deletion crypto3/libs/blueprint/include/nil/blueprint/lookup_library.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,52 @@ namespace nil {
virtual std::size_t get_rows_number(){ return 4; }
};

class keccak_pack_table_type : public lookup_table_definition{
typename BlueprintFieldType::value_type to_sparse(typename BlueprintFieldType::value_type value) {
using value_type = typename BlueprintFieldType::value_type;
using integral_type = typename BlueprintFieldType::integral_type;
integral_type value_integral = integral_type(value.data);
integral_type result_integral = 0;
integral_type power = 1;
for (int i = 0; i < 64; ++i) {
integral_type bit = value_integral & 1;
result_integral = result_integral + bit * power;
value_integral = value_integral >> 1;
power = power << 3;
}
return value_type(result_integral);
}
public:
keccak_pack_table_type(): lookup_table_definition("keccak_pack_table"){
this->subtables["full"] = {{0,1}, 0, 255};
this->subtables["range_check"] = {{0}, 0, 255};
this->subtables["range_check_sparse"] = {{1}, 0, 255};
this->subtables["range_check_135"] = {{0}, 0, 135};
this->subtables["extended"] = {{0,1}, 0, 65535};
this->subtables["range_check_16bit"] = {{0}, 0, 65535};
this->subtables["sparse_16bit"] = {{1}, 0, 65535};
this->subtables["extended_swap"] = {{2,1}, 0, 65535};
}
virtual void generate(){
this->_table.resize(3);

for (typename BlueprintFieldType::integral_type i = 0;
i < typename BlueprintFieldType::integral_type(65536);
i++
) {
this->_table[0].push_back(i);
this->_table[1].push_back(to_sparse(i));
this->_table[2].push_back(typename BlueprintFieldType::value_type((
((i & typename BlueprintFieldType::integral_type(0xFF)) << 8) +
((i & typename BlueprintFieldType::integral_type(0xFF00)) >> 8)
)));
}
}
virtual std::size_t get_columns_number(){ return 3; }
virtual std::size_t get_rows_number(){ return 256; }
};
protected:

class binary_and_table_type : public lookup_table_definition{
public:
binary_and_table_type(): lookup_table_definition("binary_and_table"){
Expand Down Expand Up @@ -315,10 +361,159 @@ namespace nil {
virtual std::size_t get_rows_number(){return 5764801;}
};

class sparse_values_base8_table : public lookup_table_definition{
typename BlueprintFieldType::value_type to_sparse(typename BlueprintFieldType::value_type value) {
using value_type = typename BlueprintFieldType::value_type;
using integral_type = typename BlueprintFieldType::integral_type;
integral_type value_integral = integral_type(value.data);
integral_type result_integral = 0;
integral_type power = 1;
for (int i = 0; i < 64; ++i) {
integral_type bit = value_integral & 1;
result_integral = result_integral + bit * power;
value_integral = value_integral >> 1;
power = power << 3;
}
return value_type(result_integral);
}
public:
sparse_values_base8_table(): lookup_table_definition("keccak_pack_table"){
this->subtables["full"] = {{0,1}, 0, 255};
this->subtables["range_check"] = {{0}, 0, 255};
this->subtables["range_check_sparse"] = {{1}, 0, 255};
this->subtables["64bit"] = {{0}, 128, 255};
}
virtual void generate(){
this->_table.resize(2);

for (typename BlueprintFieldType::integral_type i = 0;
i < typename BlueprintFieldType::integral_type(256);
i++
) {
this->_table[0].push_back(i);
this->_table[1].push_back(to_sparse(i));
}
}
virtual std::size_t get_columns_number(){ return 2; }
virtual std::size_t get_rows_number(){ return 256; }
};

class sparse_values_base8_sign_bit_table : public lookup_table_definition{
// "keccak_pack_table/64bit" doesn't work, so we need to use this temporary table
typename BlueprintFieldType::value_type to_sparse(typename BlueprintFieldType::value_type value) {
using value_type = typename BlueprintFieldType::value_type;
using integral_type = typename BlueprintFieldType::integral_type;
integral_type value_integral = integral_type(value.data);
integral_type result_integral = 0;
integral_type power = 1;
for (int i = 0; i < 64; ++i) {
integral_type bit = value_integral & 1;
result_integral = result_integral + bit * power;
value_integral = value_integral >> 1;
power = power << 3;
}
return value_type(result_integral);
}
public:
sparse_values_base8_sign_bit_table(): lookup_table_definition("keccak_sign_bit_table"){
this->subtables["full"] = {{0}, 0, 128};
}
virtual void generate(){
this->_table.resize(2);
this->_table[0].push_back(0);
this->_table[1].push_back(0);
for (typename BlueprintFieldType::integral_type i = 128;
i < typename BlueprintFieldType::integral_type(256);
i++
) {
this->_table[0].push_back(i);
this->_table[1].push_back(to_sparse(i));
}
}
virtual std::size_t get_columns_number(){ return 1; }
virtual std::size_t get_rows_number(){ return 129; }
};

class normalize_base8_table_type : public lookup_table_definition{
std::size_t base;
virtual std::array<typename BlueprintFieldType::integral_type, 2> to_base(std::size_t base, typename BlueprintFieldType::integral_type num) {
typename BlueprintFieldType::integral_type result = 0;
typename BlueprintFieldType::integral_type normalized_result = 0;
typename BlueprintFieldType::integral_type power = 1;
while (num > 0) {
result = result + (num % base)*power;
normalized_result = normalized_result + ((num % base) & 1)*power;
num /= base;
power <<= 3;
}
return {result, normalized_result};
}
public:
normalize_base8_table_type(std::size_t base_)
: lookup_table_definition("keccak_normalize" + std::to_string(base_) + "_table"), base(base_) {

this->subtables["full"] = {{0,1}, 0, 65535};
}

virtual void generate(){
this->_table.resize(2);
std::vector<std::size_t> value_sizes = {8};

for (typename BlueprintFieldType::integral_type i = 0;
i < typename BlueprintFieldType::integral_type(65536);
i++
) {
std::array<typename BlueprintFieldType::integral_type, 2> value = to_base(base, i);
this->_table[0].push_back(value[0]);
this->_table[1].push_back(value[1]);
}
}
virtual std::size_t get_columns_number(){ return 2; }
virtual std::size_t get_rows_number(){ return 65536; }
};

class chi_table_type : public lookup_table_definition{
virtual std::array<typename BlueprintFieldType::integral_type, 2> to_base_chi(typename BlueprintFieldType::integral_type num) {
std::size_t base = 5;
typename BlueprintFieldType::integral_type table[5] = {0, 1, 1, 0, 0};
typename BlueprintFieldType::integral_type result = 0;
typename BlueprintFieldType::integral_type chi_result = 0;
typename BlueprintFieldType::integral_type power = 1;
while (num > 0) {
result = result + (num % base) * power;
chi_result = chi_result + table[int(num % base)] * power;
num /= base;
power <<= 3;
}
return {result, chi_result};
}
public:
chi_table_type(): lookup_table_definition("keccak_chi_table") {
this->subtables["full"] = {{0,1}, 0, 65535};
}
virtual void generate(){
this->_table.resize(2);
std::vector<std::size_t> value_sizes = {8};

for (typename BlueprintFieldType::integral_type i = 0;
i < typename BlueprintFieldType::integral_type(65536);
i++
) {
std::array<typename BlueprintFieldType::integral_type, 2> value = to_base_chi(i);
this->_table[0].push_back(value[0]);
this->_table[1].push_back(value[1]);
}
}
virtual std::size_t get_columns_number(){ return 2; }
virtual std::size_t get_rows_number(){ return 65536; }
};

class chunk_16_bits_table: public lookup_table_definition{
public:
chunk_16_bits_table(): lookup_table_definition("chunk_16_bits"){
this->subtables["full"] = {{0}, 0, 65535};
this->subtables["8bits"] = {{0}, 0, 255};
this->subtables["10bits"] = {{0}, 0, 1023};
};
virtual void generate(){
this->_table.resize(1);
Expand All @@ -330,6 +525,30 @@ namespace nil {
virtual std::size_t get_columns_number(){return 1;}
virtual std::size_t get_rows_number(){return 65536;}
};

class byte_and_xor_table_type : public lookup_table_definition{
public:
byte_and_xor_table_type(): lookup_table_definition("byte_and_xor_table"){
this->subtables["full"] = {{0,1,2,3}, 0, 65535};
this->subtables["and"] = {{0,1,2}, 0, 65535};
this->subtables["xor"] = {{0,1,3}, 0, 65535};
this->subtables["word"] = {{0,1}, 0, 65535};
}
virtual void generate(){
this->_table.resize(4);
for(std::size_t x = 0; x < 256; x++) {
for(std::size_t y = 0; y < 256; y++) {
this->_table[0].push_back(x);
this->_table[1].push_back(y);
this->_table[2].push_back(x & y);
this->_table[3].push_back(x ^ y);
}
}
}
virtual std::size_t get_columns_number(){ return 4; }
virtual std::size_t get_rows_number(){ return 65536; }
};

public:
using bimap_type = boost::bimap<boost::bimaps::set_of<std::string>, boost::bimaps::set_of<std::size_t>>;
using left_reserved_type = typename bimap_type::left_map;
Expand All @@ -347,8 +566,16 @@ namespace nil {
tables["sha256_reverse_sparse_base7"] = std::shared_ptr<lookup_table_definition>(new reverse_sparse_sigmas_base7_table());
tables["sha256_maj"] = std::shared_ptr<lookup_table_definition>(new maj_function_table());
tables["sha256_ch"] = std::shared_ptr<lookup_table_definition>(new ch_function_table());
tables["keccak_pack_table"] = std::shared_ptr<lookup_table_definition>(new keccak_pack_table_type());
// tables["keccak_pack_table"] = std::shared_ptr<lookup_table_definition>(new sparse_values_base8_table());
tables["keccak_sign_bit_table"] = std::shared_ptr<lookup_table_definition>(new sparse_values_base8_sign_bit_table());
tables["keccak_normalize3_table"] = std::shared_ptr<lookup_table_definition>(new normalize_base8_table_type(3));
tables["keccak_normalize4_table"] = std::shared_ptr<lookup_table_definition>(new normalize_base8_table_type(4));
tables["keccak_normalize6_table"] = std::shared_ptr<lookup_table_definition>(new normalize_base8_table_type(6));
tables["keccak_chi_table"] = std::shared_ptr<lookup_table_definition>(new chi_table_type());
tables["byte_range_table"] = std::shared_ptr<lookup_table_definition>(new byte_range_table_type());
tables["zkevm_opcodes"] = std::shared_ptr<lookup_table_definition>(new zkevm_opcode_table());
tables["byte_and_xor_table"] = std::shared_ptr<lookup_table_definition>(new byte_and_xor_table_type());
}

void register_lookup_table(std::shared_ptr<lookup_table_definition> table){
Expand Down Expand Up @@ -447,4 +674,4 @@ namespace nil {
};
} // namespace blueprint
} // namespace nil
#endif // CRYPTO3_LOOKUP_TABLE_HPP
#endif // CRYPTO3_LOOKUP_TABLE_HPP
1 change: 1 addition & 0 deletions crypto3/libs/blueprint/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ set(PLONK_TESTS_FILES
"hashes/plonk/sha256_process"
"hashes/plonk/sha512_process"
"hashes/plonk/decomposition"
"bbf/hashes/keccak/keccak_round"
#"hashes/plonk/detail/sha_table_generators_base4"
#"hashes/plonk/detail/sha_table_generators_base7"
#"verifiers/kimchi/base_field"
Expand Down
Loading