Skip to content

Commit f2be22d

Browse files
authored
kupyna: re-organize module structure (#676)
Additionally, move some common code to the `utils` modules.
1 parent dfac1d6 commit f2be22d

File tree

7 files changed

+421
-455
lines changed

7 files changed

+421
-455
lines changed
File renamed without changes.

Diff for: kupyna/src/lib.rs

+14-287
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,20 @@
99
#![warn(missing_docs)]
1010

1111
pub use digest::{self, Digest};
12-
13-
use core::{convert::TryInto, fmt};
14-
#[cfg(feature = "zeroize")]
15-
use digest::zeroize::{Zeroize, ZeroizeOnDrop};
1612
use digest::{
17-
HashMarker, InvalidOutputSize, Output,
18-
block_buffer::Eager,
19-
core_api::{
20-
AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper,
21-
CtVariableCoreWrapper, OutputSizeUser, RtVariableCoreWrapper, TruncSide, UpdateCore,
22-
VariableOutputCore,
23-
},
24-
crypto_common::hazmat::{DeserializeStateError, SerializableState, SerializedState},
25-
typenum::{U28, U32, U48, U64, U72, U128, U136, Unsigned},
13+
core_api::{CoreWrapper, CtVariableCoreWrapper, RtVariableCoreWrapper},
14+
typenum::{U28, U32, U48, U64},
2615
};
2716

28-
mod compress1024;
29-
mod compress512;
30-
mod tables;
17+
mod consts;
18+
mod long;
19+
mod long_compress;
20+
mod short;
21+
mod short_compress;
22+
pub(crate) mod utils;
3123

32-
/// Lowest-level core hasher state of the short Kupyna variant.
33-
#[derive(Clone)]
34-
pub struct KupynaShortVarCore {
35-
state: [u64; compress512::COLS],
36-
blocks_len: u64,
37-
}
24+
pub use long::KupynaLongVarCore;
25+
pub use short::KupynaShortVarCore;
3826

3927
/// Short Kupyna variant which allows to choose output size at runtime.
4028
pub type KupynaShortVar = RtVariableCoreWrapper<KupynaShortVarCore>;
@@ -43,279 +31,18 @@ pub type KupynaShortCore<OutSize> = CtVariableCoreWrapper<KupynaShortVarCore, Ou
4331
/// Hasher state of the short Kupyna variant generic over output size.
4432
pub type KupynaShort<OutSize> = CoreWrapper<KupynaShortCore<OutSize>>;
4533

46-
/// Kupyna-224 hasher state.
47-
pub type Kupyna224 = CoreWrapper<KupynaShortCore<U28>>;
48-
/// Kupyna-256 hasher state.
49-
pub type Kupyna256 = CoreWrapper<KupynaShortCore<U32>>;
50-
51-
impl HashMarker for KupynaShortVarCore {}
52-
53-
impl BlockSizeUser for KupynaShortVarCore {
54-
type BlockSize = U64;
55-
}
56-
57-
impl BufferKindUser for KupynaShortVarCore {
58-
type BufferKind = Eager;
59-
}
60-
61-
impl UpdateCore for KupynaShortVarCore {
62-
#[inline]
63-
fn update_blocks(&mut self, blocks: &[Block<Self>]) {
64-
self.blocks_len += blocks.len() as u64;
65-
for block in blocks {
66-
compress512::compress(&mut self.state, block.as_ref());
67-
}
68-
}
69-
}
70-
71-
impl OutputSizeUser for KupynaShortVarCore {
72-
type OutputSize = U32;
73-
}
74-
75-
impl VariableOutputCore for KupynaShortVarCore {
76-
const TRUNC_SIDE: TruncSide = TruncSide::Right;
77-
78-
#[inline]
79-
fn new(output_size: usize) -> Result<Self, InvalidOutputSize> {
80-
if output_size > Self::OutputSize::USIZE {
81-
return Err(InvalidOutputSize);
82-
}
83-
let mut state = [0; compress512::COLS];
84-
state[0] = 0x40;
85-
state[0] <<= 56;
86-
let blocks_len = 0;
87-
Ok(Self { state, blocks_len })
88-
}
89-
90-
fn finalize_variable_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
91-
let block_size = Self::BlockSize::USIZE as u128;
92-
let msg_len_bytes = (self.blocks_len as u128) * block_size + (buffer.get_pos() as u128);
93-
let msg_len_bits = 8 * msg_len_bytes;
94-
95-
buffer.digest_pad(0x80, &msg_len_bits.to_le_bytes()[0..12], |block| {
96-
compress512::compress(&mut self.state, block.as_ref());
97-
});
98-
99-
let mut state_u8 = [0u8; 64];
100-
for (src, dst) in self.state.iter().zip(state_u8.chunks_exact_mut(8)) {
101-
dst.copy_from_slice(&src.to_be_bytes());
102-
}
103-
104-
// Call t_xor_l with u8 array
105-
let t_xor_ult_processed_block = compress512::t_xor_l(state_u8);
106-
107-
let result_u8 = compress512::xor_bytes(state_u8, t_xor_ult_processed_block);
108-
109-
// Convert result back to u64s
110-
let mut res = [0u64; 8];
111-
for (dst, src) in res.iter_mut().zip(result_u8.chunks_exact(8)) {
112-
*dst = u64::from_be_bytes(src.try_into().unwrap());
113-
}
114-
let n = compress512::COLS / 2;
115-
for (chunk, v) in out.chunks_exact_mut(8).zip(res[n..].iter()) {
116-
chunk.copy_from_slice(&v.to_be_bytes());
117-
}
118-
}
119-
}
120-
121-
impl AlgorithmName for KupynaShortVarCore {
122-
#[inline]
123-
fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
124-
f.write_str("KupynaShort")
125-
}
126-
}
127-
128-
impl fmt::Debug for KupynaShortVarCore {
129-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130-
f.write_str("KupynaShortVarCore { ... }")
131-
}
132-
}
133-
134-
impl Drop for KupynaShortVarCore {
135-
fn drop(&mut self) {
136-
#[cfg(feature = "zeroize")]
137-
{
138-
self.state.zeroize();
139-
self.blocks_len.zeroize();
140-
}
141-
}
142-
}
143-
144-
impl SerializableState for KupynaShortVarCore {
145-
type SerializedStateSize = U72;
146-
147-
fn serialize(&self) -> SerializedState<Self> {
148-
let mut serialized_state = SerializedState::<Self>::default();
149-
150-
for (val, chunk) in self.state.iter().zip(serialized_state.chunks_exact_mut(8)) {
151-
chunk.copy_from_slice(&val.to_le_bytes());
152-
}
153-
154-
serialized_state[64..].copy_from_slice(&self.blocks_len.to_le_bytes());
155-
serialized_state
156-
}
157-
158-
fn deserialize(
159-
serialized_state: &SerializedState<Self>,
160-
) -> Result<Self, DeserializeStateError> {
161-
let (serialized_state, serialized_block_len) = serialized_state.split::<U64>();
162-
163-
let mut state = [0; compress512::COLS];
164-
for (val, chunk) in state.iter_mut().zip(serialized_state.chunks_exact(8)) {
165-
*val = u64::from_le_bytes(chunk.try_into().unwrap());
166-
}
167-
168-
let blocks_len = u64::from_le_bytes(*serialized_block_len.as_ref());
169-
170-
Ok(Self { state, blocks_len })
171-
}
172-
}
173-
174-
#[cfg(feature = "zeroize")]
175-
impl ZeroizeOnDrop for KupynaShortVarCore {}
176-
177-
/// Lowest-level core hasher state of the long Kupyna variant.
178-
#[derive(Clone)]
179-
pub struct KupynaLongVarCore {
180-
state: [u64; compress1024::COLS],
181-
blocks_len: u64,
182-
}
183-
18434
/// Long Kupyna variant which allows to choose output size at runtime.
18535
pub type KupynaLongVar = RtVariableCoreWrapper<KupynaLongVarCore>;
18636
/// Core hasher state of the long Kupyna variant generic over output size.
18737
pub type KupynaLongCore<OutSize> = CtVariableCoreWrapper<KupynaLongVarCore, OutSize>;
18838
/// Hasher state of the long Kupyna variant generic over output size.
18939
pub type KupynaLong<OutSize> = CoreWrapper<KupynaLongCore<OutSize>>;
19040

