def parityOracle(c): _, n = pub k = (n.bit_length() + 7) // 8 p = challenge39.decryptnum(priv, c) pbytes = challenge39.numtobytes(p) pbytes = (b'\x00' * (k - len(pbytes))) + pbytes return pbytes[0:2] == b'\x00\x02'
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
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 floorRoot(n, s): b = n.bit_length() p = math.ceil(b / s) x = 2**p while x > 1: y = (((s - 1) * x) + (n // (x**(s - 1)))) // s if y >= x: return x x = y return 1 if __name__ == '__main__': m = floorRoot(r, 3) mstr = challenge39.numtobytes(m) if mstr != plaintext: raise Exception(mstr + b' != ' + 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)
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)
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 floorRoot(n, s): b = n.bit_length() p = math.ceil(b/s) x = 2**p while x > 1: y = (((s - 1) * x) + (n // (x**(s-1)))) // s if y >= x: return x x = y return 1 if __name__ == '__main__': m = floorRoot(r, 3) mstr = challenge39.numtobytes(m) if mstr != plaintext: raise Exception(mstr + b' != ' + plaintext)