@@ -197,7 +197,7 @@ fn (mut s Stream) keystream_full(mut dst []u8, src []u8) ! {
197197fn (mut s Stream) keystream () ! []u8 {
198198 // initializes current state and working state
199199 mut awal := s.new_curr_state ()
200- mut ws := clone_state ( awal)
200+ mut ws := awal. clone ( )
201201
202202 // precomputes cache counter-independent values
203203 if s.mode == .standard && ! s.precomp {
@@ -222,27 +222,8 @@ fn (mut s Stream) keystream() ![]u8 {
222222 //
223223 // perform chacha20 quarter round n-times
224224 n := if s.mode == .standard { 9 } else { default_qround_nr }
225- for i := 0 ; i < n; i++ {
226- // Column-round
227- // 0 | 1 | 2 | 3
228- // 4 | 5 | 6 | 7
229- // 8 | 9 | 10 | 11
230- // 12 | 13 | 14 | 15
231- qround_on_state (mut ws, 0 , 4 , 8 , 12 ) // 0
232- qround_on_state (mut ws, 1 , 5 , 9 , 13 ) // 1
233- qround_on_state (mut ws, 2 , 6 , 10 , 14 ) // 2
234- qround_on_state (mut ws, 3 , 7 , 11 , 15 ) // 3
225+ ws.qround (n)
235226
236- // Diagonal round.
237- // 0 \ 1 \ 2 \ 3
238- // 5 \ 6 \ 7 \ 4
239- // 10 \ 11 \ 8 \ 9
240- // 15 \ 12 \ 13 \ 14
241- qround_on_state (mut ws, 0 , 5 , 10 , 15 )
242- qround_on_state (mut ws, 1 , 6 , 11 , 12 )
243- qround_on_state (mut ws, 2 , 7 , 8 , 13 )
244- qround_on_state (mut ws, 3 , 4 , 9 , 14 )
245- }
246227 // Adding the working state values with inital state values.
247228 // We dont performs xor-ing here, its done on xor_key_stream and or keystream_full.
248229 for i, _ in ws {
@@ -379,17 +360,53 @@ fn (b Stream) max_ctr() u64 {
379360}
380361
381362// State represents the running 64-bytes of chacha20 stream,
382- type State = [16 ]u32
363+ pub type State = [16 ]u32
383364
365+ // clone returns a new copy of this state.
384366@[direct_array_access; inline]
385- fn clone_state (s State) State {
367+ pub fn (s State) clone ( ) State {
386368 mut sc := State{}
387369 for i, v in s {
388370 sc[i] = v
389371 }
390372 return sc
391373}
392374
375+ // reset resets internal values of this state.
376+ @[direct_array_access; inline]
377+ pub fn (mut s State) reset () {
378+ for i, _ in s {
379+ s[i] = u32 (0 )
380+ }
381+ }
382+
383+ // qround performs quarter round on the working state ws with round number specified in nr.
384+ // Its responsibility the user to provide the correct round number.
385+ @[direct_array_access]
386+ pub fn (mut ws State) qround (nr int ) {
387+ for i := 0 ; i < nr; i++ {
388+ // Column-round
389+ // 0 | 1 | 2 | 3
390+ // 4 | 5 | 6 | 7
391+ // 8 | 9 | 10 | 11
392+ // 12 | 13 | 14 | 15
393+ qround_on_state (mut ws, 0 , 4 , 8 , 12 ) // 0
394+ qround_on_state (mut ws, 1 , 5 , 9 , 13 ) // 1
395+ qround_on_state (mut ws, 2 , 6 , 10 , 14 ) // 2
396+ qround_on_state (mut ws, 3 , 7 , 11 , 15 ) // 3
397+
398+ // Diagonal round.
399+ // 0 \ 1 \ 2 \ 3
400+ // 5 \ 6 \ 7 \ 4
401+ // 10 \ 11 \ 8 \ 9
402+ // 15 \ 12 \ 13 \ 14
403+ qround_on_state (mut ws, 0 , 5 , 10 , 15 )
404+ qround_on_state (mut ws, 1 , 6 , 11 , 12 )
405+ qround_on_state (mut ws, 2 , 7 , 8 , 13 )
406+ qround_on_state (mut ws, 3 , 4 , 9 , 14 )
407+ }
408+ }
409+
393410// qround_on_state_with_quartet run qround_on_state by previously set up state values in offset
394411// (a,b,c,d) with values from quartet (q0, q1, q2, q3)
395412@[direct_array_access]
0 commit comments