cryptnox-sdk-arduino 1.0.0
Arduino library for Cryptnox Hardware Wallet
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
14
15#include "keccak256.h"
16#include <string.h>
17
18// Number of rounds for the Keccak-f[1600] permutation
19#define KECCAK_ROUNDS 24
20
21// Round constants for Keccak-f[1600]
22static const uint64_t keccakf_rndc[24] = {
23 0x0000000000000001ULL, 0x0000000000008082ULL,
24 0x800000000000808aULL, 0x8000000080008000ULL,
25 0x000000000000808bULL, 0x0000000080000001ULL,
26 0x8000000080008081ULL, 0x8000000000008009ULL,
27 0x000000000000008aULL, 0x0000000000000088ULL,
28 0x0000000080008009ULL, 0x000000008000000aULL,
29 0x000000008000808bULL, 0x800000000000008bULL,
30 0x8000000000008089ULL, 0x8000000000008003ULL,
31 0x8000000000008002ULL, 0x8000000000000080ULL,
32 0x000000000000800aULL, 0x800000008000000aULL,
33 0x8000000080008081ULL, 0x8000000000008080ULL,
34 0x0000000080000001ULL, 0x8000000080008008ULL
35};
36
44static inline uint64_t rol(uint64_t x, int s) { return (x << s) | (x >> (64 - s)); }
45
54static const int8_t keccakf_rotc[24] = {
55 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14,
56 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44
57};
58static const int8_t keccakf_piln[24] = {
59 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
60 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1
61};
62
63static void keccakf(uint64_t st[25]) {
64 for (int r = 0; r < KECCAK_ROUNDS; ++r) {
65 uint64_t bc[5];
66 for (int i = 0; i < 5; ++i)
67 bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20];
68
69 for (int i = 0; i < 5; ++i) {
70 uint64_t t = bc[(i + 4) % 5] ^ rol(bc[(i + 1) % 5], 1);
71 for (int j = 0; j < 25; j += 5)
72 st[j + i] ^= t;
73 }
74
75 uint64_t t = st[1];
76 for (int i = 0; i < 24; ++i) {
77 int8_t j = keccakf_piln[i];
78 uint64_t tmp = st[j];
79 st[j] = rol(t, keccakf_rotc[i]);
80 t = tmp;
81 }
82
83 for (int j = 0; j < 25; j += 5) {
84 uint64_t bc0 = st[j];
85 uint64_t bc1 = st[j+1];
86 uint64_t bc2 = st[j+2];
87 uint64_t bc3 = st[j+3];
88 uint64_t bc4 = st[j+4];
89
90 st[j] ^= (~bc1) & bc2;
91 st[j+1] ^= (~bc2) & bc3;
92 st[j+2] ^= (~bc3) & bc4;
93 st[j+3] ^= (~bc4) & bc0;
94 st[j+4] ^= (~bc0) & bc1;
95 }
96 st[0] ^= keccakf_rndc[r];
97 }
98}
99
110// cppcheck-suppress unusedFunction
111void keccak256(const uint8_t *in, size_t inlen, uint8_t out[32]) {
112 uint64_t st[25];
113 memset(st, 0, sizeof(st));
114
115 size_t rate = 1088/8; // SHA3-256 rate in bytes
116
117 // Absorb full rate blocks
118 while (inlen >= rate) {
119 for (size_t i = 0; i < rate/8; ++i) {
120 uint64_t t = 0;
121 memcpy(&t, in + i*8, 8);
122 st[i] ^= t;
123 }
124 keccakf(st);
125 inlen -= rate;
126 in += rate;
127 }
128
129 // Absorb remaining bytes and pad
130 uint8_t temp[200];
131 memset(temp, 0, sizeof(temp));
132 memcpy(temp, in, inlen);
133 temp[inlen] = 0x01; // Ethereum Keccak-256 padding
134 temp[rate-1] |= 0x80;
135
136 for (size_t i = 0; i < rate/8; ++i) {
137 uint64_t t = 0;
138 memcpy(&t, temp + i*8, 8);
139 st[i] ^= t;
140 }
141 keccakf(st);
142
143 // Copy first 32 bytes of state as hash output
144 memcpy(out, st, 32);
145}
static uint64_t rol(uint64_t x, int s)
Rotate a 64-bit integer left by s bits.
Definition keccak256.cpp:44
static const uint64_t keccakf_rndc[24]
Definition keccak256.cpp:22
static void keccakf(uint64_t st[25])
Definition keccak256.cpp:63
void keccak256(const uint8_t *in, size_t inlen, uint8_t out[32])
Compute Keccak-256 hash of input data.
#define KECCAK_ROUNDS
Definition keccak256.cpp:19
static const int8_t keccakf_rotc[24]
Keccak-f[1600] permutation on the state array.
Definition keccak256.cpp:54
static const int8_t keccakf_piln[24]
Definition keccak256.cpp:58
Keccak-256 (SHA3 variant) hash function for Ethereum.