Ejemplo n.º 1
0
def challenge_44():
    # Set up `p`, `q` and `g` parameters
    p = 0x800000000000000089e1855218a0e7dac38136ffafa72eda7859f2171e25e65eac698c1702578b07dc2a1076da241c76c62d374d8389ea5aeffd3226a0530cc565f3bf6b50929139ebeac04f48c3c84afb796d61e5a4f9a8fda812ab59494232c7d2b4deb50aa18ee9e132bfa85ac4374d7f9091abc3d015efc871a584471bb1
    q = 0xf4f47f05794b256174bba6e9b396a7707e563c5b
    g = 0x5958c9d3898b224b12672c0b98e06c60df923cb8bc999d119458fef538b8fa4046c8db53039db620c094c9fa077ef389b5322a559946a71903f990f1f7e0e025e2d7f7cf494aff1a0470f5b64c36b625a097f1651fe775323556fe00b3608c887892878480e99041be601a62166ca6894bdd41a7054ec89f756ba9fc95302291
    # Create new DSA instance
    dsa = DSA(p, q, g)
    # Read inputs for this challenge from file
    messages = get_challenge_44_messages()
    # Iterate over messages
    for i, msg1 in enumerate(messages):
        for msg2 in messages[(i+1):]:
            # Check if the same `k` was used (implies `r` values are equal)
            if msg1['r'] == msg2['r']:
                # Use '9th grade math' to recover `k`
                a = (msg1['m'] - msg2['m']) % q
                b1 = (msg1['s'] - msg2['s']) % q
                b2 = set5.modinv(b1, q)
                k = (a * b2) % q
                print('Recovered k: {}'.format(k))
                # Recover `x`
                x = dsa.crack_x(k, msg=msg1['msg'], sig=(msg1['r'], msg1['s']))
                print('Recovered x: {}'.format(hashlib.sha1(hex(x)[2:].encode()).hexdigest()))
                # Verify the found private key `x` is the one we are looking for
                assert_true(hashlib.sha1(hex(x)[2:].encode()).hexdigest() == 'ca8f6f7c66fa362d40760d135b763eb8527d3d52')
                return
Ejemplo n.º 2
0
 def sign(self, msg, x):
     k = random.randrange(2, self.q)
     r = set5.modexp(self.g, k, self.p) % self.q
     if k == 0: return self.sign(msg, x)
     s = (set5.modinv(k, self.q) * (self.__get_hash__(msg) + (x*r))) % self.q
     if s == 0: return self.sign(msg, x)
     return (r, s), k
Ejemplo n.º 3
0
 def verify(self, msg, sig, y):
     r, s = sig
     if not(0 < r and r < self.q): raise ValueError('r not between 0 and q (r={})'.format(r))
     if not(0 < s and s < self.q): raise ValueError('s not between 0 and q (s={})'.format(s))
     w = set5.modinv(s, self.q)
     u1 = (self.__get_hash__(msg) * w) % self.q
     u2 = (r * w) % self.q
     v = ((set5.modexp(self.g, u1, self.p) * set5.modexp(y, u2, self.p)) % self.p) % self.q
     return v == r
Ejemplo n.º 4
0
def verify(mhash, signature, pub_key):
    r, s = signature[0], signature[1]
    if r == 0 or s == 0:
        return False
    w = modinv(s, q)
    H = int(mhash, 16)
    u1 = (H * w) % q
    u2 = (r * w) % q
    v = ((pow(g, u1, p) * pow(pub_key, u2, p)) % p) % q
    return True if v == r else False
Ejemplo n.º 5
0
def sign(mhash, priv_key):
    r = 0
    s = 0
    sha = hashlib.sha1()
    while r == 0 or s == 0:
        ephemeral = random.SystemRandom().randint(2, q - 1)
        r = pow(g, ephemeral, p) % q
        H = int(mhash, 16)
        s = (modinv(ephemeral, q) * (H + (priv_key * r))) % q
    return r, s
Ejemplo n.º 6
0
 def crack_x(self, k, msg, sig):
     r, s = sig
     return (((s * k) - self.__get_hash__(msg)) * set5.modinv(r, self.q)) % self.q