示例#1
0
def insecureVerify(params, public_key, message, tag):
    r, s = tag[0], tag[1]

    hash_obj = sha256.SHA256()
    hash_obj.Update(message)
    msg_hash = hash_obj.Sum() % params["q"]
    s_inv = GroupOp.find_inverse(s, params["q"])
    arg1 = GroupOp.mod_exp(params["g"], (s_inv * msg_hash) % params["q"],
                           params["p"])
    arg2 = GroupOp.mod_exp(public_key, (r * s_inv) % params["q"], params["p"])
    lhs = ((arg1 * arg2) % params["p"]) % params["q"]
    return (lhs == r)
示例#2
0
def insecureSign(params, private_key, message):
    k = random.randrange(1, params["q"])
    r = GroupOp.mod_exp(params["g"], k, params["p"]) % params["q"]

    init_hash = sha1.SHA1()
    init_hash.Update(message)
    hashed_msg_val = int.from_bytes(init_hash.Sum(),
                                    byteorder="big") % params["q"]
    k_inv = GroupOp.find_inverse(k, params["q"])
    s = (k_inv * (hashed_msg_val + private_key * r)) % params["q"]

    return (r, s)
示例#3
0
def attacker(pub_key, old_ct):
    #pick a number rel. prime with the modulus
    random_s = random.randrange(1, pub_key[0])
    while GroupOp.find_gcd(random_s, pub_key[0]) != 1:
        random_s = random.randrange(1, pub_key[0])
    inv_s = GroupOp.find_inverse(random_s, pub_key[0])
    old_ct_as_number = int.from_bytes(old_ct, byteorder="big")
    new_ct = (GroupOp.mod_exp(random_s, pub_key[1], pub_key[0]) *
              old_ct_as_number) % pub_key[0]
    oracle_res = recovery_oracle(
        new_ct.to_bytes((new_ct.bit_length() + 7) // 8, byteorder="big"))
    val = (inv_s * int.from_bytes(oracle_res, byteorder="big")) % pub_key[0]
    print("Original message was {}".format(
        val.to_bytes((val.bit_length() + 7) // 8, byteorder="big")))
示例#4
0
def crt_reconstruct(modulus_one, modulus_two, modulus_three, rem_one, rem_two,
                    rem_three):
    large_mod = modulus_one * modulus_two * modulus_three
    crt_factor = (modulus_one * modulus_two) + \
        (modulus_two*modulus_three) + \
        (modulus_one*modulus_three)
    crt_factor = crt_factor % large_mod
    crt_factor_inv = GroupOp.find_inverse(crt_factor, large_mod)
    mod_one_factor = (crt_factor_inv * modulus_two * modulus_three * rem_one)
    mod_two_factor = (crt_factor_inv * modulus_three * modulus_one * rem_two)
    mod_three_factor = (crt_factor_inv * modulus_two * modulus_one * rem_three)
    reconstructed_ct_value = (mod_two_factor + mod_one_factor +
                              mod_three_factor) % large_mod
    return reconstructed_ct_value
示例#5
0
def AttackerWithKnownSubKeyK(params,
                             public_key,
                             k,
                             msg,
                             msg_sig,
                             msg_hash=None):
    recover_x = (msg_sig[1] * k) % params["q"]
    if not msg_hash:
        hash_obj = sha1.SHA1()
        hash_obj.Update(msg)
        msg_as_int = int.from_bytes(hash_obj.Sum(), byteorder="big")
    else:
        msg_as_int = msg_hash
    recover_x = (recover_x - (msg_as_int % params["q"])) % params["q"]
    recover_x = recover_x * (GroupOp.find_inverse(msg_sig[0], params["q"]))
    return recover_x % params["q"]
示例#6
0
def DSASign(params, private_key, message, print_k=False, k=0):
    r = 0
    s = 0
    while r == 0 and s == 0:
        if k == 0:
            k = random.randrange(1, params["q"])
        if print_k:
            print("K value is {:x}".format(k))
        r = GroupOp.mod_exp(params["g"], k, params["p"]) % params["q"]

        if r != 0:
            init_hash = sha1.SHA1()
            init_hash.Update(message)
            hashed_msg_val = int.from_bytes(init_hash.Sum(),
                                            byteorder="big") % params["q"]
            k_inv = GroupOp.find_inverse(k, params["q"])
            s = (k_inv * (hashed_msg_val + private_key * r)) % params["q"]

    return (r, s)
示例#7
0
def main():
    dictionary = from_file("44.txt")
    dict1, dict2 = isolate_repeated_k(dictionary)
    if not dict1:
        print("Could not run attack :(")
    else:
        inv_s_elt = (dict1["s"] - dict2["s"]) % challenge_params["q"]
        inv_s_elt = GroupOp.find_inverse(inv_s_elt, challenge_params["q"])
        exp_k = (dict1["m"] - dict2["m"]) % challenge_params["q"]
        exp_k = (exp_k * inv_s_elt) % challenge_params["q"]
        recovered_x = CP43.AttackerWithKnownSubKeyK(challenge_params,
                                                    challenge_public_key,
                                                    exp_k, dict1["msg"],
                                                    (dict1["r"], dict1["s"]),
                                                    dict1["m"])
        key_hash_obj = sha1.SHA1()
        key_hash_obj.Update(hex(recovered_x)[2:])
        key = int.from_bytes(key_hash_obj.Sum(), byteorder="big")
        print("Recovered key is {:x}  with fp {:x}".format(recovered_x, key))
    return
示例#8
0
def main():
    global challenge_params

    # assuming we want to keep the same public key because if we didn't
    # and it was based on the bogus generator then we have big problems

    tag = insecureSign(challenge_params, recovered_priv_key, b"A message")

    # r will be 0 here, s will be k^inv * H(msg)
    # but it really doesn't matter, because the other side needs to
    #  find the inverse of s so as long as s is invertible, you'll
    # validate. This signature would "work" for every message and moreover
    # ANYTHING will work as long as r=0 and s is invert.
    message = b"If music be the food of love, play on; Give me excess of it, that, surfeiting,The appetite may sicken, and so die. --Twelfth Night"
    res = insecureVerify(challenge_params, challenge_public_key, message,
                         (0, 0xdeadbeef))
    print("Generator g = 0\n")
    print("Message: {}, Sig: (0x{:x},0x{:x}), Result: {}".format(
        message, 0, 0xdeadbeef, res))
    # change the generator is p+1 and not
    challenge_params["g"] = challenge_params["p"] + 1
    # I'm going to assume the key was genereated honestly, because if it wasn't
    # we would get g**x = (p+1)**x mod p which is just 1

    choose_random = random.randrange(1, challenge_params["q"])
    r = GroupOp.mod_exp(challenge_public_key, choose_random,
                        challenge_params["p"]) % challenge_params["q"]
    s = (r * GroupOp.find_inverse(
        choose_random, challenge_params["q"])) % challenge_params["q"]
    result = insecureVerify(challenge_params, challenge_public_key,
                            b"Hello, world", (r, s))
    res2 = insecureVerify(challenge_params, challenge_public_key,
                          b"Goodbye, world", (r, s))
    print("Generator g = p + 1")
    print("Message: {}, Random val: 0x{:x}, Sig: (0x{:x},0x{:x}), Result: {}".
          format(b"Hello, world", choose_random, r, s, result))
    print("Message: {}, Random val: 0x{:x}, Sig: (0x{:x}, 0x{:x}), Result: {}".
          format(b"Goodbye, world", choose_random, r, s, res2))
    return
示例#9
0
def generate_RSA_key(bit_size_modulus, primes=None):
    if primes:
        p = primes[0]
        q = primes[1]
    else:
        desired_prime_size = (bit_size_modulus + 1) // 2
        p = GroupOp.generate_prime(desired_prime_size)
        q = GroupOp.generate_prime(desired_prime_size)
        while p == q or GroupOp.find_totient(p * q, [(p, 1), (q, 1)]) % 3 == 0:
            q = GroupOp.generate_prime(desired_prime_size)
    print("Prime p {:x} and q {:x}".format(p, q))
    n = p * q
    assert (n.bit_length() >= bit_size_modulus)

    group_of_mult_inv = GroupOp.find_totient(n, [(p, 1), (q, 1)])
    assert (group_of_mult_inv == ((p - 1) * (q - 1)))
    e = 3
    d = GroupOp.find_inverse(e, group_of_mult_inv)

    pub_key = (n, e)
    priv_key = (n, d)

    return pub_key, priv_key