99#![ warn( missing_docs) ]  
1010
1111pub  use  digest:: { self ,  Digest } ; 
12- 
13- use  core:: { convert:: TryInto ,  fmt} ; 
14- #[ cfg( feature = "zeroize" ) ]  
15- use  digest:: zeroize:: { Zeroize ,  ZeroizeOnDrop } ; 
1612use  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. 
4028pub  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. 
4432pub  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. 
18535pub  type  KupynaLongVar  = RtVariableCoreWrapper < KupynaLongVarCore > ; 
18636/// Core hasher state of the long Kupyna variant generic over output size. 
18737pub  type  KupynaLongCore < OutSize >  = CtVariableCoreWrapper < KupynaLongVarCore ,  OutSize > ; 
18838/// Hasher state of the long Kupyna variant generic over output size. 
18939pub  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. 
19246pub  type  Kupyna384  = CoreWrapper < KupynaLongCore < U48 > > ; 
19347/// Kupyna-512 hasher state. 
19448pub  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