11from typing import List
22import struct
3-
3+ import numpy as np
4+ from copy import deepcopy as dp
45__all__ = ['ChaCha20' ]
56class ChaCha20 :
67 """
@@ -46,4 +47,23 @@ def _double_round(self, state: List[int]):
4647 self ._quarter_round (state , 0 , 5 , 10 , 15 )
4748 self ._quarter_round (state , 1 , 6 , 11 , 12 )
4849 self ._quarter_round (state , 2 , 7 , 8 , 13 )
49- self ._quarter_round (state , 3 , 4 , 9 , 14 )
50+ self ._quarter_round (state , 3 , 4 , 9 , 14 )
51+ def _chacha20_block (self , counter : int ) -> bytes :
52+ """
53+ Generates a 64-byte keystream block from 16-word (512-bit) state
54+ The initial state is copied to preserve the original.
55+ 20 rounds (10 double rounds) are performed using quarter-round operations.
56+ The modified working state is combined with the original state using modular addition (mod 2^32).
57+ The result is returned as a 64-byte keystream block.
58+ """
59+ constants = b"expand 32-byte k"
60+ state_values = struct .unpack (
61+ '<16I' ,
62+ constants + self .key + struct .pack ('<I' , counter ) + self .nonce
63+ )
64+ state = np .array (state_values , dtype = np .uint32 ).reshape (4 , 4 )
65+ working_state = dp (state )
66+ for _ in range (10 ):
67+ self ._double_round (working_state )
68+ final_state = (working_state + state ) % (2 ** 32 )
69+ return struct .pack ('<16I' , * final_state .flatten ())
0 commit comments