def construct_signature(curve, hash, data, r, s, elapsed): """Parse the signature into a Signature object.""" h = hash.copy() h.update(data) data_hash = int(h.hexdigest(), 16) if h.digest_size * 8 > curve.group.n.bit_length(): data_hash >>= h.digest_size * 8 - curve.group.n.bit_length() r = Mod(r, curve.group.n) s = Mod(s, curve.group.n) sinv = s.inverse() t = (sinv * r) u = (-sinv * data_hash) return Signature(elapsed, data_hash, int(t), int(u))
def recompute_nonce(self, sig): hm = Mod(sig.h, self.curve.group.n) r = Mod(sig.r, self.curve.group.n) x = Mod(self.privkey, self.curve.group.n) hmrx = hm + r * x return Mod(sig.sinv, self.curve.group.n) * hmrx
parser.add_argument("--iter-time", type=int, default=1) parser.add_argument("--sdev", type=float, default=None) args = parser.parse_args() curve = get_curve(args.curve) hash = hashlib.new(args.hash) private = secrets.randbelow(curve.group.n) public = private * curve.g data = secrets.token_bytes(64) print(hexlify(curve.encode_point(public)).decode(), hexlify(data).decode(), hex(private)[2:]) hash.update(data) hashed = int(hash.hexdigest(), 16) if hash.digest_size * 8 > curve.group.n.bit_length(): hashed >>= hash.digest_size * 8 - curve.group.n.bit_length() hashed = Mod(hashed, curve.group.n) if args.sdev is None or args.sdev == 0: noise_f = lambda: 0 else: noise = norm(0, args.sdev) noise_f = lambda: noise.rvs() for i in range(args.count): k = secrets.randbelow(curve.group.n) pt = k * curve.g r = int(pt.x) s = int(Mod(k, curve.group.n).inverse() * (hashed + r * private)) elapsed = args.base + args.iter_time * k.bit_length() + int(noise_f()) print(hex(r)[2:] + "," + hex(s)[2:] + "," + str(elapsed))