def forgeSignature(pub, message): sha1 = hashlib.sha1() sha1.update(message) digest = sha1.digest() block = b'\x00\x01\xff\x00' + digest + (b'\x00' * (128 - len(digest) - 4)) blocknum = challenge39.bytestonum(block) signaturenum = challenge40.floorRoot(blocknum, 3) + 1 signature = challenge39.numtobytes(signaturenum) return signature
def forgeSignature(pub, message): sha1 = hashlib.sha1() sha1.update(message) digest = sha1.digest() block = b'\x00\x01\xff\x00' + digest + (b'\x00' * (128 - len(digest) - 4)) (d, n) = pub blocknum = challenge39.bytestonum(block) signaturenum = challenge40.floorRoot(blocknum, 3) + 1 signature = challenge39.numtobytes(signaturenum) return signature
def deducePlaintext(ciphertext, pub, parityOracle): e, n = pub k = (n.bit_length() + 7) // 8 B = 2**(8*(k-2)) c0 = challenge39.bytestonum(ciphertext) M = [(2*B, 3*B - 1)] (s, c) = computeFirstS(e, n, B, c0, parityOracle) M = getNextInterval(n, M, s, B) while True: if len(M) == 1 and M[0][0] == M[0][1]: m = M[0][0] return b'\x00' + challenge39.numtobytes(m) (s, c) = computeNextS(e, n, M, s, B, c0) M = getNextInterval(n, M, s, B)
def deducePlaintext(ciphertext, pub, parityOracle): (e, n) = pub low = 0 high = 1 denom = 1 c = challenge39.bytestonum(ciphertext) k = pow(2, e, n) for _ in range(n.bit_length()): c = (c * k) % n p = parityOracle(c) d = high - low low *= 2 high *= 2 denom *= 2 if p == 0: high -= d else: low += d hightext = challenge39.numtobytes(n * high // denom) print(hightext) return hightext
import challenge39 import binascii import math (pub0, priv0) = challenge39.genKey(256) (pub1, priv1) = challenge39.genKey(256) (pub2, priv2) = challenge39.genKey(256) plaintext = b'This is a plaintext string' plainnum = challenge39.bytestonum(plaintext) c0 = challenge39.encryptnum(pub0, plainnum) c1 = challenge39.encryptnum(pub1, plainnum) c2 = challenge39.encryptnum(pub2, plainnum) n0 = pub0[1] n1 = pub1[1] n2 = pub2[1] ms0 = n1 * n2 ms1 = n0 * n2 ms2 = n0 * n1 N = n0 * n1 * n2 r0 = (c0 * ms0 * challenge39.invmod(ms0, n0)) r1 = (c1 * ms1 * challenge39.invmod(ms1, n1)) r2 = (c2 * ms2 * challenge39.invmod(ms2, n2)) r = (r0 + r1 + r2) % N
def decryptOnce(ciphertext): sha1 = hashlib.sha1() sha1.update(ciphertext) digest = sha1.digest() if digest in decryptedHashes: raise ValueError('Already decrypted') decryptedHashes.add(digest) return challenge39.decryptbytes(priv, ciphertext) if __name__ == '__main__': plaintext = b'secret text' ciphertext = encrypt(plaintext) plaintext2 = decryptOnce(ciphertext) if plaintext2 != plaintext: raise ValueError(plaintext2 + b' != ' + plaintext) (e, n) = pub s = random.randint(2, n - 1) c = challenge39.bytestonum(ciphertext) c2 = (pow(s, e, n) * c) % n ciphertext2 = challenge39.numtobytes(c2) plaintext3 = decryptOnce(ciphertext2) p3 = challenge39.bytestonum(plaintext3) p4 = (p3 * challenge39.invmod(s, n)) % n plaintext4 = challenge39.numtobytes(p4) if plaintext4 != plaintext: raise ValueError(plaintext4 + b' != ' + plaintext)
return challenge39.encryptbytes(pub, plaintext) def decryptOnce(ciphertext): sha1 = hashlib.sha1() sha1.update(ciphertext) digest = sha1.digest() if digest in decryptedHashes: raise ValueError('Already decrypted') decryptedHashes.add(digest) return challenge39.decryptbytes(priv, ciphertext) if __name__ == '__main__': plaintext = b'secret text' ciphertext = encrypt(plaintext) plaintext2 = decryptOnce(ciphertext) if plaintext2 != plaintext: raise ValueError(plaintext2 + b' != ' + plaintext) (e, n) = pub s = random.randint(2, n - 1) c = challenge39.bytestonum(ciphertext) c2 = (pow(s, e, n) * c) % n ciphertext2 = challenge39.numtobytes(c2) plaintext3 = decryptOnce(ciphertext2) p3 = challenge39.bytestonum(plaintext3) p4 = (p3 * challenge39.invmod(s, n)) % n plaintext4 = challenge39.numtobytes(p4) if plaintext4 != plaintext: raise ValueError(plaintext4 + b' != ' + plaintext)