41+
/// Kupyna-224 hasher state.
42+
pub type Kupyna224 = CoreWrapper<KupynaShortCore<U28>>;
43+
/// Kupyna-256 hasher state.
44+
pub type Kupyna256 = CoreWrapper<KupynaShortCore<U32>>;
19145
/// Kupyna-384 hasher state.
19246
pub type Kupyna384 = CoreWrapper<KupynaLongCore<U48>>;
19347
/// Kupyna-512 hasher state.
19448
pub type Kupyna512 = CoreWrapper<KupynaLongCore<U64>>;
195-
196-
impl HashMarker for KupynaLongVarCore {}
197-
198-
impl BlockSizeUser for KupynaLongVarCore {
199-
type BlockSize = U128;
200-
}
201-
202-
impl BufferKindUser for KupynaLongVarCore {
203-
type BufferKind = Eager;
204-
}
205-
206-
impl UpdateCore for KupynaLongVarCore {
207-
#[inline]
208-
fn update_blocks(&mut self, blocks: &[Block<Self>]) {
209-
self.blocks_len += blocks.len() as u64;
210-
for block in blocks {
211-
compress1024::compress(&mut self.state, block.as_ref());
212-
}
213-
}
214-
}
215-
216-
impl OutputSizeUser for KupynaLongVarCore {
217-
type OutputSize = U64;
218-
}
219-
220-
impl VariableOutputCore for KupynaLongVarCore {
221-
const TRUNC_SIDE: TruncSide = TruncSide::Right;
222-
223-
#[inline]
224-
fn new(output_size: usize) -> Result<Self, InvalidOutputSize> {
225-
if output_size > Self::OutputSize::USIZE {
226-
return Err(InvalidOutputSize);
227-
}
228-
let mut state = [0; compress1024::COLS];
229-
state[0] = 0x80;
230-
state[0] <<= 56;
231-
let blocks_len = 0;
232-
Ok(Self { state, blocks_len })
233-
}
234-
235-
#[inline]
236-
fn finalize_variable_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
237-
let block_size = Self::BlockSize::USIZE as u128;
238-
let msg_len_bytes = (self.blocks_len as u128) * block_size + (buffer.get_pos() as u128);
239-
let msg_len_bits = 8 * msg_len_bytes;
240-
241-
buffer.digest_pad(0x80, &msg_len_bits.to_le_bytes()[0..12], |block| {
242-
compress1024::compress(&mut self.state, block.as_ref());
243-
});
244-
245-
let mut state_u8 = [0u8; 128];
246-
for (src, dst) in self.state.iter().zip(state_u8.chunks_exact_mut(8)) {
247-
dst.copy_from_slice(&src.to_be_bytes());
248-
}
249-
250-
// Call t_xor_l with u8 array
251-
let t_xor_ult_processed_block = compress1024::t_xor_l(state_u8);
252-
253-
let result_u8 = compress1024::xor_bytes(state_u8, t_xor_ult_processed_block);
254-
255-
// Convert result back to u64s
256-
let mut res = [0u64; 16];
257-
for (dst, src) in res.iter_mut().zip(result_u8.chunks_exact(8)) {
258-
*dst = u64::from_be_bytes(src.try_into().unwrap());
259-
}
260-
let n = compress1024::COLS / 2;
261-
for (chunk, v) in out.chunks_exact_mut(8).zip(res[n..].iter()) {
262-
chunk.copy_from_slice(&v.to_be_bytes());
263-
}
264-
}
265-
}
266-
267-
impl AlgorithmName for KupynaLongVarCore {
268-
#[inline]
269-
fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
270-
f.write_str("KupynaLong")
271-
}
272-
}
273-
274-
impl fmt::Debug for KupynaLongVarCore {
275-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
276-
f.write_str("KupynaLongVarCore { ... }")
277-
}
278-
}
279-
280-
impl Drop for KupynaLongVarCore {
281-
fn drop(&mut self) {
282-
#[cfg(feature = "zeroize")]
283-
{
284-
self.state.zeroize();
285-
self.blocks_len.zeroize();
286-
}
287-
}
288-
}
289-
290-
impl SerializableState for KupynaLongVarCore {
291-
type SerializedStateSize = U136;
292-
293-
fn serialize(&self) -> SerializedState<Self> {
294-
let mut serialized_state = SerializedState::<Self>::default();
295-
296-
for (val, chunk) in self.state.iter().zip(serialized_state.chunks_exact_mut(8)) {
297-
chunk.copy_from_slice(&val.to_le_bytes());
298-
}
299-
300-
serialized_state[128..].copy_from_slice(&self.blocks_len.to_le_bytes());
301-
serialized_state
302-
}
303-
304-
fn deserialize(
305-
serialized_state: &SerializedState<Self>,
306-
) -> Result<Self, DeserializeStateError> {
307-
let (serialized_state, serialized_block_len) = serialized_state.split::<U128>();
308-
309-
let mut state = [0; compress1024::COLS];
310-
for (val, chunk) in state.iter_mut().zip(serialized_state.chunks_exact(8)) {
311-
*val = u64::from_le_bytes(chunk.try_into().unwrap());
312-
}
313-
314-
let blocks_len = u64::from_le_bytes(*serialized_block_len.as_ref());
315-
316-
Ok(Self { state, blocks_len })
317-
}
318-
}
319-
320-
#[cfg(feature = "zeroize")]
321-
impl ZeroizeOnDrop for KupynaLongVarCore {}

0 commit comments

Comments
 (0)