Hazmat EC Signatures (Ed448)With Ed448 we use a private key to sign data, and then the public key can prove it. We use Curve 448 for the generation of the public key and for the signing process. X448 is based on Curve 448, and is used for key exchange with ECDH (Elliptic Curve Diffie Hellman) as X448 and Ed448 for a digital signature. It supports a 224-bit security level, and where we use a 448-bit (56-byte) prime number of \(P = 2^{448} - 2^{224} - 1\). It has improved security over Curve 25519, and which has a 255-bit prime number (\(P = 2^{255} - 19\)). As with X25519, in X448 we use a Montgomery curve (\(v^2 = u^3 + A \times u^2 + u\)) with scalar multiplication. In X448, we use 56-byte string values, rather than 32-byte values for X25519. Overall, X448 uses a little-endian method to store an array of bytes, and has a value of \(A = 39,081\) [article]. |
Coding
The following is the code:
from cryptography.hazmat.primitives.asymmetric.ed448 import Ed448PrivateKey from cryptography import exceptions from cryptography.hazmat.primitives import serialization import binascii import sys data=b"Test" if (len(sys.argv)>1): data=str(sys.argv[1]).encode() private_key = Ed448PrivateKey.generate() public_key = private_key.public_key() public_key = private_key.public_key() print ("Message: ",data.decode()) try: signature = private_key.sign(data) print ("Good Signature: ",binascii.b2a_hex(signature).decode()) public_key.verify(signature, data) except exceptions.InvalidSignature: print("A bad signature failed") else: print("Good signature verified") try: signature = private_key.sign(b"Bad data") print ("Bad Signature: ",binascii.b2a_hex(signature).decode()) public_key.verify(signature, data) except exceptions.InvalidSignature: print("A bad signature failed") else: print("Good signature verified") pem = private_key.private_bytes(encoding=serialization.Encoding.PEM,format=serialization.PrivateFormat.PKCS8,encryption_algorithm=serialization.NoEncryption()) der = private_key.private_bytes(encoding=serialization.Encoding.DER,format=serialization.PrivateFormat.PKCS8,encryption_algorithm=serialization.NoEncryption()) print ("\nPrivate key (PEM):\n",pem.decode()) print ("Private key (DER):\n",binascii.b2a_hex(der)) pem = public_key.public_bytes(encoding=serialization.Encoding.PEM,format=serialization.PublicFormat.SubjectPublicKeyInfo) der = public_key.public_bytes(encoding=serialization.Encoding.DER,format=serialization.PublicFormat.SubjectPublicKeyInfo) print ("\nPublic key (PEM):\n",pem.decode()) print ("Public key (DER):\n",binascii.b2a_hex(der))
The following is a sample run:
Message: My test data Good Signature: 1a00b309bbc1db576f69223a9fe51a318904cd09eeeaca85f57f48702ea181acbc222752eb7cf26ea346ff90bc37afe253077b767de9519580ad87b75ed69f05a6836dc96f0b39734288bffe8be76dd45ff9572063414d442fbfe32bb1eabe63ebc03cfaae8cd978fbf4f784dc3cf6893700 Good signature verified Bad Signature: 74245ff08a3701451d16083873770572cea1c48dc3885d5ae706f884c6b1b5696b4759d99102ea1f03f2ba7f4228a12bf3908b494df2f81c003445f6dd06de79a88bc66f9c479817269bc8cc4e02b1e8dad41f01f3574d5f2708544efbf843b40d0c55f37258e8092630c42dd710503f0800 A bad signature failed Private key (PEM): -----BEGIN PRIVATE KEY----- MEcCAQAwBQYDK2VxBDsEOWHblcx3vUz3LhK2fZd3rbNOGecQpl8M0C4v3zfcEh7T LHc79ShJkxSBvuIitNDqKdzOiKY475gO9A== -----END PRIVATE KEY----- Private key (DER): b'3047020100300506032b6571043b043961db95cc77bd4cf72e12b67d9777adb34e19e710a65f0cd02e2fdf37dc121ed32c773bf52849931481bee222b4d0ea29dcce88a638ef980ef4' Public key (PEM): -----BEGIN PUBLIC KEY----- MEMwBQYDK2VxAzoAvu1/UQYZHE6scPqG8SUYuo8Vtj3NFh6S3jUb8hzvNFPHDPB+ arsOoQ7d/RhJz8A4hKVZp6ElmAYA -----END PUBLIC KEY----- Public key (DER): b'3043300506032b6571033a00beed7f5106191c4eac70fa86f12518ba8f15b63dcd161e92de351bf21cef3453c70cf07e6abb0ea10eddfd1849cfc03884a559a7a125980600'