Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
blake2s.cpp
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#include "blake_util.hpp"
8
11
19namespace bb::stdlib {
20
40template <typename Builder> void Blake2s<Builder>::increment_counter(blake2s_state& S, const uint32_t inc)
41{
42 field_ct inc_scalar(static_cast<uint256_t>(inc));
43 S.t[0] = S.t[0] + inc_scalar;
44 // TODO: Secure!? Think so as inc is known at "compile" time as it's derived from the msg length.
45 const bool to_inc = uint32_t(uint256_t(S.t[0].get_value())) < inc;
46 S.t[1] = S.t[1] + (to_inc ? field_ct(1) : field_ct(0));
47}
48
49template <typename Builder> void Blake2s<Builder>::compress(blake2s_state& S, byte_array_ct const& in)
50{
52 using namespace blake_util;
53 field_ct m[BLAKE2S_STATE_SIZE];
54 field_ct v[BLAKE2S_STATE_SIZE];
55
56 for (size_t i = 0; i < BLAKE2S_STATE_SIZE; ++i) {
57 m[i] = static_cast<field_ct>(in.slice(i * 4, 4).reverse());
58 }
59
60 for (size_t i = 0; i < 8; ++i) {
61 v[i] = S.h[i];
62 }
63
64 v[8] = field_ct(uint256_t(blake2s_IV[0]));
65 v[9] = field_ct(uint256_t(blake2s_IV[1]));
66 v[10] = field_ct(uint256_t(blake2s_IV[2]));
67 v[11] = field_ct(uint256_t(blake2s_IV[3]));
68
69 // Use the lookup tables to perform XORs
70 const auto lookup_1 =
72 v[12] = lookup_1[ColumnIdx::C3][0];
73 const auto lookup_2 =
75 v[13] = lookup_2[ColumnIdx::C3][0];
76 const auto lookup_3 =
78 v[14] = lookup_3[ColumnIdx::C3][0];
79 const auto lookup_4 =
81 v[15] = lookup_4[ColumnIdx::C3][0];
82
83 for (size_t idx = 0; idx < 10; idx++) {
84 blake_util::round_fn(v, m, idx);
85 }
86
87 // At this point in the algorithm, the elements (v0, v1, v2, v3) and (v8, v9, v10, v11) in the state matrix 'v' can
88 // be 'overflowed' i.e. contain values > 2^{32}. However we do NOT need to normalize them to be < 2^{32}, the
89 // following `read_sequence_from_table` calls correctly constrain the output to be 32-bits
90 for (size_t i = 0; i < 8; ++i) {
91 const auto lookup_a = plookup_read<Builder>::get_lookup_accumulators(BLAKE_XOR, S.h[i], v[i], true);
92 const auto lookup_b =
93 plookup_read<Builder>::get_lookup_accumulators(BLAKE_XOR, lookup_a[ColumnIdx::C3][0], v[i + 8], true);
94 S.h[i] = lookup_b[ColumnIdx::C3][0];
95 }
96}
97
98template <typename Builder> void Blake2s<Builder>::blake2s(blake2s_state& S, byte_array_ct const& in)
99{
100 using plookup::ColumnIdx;
101 using namespace blake_util;
102
103 size_t offset = 0;
104 size_t size = in.size();
105
106 while (size > BLAKE2S_BLOCKBYTES) {
107 increment_counter(S, BLAKE2S_BLOCKBYTES);
108 compress(S, in.slice(offset, BLAKE2S_BLOCKBYTES));
109 offset += BLAKE2S_BLOCKBYTES;
110 size -= BLAKE2S_BLOCKBYTES;
111 }
112
113 // Set last block.
114 S.f[0] = field_t<Builder>(uint256_t((uint32_t)-1));
115
116 byte_array_ct final(in.get_context());
117 final.write(in.slice(offset)).write(byte_array_ct(in.get_context(), BLAKE2S_BLOCKBYTES - size));
118 increment_counter(S, static_cast<uint32_t>(size));
119 compress(S, final);
120}
121
122template <typename Builder> byte_array<Builder> Blake2s<Builder>::hash(const byte_array_ct& input)
123{
125
126 for (size_t i = 0; i < 8; i++) {
127 S.h[i] = field_ct(uint256_t(initial_H[i]));
128 }
129
130 blake2s(S, input);
131
132 byte_array_ct result(input.get_context());
133 for (auto h : S.h) {
134 byte_array_ct v(h, 4);
135 result.write(v.reverse());
136 }
137 return result;
138}
139
140template class Blake2s<UltraCircuitBuilder>;
141template class Blake2s<MegaCircuitBuilder>;
142
143} // namespace bb::stdlib
static void compress(blake2s_state &S, byte_array_ct const &in)
Definition blake2s.cpp:49
static void blake2s(blake2s_state &S, byte_array_ct const &in)
Definition blake2s.cpp:98
static byte_array_ct hash(const byte_array_ct &input)
Definition blake2s.cpp:122
static void increment_counter(blake2s_state &S, const uint32_t inc)
Definition blake2s.cpp:40
Represents a dynamic array of bytes in-circuit.
byte_array slice(size_t offset) const
Slice bytes from the byte array starting at offset. Does not add any constraints.
byte_array reverse() const
Reverse the bytes in the byte array.
byte_array & write(byte_array const &other)
Appends the contents of another byte_array (other) to the end of this one.
size_t size() const
Builder * get_context() const
bb::fr get_value() const
Given a := *this, compute its value given by a.v * a.mul + a.add.
Definition field.cpp:827
WASM_EXPORT void blake2s(uint8_t const *data, out_buf32 out)
Definition c_bind.cpp:13
ssize_t offset
Definition engine.cpp:36
stdlib::field_t< Builder > field_ct
stdlib::byte_array< Builder > byte_array_ct
void round_fn(field_t< Builder > state[BLAKE_STATE_SIZE], field_t< Builder > msg[BLAKE_STATE_SIZE], size_t round, const bool which_blake=false)
std::vector< uint8_t > compress(const std::vector< uint8_t > &input)
void write(B &buf, field2< base_field, Params > const &value)
field_t< Builder > f[2]
Definition blake2s.hpp:33
field_t< Builder > t[2]
Definition blake2s.hpp:32
field_t< Builder > h[8]
Definition blake2s.hpp:31