Files
palemoon27/python/PyECC/ecc/Rabbit.py
T
roytam1 688c3af674 import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1235021 - Re-emit ChromeManifestEntries from the jar manifest handler code in the FasterMake backend. r=gps (a8d899a6da)
- Bug 1233282 - Make CONFIGURE_DEFINE_FILES considered more as GENERATED_FILES in the emitter. r=gps (d29506fb55)
- Bug 1235021 - Add a RenamedSourcePath helper class. r=gps (62e78b867b)
- Bug 1235021 - Re-emit FinalTarget{,Preprocessed}Files from the jar manifest handler code in the FasterMake backend. r=gps (c37287a5d7)
- Bug 1235021 - Avoid passing defines to FasterMakeBackend._consume_jar_manifest. r=gps (dc0d17c3a6)
- Bug 1235021 - Move FasterMakeBackend._consume_jar_manifest to CommonBackend. r=gps (b9bb6b7d1e)
- Bug 1239217 - Add the notion of Partial and Hybrid build backends. r=gps Make the FasterMake backend a partial build backend. (219c0811e6)
- Bug 1239217 - Stop making the FasterMake build system refresh the backend on its own. r=gps (4f79f966ce)
- Bug 1241398 - Show the diff for created and deleted files in `mach build-backend --diff`. r=gps (d497d3aef8)
- Bug 1214885 - Add a "ChromeUrl" build backend to write out information useful for resolving chrome urls. r=glandium (83ad13d109)
- Bug 1216817 - Part 1: Add install_callback to artifacts. r=gps (95b4860d09)
- Bug 1216817 - Part 2: Narrow distdir to bindir in artifacts. r=gps (e48b531455)
- Bug 1216817 - Part 4: Add --enable-artifact-builds and MOZ_ARTIFACT_BUILDS. r=glandium (8d7ed76621)
- bug 1164816 - Import concurrent.futures into the tree. r=gps (bc83211833)
- bug 1190603 - import PyECC library r=gps,gerv (e0c5afeee0)
- Bug 1216817 - Part 5: Run |mach artifact install| automatically when asked. r=glandium (835c27d9c2)
- Bug 1216817 - Follow-up: Fix "KeyError: uMOZ_ARTIFACT_BUILDS" in config.status. r=bustage (e87e04e23b)
- Bug 1216817 - Follow-up: Fix "KeyError: u'MOZ_ARTIFACT_BUILDS'". r=bustage (797331293b)
- Bug 1207897 - Add a configure option to build multiple build backends. r=gps (35f62c27ca)
- Bug 1241398 - Allow to pass the --verbose flag down to config.status from `mach build-backend`. r=gps (78610c40d0)
- Bug 1236111 - part 1: avoid configure.in Windows-only goop when running with disable-compile-environment, r=gps (d27a7e522a)
- Bug 1236111 - part 2: fix mozbuild to use the file mode modifiers specified for opening when writing a FileAvoidWrite, r=gps,nalexander (e240c613b7)
- Bug 1207890 - Part 1: Add rich ArtifactJob extension point. r=glandium (e402f5fcec)
- Bug 1207890 - Part 2: Stop extracting build ID from artifacts. r=glandium (314d6895c1)
- Bug 1207890 - Part 3: Post-process downloaded artifacts. r=glandium (09d60ac030)
- Bug 1207890 - Part 4: Download and process Mac OS X artifacts. r=glandium (181ba370b1)
- Bug 1207890 - Pre: Make JarWriter handle inputs with read() but not seek(). r=glandium (6ebb5dfe94)
- Bug 1207890 - Post: Hacks to make --disable-compile-environment work on Mac OS X. r=glandium (c5f88b6adf)
- Bug 1207890 - Post: Move |mach artifact| command out of mobile/android. r=glandium (a06f97dfb9)
- Bug 1207890 - Post: Hack to make |mach run| for Mac OS X artifact builds. r=me (4c6d2f6bfe)
- Bug 1207890 - Follow-up: Fix |mach artifact install| for mobile/android. r=me (a2e4347ca9)
- Bug 1236111 - part 3: ensure calls to hg and mach work on Windows, and that we use the right file mode when writing artifacts, r=nalexander,gps (d0090a5a56)
- Bug 1236111 - part 4: actually add Windows support to artifact code, r=nalexander,gps (ab40057ffa)
- Bug 1236111 - part 0: improve logging from process mixin, r=gps (d85265c134)
- Bug 1241398 - Add a dry-run mode to mach build-backend. r=gps (b300169915)
- Bug 1239217 - Make the RecursiveMake build system create backend files generically. r=gps (fba90d6bcb)
- fix minor misspatch of 1240990 (b7d44692bc)
- Bug 1239296 - Use telemetry_handler to store build resource data r=gps (58d7c3a260)
- Bug 1244143 - Record whether or not an artifact build was used in build telemetry data r=gps (d1821d1987)
- Bug 1246264 - Ensure cache directory exists for artifacts installation r=chmanchester (ef5c4a0fba)
- bug 1237619: save resource usage for "what" builds r=gps (6a311c71bc)
- Bug 1239296 - Add telemetry_handler function to mach context r=gps (4a7a67740d)
- Bug 1246402 - Environment variable to disable mercurial setup check. r=gps (d9cf129b6c)
- Bug 1239296 - add post_dispatch_handler hook to mach r=gps (aa55c9a36e)
- Bug 1236110 - Extend mach artifact to handle Linux Desktop builds. r=gps (cb29ca6d1d)
- Bug 1234912 - Check for mozext and pushlog entries after |mach artifact install| hg failure. r=gps (7bfb064c7c)
- Bug 1239096 - Improve English is artifacts.py comments. r=me (38aa5ecb19)
- Bug 1238320 - Part 1 (Linux): Download test binaries necessary to run xpcshell tests and mochitests in artifact builds. r=nalexander (f6407791ae)
- Bug 1238320 - Part 2 (Mac): Download test binaries necessary to run xpcshell tests and mochitests in artifact builds. r=nalexander (4d72cfc6f2)
- Bug 1238320 - Part 3 (Windows): Download test binaries necessary to run xpcshell tests and mochitests in artifact builds. r=nalexander# Please enter the commit message for your changes. Lines starting (40ac9f9f7d)
- Bug 1239678 - fix dll inclusion pattern on Windows and the placement of nested dlls like browsercomps and clearkey, r=nalexander (ad9015c9d9)
- Bug 1239738 - Handle artifact builds with no test binaries cleanly. r=ahunt (ba1593837a)
- Bug 1240323 - Fix installation of binary components in a subdir of dist/bin for linux artifact builds. r=nalexander (2f4b719ea3)
- Bug 1240239 - Install test plugins in artifact based builds. r=nalexander (edc24f4fd2)
- Bug 1240667 - Detect a tree to use for artifact builds based on recent changesets. r=nalexander (947879cb19)
- Bug 1244941 - Don't fill install manifest with artifacts. r=nalexander (8fa9793c53)
- Bug 1237619: Record build objects in resource_usage.json r=gps (c323d21c9f)
- bug 1237619: Add system and command metadata to resouce_usage.json r=gps (c93fb18c37)
- Bug 1240059 - Treat psutil as optional in record_resource_usage. r=gps (c91103ebce)
- Bug 1244160 - Create json-schema for build telemetry data r=gps (d8b3419cfd)
- Bug 1250624 - Overall system resources is displayed twice; r=chmanchester (a115c86902)
- Bug 1144842 (part 1) - Don't use MOZ_PROFILING before all the places it can be set. r=glandium. (3c12a2e29a)
- Bug 1144842 (part 2) - Make --enable-dmd imply --enable-profiling. r=glandium. (85c9ff5c32)
- Bug 1144842 (part 3) - Remove --enable-dmd code from js/src/configure.in. r=glandium. (52cf663bc7)
- Bug 1204260 - Pre: Don't expose ANDROID_{BUILD,PLATFORM}_TOOLS. r=glandium,gbrown (d4f560dd46)
- Bug 1219803 - Support 'mach run' for Android; r=jmaher (5a1a1ab16e)
- Bug 1219807 - Add tooltool manifests for jimdb; r=jmaher (4d7a211569)
- Bug 1221846 - Get Task Tracer building on desktop r=cyu. (5d1a0fabe9)
- Bug 1216681 - Add a fileid utility to extract the breakpad GUID from object files for identification in fix_stack_using_bpsyms. r=ted (e53eb5acc6)
- Bug 1237156 - Only build the fileid utility when MOZ_CRASHREPORTER is set. r=ted.mielczarek (328a80ae18)
- Bug 1239866 - Remove signaling standalone tests. r=bwc (b05b091059)
2023-09-27 11:04:31 +08:00

