Пример #1
0
def recover_private_key(m: bytes, signature: DSASignature, k: int,
                        q: int) -> int:
    """Recover private key from signature and subkey k"""
    r, s = signature
    h_m = m39.to_int(m28.SHA1(m).digest())
    r_inv = m39.invmod(r, q)
    return r_inv * (s * k - h_m) % q
Пример #2
0
def magic_signature_generator(y: int, p: int, q: int) -> m43.DSASignature:
    """Generate a magic signature, assuming verification with g = 1 mod p"""

    # See https://infoscience.epfl.ch/record/99390/files/Vau96c.ps §4.
    #
    # The trick is to realise at what point we assume g = 1 mod p. Here, it's
    # after key generation but before validation, i,e. the value of g changes
    # mid-way. This means we have to work with some given public key y != 1.
    #
    # The last validation calculation is v = g^u_1 y^u_2 mod p mod q. At this
    # point, g = 1 mod p so this reduces to
    #
    #    v = g^u_1 y^u_2 mod p mod q
    #      = y^u_2 mod p mod q
    #      = y^(rw) mod p mod q
    #      = y^(r / s) mod p mod q.
    #
    # Since validation requires r = v, we solve
    #
    #    r = y^(r / s) mod p mod q.
    #
    # Note that r necessarily depends on y. r = y^z mod p mod q and
    # s = r / z mod q is a solution, for arbitrary z != 0 mod q.

    z = randint(1, q - 1)
    z_inv = m39.invmod(z, q)

    r = pow(y, z, p) % q
    s = z_inv * r % q

    return m43.DSASignature(r, s)
Пример #3
0
def recover_k(message_1: dict[str, Any], message_2: dict[str, Any],
              q: int) -> int:
    m_1 = message_1["m"]
    m_2 = message_2["m"]
    s_1 = message_1["s"]
    s_2 = message_2["s"]

    return m39.invmod((s_1 - s_2) % q, q) * ((m_1 - m_2) % q) % q
Пример #4
0
def sign(m: bytes, x: int, p: int, q: int, g: int) -> DSASignature:
    """Sign message with DSA private key"""
    h_m = m39.to_int(m28.SHA1(m).digest())
    r, s = 0, 0
    while r == 0 or s == 0:
        k = randint(1, q - 1)
        r = pow(g, k, p) % q
        k_inv = m39.invmod(k, q)
        s = (k_inv * (h_m + x * r)) % q

    return DSASignature(r, s)
Пример #5
0
def verify_relaxed(m: bytes, signature: m43.DSASignature, y: int, p: int,
                   q: int, g: int) -> bool:
    """Verify DSA signature without checking constraints on r, s"""
    r, s = signature

    w = m39.invmod(s, q)
    h_m = m39.to_int(m28.SHA1(m).digest())
    u_1 = h_m * w % q
    u_2 = r * w % q
    v = pow(g, u_1, p) * pow(y, u_2, p) % p % q

    return v == r
Пример #6
0
def sign_relaxed(m: bytes, x: int, p: int, q: int, g: int) -> m43.DSASignature:
    """Sign message without checking constraints on r, s"""
    # The original implementation checks this and falls into
    # an infinite loop.
    h_m = m39.to_int(m28.SHA1(m).digest())
    k = randint(1, q - 1)
    k_inv = m39.invmod(k, q)

    r = pow(g, k, p) % q
    s = (k_inv * (h_m + x * r)) % q

    return m43.DSASignature(r, s)
Пример #7
0
def recover_message(c: int, server: DecryptionServer) -> bytes:
    """Recover plaintext via homeomorphic transformation"""
    e, n = server.public_key
    # We use a random number so we can perform repeated decryptions
    s = randint(2, 4096)

    c_prime = pow(s, e, n) * c % n
    p_prime = m39.to_int(server.decrypt(c_prime))

    s_inverse = m39.invmod(s, n)
    p = p_prime * s_inverse % n

    return m39.to_bytes(p)
Пример #8
0
def crt(a: list[int], n: list[int]) -> int:
    """
    Given lists a_1, ..., a_k and n_1, ..., n_k, solve the
    system x = a_i mod n_i for all i such that 0 <= x < prod(n_i),
    assuming n_i are pairwise coprime.
    """
    r = 0
    N = math.prod(n)
    for a_i, n_i in zip(a, n, strict=True):
        m_s = N // n_i
        r += a_i * m_s * m39.invmod(m_s, n_i)

    return r % N
Пример #9
0
def verify(m: bytes, signature: DSASignature, y: int, p: int, q: int,
           g: int) -> bool:
    """Verify DSA signature"""
    r, s = signature

    if not 0 < r < q or not 0 < s < q:
        return False

    w = m39.invmod(s, q)
    h_m = m39.to_int(m28.SHA1(m).digest())
    u_1 = h_m * w % q
    u_2 = r * w % q
    v = pow(g, u_1, p) * pow(y, u_2, p) % p % q

    return v == r