Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
keccak.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/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
8 * Copyright 2018-2019 Pawel Bylica.
9 * Licensed under the Apache License, Version 2.0.
10 */
11
12#include "keccak.hpp"
13
14#include "./hash_types.hpp"
15
16#if _MSC_VER
17#include <string.h>
18#define __builtin_memcpy memcpy
19#endif
20
21#if _WIN32
22/* On Windows assume little endian. */
23#define __LITTLE_ENDIAN 1234
24#define __BIG_ENDIAN 4321
25#define __BYTE_ORDER __LITTLE_ENDIAN
26#elif __APPLE__
27#include <machine/endian.h>
28#else
29#include <endian.h>
30#endif
31
32#if __BYTE_ORDER == __LITTLE_ENDIAN
33#define to_le64(X) X
34#else
35#define to_le64(X) __builtin_bswap64(X)
36#endif
37
38#if __BYTE_ORDER == __LITTLE_ENDIAN
39#define to_be64(X) __builtin_bswap64(X)
40#else
41#define to_be64(X) X
42#endif
43
45static inline uint64_t load_le(const uint8_t* data)
46{
47 /* memcpy is the best way of expressing the intention. Every compiler will
48 optimize is to single load instruction if the target architecture
49 supports unaligned memory access (GCC and clang even in O0).
50 This is great trick because we are violating C/C++ memory alignment
51 restrictions with no performance penalty. */
52 uint64_t word;
53 __builtin_memcpy(&word, data, sizeof(word));
54 return to_le64(word);
55}
56
57static inline void keccak(uint64_t* out, size_t bits, const uint8_t* data, size_t size)
58{
59 static const size_t word_size = sizeof(uint64_t);
60 const size_t hash_size = bits / 8;
61 const size_t block_size = (1600 - bits * 2) / 8;
62
63 size_t i;
64 uint64_t* state_iter;
65 uint64_t last_word = 0;
66 uint8_t* last_word_iter = (uint8_t*)&last_word;
67
68 uint64_t state[25] = { 0 };
69
70 while (size >= block_size) {
71 for (i = 0; i < (block_size / word_size); ++i) {
72 state[i] ^= load_le(data);
73 data += word_size;
74 }
75
76 ethash_keccakf1600(state);
77
78 size -= block_size;
79 }
80
81 state_iter = state;
82
83 while (size >= word_size) {
84 *state_iter ^= load_le(data);
85 ++state_iter;
86 data += word_size;
87 size -= word_size;
88 }
89
90 while (size > 0) {
91 *last_word_iter = *data;
92 ++last_word_iter;
93 ++data;
94 --size;
95 }
96 *last_word_iter = 0x01;
97 *state_iter ^= to_le64(last_word);
98
99 state[(block_size / word_size) - 1] ^= 0x8000000000000000;
100
101 ethash_keccakf1600(state);
102
103 for (i = 0; i < (hash_size / word_size); ++i)
104 out[i] = to_le64(state[i]);
105}
106
107struct keccak256 ethash_keccak256(const uint8_t* data, size_t size) NOEXCEPT
108{
109 struct keccak256 hash;
110 keccak(hash.word64s, 256, data, size);
111 return hash;
112}
113
114struct keccak256 hash_field_elements(const uint64_t* limbs, size_t num_elements)
115{
116 uint8_t input_buffer[num_elements * 32];
117
118 for (size_t i = 0; i < num_elements; ++i) {
119 for (size_t j = 0; j < 4; ++j) {
120 uint64_t word = (limbs[i * 4 + j]);
121 size_t idx = i * 32 + j * 8;
122 input_buffer[idx] = (uint8_t)((word >> 56) & 0xff);
123 input_buffer[idx + 1] = (uint8_t)((word >> 48) & 0xff);
124 input_buffer[idx + 2] = (uint8_t)((word >> 40) & 0xff);
125 input_buffer[idx + 3] = (uint8_t)((word >> 32) & 0xff);
126 input_buffer[idx + 4] = (uint8_t)((word >> 24) & 0xff);
127 input_buffer[idx + 5] = (uint8_t)((word >> 16) & 0xff);
128 input_buffer[idx + 6] = (uint8_t)((word >> 8) & 0xff);
129 input_buffer[idx + 7] = (uint8_t)(word & 0xff);
130 }
131 }
132
133 return ethash_keccak256(input_buffer, num_elements * 32);
134}
135
136struct keccak256 hash_field_element(const uint64_t* limb)
137{
138 return hash_field_elements(limb, 1);
139}
const std::vector< FF > data
struct keccak256 ethash_keccak256(const uint8_t *data, size_t size) NOEXCEPT
Definition keccak.cpp:107
#define to_le64(X)
Definition keccak.cpp:33
struct keccak256 hash_field_elements(const uint64_t *limbs, size_t num_elements)
Definition keccak.cpp:114
struct keccak256 hash_field_element(const uint64_t *limb)
Definition keccak.cpp:136
#define NOEXCEPT
Definition keccak.hpp:21
void ethash_keccakf1600(uint64_t state[25]) NOEXCEPT
void hash(State &state) noexcept
KeccakF1600 keccak