uselesskey-ed25519 0.7.0

Ed25519 key fixtures (PKCS#8/SPKI, PEM/DER) with deterministic generation.
Documentation
/// Specification for Ed25519 key generation.
///
/// Ed25519 has no configurable parameters like RSA bit size,
/// so this struct is simple and always returns the same spec.
///
/// # Examples
///
/// ```
/// use uselesskey_ed25519::Ed25519Spec;
///
/// let spec = Ed25519Spec::new();
/// // Ed25519 has no configurable parameters
/// assert_eq!(spec, Ed25519Spec::default());
/// ```
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Default)]
pub struct Ed25519Spec {
    // Ed25519 has fixed parameters, but we keep this struct for API consistency
    // and future-proofing (e.g., context strings if we add Ed25519ctx support).
    _private: (),
}

impl Ed25519Spec {
    /// Create a new Ed25519 spec.
    ///
    /// Ed25519 has no configurable parameters, so this always
    /// returns the same spec.
    ///
    /// # Examples
    ///
    /// ```
    /// use uselesskey_ed25519::Ed25519Spec;
    ///
    /// let spec = Ed25519Spec::new();
    /// assert_eq!(spec, Ed25519Spec::default());
    /// ```
    pub fn new() -> Self {
        Self { _private: () }
    }

    /// Stable encoding for cache keys / deterministic derivation.
    ///
    /// If you change this, bump the derivation version in `uselesskey-core`.
    ///
    /// # Examples
    ///
    /// ```
    /// use uselesskey_ed25519::Ed25519Spec;
    ///
    /// let bytes = Ed25519Spec::new().stable_bytes();
    /// assert_eq!(bytes.len(), 4);
    /// ```
    pub fn stable_bytes(&self) -> [u8; 4] {
        // Fixed identifier for Ed25519 keys.
        // Format: [magic byte, version, reserved, reserved]
        [b'E', b'd', 0x01, 0x00]
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn new_and_default_match() {
        let a = Ed25519Spec::new();
        let b = Ed25519Spec::default();
        assert_eq!(a, b);
    }

    #[test]
    fn stable_bytes_are_fixed() {
        let spec = Ed25519Spec::new();
        assert_eq!(spec.stable_bytes(), [b'E', b'd', 0x01, 0x00]);
    }
}