Files
bikini-patchwork/patchwork/crypto.py
T
2026-04-29 00:17:18 -05:00

49 lines
1.4 KiB
Python

from __future__ import annotations
import hashlib
import random
def keystream(key: bytes, length: int) -> bytes:
out = bytearray()
ctr = 0
while len(out) < length:
out.extend(hashlib.sha256(key + ctr.to_bytes(8, 'big')).digest())
ctr += 1
return bytes(out[:length])
def stream_xor(data: bytes, key: bytes) -> bytes:
ks = keystream(key, len(data))
return bytes((a ^ b for a, b in zip(data, ks)))
def make_perm(key: bytes) -> bytes:
seed = int.from_bytes(hashlib.sha256(key).digest(), 'big')
rng = random.Random(seed)
perm = list(range(256))
rng.shuffle(perm)
return bytes(perm)
def invert_perm(perm: bytes) -> bytes:
inv = bytearray(256)
for i, p in enumerate(perm):
inv[p] = i
return bytes(inv)
def perm_apply(data: bytes, key: bytes) -> bytes:
perm = make_perm(key)
return bytes((perm[b] for b in data))
def perm_invert(data: bytes, key: bytes) -> bytes:
inv = invert_perm(make_perm(key))
return bytes((inv[b] for b in data))
def _rot_left(b: int, n: int) -> int:
n &= 7
if not n:
return b
return (b << n | b >> 8 - n) & 255
def rot_apply(data: bytes, key: bytes) -> bytes:
return bytes((_rot_left(b, key[i % len(key)]) for i, b in enumerate(data)))
def rot_invert(data: bytes, key: bytes) -> bytes:
return bytes((_rot_left(b, -key[i % len(key)] & 7) for i, b in enumerate(data)))