Link to this headingXEdDSA

https://signal.org/docs/specifications/xeddsa/

Link to this headingImplimentation

from ecc_lib import * import hashlib, os, math from cryptopals_lib import bytes_to_int, int_to_bytes, secure_rand_between def xeddsa_sign(private_key, message, nonce=secure_rand_between(1, 2**64), curve_generator=Curve25519_Generator_Point, hash_obj=hashlib.sha512): #Derive Information curve = curve_generator.curve order = curve.order public_key = curve_generator * private_key #r = hash1(private_key || message || nonce) (mod q) hash_bytes = hash_obj( int_to_bytes(private_key) + message + nonce ).digest() random_r = bytes_to_int(hash_bytes) % order #R = rB random_point = curve_generator * random_r #h = hash(R || public_key || message) (mod q) hash_bytes = hash_obj(random_point.compressed() + public_key.compressed() + message ).digest() hash_int = bytes_to_int(hash_bytes) % order #s = r + ha (mod q) signature = (random_r + (hash_int * private_key )) % order #return R || s return {"random_point": random_point, "signature": signature} def xeddsa_verify(public_key, message, signature, curve_generator=Curve25519_Generator_Point, hash_obj=hashlib.sha512): #Derive Information curve = curve_generator.curve order = curve.order prime_mod = curve.prime_mod #Check Inputs for bounds #if public_key >= p: if public_key.x >= prime_mod or public_key.y >= prime_mod: raise Exception("Invalid public_key") #if random_point.y >= 2^|p| or s >= 2^|q| if signature["random_point"].y >= 2**(math.ceil(math.log2(prime_mod))) or signature["signature"] >= 2**(math.ceil(math.log2(order))): raise Exception("Invalid signature") #Check if Public Key is on the Curve if not curve.is_on_curve(public_key): raise Exception(f"public_key is not on {curve.name}") #h = hash(random_point || public_key || message) (mod q) hash_bytes = hash_obj(signature["random_point"].compressed() + public_key.compressed() + message ).digest() hash_int = bytes_to_int(hash_bytes) % order #Rcheck = s*generator - h*public_key check_random_point = (curve_generator * signature["signature"]) - (hash_int * public_key) return check_random_point == signature["random_point"] if __name__ == '__main__': #Generate Keys message = b"Test Message" nonce = os.urandom(64) #Generate KeyPair private_key, public_point = generate_KeyPair(Curve25519_Generator_Point) print(private_key, public_point) #Sign message signature = xeddsa_sign(private_key, message, nonce) print(signature) #Verify Message verify = xeddsa_verify(public_point, message, signature) print(f"The Signature has been verified as {verify}")

Link to this headingVerifiable XEdDSA (VXEdDSA )