Beispiel #1
0
def find_key(sigs, q=q):
    '''takes list of triples (s, r, H(m) as bigint) looks for repeated
	nonces and recovers nonce and private key
	'''
    #s = k^(-1)(H(m) + xr) mod q
    #=> k = s^(-1)(H(m) + xr) mod q  (1)

    #r = g^k mod q
    #s = k^(-1)(H(m) + xr) mod q

    #r' = g^k' mod q
    #s' = k'^(-1)(H(m') + xr') mod q

    #Detecting Repeated Nonce
    #k == k' ==> r == r
    #r == r' ==> k probably equals k'
    #
    #r = (sk - H(m))/x mod q
    #r == r'=> (sk - H(m))/x == (s'k - H(m'))/x mod q
    #=> k(s - s') = H(m) - H(m') mod q
    #=> K = (H(m) - H(m'))/(s - s') mod q
    sigs_by_r = {}
    for s, r, m in sigs:
        if r not in sigs_by_r:
            sigs_by_r[r] = (s, m)
            continue
        #same r ==> same k?
        if r in sigs_by_r:
            sp, mp = sigs_by_r[r]
            #find nonce
            k = ((m - mp) * number_theory.mod_inv(s - sp, q)) % q
            #find private key from nonce
            x = p43.recover_private_key(None, r, s, k, q, m)
            return x
Beispiel #2
0
def dsa_sign_with_k(H_m, x, k):
    g, p, q = dsa.g, dsa.p, dsa.q

    #r = (g^k mod p) mod q
    r = pow(g, k, p) % q
    #s = k^(-1)(H(m) + xr) mod q
    k_inv = number_theory.mod_inv(k, q)
    s = (k_inv * ((H_m + ((x * r) % q)) % q)) % q
    return (r, s)
Beispiel #3
0
def recover_private_key(m, r, s, k, q, H_m=None):
    '''recover dsa private key from k and signature'''
    #s = k^(-1)(H(m) + xr) mod q
    #==> sk - H(m) = xr (mod q)
    #==> x = r^(-1)(sk - H(m)) mod q
    if not H_m:
        H_m = util.bytes_to_bigint(util.sha1sum(m))
    r_inv = number_theory.mod_inv(r, q)
    x = ((((s * k) % q - H_m) % q) * r_inv) % q
    return x
Beispiel #4
0
def dsa_verify(r, s, m, y, p=p, q=q, g=g, h=util.sha1sum):
    #check that 0 < r < q and 0 < s < q
    if 0 >= r or r >= q or 0 >= s or r >= q:
        return False
    H_m = util.bytes_to_bigint(h(m))
    #w = s^(-1) mod q
    w = number_theory.mod_inv(s, q)
    u1 = (H_m * w) % q
    #u_2 = r*w = r*s^(-1)
    u2 = (r * w) % q
    v = ((pow(g, u1, p) * pow(y, u2, p)) % p) % q
    return v == r
Beispiel #5
0
def dsa_sign(m, x, p=p, q=q, g=g, h=util.sha1sum):
    H_m = util.bytes_to_bigint(h(m))
    while True:
        #generate nonce 1 < k < q
        k = random.SystemRandom().randrange(1, q - 1)
        #r = (g^k mod p) mod q
        r = pow(g, k, p) % q
        #if r == 0, pick new k and try again
        if r == 0: continue

        #s = k^(-1)(H(m) + xr) mod q
        k_inv = number_theory.mod_inv(k, q)
        s = (k_inv * ((H_m + ((x * r) % q)) % q)) % q
        #if s == 0, pick new k and try again
        if s == 0: continue

        return (r, s)
Beispiel #6
0
def gen_key_pair(bit_length=1024, verbose=False):
    '''generates an RSA public private key pair and returns
		d, e, n
	'''
    p = _find_rsa_prime(bit_length / 2)
    if verbose:
        print 'p =', p
    q = _find_rsa_prime(bit_length / 2)
    if verbose:
        print 'q =', q
    n = p * q
    if verbose:
        print 'n =', n
    phi_n = (p - 1) * (q - 1)
    if verbose:
        print 'phi(n) =', phi_n
    #this is not secure (duh!!!)
    e = 3
    d = number_theory.mod_inv(e, phi_n)
    if verbose:
        print 'e, d = %d, %d' % (e, d)
    return d, e, n
Beispiel #7
0
        if rsa_blob in self._seen:
            return
        return rsa.rsa_decrypt(rsa_blob, self._d, self._n)

    def get_ct(self):
        pt = "%d something" % int(time.time())
        ct = rsa.rsa_encrypt(pt, self._e, self._n)
        self._seen.add(ct)
        return ct

    def get_public_key(self):
        return self._e, self._n


if __name__ == '__main__':
    oracle = Oracle()
    ct = oracle.get_ct()

    #cannot query oracle on ciphertexts it has already seen
    assert (oracle.query(ct) == None)

    e, n = oracle.get_public_key()

    #c' = s^e*c ==> p' = (s^e*c)^d = s*p
    s = 2
    ctp = (pow(s, e, n) * ct) % n

    ptp = oracle.query(ctp)
    pt = (ptp * number_theory.mod_inv(s, n)) % n
    print util.bigint_to_bytes(pt)
Beispiel #8
0
    #s = k^(-1)(H(m) + xr) mod q
    k_inv = number_theory.mod_inv(k, q)
    s = (k_inv * ((H_m + ((x * r) % q)) % q)) % q
    return (r, s)


if __name__ == '__main__':
    y = 0x84ad4719d044495496a3201c8ff484feb45b962e7302e56a392aee4abab3e4bdebf2955b4736012f21a08084056b19bcd7fee56048e004e44984e2f411788efdc837a0d2e5abb7b555039fd243ac01f0fb2ed1dec568280ce678e931868d23eb095fde9d3779191b8c0299d6e07bbb283e6633451e535c45513b2d33c99ea17

    msg = '''For those that envy a MC it can be hazardous to your health\nSo be friendly, a matter of life and death, just like a etch-a-sketch\n'''

    r = 548099063082341131477253921760299949438196259240
    s = 857042759984254168557880549501802188789837994940
    assert (util.sha1sum(msg).encode('hex') ==
            'd2d0714f014a9784047eaeccf956520045c45265')

    H_m = util.bytes_to_bigint(util.sha1sum(msg))
    r_inv = number_theory.mod_inv(r, dsa.q)

    for k in range(1, 1 << 16):
        #x = ((((s*k) % dsa.q  + dsa.q - H_m) % dsa.q) * r_inv) % dsa.q
        x = ((s * k - H_m) * r_inv) % dsa.q
        if dsa_sign_with_k(H_m, x, k) == (r, s):
            #if x is actual privake key => y = g^x mod p
            assert (y == pow(dsa.g, x, dsa.p))
            print 'k =', k
            print 'Private key =', x
            key_hash = util.sha1sum('%x' % x).encode('hex')
            assert (key_hash == '0954edd5e0afe5542a4adf012611a91912a3ec16')
            break