9
9
#![ warn( missing_docs) ]
10
10
11
11
pub use digest:: { self , Digest } ;
12
-
13
- use core:: { convert:: TryInto , fmt} ;
14
- #[ cfg( feature = "zeroize" ) ]
15
- use digest:: zeroize:: { Zeroize , ZeroizeOnDrop } ;
16
12
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 } ,
26
15
} ;
27
16
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;
31
23
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 ;
38
26
39
27
/// Short Kupyna variant which allows to choose output size at runtime.
40
28
pub type KupynaShortVar = RtVariableCoreWrapper < KupynaShortVarCore > ;
@@ -43,279 +31,18 @@ pub type KupynaShortCore<OutSize> = CtVariableCoreWrapper<KupynaShortVarCore, Ou
43
31
/// Hasher state of the short Kupyna variant generic over output size.
44
32
pub type KupynaShort < OutSize > = CoreWrapper < KupynaShortCore < OutSize > > ;
45
33
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
-
184
34
/// Long Kupyna variant which allows to choose output size at runtime.
185
35
pub type KupynaLongVar = RtVariableCoreWrapper < KupynaLongVarCore > ;
186
36
/// Core hasher state of the long Kupyna variant generic over output size.
187
37
pub type KupynaLongCore < OutSize > = CtVariableCoreWrapper < KupynaLongVarCore , OutSize > ;
188
38
/// Hasher state of the long Kupyna variant generic over output size.
189
39
pub type KupynaLong < OutSize > = CoreWrapper < KupynaLongCore < OutSize > > ;
190
40
41
+ /// Kupyna-224 hasher state.
42
+ pub type Kupyna224 = CoreWrapper < KupynaShortCore < U28 > > ;
43
+ /// Kupyna-256 hasher state.
44
+ pub type Kupyna256 = CoreWrapper < KupynaShortCore < U32 > > ;
191
45
/// Kupyna-384 hasher state.
192
46
pub type Kupyna384 = CoreWrapper < KupynaLongCore < U48 > > ;
193
47
/// Kupyna-512 hasher state.
194
48
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