Skip to content

Instantly share code, notes, and snippets.

@gtank
Last active October 5, 2019 17:18
Show Gist options
  • Save gtank/c9154250c3fce581676cc249a3c7fc4d to your computer and use it in GitHub Desktop.
Save gtank/c9154250c3fce581676cc249a3c7fc4d to your computer and use it in GitHub Desktop.
designated-verifier Schnorr (Saeednia)
# Returns (field, curve, scalars, basepoint)
def generate_parameters():
K = GF(2^255 - 19)
a = K(-1)
d = K(-121665/121666)
base_y = K(4/5)
base_x = ((1 - base_y^2) / (-1 - d*(base_y^2))).sqrt()
# Convert Edwards to Montgomery
A = 2*(a+d)/(a-d)
B = 4/(a-d)
base_u = (1+base_y)/(1-base_y)
base_v = base_u/base_x
# Convert Montgomery to Weierstrass
a = (3-A^2)/(3*B^2)
b = (2*A^3-9*A)/(27*B^3)
x0, y0 = (base_u+A/3)/B, base_v/B
# This is Ed25519, now in the model Sage understands.
E = EllipticCurve(GF(2^255-19), [a, b])
Scalars = GF(E.cardinality() / 8)
G = E(x0, y0)
return (K, E, Scalars, G)
Fp, E, Fq, G = generate_parameters()
# Returns (secret, public)
def generate_key(label):
sk = Fq.random_element()
pk = Integer(sk)*G
return (sk, pk)
def main():
# Each user generates a keypair
sk_A, pk_A = generate_key("Alice")
sk_B, pk_B = generate_key("Bob")
msg = b"Hello, world!"
# Alice signs to Bob
k, t = Fq.random_element(), Fq.random_element()
t_inv = Fq(inverse_mod(Integer(t), Fq.cardinality()))
c = Integer(k)*pk_B
r = Fq(Integer(hashlib.sha256(msg + c.dumps()).hexdigest(), base=16))
s = Fq(k*t_inv - r*sk_A)
# Signature is (r, s, t)
# Bob verifies
tmp = Integer(t*sk_B)*(Integer(s)*G + Integer(r)*pk_A)
r_prime = Fq(Integer(hashlib.sha256(msg + tmp.dumps()).hexdigest(), base=16))
assert(r == r_prime)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment