• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# This file is dual licensed under the terms of the Apache License, Version
2# 2.0, and the BSD License. See the LICENSE file in the root of this repository
3# for complete details.
4
5from __future__ import absolute_import, division, print_function
6
7import binascii
8
9from cryptography.hazmat.backends import default_backend
10from cryptography.hazmat.primitives import ciphers
11from cryptography.hazmat.primitives.ciphers import algorithms
12
13
14_RFC6229_KEY_MATERIALS = [
15    (True,
16     8 * '0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20'),
17    (False,
18     8 * '1ada31d5cf688221c109163908ebe51debb46227c6cc8b37641910833222772a')
19]
20
21
22_RFC6229_OFFSETS = [
23    0,
24    16,
25    240,
26    256,
27    496,
28    512,
29    752,
30    768,
31    1008,
32    1024,
33    1520,
34    1536,
35    2032,
36    2048,
37    3056,
38    3072,
39    4080,
40    4096
41]
42
43
44_SIZES_TO_GENERATE = [
45    160
46]
47
48
49def _key_for_size(size, keyinfo):
50    msb, key = keyinfo
51    if msb:
52        return key[:size // 4]
53    else:
54        return key[-size // 4:]
55
56
57def _build_vectors():
58    count = 0
59    output = []
60    key = None
61    plaintext = binascii.unhexlify(32 * '0')
62    for size in _SIZES_TO_GENERATE:
63        for keyinfo in _RFC6229_KEY_MATERIALS:
64            key = _key_for_size(size, keyinfo)
65            cipher = ciphers.Cipher(
66                algorithms.ARC4(binascii.unhexlify(key)),
67                None,
68                default_backend())
69            encryptor = cipher.encryptor()
70            current_offset = 0
71            for offset in _RFC6229_OFFSETS:
72                if offset % 16 != 0:
73                    raise ValueError(
74                        "Offset {} is not evenly divisible by 16"
75                        .format(offset))
76                while current_offset < offset:
77                    encryptor.update(plaintext)
78                    current_offset += len(plaintext)
79                output.append("\nCOUNT = {}".format(count))
80                count += 1
81                output.append("KEY = {}".format(key))
82                output.append("OFFSET = {}".format(offset))
83                output.append("PLAINTEXT = {}".format(
84                    binascii.hexlify(plaintext)))
85                output.append("CIPHERTEXT = {}".format(
86                    binascii.hexlify(encryptor.update(plaintext))))
87                current_offset += len(plaintext)
88            assert not encryptor.finalize()
89    return "\n".join(output)
90
91
92def _write_file(data, filename):
93    with open(filename, 'w') as f:
94        f.write(data)
95
96
97if __name__ == '__main__':
98    _write_file(_build_vectors(), 'arc4.txt')
99