Edwards-curve Digital Signature Algorithm (EdDSA)ΒΆ
EdDSA is a deterministic digital signature scheme based on twisted Edwards elliptic curves (Ed25519 and Ed448). It is specified in RFC8032, as two variants:
PureEdDSA, where the message is signed directly.
HashEdDSA, where the message is first hashed, and only the resulting digest is signed. This should only be used by streaming applications because it avoids double passes on messages, at the cost of reduced collision resistance.
This module supports signatures for both variants (PureEdDSA and HashEdDSA), on the Ed25519 curve (with a 128-bit security level), and on the Ed448 curve (with a 224-bit security level).
For HashEdDSA, the hash function must be SHA-512 in case of Ed25519, and SHAKE256 for Ed448.
A sender can use a private key (loaded from a file) to sign a message:
from Crypto.PublicKey import ECC
from Signature import eddsa
message = b'I give my permission to order #4355'
key = ECC.import_key(open("private_ed25519.pem").read()))
signer = eddsa.new(key, 'rfc8032')
signature = signer.sign(message)
The receiver can use the matching public key to verify authenticity of the received message:
from Crypto.PublicKey import ECC
from Signature import eddsa
message = b'I give my permission to order #4355'
key = ECC.import_key(open("public_ed25519.pem").read()))
verifier = eddsa.new(key, 'rfc8032')
try:
verifier.verify(message, signature)
print("The message is authentic")
except ValueError:
print("The message is not authentic")
Alternatively the HashedEdDSA variant can be used to sign a message with Ed25519:
from Crypto.PublicKey import ECC
from Signature import eddsa
from Crypto.Hash import SHA512
message = b'I give my permission to order #4355'
prehashed_message = SHA512.new(message)
key = ECC.import_key(open("private_ed25519.pem").read()))
signer = eddsa.new(key, 'rfc8032')
signature = signer.sign(prehashed_message)
HashedEdDSA also exists for Ed448:
from Crypto.PublicKey import ECC
from Signature import eddsa
from Crypto.Hash import SHAKE256
message = b'I give my permission to order #4355'
prehashed_message = SHAKE256.new(message)
key = ECC.import_key(open("private_ed448.pem").read()))
signer = eddsa.new(key, 'rfc8032')
signature = signer.sign(prehashed_message)