fromecc_libimport*importhashlib,os,mathfromcryptopals_libimportbytes_to_int,int_to_bytes,secure_rand_betweendefxeddsa_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.curveorder=curve.orderpublic_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}defxeddsa_verify(public_key,message,signature,curve_generator=Curve25519_Generator_Point,hash_obj=hashlib.sha512):#Derive Information
curve=curve_generator.curveorder=curve.orderprime_mod=curve.prime_mod#Check Inputs for bounds
#if public_key >= p:
ifpublic_key.x>=prime_modorpublic_key.y>=prime_mod:raiseException("Invalid public_key")#if random_point.y >= 2^|p| or s >= 2^|q|
ifsignature["random_point"].y>=2**(math.ceil(math.log2(prime_mod)))orsignature["signature"]>=2**(math.ceil(math.log2(order))):raiseException("Invalid signature")#Check if Public Key is on the Curve
ifnotcurve.is_on_curve(public_key):raiseException(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)returncheck_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}")