def verify(self, m, r, s, y, dgst=hashlib.sha1): # signature verification # https://en.wikipedia.org/wiki/Digital_Signature_Algorithm#Verifying assert (r > 0 and r < self.q), "wrong r: 0 < r < q" assert (s > 0 and s < self.q), "wrong s: 0 < s < q" w = invmod(s, self.q) u1 = (s2i(dgst(m).digest())*w) % self.q u2 = (r*w) % self.q v = ((modexp(self.g, u1, self.p)*modexp(y, u2, self.p)) % self.p )% self.q assert (v == r), "verification failed, v != r" return True
def signk(self, m, x, dgst=hashlib.sha1): # signing with a leak of the k value # m - message # x - private key # https://en.wikipedia.org/wiki/Digital_Signature_Algorithm#Signing r = 0 k = 0 while r == 0: k = randint(0, self.q) r = modexp(self.g, k, self.p) % self.q s = (invmod(k, self.q) * (s2i(dgst(m).digest())+(x*r))) % self.q return (r, s, k)
def b_step2a (pubkey, prvkey, c, oracle): """ Bleichenbacher step 2a """ e = pubkey[0] n = pubkey[1] c = s2i("".join(c)) c0 = (c * modexp(1, e, n)) % n s1 = n // 0x3B count = 0 while True: c1 = (c0 * modexp(s1, e, n)) % n if oracle(prvkey, list(i2s(c1))): break s1 += 1 if count % 10 == 0: sys.stdout.write("%s \r" % (count)) sys.stdout.flush() count += 1 return s1
def y_gen(self, x): # y generator return modexp(self.g, x, self.p)
def magic_sign(self, y, z = 20): # only if g == p+1 assert (self.g == self.p+1), "only if g == p+1" r = modexp(y, z, self.p) % self.q s = r * invmod(z, self.q) return (r, s)