@@ -21,11 +21,25 @@ def __new__(cls, key: bytes, nonce: bytes, counter: int = 0):
2121 raise ValueError ("Key must be exactly 32 bytes (256 bits)." )
2222 if not isinstance (nonce , bytes ) or len (nonce ) != 12 :
2323 raise ValueError ("Nonce must be exactly 12 bytes (96 bits)." )
24+ if not isinstance (counter , int ) or counter < 0 :
25+ raise ValueError ("Counter must be a non-negative integer." )
2426 instance = super ().__new__ (cls )
2527 instance .key = key
2628 instance .nonce = nonce
2729 instance .counter = counter
2830 return instance
31+
32+ def __init__ (self , key : bytes , nonce : bytes , counter : int = 0 ):
33+ """Initializes the ChaCha20 object."""
34+ # Guard against multiple initializations
35+ if hasattr (self , "_initialized" ) and self ._initialized :
36+ return
37+ self ._initialized = True
38+
39+ def __repr__ (self ):
40+ """Returns a string representation of the object for debugging."""
41+ return f"<ChaCha20(key={ self .key [:4 ].hex ()} ..., nonce={ self .nonce .hex ()} , counter={ self .counter } )>"
42+
2943 def _quarter_round (self , state : List [int ], a : int , b : int , c : int , d : int ):
3044 state [a ] = (state [a ] + state [b ]) % (2 ** 32 )
3145 state [d ] ^= state [a ]
@@ -133,4 +147,10 @@ def decrypt(self, ciphertext: bytes) -> bytes:
133147 Returns:
134148 bytes: The resulting plaintext.
135149 """
136- return self .apply_keystream (ciphertext )
150+ return self .apply_keystream (ciphertext )
151+
152+ def reset (self , counter : int = 0 ):
153+ """Resets the ChaCha20 counter to the specified value (default is 0)."""
154+ if not isinstance (counter , int ) or counter < 0 :
155+ raise ValueError ("Counter must be a non-negative integer." )
156+ self .counter = counter
0 commit comments