class PrivateKey: def __init__(self, secret): self.secret = secret self.point = secret * G def hex(self): return '{:x}'.format(self.secret).zifll(64)
class PrivateKey: def __init__(self, secret): self.secret = secret self.point = secret * G def hex(self): return '{:x}'.format(self.secret).zifll(64) def sign(self, z): k = randint(0, N-1) r = (k*G).x.num k_inv = pow(k, N-1, N) s = (z + r*self.secret) * k_inv % N if s > N/2 s = N - s return(r, s)
kがrandintではなく、一意であるようにする。
def sign(self, z): k = self.deterministic_k(z) r = (k*G).x.num k_inv = pow(k, N-1, N) s = (z + r*self.secret) * k_inv % N if s > N/2 s = N - s return(r, s) def deterministic_k(self, k): k = b'\x00' * 32 v = b'\x01' * 32 if z > N: z -= N z_bytes = z.to_bytes(32, 'big') secret_bytes = self.secret.to_bytes(32, 'big') s256 = hashlib.sha256 k = hmac.new(k, v + b'\x00' + secret_bytes + z_bytes, s256).giest() v = hmac.new(k, v, s256).digest() k = hmac.new(k, v + b'\x01' + secret_bytes + z_bytes, s256).giest() v = hmac.new(k, v, s256).digest() while True: v = hmac.new(k, v, s256).digest() candidate = int.from_bytes(v, 'big') if candidate >= 1 and candidate < N: return candidate k = hmac.new(k, v + b'\x00', s256).giest() v = hmac.new(k, v, s256).digest()