Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
keccak.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7#pragma once
9#include <array>
10
11namespace bb::stdlib {
12
25template <typename Builder> class keccak {
26 public:
31
32 // base of extended representation we use for efficient logic operations
33 static constexpr uint256_t BASE = 11;
34
35 // number of bits of hash output
36 static constexpr size_t BITS = 256;
37
38 // word size of hash lane
39 static constexpr size_t WORD_SIZE = 8;
40
41 // block size. We only support keccak256 with a 1088-bit rate! This is what Ethereum uses
42 static constexpr size_t BLOCK_SIZE = (1600 - BITS * 2) / WORD_SIZE;
43
44 // how many limbs fit into a block (17)
45 static constexpr size_t LIMBS_PER_BLOCK = BLOCK_SIZE / 8;
46
47 static constexpr size_t NUM_KECCAK_ROUNDS = 24;
48
49 // 1 "lane" = 64 bits. Instead of interpreting the keccak sponge as 1,600 bits, it's easier to work over 64-bit
50 // "lanes". 1,600 / 64 = 25.
51 static constexpr size_t NUM_KECCAK_LANES = 25;
52
53 // round constants. Used in IOTA round
54 static constexpr std::array<uint64_t, NUM_KECCAK_ROUNDS> RC = {
55 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000, 0x000000000000808b,
56 0x0000000080000001, 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, 0x0000000000000088,
57 0x0000000080008009, 0x000000008000000a, 0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
58 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a,
59 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008
60 };
61
62 // Rotation offsets, y vertically, x horizontally: r[y * 5 + x]
63 static constexpr std::array<size_t, NUM_KECCAK_LANES> ROTATIONS = {
64 0, 1, 62, 28, 27, 36, 44, 6, 55, 20, 3, 10, 43, 25, 39, 41, 45, 15, 21, 8, 18, 2, 61, 56, 14,
65 };
66
76 static constexpr uint256_t convert_to_sparse(uint256_t input)
77 {
79 size_t count = 0;
80 while (input > 0) {
81 uint64_t bit = static_cast<uint64_t>(input & 1);
82 out_bits[count++] = bit;
83 input = input >> 1;
84 }
85 uint256_t output = 0;
86 for (size_t i = 0; i < count; ++i) {
87 output *= BASE;
88 output += out_bits[count - 1 - i];
89 }
90 return output;
91 };
92
104 static constexpr uint256_t normalize_sparse(uint256_t input)
105 {
107 size_t count = 0;
108 while (input > 0) {
109 const auto [quotient, slice] = input.divmod(BASE);
110 uint64_t bit = static_cast<uint64_t>(slice) & 1;
111 out_bits[count++] = bit;
112 input = quotient;
113 }
114 uint256_t out;
115 for (size_t i = 0; i < count; ++i) {
116 out *= BASE;
117 out += out_bits[count - 1 - i];
118 }
119 return out;
120 }
121
128 {
130 for (size_t i = 0; i < 24; ++i) {
131 output[i] = convert_to_sparse(RC[i]);
132 }
133 return output;
134 }
136
147 static constexpr uint256_t get_chi_offset()
148 {
149 uint256_t result = 0;
150 for (size_t i = 0; i < 64; ++i) {
151 result *= 11;
152 result += 1;
153 }
154 return result;
155 }
156 static constexpr uint256_t CHI_OFFSET = get_chi_offset();
157
164
165 template <size_t lane_index> static field_t<Builder> normalize_and_rotate(const field_ct& limb, field_ct& msb);
166 static void compute_twisted_state(keccak_state& internal);
167 static void theta(keccak_state& state);
168 static void rho(keccak_state& state);
169 static void pi(keccak_state& state);
170 static void chi(keccak_state& state);
171 static void iota(keccak_state& state, size_t round);
172 static void sponge_absorb(keccak_state& internal,
173 const std::vector<field_ct>& input_buffer,
174 const std::vector<field_ct>& msb_buffer);
175 static byte_array_ct sponge_squeeze(keccak_state& internal);
176 static void keccakf1600(keccak_state& state);
177 static byte_array_ct hash(byte_array_ct& input);
178
180
181 static std::vector<uint8_t> hash_native(const std::vector<uint8_t>& data)
182 {
183 auto hash_result = ethash_keccak256(&data[0], data.size());
184
185 std::vector<uint8_t> output;
186 output.resize(32);
187
188 memcpy((void*)&output[0], (void*)&hash_result.word64s[0], 32);
189 return output;
190 }
191
192 // exposing keccak f1600 permutation
196 static void sponge_absorb_with_permutation_opcode(keccak_state& internal,
197 std::vector<field_ct>& input_buffer,
198 const size_t input_size);
199 static std::array<field_ct, NUM_KECCAK_LANES> extended_2_normal(keccak_state& internal);
202};
203
204template <typename Builder> void generate_keccak_test_circuit(Builder& builder, size_t num_iterations);
205
206} // namespace bb::stdlib
constexpr std::pair< uint256_t, uint256_t > divmod(const uint256_t &b) const
Implements boolean logic in-circuit.
Definition bool.hpp:59
Represents a dynamic array of bytes in-circuit.
KECCAAAAAAAAAAK.
Definition keccak.hpp:25
static constexpr uint256_t get_chi_offset()
Compute the constant offset added in the Chi round.
Definition keccak.hpp:147
static void rho(keccak_state &state)
RHO round.
Definition keccak.cpp:387
static constexpr uint256_t CHI_OFFSET
Definition keccak.hpp:156
static constexpr uint256_t BASE
Definition keccak.hpp:33
static constexpr uint256_t normalize_sparse(uint256_t input)
Normalize a base-11 integer where each base value can be > 1.
Definition keccak.hpp:104
static constexpr std::array< uint256_t, NUM_KECCAK_ROUNDS > get_sparse_round_constants()
Get the sparse round constants object.
Definition keccak.hpp:127
static void sponge_absorb_with_permutation_opcode(keccak_state &internal, std::vector< field_ct > &input_buffer, const size_t input_size)
Definition keccak.cpp:650
static byte_array_ct sponge_squeeze_for_permutation_opcode(std::array< field_ct, NUM_KECCAK_LANES > lanes, Builder *context)
Definition keccak.cpp:765
static void pi(keccak_state &state)
PI.
Definition keccak.cpp:402
static void theta(keccak_state &state)
THETA round.
Definition keccak.cpp:253
static std::vector< field_ct > format_input_lanes(byte_array_ct &input)
Convert the input buffer into 8-bit keccak lanes in little-endian form. Additionally,...
Definition keccak.cpp:559
static void compute_twisted_state(keccak_state &internal)
Compute twisted representation of hash lane.
Definition keccak.cpp:199
static void chi(keccak_state &state)
CHI.
Definition keccak.cpp:438
static std::vector< uint8_t > hash_native(const std::vector< uint8_t > &data)
Definition keccak.hpp:181
static byte_array_ct sponge_squeeze(keccak_state &internal)
Definition keccak.cpp:526
static constexpr size_t LIMBS_PER_BLOCK
Definition keccak.hpp:45
static field_t< Builder > normalize_and_rotate(const field_ct &limb, field_ct &msb)
Normalize a base-11 limb and left-rotate by keccak::ROTATIONS[lane_index] bits. This method also extr...
Definition keccak.cpp:37
static constexpr std::array< size_t, NUM_KECCAK_LANES > ROTATIONS
Definition keccak.hpp:63
static constexpr std::array< uint64_t, NUM_KECCAK_ROUNDS > RC
Definition keccak.hpp:54
static constexpr size_t NUM_KECCAK_ROUNDS
Definition keccak.hpp:47
static constexpr std::array< uint256_t, NUM_KECCAK_ROUNDS > SPARSE_RC
Definition keccak.hpp:135
static std::array< field_ct, NUM_KECCAK_LANES > permutation_opcode(std::array< field_ct, NUM_KECCAK_LANES > state, Builder *context)
Definition keccak.cpp:627
static std::array< field_ct, NUM_KECCAK_LANES > extended_2_normal(keccak_state &internal)
Definition keccak.cpp:748
static byte_array_ct hash_using_permutation_opcode(byte_array_ct &input)
Definition keccak.cpp:680
static constexpr size_t WORD_SIZE
Definition keccak.hpp:39
static void keccakf1600(keccak_state &state)
Definition keccak.cpp:484
static byte_array_ct hash(byte_array_ct &input)
Definition keccak.cpp:706
static constexpr size_t NUM_KECCAK_LANES
Definition keccak.hpp:51
static constexpr size_t BLOCK_SIZE
Definition keccak.hpp:42
static void sponge_absorb(keccak_state &internal, const std::vector< field_ct > &input_buffer, const std::vector< field_ct > &msb_buffer)
Definition keccak.cpp:496
static constexpr size_t BITS
Definition keccak.hpp:36
static void iota(keccak_state &state, size_t round)
IOTA.
Definition keccak.cpp:471
static constexpr uint256_t convert_to_sparse(uint256_t input)
Convert a binary integer into a base11 integer.
Definition keccak.hpp:76
AluTraceBuilder builder
Definition alu.test.cpp:123
const std::vector< FF > data
StrictMock< MockContext > context
struct keccak256 ethash_keccak256(const uint8_t *data, size_t size) NOEXCEPT
Definition keccak.cpp:107
void generate_keccak_test_circuit(Builder &builder, size_t num_iterations)
Generate a simple keccak circuit for testing purposes.
Definition keccak.cpp:794
C slice(C const &container, size_t start)
Definition container.hpp:9
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::array< field_ct, NUM_KECCAK_LANES > state
Definition keccak.hpp:159
std::array< field_ct, NUM_KECCAK_LANES > twisted_state
Definition keccak.hpp:161
std::array< field_ct, NUM_KECCAK_LANES > state_msb
Definition keccak.hpp:160