Skip to content

Commit 8ef3861

Browse files
Implement apply_keystream() method for ChaCha20 XOR operation
1 parent 67e7e89 commit 8ef3861

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

crypto/ChaCha20.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,40 @@ def _chacha20_block(self, counter: int) -> bytes:
6666
for _ in range(10):
6767
self._double_round(working_state)
6868
final_state = (working_state + state) % (2**32)
69-
return struct.pack('<16I', *final_state.flatten())
69+
return struct.pack('<16I', *final_state.flatten())
70+
71+
def _apply_keystream(self, data: bytes) -> bytes:
72+
"""
73+
Applies the ChaCha20 keystream to the input data (plaintext or ciphertext)
74+
to perform encryption or decryption.
75+
76+
This method processes the input data in 64-byte blocks. For each block:
77+
- A 64-byte keystream is generated using the `_chacha20_block()` function.
78+
- Each byte of the input block is XORed with the corresponding keystream byte.
79+
- The XORed result is appended to the output.
80+
81+
The same function is used for both encryption and decryption because
82+
XORing the ciphertext with the same keystream returns the original plaintext.
83+
84+
Args:
85+
data (bytes): The input data to be encrypted or decrypted (plaintext or ciphertext).
86+
87+
Returns:
88+
bytes: The result of XORing the input data with the ChaCha20 keystream
89+
(ciphertext if plaintext was provided, plaintext if ciphertext was provided).
90+
"""
91+
result = b""
92+
chunk_size = 64
93+
start = 0
94+
while start < len(data):
95+
chunk = data[start:start + chunk_size]
96+
start += chunk_size
97+
keystream = self._chacha20_block(self.counter)
98+
self.counter += 1
99+
xor_block = []
100+
for idx in range(len(chunk)):
101+
input_byte = chunk[idx]
102+
keystream_byte = keystream[idx]
103+
xor_block.append(input_byte ^ keystream_byte)
104+
result += bytes(xor_block)
105+
return result

0 commit comments

Comments
 (0)