Skip to content

Commit 6768d59

Browse files
committed
Minor code refactoring
Signed-off-by: Anjan Roy <hello@itzmeanjan.in>
1 parent eeaa963 commit 6768d59

File tree

9 files changed

+174
-106
lines changed

9 files changed

+174
-106
lines changed

include/sha3/internals/keccak.hpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <bit>
44
#include <cstddef>
55
#include <cstdint>
6+
#include <limits>
67

78
// Keccak-p[1600, 24] permutation
89
namespace keccak {
@@ -13,8 +14,15 @@ static constexpr size_t L = 6;
1314
// Bit width of each lane of Keccak-p[1600, 24] state
1415
static constexpr size_t LANE_BW = 1ul << L;
1516

17+
// Bit length of Keccak-p[1600, 24] permutation state
18+
static constexpr size_t STATE_BIT_LEN = 1600;
19+
20+
// Byte length of Keccak-p[1600, 24] permutation state
21+
static constexpr size_t STATE_BYTE_LEN =
22+
STATE_BIT_LEN / std::numeric_limits<uint8_t>::digits;
23+
1624
// # -of lanes ( each of 64 -bit width ) in Keccak-p[1600, 24] state
17-
static constexpr size_t LANE_CNT = 1600 / LANE_BW;
25+
static constexpr size_t LANE_CNT = STATE_BIT_LEN / LANE_BW;
1826

1927
// Keccak-p[b, nr] permutation to be applied `nr` ( = 24 ) rounds
2028
// s.t. b = 1600, w = b/ 25, l = log2(w), nr = 12 + 2l

include/sha3/internals/sponge.hpp

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <array>
66
#include <cstdint>
77
#include <cstring>
8+
#include <limits>
89
#include <span>
910

1011
// Keccak family of sponge functions
@@ -21,7 +22,7 @@ namespace sponge {
2122
constexpr bool
2223
check_domain_separator(const size_t dom_sep_bit_len)
2324
{
24-
return (dom_sep_bit_len == 2) | (dom_sep_bit_len == 4);
25+
return (dom_sep_bit_len == 2u) | (dom_sep_bit_len == 4u);
2526
}
2627

2728
// Pad10*1 - generates a padding, while also considering domain separator bits (
@@ -37,17 +38,18 @@ check_domain_separator(const size_t dom_sep_bit_len)
3738
// This function implementation collects motivation from
3839
// https://github.com/itzmeanjan/turboshake/blob/e1a6b950/src/sponge.rs#L70-L72
3940
template<uint8_t domain_separator, size_t ds_bits, size_t rate>
40-
static inline constexpr std::array<uint8_t, rate / 8>
41+
static inline constexpr std::array<uint8_t,
42+
rate / std::numeric_limits<uint8_t>::digits>
4143
pad10x1(const size_t offset)
4244
requires(check_domain_separator(ds_bits))
4345
{
44-
std::array<uint8_t, rate / 8> res{};
46+
std::array<uint8_t, rate / std::numeric_limits<uint8_t>::digits> res{};
4547

46-
constexpr uint8_t mask = (1 << ds_bits) - 1;
47-
constexpr uint8_t pad_byte = (1 << ds_bits) | (domain_separator & mask);
48+
constexpr uint8_t mask = (1u << ds_bits) - 1u;
49+
constexpr uint8_t pad_byte = (1u << ds_bits) | (domain_separator & mask);
4850

4951
res[offset] = pad_byte;
50-
res[(rate / 8) - 1] ^= 0x80;
52+
res[res.size() - 1] ^= 0x80u;
5153

5254
return res;
5355
}
@@ -67,14 +69,14 @@ absorb(uint64_t state[keccak::LANE_CNT],
6769
size_t& offset,
6870
std::span<const uint8_t> msg)
6971
{
70-
constexpr size_t rbytes = rate >> 3; // # -of bytes
71-
constexpr size_t rwords = rbytes >> 3; // # -of 64 -bit words
72+
constexpr size_t rbytes = rate >> 3u; // # -of bytes
73+
constexpr size_t rwords = rbytes >> 3u; // # -of 64 -bit words
7274

7375
std::array<uint8_t, rbytes> blk_bytes{};
7476
std::array<uint64_t, rwords> blk_words{};
7577

76-
auto _blk_bytes = std::span(blk_bytes);
77-
auto _blk_words = std::span(blk_words);
78+
auto blk_bytes_span = std::span(blk_bytes);
79+
auto blk_words_span = std::span(blk_words);
7880

7981
const size_t mlen = msg.size();
8082
const size_t blk_cnt = (offset + mlen) / rbytes;
@@ -84,14 +86,14 @@ absorb(uint64_t state[keccak::LANE_CNT],
8486
for (size_t i = 0; i < blk_cnt; i++) {
8587
const size_t readable = rbytes - offset;
8688

87-
auto _msg = msg.subspan(moff, readable);
88-
auto _blk = _blk_bytes.subspan(offset, readable);
89+
auto msg_span = msg.subspan(moff, readable);
90+
auto blk_span = blk_bytes_span.subspan(offset, readable);
8991

90-
std::copy(_msg.begin(), _msg.end(), _blk.begin());
91-
sha3_utils::le_bytes_to_u64_words<rate>(_blk_bytes, _blk_words);
92+
std::copy(msg_span.begin(), msg_span.end(), blk_span.begin());
93+
sha3_utils::le_bytes_to_u64_words<rate>(blk_bytes_span, blk_words_span);
9294

9395
for (size_t j = 0; j < rwords; j++) {
94-
state[j] ^= _blk_words[j];
96+
state[j] ^= blk_words_span[j];
9597
}
9698

9799
keccak::permute(state);
@@ -102,15 +104,15 @@ absorb(uint64_t state[keccak::LANE_CNT],
102104

103105
const size_t rm_bytes = mlen - moff;
104106

105-
auto _msg = msg.subspan(moff, rm_bytes);
106-
auto _blk = _blk_bytes.subspan(offset, rm_bytes);
107+
auto msg_span = msg.subspan(moff, rm_bytes);
108+
auto blk_span = blk_bytes_span.subspan(offset, rm_bytes);
107109

108110
blk_bytes.fill(0x00);
109-
std::copy(_msg.begin(), _msg.end(), _blk.begin());
110-
sha3_utils::le_bytes_to_u64_words<rate>(_blk_bytes, _blk_words);
111+
std::copy(msg_span.begin(), msg_span.end(), blk_span.begin());
112+
sha3_utils::le_bytes_to_u64_words<rate>(blk_bytes_span, blk_words_span);
111113

112114
for (size_t j = 0; j < rwords; j++) {
113-
state[j] ^= _blk_words[j];
115+
state[j] ^= blk_words_span[j];
114116
}
115117

116118
offset += rm_bytes;
@@ -132,19 +134,19 @@ static inline constexpr void
132134
finalize(uint64_t state[keccak::LANE_CNT], size_t& offset)
133135
requires(check_domain_separator(ds_bits))
134136
{
135-
constexpr size_t rbytes = rate >> 3; // # -of bytes
136-
constexpr size_t rwords = rbytes >> 3; // # -of 64 -bit words
137+
constexpr size_t rbytes = rate >> 3u; // # -of bytes
138+
constexpr size_t rwords = rbytes >> 3u; // # -of 64 -bit words
137139

138140
const auto padb = pad10x1<domain_separator, ds_bits, rate>(offset);
139141
std::array<uint64_t, rwords> padw{};
140142

141-
auto _padb = std::span(padb);
142-
auto _padw = std::span(padw);
143+
auto padb_span = std::span(padb);
144+
auto padw_span = std::span(padw);
143145

144-
sha3_utils::le_bytes_to_u64_words<rate>(_padb, _padw);
146+
sha3_utils::le_bytes_to_u64_words<rate>(padb_span, padw_span);
145147

146148
for (size_t j = 0; j < rwords; j++) {
147-
state[j] ^= _padw[j];
149+
state[j] ^= padw_span[j];
148150
}
149151

150152
keccak::permute(state);
@@ -168,14 +170,14 @@ squeeze(uint64_t state[keccak::LANE_CNT],
168170
size_t& squeezable,
169171
std::span<uint8_t> out)
170172
{
171-
constexpr size_t rbytes = rate >> 3; // # -of bytes
172-
constexpr size_t rwords = rbytes >> 3; // # -of 64 -bit words
173+
constexpr size_t rbytes = rate >> 3u; // # -of bytes
174+
constexpr size_t rwords = rbytes >> 3u; // # -of 64 -bit words
173175

174176
std::array<uint8_t, rbytes> blk_bytes{};
175-
auto _blk_bytes = std::span(blk_bytes);
177+
auto blk_bytes_span = std::span(blk_bytes);
176178

177179
auto swords = std::span{ state, keccak::LANE_CNT };
178-
auto _swords = swords.template subspan<0, rwords>();
180+
auto swords_span = swords.template subspan<0, rwords>();
179181

180182
const size_t olen = out.size();
181183
size_t off = 0;
@@ -184,12 +186,12 @@ squeeze(uint64_t state[keccak::LANE_CNT],
184186
const size_t read = std::min(squeezable, olen - off);
185187
const size_t soff = rbytes - squeezable;
186188

187-
sha3_utils::u64_words_to_le_bytes<rate>(_swords, _blk_bytes);
189+
sha3_utils::u64_words_to_le_bytes<rate>(swords_span, blk_bytes_span);
188190

189-
auto _blk = _blk_bytes.subspan(soff, read);
190-
auto _out = out.subspan(off, read);
191+
auto blk_span = blk_bytes_span.subspan(soff, read);
192+
auto out_span = out.subspan(off, read);
191193

192-
std::copy(_blk.begin(), _blk.end(), _out.begin());
194+
std::copy(blk_span.begin(), blk_span.end(), out_span.begin());
193195

194196
squeezable -= read;
195197
off += read;

include/sha3/internals/utils.hpp

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#pragma once
2+
#include "sha3/internals/keccak.hpp"
23
#include <cassert>
34
#include <cstddef>
45
#include <cstdint>
56
#include <cstring>
7+
#include <limits>
68
#include <span>
79

810
// Utility ( or commonly used ) functions for SHA3 implementation
@@ -19,30 +21,30 @@ bswap(const uint64_t a)
1921
#if defined __GNUG__
2022
return __builtin_bswap64(a);
2123
#else
22-
return ((a & 0x00000000000000fful) << 56) |
23-
((a & 0x000000000000ff00ul) << 40) |
24-
((a & 0x0000000000ff0000ul) << 24) |
25-
((a & 0x00000000ff000000ul) << 0x8) |
26-
((a & 0x000000ff00000000ul) >> 0x8) |
27-
((a & 0x0000ff0000000000ul) >> 24) |
28-
((a & 0x00ff000000000000ul) >> 40) |
29-
((a & 0xff00000000000000ul) >> 56);
24+
return ((a & 0x00000000000000fful) << 56u) |
25+
((a & 0x000000000000ff00ul) << 40u) |
26+
((a & 0x0000000000ff0000ul) << 24u) |
27+
((a & 0x00000000ff000000ul) << 0x8u) |
28+
((a & 0x000000ff00000000ul) >> 0x8u) |
29+
((a & 0x0000ff0000000000ul) >> 24u) |
30+
((a & 0x00ff000000000000ul) >> 40u) |
31+
((a & 0xff00000000000000ul) >> 56u);
3032
#endif
3133
}
3234

3335
// Given a byte array of length 8, this routine can be used for interpreting
3436
// those 8 -bytes in little-endian order, as a 64 -bit unsigned integer.
3537
static inline constexpr uint64_t
36-
le_bytes_to_u64(std::span<const uint8_t> bytes)
38+
le_bytes_to_u64(std::span<const uint8_t, sizeof(uint64_t)> bytes)
3739
{
38-
const uint64_t word = (static_cast<uint64_t>(bytes[7]) << 56) |
39-
(static_cast<uint64_t>(bytes[6]) << 48) |
40-
(static_cast<uint64_t>(bytes[5]) << 40) |
41-
(static_cast<uint64_t>(bytes[4]) << 32) |
42-
(static_cast<uint64_t>(bytes[3]) << 24) |
43-
(static_cast<uint64_t>(bytes[2]) << 16) |
44-
(static_cast<uint64_t>(bytes[1]) << 8) |
45-
(static_cast<uint64_t>(bytes[0]) << 0);
40+
const uint64_t word = (static_cast<uint64_t>(bytes[7]) << 56u) |
41+
(static_cast<uint64_t>(bytes[6]) << 48u) |
42+
(static_cast<uint64_t>(bytes[5]) << 40u) |
43+
(static_cast<uint64_t>(bytes[4]) << 32u) |
44+
(static_cast<uint64_t>(bytes[3]) << 24u) |
45+
(static_cast<uint64_t>(bytes[2]) << 16u) |
46+
(static_cast<uint64_t>(bytes[1]) << 8u) |
47+
(static_cast<uint64_t>(bytes[0]) << 0u);
4648

4749
if constexpr (std::endian::native == std::endian::big) {
4850
return bswap(word);
@@ -56,46 +58,57 @@ le_bytes_to_u64(std::span<const uint8_t> bytes)
5658
// unsigned interger ) s.t. bytes in a word are placed in little-endian order.
5759
template<size_t rate>
5860
static inline constexpr void
59-
le_bytes_to_u64_words(std::span<const uint8_t, rate / 8> bytes,
60-
std::span<uint64_t, rate / 64> words)
61+
le_bytes_to_u64_words(
62+
std::span<const uint8_t, rate / std::numeric_limits<uint8_t>::digits> bytes,
63+
std::span<uint64_t, rate / keccak::LANE_BW> words)
6164
{
65+
using u64_span_t = std::span<const uint8_t, sizeof(uint64_t)>;
66+
constexpr size_t step_by_bytes = sizeof(uint64_t);
67+
6268
size_t off = 0;
6369
while (off < bytes.size()) {
64-
words[off / 8] = le_bytes_to_u64(bytes.subspan(off, 8));
65-
off += 8;
70+
words[off / step_by_bytes] =
71+
le_bytes_to_u64(u64_span_t(bytes.subspan(off, step_by_bytes)));
72+
off += step_by_bytes;
6673
}
6774
}
6875

6976
// Given a 64 -bit unsigned integer as input, this routine can be used for
7077
// interpreting those 8 -bytes in little-endian byte order.
7178
static inline constexpr void
72-
u64_to_le_bytes(uint64_t word, std::span<uint8_t> bytes)
79+
u64_to_le_bytes(uint64_t word, std::span<uint8_t, sizeof(word)> bytes)
7380
{
7481
if constexpr (std::endian::native == std::endian::big) {
7582
word = bswap(word);
7683
}
7784

78-
bytes[0] = static_cast<uint8_t>(word >> 0);
79-
bytes[1] = static_cast<uint8_t>(word >> 8);
80-
bytes[2] = static_cast<uint8_t>(word >> 16);
81-
bytes[3] = static_cast<uint8_t>(word >> 24);
82-
bytes[4] = static_cast<uint8_t>(word >> 32);
83-
bytes[5] = static_cast<uint8_t>(word >> 40);
84-
bytes[6] = static_cast<uint8_t>(word >> 48);
85-
bytes[7] = static_cast<uint8_t>(word >> 56);
85+
bytes[0] = static_cast<uint8_t>(word >> 0u);
86+
bytes[1] = static_cast<uint8_t>(word >> 8u);
87+
bytes[2] = static_cast<uint8_t>(word >> 16u);
88+
bytes[3] = static_cast<uint8_t>(word >> 24u);
89+
bytes[4] = static_cast<uint8_t>(word >> 32u);
90+
bytes[5] = static_cast<uint8_t>(word >> 40u);
91+
bytes[6] = static_cast<uint8_t>(word >> 48u);
92+
bytes[7] = static_cast<uint8_t>(word >> 56u);
8693
}
8794

8895
// Given an array of rate/64 -many 64 -bit unsigned integer words, this routine
8996
// can be used for interpreting words in little-endian byte-order, computing
9097
// rate/8 -many bytes output.
9198
template<size_t rate>
9299
static inline constexpr void
93-
u64_words_to_le_bytes(std::span<const uint64_t, rate / 64> words,
94-
std::span<uint8_t, rate / 8> bytes)
100+
u64_words_to_le_bytes(
101+
std::span<const uint64_t, rate / keccak::LANE_BW> words,
102+
std::span<uint8_t, rate / std::numeric_limits<uint8_t>::digits> bytes)
95103
{
104+
using u64_span_t = std::span<uint8_t, sizeof(uint64_t)>;
105+
constexpr size_t step_by_bytes = sizeof(uint64_t);
106+
96107
size_t off = 0;
97108
while (off < words.size()) {
98-
u64_to_le_bytes(words[off], bytes.subspan(off * 8, 8));
109+
u64_to_le_bytes(
110+
words[off],
111+
u64_span_t(bytes.subspan(off * step_by_bytes, step_by_bytes)));
99112
off++;
100113
}
101114
}

include/sha3/sha3_224.hpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
#pragma once
22
#include "sha3/internals/sponge.hpp"
3+
#include <cstdint>
4+
#include <limits>
35

46
// SHA3-224 Hash Function : Keccak[448](M || 01, 224)
57
namespace sha3_224 {
68

79
// Bit length of SHA3-224 message digest.
8-
constexpr size_t DIGEST_BIT_LEN = 224;
10+
static constexpr size_t DIGEST_BIT_LEN = 224;
911

1012
// Byte length of SHA3-224 message digest.
11-
constexpr size_t DIGEST_LEN = DIGEST_BIT_LEN / 8;
13+
static constexpr size_t DIGEST_LEN = DIGEST_BIT_LEN / 8;
1214

1315
// Width of capacity portion of the sponge, in bits.
14-
constexpr size_t CAPACITY = 2 * DIGEST_BIT_LEN;
16+
static constexpr size_t CAPACITY = 2 * DIGEST_BIT_LEN;
1517

1618
// Width of rate portion of the sponge, in bits.
17-
constexpr size_t RATE = 1600 - CAPACITY;
19+
static constexpr size_t RATE = 1600 - CAPACITY;
1820

1921
// Domain separator bits, used for finalization.
20-
constexpr uint8_t DOM_SEP = 0b00000010;
22+
static constexpr uint8_t DOM_SEP = 0b00000010;
2123

2224
// Bit-width of domain separator, starting from least significant bit.
23-
constexpr size_t DOM_SEP_BW = 2;
25+
static constexpr size_t DOM_SEP_BW = 2;
2426

2527
// Given arbitrary many input message bytes, this routine consumes it into
2628
// keccak[448] sponge state and squeezes out 28 -bytes digest.
@@ -67,7 +69,7 @@ struct sha3_224_t
6769
inline constexpr void digest(std::span<uint8_t, DIGEST_LEN> md)
6870
{
6971
if (finalized && !squeezed) {
70-
size_t squeezable = RATE / 8;
72+
size_t squeezable = RATE / std::numeric_limits<uint8_t>::digits;
7173
sponge::squeeze<RATE>(state, squeezable, md);
7274

7375
squeezed = true;

0 commit comments

Comments
 (0)