-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathromulush.hpp
85 lines (65 loc) · 2.38 KB
/
romulush.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#pragma once
#include "skinny.hpp"
// Romulus Hash Function
namespace romulush {
// 32 -bytes input message compression function, used in Romulus-H hash
// function, where message is consumed into two 128 -bit states ( i.e. denoted
// by left & right )
//
// See algorithm `CF(...)` in section 2.4.6 of Romulus specification
// https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/romulus-spec-final.pdf
inline static void compress(
uint8_t* const __restrict left, // 16 -bytes state
uint8_t* const __restrict right, // 16 -bytes state
const uint8_t* const __restrict msg // 32 -bytes message to be compressed
) {
skinny::state_t st;
uint8_t left_prime[16];
std::memcpy(st.arr + 0, left, 16);
std::memcpy(st.arr + 16, right, 16);
std::memcpy(st.arr + 32, msg, 32);
skinny::tbc(&st);
for (size_t i = 0; i < 16; i++) {
left_prime[i] = st.arr[i] ^ left[i];
}
left[0] ^= 0b00000001;
std::memcpy(st.arr + 0, left, 16);
std::memcpy(st.arr + 16, right, 16);
std::memcpy(st.arr + 32, msg, 32);
skinny::tbc(&st);
for (size_t i = 0; i < 16; i++) {
right[i] = st.arr[i] ^ left[i];
}
std::memcpy(left, left_prime, 16);
}
// Given N -bytes input message this routine computes 32 -bytes digest using
// Romulus-H hash function | N >= 0
//
// See algorithm `Romulus-H(...)` in section 2.4.6 of Romulus specification
// https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/romulus-spec-final.pdf
inline static void hash(
const uint8_t* const __restrict msg, // input message to be hashed
const size_t mlen, // len(msg) >= 0
uint8_t* const __restrict dig // 32 -bytes digest computed
) {
uint8_t left[16];
uint8_t right[16];
uint8_t last_blk[32];
std::memset(left, 0, sizeof(left));
std::memset(right, 0, sizeof(right));
std::memset(last_blk, 0, sizeof(last_blk));
const size_t blk_cnt = mlen >> 5;
const size_t rm_bytes = mlen & 31;
for (size_t i = 0; i < blk_cnt; i++) {
const size_t off = i << 5;
compress(left, right, msg + off);
}
const size_t off = blk_cnt << 5;
std::memcpy(last_blk, msg + off, rm_bytes);
last_blk[31] = rm_bytes;
left[0] ^= 0b00000010;
compress(left, right, last_blk);
std::memcpy(dig, left, 16);
std::memcpy(dig + 16, right, 16);
}
} // namespace romulush