| # This file is dual licensed under the terms of the Apache License, Version |
| # 2.0, and the BSD License. See the LICENSE file in the root of this repository |
| # for complete details. |
| |
| from __future__ import absolute_import, division, print_function |
| |
| import binascii |
| |
| from cryptography.hazmat.backends import default_backend |
| from cryptography.hazmat.primitives import ciphers |
| from cryptography.hazmat.primitives.ciphers import algorithms |
| |
| |
| _RFC6229_KEY_MATERIALS = [ |
| ( |
| True, |
| 8 * "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20", |
| ), |
| ( |
| False, |
| 8 * "1ada31d5cf688221c109163908ebe51debb46227c6cc8b37641910833222772a", |
| ), |
| ] |
| |
| |
| _RFC6229_OFFSETS = [ |
| 0, |
| 16, |
| 240, |
| 256, |
| 496, |
| 512, |
| 752, |
| 768, |
| 1008, |
| 1024, |
| 1520, |
| 1536, |
| 2032, |
| 2048, |
| 3056, |
| 3072, |
| 4080, |
| 4096, |
| ] |
| |
| |
| _SIZES_TO_GENERATE = [160] |
| |
| |
| def _key_for_size(size, keyinfo): |
| msb, key = keyinfo |
| if msb: |
| return key[: size // 4] |
| else: |
| return key[-size // 4 :] |
| |
| |
| def _build_vectors(): |
| count = 0 |
| output = [] |
| key = None |
| plaintext = binascii.unhexlify(32 * "0") |
| for size in _SIZES_TO_GENERATE: |
| for keyinfo in _RFC6229_KEY_MATERIALS: |
| key = _key_for_size(size, keyinfo) |
| cipher = ciphers.Cipher( |
| algorithms.ARC4(binascii.unhexlify(key)), |
| None, |
| default_backend(), |
| ) |
| encryptor = cipher.encryptor() |
| current_offset = 0 |
| for offset in _RFC6229_OFFSETS: |
| if offset % 16 != 0: |
| raise ValueError( |
| "Offset {} is not evenly divisible by 16".format( |
| offset |
| ) |
| ) |
| while current_offset < offset: |
| encryptor.update(plaintext) |
| current_offset += len(plaintext) |
| output.append("\nCOUNT = {}".format(count)) |
| count += 1 |
| output.append("KEY = {}".format(key)) |
| output.append("OFFSET = {}".format(offset)) |
| output.append( |
| "PLAINTEXT = {}".format(binascii.hexlify(plaintext)) |
| ) |
| output.append( |
| "CIPHERTEXT = {}".format( |
| binascii.hexlify(encryptor.update(plaintext)) |
| ) |
| ) |
| current_offset += len(plaintext) |
| assert not encryptor.finalize() |
| return "\n".join(output) |
| |
| |
| def _write_file(data, filename): |
| with open(filename, "w") as f: |
| f.write(data) |
| |
| |
| if __name__ == "__main__": |
| _write_file(_build_vectors(), "arc4.txt") |