271 lines
8.0 KiB
Python

# ------------------------------------------------------------------------------
#
# R A B B I T Stream Cipher
# by M. Boesgaard, M. Vesterager, E. Zenner (specified in RFC 4503)
#
#
# Pure Python Implementation by Toni Mattis
#
# ------------------------------------------------------------------------------
WORDSIZE = 0x100000000
rot08 = lambda x: ((x << 8) & 0xFFFFFFFF) | (x >> 24)
rot16 = lambda x: ((x << 16) & 0xFFFFFFFF) | (x >> 16)
def _nsf(u, v):
'''Internal non-linear state transition'''
s = (u + v) % WORDSIZE
s = s * s
return (s ^ (s >> 32)) % WORDSIZE
class Rabbit:
def __init__(self, key, iv = None):
'''Initialize Rabbit cipher using a 128 bit integer/string'''
if isinstance(key, str):
# interpret key string in big endian byte order
if len(key) < 16:
key = '\x00' * (16 - len(key)) + key
# if len(key) > 16 bytes only the first 16 will be considered
k = [ord(key[i + 1]) | (ord(key[i]) << 8)
for i in xrange(14, -1, -2)]
else:
# k[0] = least significant 16 bits
# k[7] = most significant 16 bits
k = [(key >> i) & 0xFFFF for i in xrange(0, 128, 16)]
# State and counter initialization
x = [(k[(j + 5) % 8] << 16) | k[(j + 4) % 8] if j & 1 else
(k[(j + 1) % 8] << 16) | k[j] for j in xrange(8)]
c = [(k[j] << 16) | k[(j + 1) % 8] if j & 1 else
(k[(j + 4) % 8] << 16) | k[(j + 5) % 8] for j in xrange(8)]
self.x = x
self.c = c
self.b = 0
self._buf = 0 # output buffer
self._buf_bytes = 0 # fill level of buffer
self.next()
self.next()
self.next()
self.next()
for j in xrange(8):
c[j] ^= x[(j + 4) % 8]
self.start_x = self.x[:] # backup initial key for IV/reset
self.start_c = self.c[:]
self.start_b = self.b
if iv != None:
self.set_iv(iv)
def reset(self, iv = None):
'''Reset the cipher and optionally set a new IV (int64 / string).'''
self.c = self.start_c[:]
self.x = self.start_x[:]
self.b = self.start_b
self._buf = 0
self._buf_bytes = 0
if iv != None:
self.set_iv(iv)
def set_iv(self, iv):
'''Set a new IV (64 bit integer / bytestring).'''
if isinstance(iv, str):
i = 0
for c in iv:
i = (i << 8) | ord(c)
iv = i
c = self.c
i0 = iv & 0xFFFFFFFF
i2 = iv >> 32
i1 = ((i0 >> 16) | (i2 & 0xFFFF0000)) % WORDSIZE
i3 = ((i2 << 16) | (i0 & 0x0000FFFF)) % WORDSIZE
c[0] ^= i0
c[1] ^= i1
c[2] ^= i2
c[3] ^= i3
c[4] ^= i0
c[5] ^= i1
c[6] ^= i2
c[7] ^= i3
self.next()
self.next()
self.next()
self.next()
def next(self):
'''Proceed to the next internal state'''
c = self.c
x = self.x
b = self.b
t = c[0] + 0x4D34D34D + b
c[0] = t % WORDSIZE
t = c[1] + 0xD34D34D3 + t // WORDSIZE
c[1] = t % WORDSIZE
t = c[2] + 0x34D34D34 + t // WORDSIZE
c[2] = t % WORDSIZE
t = c[3] + 0x4D34D34D + t // WORDSIZE
c[3] = t % WORDSIZE
t = c[4] + 0xD34D34D3 + t // WORDSIZE
c[4] = t % WORDSIZE
t = c[5] + 0x34D34D34 + t // WORDSIZE
c[5] = t % WORDSIZE
t = c[6] + 0x4D34D34D + t // WORDSIZE
c[6] = t % WORDSIZE
t = c[7] + 0xD34D34D3 + t // WORDSIZE
c[7] = t % WORDSIZE
b = t // WORDSIZE
g = [_nsf(x[j], c[j]) for j in xrange(8)]
x[0] = (g[0] + rot16(g[7]) + rot16(g[6])) % WORDSIZE
x[1] = (g[1] + rot08(g[0]) + g[7]) % WORDSIZE
x[2] = (g[2] + rot16(g[1]) + rot16(g[0])) % WORDSIZE
x[3] = (g[3] + rot08(g[2]) + g[1]) % WORDSIZE
x[4] = (g[4] + rot16(g[3]) + rot16(g[2])) % WORDSIZE
x[5] = (g[5] + rot08(g[4]) + g[3]) % WORDSIZE
x[6] = (g[6] + rot16(g[5]) + rot16(g[4])) % WORDSIZE
x[7] = (g[7] + rot08(g[6]) + g[5]) % WORDSIZE
self.b = b
return self
def derive(self):
'''Derive a 128 bit integer from the internal state'''
x = self.x
return ((x[0] & 0xFFFF) ^ (x[5] >> 16)) | \
(((x[0] >> 16) ^ (x[3] & 0xFFFF)) << 16)| \
(((x[2] & 0xFFFF) ^ (x[7] >> 16)) << 32)| \
(((x[2] >> 16) ^ (x[5] & 0xFFFF)) << 48)| \
(((x[4] & 0xFFFF) ^ (x[1] >> 16)) << 64)| \
(((x[4] >> 16) ^ (x[7] & 0xFFFF)) << 80)| \
(((x[6] & 0xFFFF) ^ (x[3] >> 16)) << 96)| \
(((x[6] >> 16) ^ (x[1] & 0xFFFF)) << 112)
def keystream(self, n):
'''Generate a keystream of n bytes'''
res = ""
b = self._buf
j = self._buf_bytes
next = self.next
derive = self.derive
for i in xrange(n):
if not j:
j = 16
next()
b = derive()
res += chr(b & 0xFF)
j -= 1
b >>= 1
self._buf = b
self._buf_bytes = j
return res
def encrypt(self, data):
'''Encrypt/Decrypt data of arbitrary length.'''
res = ""
b = self._buf
j = self._buf_bytes
next = self.next
derive = self.derive
for c in data:
if not j: # empty buffer => fetch next 128 bits
j = 16
next()
b = derive()
res += chr(ord(c) ^ (b & 0xFF))
j -= 1
b >>= 1
self._buf = b
self._buf_bytes = j
return res
decrypt = encrypt
if __name__ == "__main__":
import time
# --- Official Test Vectors ---
# RFC 4503 Appendix A.1 - Testing without IV Setup
r = Rabbit(0)
assert r.next().derive() == 0xB15754F036A5D6ECF56B45261C4AF702
assert r.next().derive() == 0x88E8D815C59C0C397B696C4789C68AA7
assert r.next().derive() == 0xF416A1C3700CD451DA68D1881673D696
r = Rabbit(0x912813292E3D36FE3BFC62F1DC51C3AC)
assert r.next().derive() == 0x3D2DF3C83EF627A1E97FC38487E2519C
assert r.next().derive() == 0xF576CD61F4405B8896BF53AA8554FC19
assert r.next().derive() == 0xE5547473FBDB43508AE53B20204D4C5E
r = Rabbit(0x8395741587E0C733E9E9AB01C09B0043)
assert r.next().derive() == 0x0CB10DCDA041CDAC32EB5CFD02D0609B
assert r.next().derive() == 0x95FC9FCA0F17015A7B7092114CFF3EAD
assert r.next().derive() == 0x9649E5DE8BFC7F3F924147AD3A947428
# RFC 4503 Appendix A.2 - Testing with IV Setup
r = Rabbit(0, 0)
assert r.next().derive() == 0xC6A7275EF85495D87CCD5D376705B7ED
assert r.next().derive() == 0x5F29A6AC04F5EFD47B8F293270DC4A8D
assert r.next().derive() == 0x2ADE822B29DE6C1EE52BDB8A47BF8F66
r = Rabbit(0, 0xC373F575C1267E59)
assert r.next().derive() == 0x1FCD4EB9580012E2E0DCCC9222017D6D
assert r.next().derive() == 0xA75F4E10D12125017B2499FFED936F2E
assert r.next().derive() == 0xEBC112C393E738392356BDD012029BA7
r = Rabbit(0, 0xA6EB561AD2F41727)
assert r.next().derive() == 0x445AD8C805858DBF70B6AF23A151104D
assert r.next().derive() == 0x96C8F27947F42C5BAEAE67C6ACC35B03
assert r.next().derive() == 0x9FCBFC895FA71C17313DF034F01551CB
# --- Performance Tests ---
def test_gen(n = 1048576):
'''Measure time for generating n bytes => (total, bytes per second)'''
r = Rabbit(0)
t = time.time()
r.keystream(n)
t = time.time() - t
return t, n / t
def test_enc(n = 1048576):
'''Measure time for encrypting n bytes => (total, bytes per second)'''
r = Rabbit(0)
x = 'x' * n
t = time.time()
r.encrypt(x)
t = time.time() - t
return t, n / t