cryptnox-pos
1.0.0
Standalone USDC payment terminal firmware (ESP32 + Cryptnox smart card)
Toggle main menu visibility
Loading...
Searching...
No Matches
keccak256.cpp
Go to the documentation of this file.
1
/*
2
* SPDX-License-Identifier: LGPL-3.0-or-later
3
* Copyright (c) 2026 Cryptnox SA
4
*/
5
10
11
/******************************************************************
12
* 1. Included files
13
******************************************************************/
14
15
#include "
keccak256.h
"
16
#include <string.h>
17
18
#include "CW_Utils.h"
/* hardened memory primitives (CODING_RULES §1.4) */
19
20
/******************************************************************
21
* 2. Constants
22
******************************************************************/
23
24
#define KECCAK_ROUNDS 24U
25
#define KECCAK_RATE 136U
/* 1088 / 8 bytes — rate for 256-bit output */
26
#define KECCAK_STATE_LANE 25U
/* 5×5 uint64_t lanes */
27
28
static
const
uint64_t
kRC
[
KECCAK_ROUNDS
] = {
29
0x0000000000000001ULL, 0x0000000000008082ULL,
30
0x800000000000808AULL, 0x8000000080008000ULL,
31
0x000000000000808BULL, 0x0000000080000001ULL,
32
0x8000000080008081ULL, 0x8000000000008009ULL,
33
0x000000000000008AULL, 0x0000000000000088ULL,
34
0x0000000080008009ULL, 0x000000008000000AULL,
35
0x000000008000808BULL, 0x800000000000008BULL,
36
0x8000000000008089ULL, 0x8000000000008003ULL,
37
0x8000000000008002ULL, 0x8000000000000080ULL,
38
0x000000000000800AULL, 0x800000008000000AULL,
39
0x8000000080008081ULL, 0x8000000000008080ULL,
40
0x0000000080000001ULL, 0x8000000080008008ULL,
41
};
42
43
/* Rho rotation offsets for lane [x + 5*y], derived from the Keccak spec. */
44
static
const
uint8_t
kRHO
[
KECCAK_STATE_LANE
] = {
45
0, 1, 62, 28, 27,
/* y=0 */
46
36, 44, 6, 55, 20,
/* y=1 */
47
3, 10, 43, 25, 39,
/* y=2 */
48
41, 45, 15, 21, 8,
/* y=3 */
49
18, 2, 61, 56, 14
/* y=4 */
50
};
51
52
/******************************************************************
53
* 3. Internal helpers
54
******************************************************************/
55
63
static
uint64_t
rot64
(uint64_t x, uint8_t n)
64
{
65
return
(n == 0U) ? x : ((x << n) | (x >> (64U - n)));
66
}
67
73
static
void
keccak_f1600
(uint64_t st[
KECCAK_STATE_LANE
])
74
{
75
uint64_t C[5], D[5], B[
KECCAK_STATE_LANE
];
76
unsigned
int
round, x, y;
77
78
for
(round = 0U; round <
KECCAK_ROUNDS
; round++) {
79
/* Theta */
80
for
(x = 0U; x < 5U; x++) {
81
C[x] = st[x] ^ st[x + 5U] ^ st[x + 10U] ^ st[x + 15U] ^ st[x + 20U];
82
}
83
for
(x = 0U; x < 5U; x++) {
84
D[x] = C[(x + 4U) % 5U] ^
rot64
(C[(x + 1U) % 5U], 1U);
85
}
86
for
(x = 0U; x < 5U; x++) {
87
for
(y = 0U; y < 5U; y++) {
88
st[x + 5U * y] ^= D[x];
89
}
90
}
91
92
/* Rho + Pi: B[dst] = ROT(st[src], rho[src]) */
93
for
(x = 0U; x < 5U; x++) {
94
for
(y = 0U; y < 5U; y++) {
95
unsigned
int
src = x + 5U * y;
96
unsigned
int
dst_x = y;
97
unsigned
int
dst_y = (2U * x + 3U * y) % 5U;
98
B[dst_x + 5U * dst_y] =
rot64
(st[src],
kRHO
[src]);
99
}
100
}
101
102
/* Chi */
103
for
(x = 0U; x < 5U; x++) {
104
for
(y = 0U; y < 5U; y++) {
105
st[x + 5U * y] = B[x + 5U * y] ^
106
((~B[(x + 1U) % 5U + 5U * y]) &
107
B[(x + 2U) % 5U + 5U * y]);
108
}
109
}
110
111
/* Iota */
112
st[0] ^=
kRC
[round];
113
}
114
}
115
116
/******************************************************************
117
* 4. Public API
118
******************************************************************/
119
120
void
keccak256
(
const
uint8_t *input,
size_t
length, uint8_t digest[32])
121
{
122
uint64_t state[
KECCAK_STATE_LANE
];
123
uint8_t *sb =
reinterpret_cast<
uint8_t *
>
(state);
124
size_t
offset = 0U;
125
size_t
i;
126
127
CW_Utils::secure_wipe(sb,
sizeof
(state));
128
129
/* Absorb full blocks */
130
while
((length - offset) >=
KECCAK_RATE
) {
131
for
(i = 0U; i <
KECCAK_RATE
; i++) {
132
sb[i] ^= input[offset + i];
133
}
134
keccak_f1600
(state);
135
offset +=
KECCAK_RATE
;
136
}
137
138
/* Absorb remaining bytes */
139
size_t
rem = length - offset;
140
for
(i = 0U; i < rem; i++) {
141
sb[i] ^= input[offset + i];
142
}
143
144
/* Pad: 0x01 for Ethereum Keccak (pre-NIST), 0x80 at end of rate block */
145
sb[rem] ^= 0x01U;
146
sb[
KECCAK_RATE
- 1U] ^= 0x80U;
147
148
keccak_f1600
(state);
149
150
/* Squeeze first 32 bytes */
151
(void)CW_Utils::safe_memcpy(digest, 32U, sb, 32U);
152
}
KECCAK_STATE_LANE
#define KECCAK_STATE_LANE
Definition
keccak256.cpp:26
keccak_f1600
static void keccak_f1600(uint64_t st[KECCAK_STATE_LANE])
Apply the full 24-round Keccak-f[1600] permutation in place.
Definition
keccak256.cpp:73
kRC
static const uint64_t kRC[KECCAK_ROUNDS]
Definition
keccak256.cpp:28
rot64
static uint64_t rot64(uint64_t x, uint8_t n)
Rotate a 64-bit lane left by n bits.
Definition
keccak256.cpp:63
kRHO
static const uint8_t kRHO[KECCAK_STATE_LANE]
Definition
keccak256.cpp:44
KECCAK_ROUNDS
#define KECCAK_ROUNDS
Definition
keccak256.cpp:24
keccak256
void keccak256(const uint8_t *input, size_t length, uint8_t digest[32])
Compute the Keccak-256 digest of a buffer.
Definition
keccak256.cpp:120
KECCAK_RATE
#define KECCAK_RATE
Definition
keccak256.cpp:25
keccak256.h
Original Keccak-256 digest as used by Ethereum.
main
keccak256.cpp
Generated by
1.17.0