55 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
66) ]
77
8- mod utils ;
8+ mod u64_le_utils ;
99
1010/// Cursor for implementing sponge-based absorption and squeezing.
1111///
12- /// This type wraps `u8` and enforces that its value is always smaller than `Rate `.
12+ /// This type wraps `u8` and enforces that its value is always smaller than `RATE `.
1313///
14- /// `Rate ` MUST be smaller than `U256 `, trying to initialize cursor with an invalid rate will
14+ /// `RATE ` MUST be smaller than `256 `, trying to initialize cursor with an invalid rate will
1515/// result in a compilation error.
1616#[ derive( Debug , Clone ) ]
1717pub struct SpongeCursor < const RATE : usize > {
@@ -30,11 +30,11 @@ impl<const RATE: usize> Default for SpongeCursor<RATE> {
3030}
3131
3232// Note that the methods should compile into a panic-free code,
33- // see: https://rust.godbolt.org/z/3v4zWr4ox
33+ // see: https://rust.godbolt.org/z/r93WE8zq3
3434impl < const RATE : usize > SpongeCursor < RATE > {
3535 /// Create new cursor with the provided position.
3636 ///
37- /// Returns `None` if `pos` is bigger or equal to `Rate `.
37+ /// Returns `None` if `pos` is bigger or equal to `RATE `.
3838 #[ must_use]
3939 pub fn new ( pos : u8 ) -> Option < Self > {
4040 if usize:: from ( pos) < RATE {
@@ -54,7 +54,7 @@ impl<const RATE: usize> SpongeCursor<RATE> {
5454 if self . pos < rate_u8 {
5555 self . pos
5656 } else {
57- // SAFETY: the type enforces that `pos` is always smaller than `Rate `
57+ // SAFETY: the type enforces that `pos` is always smaller than `RATE `
5858 unsafe { core:: hint:: unreachable_unchecked ( ) } ;
5959 }
6060 }
@@ -68,19 +68,25 @@ impl<const RATE: usize> SpongeCursor<RATE> {
6868 if pos < RATE {
6969 pos
7070 } else {
71- // SAFETY: the type enforces that `pos` is always smaller than `Rate `
71+ // SAFETY: the type enforces that `pos` is always smaller than `RATE `
7272 unsafe { core:: hint:: unreachable_unchecked ( ) } ;
7373 }
7474 }
7575
76- /// Absorb bytes from `data` into a `u64`-based state using little ednian byte order .
76+ /// Set new cursor position .
7777 ///
78- /// Size of state MUST be greater or equal to `Rate`. Using an invalid `N` will result in
79- /// a compilation error.
80- #[ allow(
81- clippy:: missing_panics_doc,
82- reason = "the method is panic-free, see: https://rust.godbolt.org/z/88Wf1qEsr"
83- ) ]
78+ /// # Panics
79+ /// If `new_pos` is greater or equal to `RATE`.
80+ fn set_pos ( & mut self , new_pos : usize ) {
81+ assert ! ( new_pos < RATE ) ;
82+ self . pos = u8:: try_from ( new_pos) . expect ( "`new_pos` is smaller than `RATE`" ) ;
83+ }
84+
85+ /// Absorb bytes from `data` into `state` using little-endian byte order.
86+ ///
87+ /// Size of `state` in bytes MUST be greater or equal to `RATE`.
88+ /// Using an invalid `N` will result in a compilation error.
89+ #[ allow( clippy:: missing_panics_doc, reason = "the method is panic-free" ) ]
8490 #[ inline]
8591 pub fn absorb_u64_le < const N : usize > (
8692 & mut self ,
@@ -96,44 +102,44 @@ impl<const RATE: usize> SpongeCursor<RATE> {
96102
97103 if self . pos != 0 {
98104 let pos = self . pos ( ) ;
99- let rem_len = RATE - pos;
100-
101- let is_partial = data. len ( ) < rem_len;
102- let head = if is_partial {
103- data
104- } else {
105- let ( head, tail) = data. split_at ( rem_len) ;
106- data = tail;
107- head
108- } ;
105+ let rem_len = RATE
106+ . checked_sub ( pos)
107+ . expect ( "`pos` is always smaller than `RATE`" ) ;
109108
110- utils:: absorb_partial :: < N , RATE > ( state, pos, head) ;
111-
112- if is_partial {
113- self . pos = u8:: try_from ( pos + head. len ( ) ) . expect ( "the sum is smaller than Rate" ) ;
109+ if data. len ( ) < rem_len {
110+ u64_le_utils:: absorb_partial :: < N , RATE > ( state, pos, data) ;
111+ self . set_pos ( pos + data. len ( ) ) ;
114112 return ;
115113 }
116114
115+ let ( head, tail) = data. split_at ( rem_len) ;
116+ data = tail;
117+ u64_le_utils:: absorb_partial :: < N , RATE > ( state, pos, head) ;
118+
117119 sponge ( state) ;
118120 }
119121
120122 let blocks = data. chunks_exact ( RATE ) ;
121123 let tail = blocks. remainder ( ) ;
122124
123125 for block in blocks {
124- let block: & [ u8 ; RATE ] = block. try_into ( ) . expect ( "block has correct size" ) ;
125- utils :: absorb_full ( state, block) ;
126+ let block: & [ u8 ; RATE ] = block. try_into ( ) . expect ( "` block` has correct size" ) ;
127+ u64_le_utils :: absorb_full ( state, block) ;
126128 sponge ( state) ;
127129 }
128130
129131 if !tail. is_empty ( ) {
130- utils :: absorb_partial :: < N , RATE > ( state, 0 , tail) ;
132+ u64_le_utils :: absorb_partial :: < N , RATE > ( state, 0 , tail) ;
131133 }
132134
133- self . pos = u8 :: try_from ( tail. len ( ) ) . expect ( "tail.len() is smaller than RATE" ) ;
135+ self . set_pos ( tail. len ( ) ) ;
134136 }
135137
136- /// Squeeze data by reading it into `buf`.
138+ /// Squeeze data from `state` by reading it into `buf` using little-endian byte order.
139+ ///
140+ /// Size of `state` in bytes MUST be greater or equal to `RATE`.
141+ /// Using an invalid `N` will result in a compilation error.
142+ #[ inline]
137143 pub fn squeeze_read_u64_le < const N : usize > (
138144 & mut self ,
139145 state : & mut [ u64 ; N ] ,
@@ -144,12 +150,16 @@ impl<const RATE: usize> SpongeCursor<RATE> {
144150 state,
145151 sponge,
146152 buf,
147- utils :: squeeze_read_partial :: < N , RATE > ,
148- utils :: squeeze_read_full,
153+ u64_le_utils :: squeeze_read_partial :: < N , RATE > ,
154+ u64_le_utils :: squeeze_read_full,
149155 ) ;
150156 }
151157
152- /// Squeeze data by XOR-ing it with data in `buf`.
158+ /// Squeeze data from `state` by XOR-ing it with data in `buf` using little-endian byte order.
159+ ///
160+ /// Size of `state` in bytes MUST be greater or equal to `RATE`.
161+ /// Using an invalid `N` will result in a compilation error.
162+ #[ inline]
153163 pub fn squeeze_xor_u64_le < const N : usize > (
154164 & mut self ,
155165 state : & mut [ u64 ; N ] ,
@@ -160,11 +170,12 @@ impl<const RATE: usize> SpongeCursor<RATE> {
160170 state,
161171 sponge,
162172 buf,
163- utils :: squeeze_xor_partial :: < N , RATE > ,
164- utils :: squeeze_xor_full,
173+ u64_le_utils :: squeeze_xor_partial :: < N , RATE > ,
174+ u64_le_utils :: squeeze_xor_full,
165175 ) ;
166176 }
167177
178+ /// Squeeze data by calling custom functions using little-endian byte order.
168179 #[ inline( always) ]
169180 fn squeeze_inner_u64_le < const N : usize > (
170181 & mut self ,
@@ -186,7 +197,7 @@ impl<const RATE: usize> SpongeCursor<RATE> {
186197
187198 if buf. len ( ) < rem_len {
188199 process_partial ( state, pos, buf) ;
189- self . pos = u8 :: try_from ( pos + buf. len ( ) ) . expect ( "the sum is smaller than RATE" ) ;
200+ self . set_pos ( pos + buf. len ( ) ) ;
190201 return ;
191202 }
192203
@@ -200,7 +211,7 @@ impl<const RATE: usize> SpongeCursor<RATE> {
200211
201212 for block in & mut blocks {
202213 sponge ( state) ;
203- let block = block. try_into ( ) . expect ( "block has correct size" ) ;
214+ let block = block. try_into ( ) . expect ( "` block` has correct size" ) ;
204215 process_full ( state, block) ;
205216 }
206217
@@ -211,7 +222,7 @@ impl<const RATE: usize> SpongeCursor<RATE> {
211222 process_partial ( state, 0 , tail) ;
212223 }
213224
214- self . pos = u8 :: try_from ( tail. len ( ) ) . expect ( "tail.len() is smaller than RATE" ) ;
225+ self . set_pos ( tail. len ( ) ) ;
215226 }
216227}
217228
0 commit comments