What a problem! From mom and pop's notes, we immediately notice the TurnKey Protocol:
We can observe from the protocol that we only need to send three messages per vault:
BLOCK_LEN = 8 | |
HEX_BLOCK_LEN = 16 | |
def encrypt_block(plaintext): | |
'''Encrypts a given block of plaintext''' | |
k = open("./key").read().rstrip() | |
result = int(binascii.hexlify(plaintext), 16) | |
for i in range(ROUNDS): | |
# The round function is the below lines | |
key = int(binascii.hexlify(k[i * BLOCK_LEN:(i + 1) * BLOCK_LEN]), 16) # Grabs a block of the key | |
key_odd = key | 1 # Creates an odd version of the key |
def create_plaintexts(): | |
sdiff = list('0' + '1' * (62) + '0') # 011110 <-- (n - 2) 1's | |
diff = int(''.join(sdiff), 2) # 011110 <-- (n - 2) 1's = 2^63 - 2 | |
assert diff == 2**63 - 2 | |
plaintexts = [] | |
for i in range(32): | |
binp = ['0'] | |
for i in range(62): | |
binp.append(str(random.randint(0, 1))) # We create random binary numbers that start and end with 0s | |
binp.append('0') |
from __future__ import division | |
from __future__ import print_function | |
import binascii | |
import math | |
import random | |
from collections import Counter | |
from itertools import repeat | |
from pwn import * | |
from termcolor import cprint |
def recurse(plaintexts, ciphertexts, kcands, keyers=[], depth=1): | |
if depth > 5: | |
return None, None | |
for k in kcands: | |
dciphertexts = ciphertexts[:] | |
# DECRPYT CIPHERTEXTS WITH THE CURRENT KEY | |
for pair in range(len(dciphertexts)): | |
ci1, ci2 = map(int, dciphertexts[pair], repeat(16)) | |
# undo modular multiplication by odd-ed key, reversal, | |
# xor by guessed key |
def rev_multiply(ciphertexts): | |
candidates, noncandidates = condition1(ciphertexts) | |
gcdd, key_scaler, _ = egcd(diff, 1 << 64) | |
keycounter = Counter() | |
for cand in candidates: | |
ci1, ci2 = map(int, cand, repeat(16)) | |
if (ci1 + ci2) % 2 != 0 or ci1 ^ ci2 == diff: | |
continue |
#!/usr/bin/python2 -u | |
import binascii | |
ROUNDS = 5 | |
BLOCK_LEN = 8 | |
HEX_BLOCK_LEN = BLOCK_LEN * 2 | |
MAX_NOTES = 2048 | |
MAX_NOTE_LEN = 512 | |
def g(i): | |
'''Reverses i in binary and fills the right side with 0s''' | |
b = bin(i).lstrip("0b").rstrip("L").rjust(BLOCK_LEN * 8, "0") | |
return int(b[::-1], 2) |
import cv2 | |
import threading | |
import http | |
from http.server import BaseHTTPRequestHandler, HTTPServer | |
from socketserver import ThreadingMixIn | |
import time | |
import sys | |
class CamHandler(BaseHTTPRequestHandler): | |
I hereby claim:
To claim this, I am signing this object: