Skip to content

Ed25519

provide.foundation.crypto.ed25519

Ed25519 digital signature implementation.

Ed25519 is the recommended algorithm for new applications: fast, small keys, deterministic signatures, and modern cryptography.

Examples:

>>> signer = Ed25519Signer.generate()
>>> signature = signer.sign(b"message")
>>> verifier = Ed25519Verifier(signer.public_key)
>>> assert verifier.verify(b"message", signature)

Classes

Ed25519Signer

Ed25519 digital signature signer.

Stateful signer that holds private key and provides signing operations. Ed25519 is the recommended choice for new applications: fast, small keys, deterministic signatures.

Examples:

Generate new keypair: >>> signer = Ed25519Signer.generate() >>> signature = signer.sign(b"message") >>> public_key = signer.public_key

Load existing key: >>> signer = Ed25519Signer(private_key=existing_32_byte_seed) >>> signature = signer.sign(b"message")

Attributes
public_key cached property
public_key: bytes

Get 32-byte Ed25519 public key.

Returns:

Name Type Description
bytes bytes

32-byte public key

Functions
__attrs_post_init__
__attrs_post_init__() -> None

Initialize private key object from bytes.

Source code in provide/foundation/crypto/ed25519.py
def __attrs_post_init__(self) -> None:
    """Initialize private key object from bytes."""
    _require_crypto()

    if self.private_key is None:
        raise CryptoKeyError(
            "private_key is required. Use Ed25519Signer.generate() to create new keypair.",
            code="CRYPTO_MISSING_PRIVATE_KEY",
        )

    if len(self.private_key) != ED25519_PRIVATE_KEY_SIZE:
        raise CryptoKeyError(
            f"Ed25519 private key must be {ED25519_PRIVATE_KEY_SIZE} bytes, got {len(self.private_key)}",
            code="CRYPTO_INVALID_PRIVATE_KEY_SIZE",
        )

    # Reconstruct private key object from seed bytes
    object.__setattr__(
        self,
        "_private_key_obj",
        ed25519.Ed25519PrivateKey.from_private_bytes(self.private_key),
    )
export_private_key
export_private_key() -> bytes

Export 32-byte private key seed.

Returns:

Name Type Description
bytes bytes

32-byte Ed25519 private key seed

Warning

Private keys should be stored securely. Consider encryption.

Source code in provide/foundation/crypto/ed25519.py
def export_private_key(self) -> bytes:
    """Export 32-byte private key seed.

    Returns:
        bytes: 32-byte Ed25519 private key seed

    Warning:
        Private keys should be stored securely. Consider encryption.
    """
    return self.private_key  # type: ignore
generate classmethod
generate() -> Self

Generate new signer with random Ed25519 keypair.

Returns:

Name Type Description
Ed25519Signer Self

Signer with newly generated keypair

Source code in provide/foundation/crypto/ed25519.py
@classmethod
def generate(cls) -> Self:
    """Generate new signer with random Ed25519 keypair.

    Returns:
        Ed25519Signer: Signer with newly generated keypair
    """
    _require_crypto()
    logger.debug("🔐 Generating new Ed25519 signer")

    private_key_obj = ed25519.Ed25519PrivateKey.generate()
    private_key_bytes = private_key_obj.private_bytes(
        encoding=serialization.Encoding.Raw,
        format=serialization.PrivateFormat.Raw,
        encryption_algorithm=serialization.NoEncryption(),
    )

    return cls(private_key=private_key_bytes)
sign
sign(data: bytes) -> bytes

Sign data with Ed25519 private key.

Parameters:

Name Type Description Default
data bytes

Data to sign

required

Returns:

Name Type Description
bytes bytes

64-byte Ed25519 signature

Raises:

Type Description
CryptoSignatureError

If signature generation fails

Source code in provide/foundation/crypto/ed25519.py
def sign(self, data: bytes) -> bytes:
    """Sign data with Ed25519 private key.

    Args:
        data: Data to sign

    Returns:
        bytes: 64-byte Ed25519 signature

    Raises:
        CryptoSignatureError: If signature generation fails
    """
    logger.debug(f"🔏 Signing {len(data)} bytes with Ed25519")

    signature = self._private_key_obj.sign(data)

    if len(signature) != ED25519_SIGNATURE_SIZE:
        raise CryptoSignatureError(
            f"Invalid signature size: expected {ED25519_SIGNATURE_SIZE} bytes, got {len(signature)}",
            code="CRYPTO_INVALID_SIGNATURE_SIZE",
        )

    return signature

Ed25519Verifier

Ed25519 signature verifier.

Stateful verifier that holds public key and provides verification operations.

Examples:

>>> signer = Ed25519Signer.generate()
>>> verifier = Ed25519Verifier(signer.public_key)
>>> signature = signer.sign(b"message")
>>> assert verifier.verify(b"message", signature)
Functions
__attrs_post_init__
__attrs_post_init__() -> None

Initialize public key object from bytes.

Source code in provide/foundation/crypto/ed25519.py
def __attrs_post_init__(self) -> None:
    """Initialize public key object from bytes."""
    _require_crypto()

    if len(self.public_key) != ED25519_PUBLIC_KEY_SIZE:
        raise CryptoKeyError(
            f"Ed25519 public key must be {ED25519_PUBLIC_KEY_SIZE} bytes, got {len(self.public_key)}",
            code="CRYPTO_INVALID_PUBLIC_KEY_SIZE",
        )

    # Reconstruct public key object from bytes
    object.__setattr__(
        self,
        "_public_key_obj",
        ed25519.Ed25519PublicKey.from_public_bytes(self.public_key),
    )
verify
verify(data: bytes, signature: bytes) -> bool

Verify Ed25519 signature.

Parameters:

Name Type Description Default
data bytes

Data that was signed

required
signature bytes

64-byte Ed25519 signature

required

Returns:

Name Type Description
bool bool

True if signature is valid, False otherwise

Source code in provide/foundation/crypto/ed25519.py
def verify(self, data: bytes, signature: bytes) -> bool:
    """Verify Ed25519 signature.

    Args:
        data: Data that was signed
        signature: 64-byte Ed25519 signature

    Returns:
        bool: True if signature is valid, False otherwise
    """
    if len(signature) != ED25519_SIGNATURE_SIZE:
        logger.warning(
            f"❌ Invalid signature size: expected {ED25519_SIGNATURE_SIZE}, got {len(signature)}",
        )
        return False

    logger.debug(f"🔍 Verifying Ed25519 signature for {len(data)} bytes")

    try:
        self._public_key_obj.verify(signature, data)
        return True
    except Exception as e:
        logger.debug(f"❌ Invalid Ed25519 signature: {e}")
        return False