Skip to main content

arcana/encoding/
keys.rs

1//! Key serialization: PKCS#1 (RSA), SEC1 (ECC), SPKI, PKCS#8.
2//!
3//! Implements `to_*_der` / `from_*_der` and `to_*_pem` / `from_*_pem`
4//! on the existing key types in `rsa::rsa` and `ecc::curves` /
5//! `ecc::eddsa`.
6
7use super::der::*;
8use super::pem::*;
9use crate::ecc::curves::{PublicKey as EcPublicKey, SecretKey as EcSecretKey};
10use crate::ecc::eddsa::{Ed25519PublicKey, Ed25519SecretKey};
11use crate::rsa::bigint::BigInt;
12use crate::rsa::rsa::{RsaPublicKey, RsaSecretKey};
13
14// ====================================================================
15// RSA — PKCS#1 DER (RFC 8017 §A.1)
16// ====================================================================
17
18impl RsaPublicKey {
19    /// Encode as PKCS#1 DER (`RSAPublicKey ::= SEQUENCE { n INTEGER, e INTEGER }`).
20    pub fn to_pkcs1_der(&self) -> Vec<u8> {
21        let n_bytes = self.n.to_be_bytes(self.n.byte_len());
22        let e_bytes = self.e.to_be_bytes(self.e.byte_len());
23        let mut inner = DerEncoder::new();
24        inner.integer(&n_bytes);
25        inner.integer(&e_bytes);
26        let content = inner.finish();
27        let mut outer = DerEncoder::new();
28        outer.sequence(&content);
29        outer.finish()
30    }
31
32    /// Parse from PKCS#1 DER.
33    pub fn from_pkcs1_der(der: &[u8]) -> Option<Self> {
34        let mut dec = DerDecoder::new(der);
35        let mut seq = dec.read_sequence()?;
36        let n = BigInt::from_be_bytes(seq.read_integer()?);
37        let e = BigInt::from_be_bytes(seq.read_integer()?);
38        if !seq.is_empty() {
39            return None;
40        }
41        Some(Self { n, e })
42    }
43
44    /// Encode as SubjectPublicKeyInfo DER (RFC 5280).
45    pub fn to_spki_der(&self) -> Vec<u8> {
46        let pkcs1 = self.to_pkcs1_der();
47        // AlgorithmIdentifier: SEQUENCE { rsaEncryption OID, NULL }
48        let mut algo = DerEncoder::new();
49        algo.oid(OID_RSA);
50        algo.null();
51        let algo_bytes = algo.finish();
52        let mut inner = DerEncoder::new();
53        inner.sequence(&algo_bytes);
54        inner.bit_string(&pkcs1);
55        let content = inner.finish();
56        let mut outer = DerEncoder::new();
57        outer.sequence(&content);
58        outer.finish()
59    }
60
61    /// Parse from SubjectPublicKeyInfo DER.
62    pub fn from_spki_der(der: &[u8]) -> Option<Self> {
63        let mut dec = DerDecoder::new(der);
64        let mut seq = dec.read_sequence()?;
65        let mut algo_seq = seq.read_sequence()?;
66        let oid = algo_seq.read_oid()?;
67        if oid != OID_RSA {
68            return None;
69        }
70        algo_seq.read_null()?;
71        let pk_bits = seq.read_bit_string()?;
72        Self::from_pkcs1_der(pk_bits)
73    }
74
75    /// Encode as PKCS#1 PEM.
76    pub fn to_pkcs1_pem(&self) -> String {
77        pem_encode("RSA PUBLIC KEY", &self.to_pkcs1_der())
78    }
79    /// Parse from PKCS#1 PEM.
80    pub fn from_pkcs1_pem(pem: &str) -> Option<Self> {
81        Self::from_pkcs1_der(&pem_decode("RSA PUBLIC KEY", pem)?)
82    }
83    /// Encode as SPKI PEM.
84    pub fn to_spki_pem(&self) -> String {
85        pem_encode("PUBLIC KEY", &self.to_spki_der())
86    }
87    /// Parse from SPKI PEM.
88    pub fn from_spki_pem(pem: &str) -> Option<Self> {
89        Self::from_spki_der(&pem_decode("PUBLIC KEY", pem)?)
90    }
91}
92
93impl RsaSecretKey {
94    /// Encode as PKCS#1 DER (`RSAPrivateKey`, RFC 8017 §A.1.2).
95    pub fn to_pkcs1_der(&self) -> Vec<u8> {
96        let n = self.n.to_be_bytes(self.n.byte_len());
97        let e_val = BigInt::from_be_bytes(&[0x01, 0x00, 0x01]); // 65537
98        let e = e_val.to_be_bytes(e_val.byte_len());
99        let d = self.d.to_be_bytes(self.d.byte_len());
100        let p = self.p.to_be_bytes(self.p.byte_len());
101        let q = self.q.to_be_bytes(self.q.byte_len());
102        let dp = self.dp.to_be_bytes(self.dp.byte_len());
103        let dq = self.dq.to_be_bytes(self.dq.byte_len());
104        let qinv = self.qinv.to_be_bytes(self.qinv.byte_len());
105
106        let mut inner = DerEncoder::new();
107        inner.integer_u64(0); // version
108        inner.integer(&n);
109        inner.integer(&e);
110        inner.integer(&d);
111        inner.integer(&p);
112        inner.integer(&q);
113        inner.integer(&dp);
114        inner.integer(&dq);
115        inner.integer(&qinv);
116        let content = inner.finish();
117        let mut outer = DerEncoder::new();
118        outer.sequence(&content);
119        outer.finish()
120    }
121
122    /// Parse from PKCS#1 DER.
123    pub fn from_pkcs1_der(der: &[u8]) -> Option<Self> {
124        let mut dec = DerDecoder::new(der);
125        let mut seq = dec.read_sequence()?;
126        let version = seq.read_integer_u64()?;
127        if version != 0 {
128            return None;
129        } // only two-prime RSA
130        let n = BigInt::from_be_bytes(seq.read_integer()?);
131        let _e = seq.read_integer()?; // public exponent (we store it in pk)
132        let d = BigInt::from_be_bytes(seq.read_integer()?);
133        let p = BigInt::from_be_bytes(seq.read_integer()?);
134        let q = BigInt::from_be_bytes(seq.read_integer()?);
135        let dp = BigInt::from_be_bytes(seq.read_integer()?);
136        let dq = BigInt::from_be_bytes(seq.read_integer()?);
137        let qinv = BigInt::from_be_bytes(seq.read_integer()?);
138        Some(Self {
139            n,
140            d,
141            p,
142            q,
143            dp,
144            dq,
145            qinv,
146        })
147    }
148
149    /// Encode as PKCS#1 PEM.
150    pub fn to_pkcs1_pem(&self) -> String {
151        pem_encode("RSA PRIVATE KEY", &self.to_pkcs1_der())
152    }
153    /// Parse from PKCS#1 PEM.
154    pub fn from_pkcs1_pem(pem: &str) -> Option<Self> {
155        Self::from_pkcs1_der(&pem_decode("RSA PRIVATE KEY", pem)?)
156    }
157}
158
159// ====================================================================
160// ECC — SPKI (public) + PKCS#8 (private) + SEC1 (private)
161// ====================================================================
162
163/// Curve identifier for ECC key serialization.
164#[derive(Clone, Copy, Debug, PartialEq, Eq)]
165pub enum EcCurve {
166    /// NIST P-256 / secp256r1.
167    P256,
168    /// NIST P-384 / secp384r1.
169    P384,
170    /// NIST P-521 / secp521r1.
171    P521,
172    /// secp256k1.
173    Secp256k1,
174    /// brainpoolP256r1.
175    BrainpoolP256r1,
176    /// brainpoolP384r1.
177    BrainpoolP384r1,
178    /// brainpoolP512r1.
179    BrainpoolP512r1,
180}
181
182impl EcCurve {
183    fn oid(self) -> &'static [u8] {
184        match self {
185            EcCurve::P256 => OID_SECP256R1,
186            EcCurve::P384 => OID_SECP384R1,
187            EcCurve::P521 => OID_SECP521R1,
188            EcCurve::Secp256k1 => OID_SECP256K1,
189            EcCurve::BrainpoolP256r1 => OID_BRAINPOOL_P256R1,
190            EcCurve::BrainpoolP384r1 => OID_BRAINPOOL_P384R1,
191            EcCurve::BrainpoolP512r1 => OID_BRAINPOOL_P512R1,
192        }
193    }
194
195    fn from_oid(oid: &[u8]) -> Option<Self> {
196        match oid {
197            x if x == OID_SECP256R1 => Some(EcCurve::P256),
198            x if x == OID_SECP384R1 => Some(EcCurve::P384),
199            x if x == OID_SECP521R1 => Some(EcCurve::P521),
200            x if x == OID_SECP256K1 => Some(EcCurve::Secp256k1),
201            x if x == OID_BRAINPOOL_P256R1 => Some(EcCurve::BrainpoolP256r1),
202            x if x == OID_BRAINPOOL_P384R1 => Some(EcCurve::BrainpoolP384r1),
203            x if x == OID_BRAINPOOL_P512R1 => Some(EcCurve::BrainpoolP512r1),
204            _ => None,
205        }
206    }
207}
208
209impl EcPublicKey {
210    /// Encode as SubjectPublicKeyInfo DER (RFC 5480).
211    pub fn to_spki_der(&self, curve: EcCurve) -> Vec<u8> {
212        // AlgorithmIdentifier: SEQUENCE { id-ecPublicKey OID, curve OID }
213        let mut algo = DerEncoder::new();
214        algo.oid(OID_EC_PUBLIC_KEY);
215        algo.oid(curve.oid());
216        let algo_bytes = algo.finish();
217        let mut inner = DerEncoder::new();
218        inner.sequence(&algo_bytes);
219        inner.bit_string(&self.bytes);
220        let content = inner.finish();
221        let mut outer = DerEncoder::new();
222        outer.sequence(&content);
223        outer.finish()
224    }
225
226    /// Parse from SubjectPublicKeyInfo DER. Returns `(key, curve)`.
227    pub fn from_spki_der(der: &[u8]) -> Option<(Self, EcCurve)> {
228        let mut dec = DerDecoder::new(der);
229        let mut seq = dec.read_sequence()?;
230        let mut algo_seq = seq.read_sequence()?;
231        let oid = algo_seq.read_oid()?;
232        if oid != OID_EC_PUBLIC_KEY {
233            return None;
234        }
235        let curve_oid = algo_seq.read_oid()?;
236        let curve = EcCurve::from_oid(curve_oid)?;
237        let pk_bits = seq.read_bit_string()?;
238        Some((
239            Self {
240                bytes: pk_bits.to_vec(),
241            },
242            curve,
243        ))
244    }
245
246    /// Encode as SPKI PEM.
247    pub fn to_spki_pem(&self, curve: EcCurve) -> String {
248        pem_encode("PUBLIC KEY", &self.to_spki_der(curve))
249    }
250
251    /// Parse from SPKI PEM.
252    pub fn from_spki_pem(pem: &str) -> Option<(Self, EcCurve)> {
253        Self::from_spki_der(&pem_decode("PUBLIC KEY", pem)?)
254    }
255}
256
257impl EcSecretKey {
258    /// Encode as SEC1 DER (RFC 5915: `ECPrivateKey`).
259    pub fn to_sec1_der(&self, curve: EcCurve, public_key: Option<&EcPublicKey>) -> Vec<u8> {
260        let mut inner = DerEncoder::new();
261        inner.integer_u64(1); // version
262
263        inner.octet_string(&self.bytes);
264
265        // [0] EXPLICIT curve OID (optional but recommended)
266        {
267            let mut oid_enc = DerEncoder::new();
268            oid_enc.oid(curve.oid());
269            let oid_bytes = oid_enc.finish();
270            inner.context_explicit(0, &oid_bytes);
271        }
272
273        // [1] EXPLICIT public key BIT STRING (optional)
274        if let Some(pk) = public_key {
275            let mut bs = DerEncoder::new();
276            bs.bit_string(&pk.bytes);
277            let bs_bytes = bs.finish();
278            inner.context_explicit(1, &bs_bytes);
279        }
280
281        let content = inner.finish();
282        let mut outer = DerEncoder::new();
283        outer.sequence(&content);
284        outer.finish()
285    }
286
287    /// Parse from SEC1 DER. Returns `(secret_key, curve, optional_public_key)`.
288    pub fn from_sec1_der(der: &[u8]) -> Option<(Self, EcCurve, Option<EcPublicKey>)> {
289        let mut dec = DerDecoder::new(der);
290        let mut seq = dec.read_sequence()?;
291        let version = seq.read_integer_u64()?;
292        if version != 1 {
293            return None;
294        }
295        let sk_bytes = seq.read_octet_string()?;
296
297        // [0] curve OID
298        let mut ctx0 = seq.read_context_explicit(0)?;
299        let curve_oid = ctx0.read_oid()?;
300        let curve = EcCurve::from_oid(curve_oid)?;
301
302        // [1] public key (optional)
303        let pk = if let Some(mut ctx1) = seq.read_context_explicit(1) {
304            let pk_bits = ctx1.read_bit_string()?;
305            Some(EcPublicKey {
306                bytes: pk_bits.to_vec(),
307            })
308        } else {
309            None
310        };
311
312        Some((
313            Self {
314                bytes: sk_bytes.to_vec(),
315            },
316            curve,
317            pk,
318        ))
319    }
320
321    /// Encode as PKCS#8 DER (RFC 5958).
322    pub fn to_pkcs8_der(&self, curve: EcCurve, public_key: Option<&EcPublicKey>) -> Vec<u8> {
323        let sec1 = self.to_sec1_der(curve, public_key);
324        // AlgorithmIdentifier: SEQUENCE { id-ecPublicKey, curve OID }
325        let mut algo = DerEncoder::new();
326        algo.oid(OID_EC_PUBLIC_KEY);
327        algo.oid(curve.oid());
328        let algo_bytes = algo.finish();
329
330        let mut inner = DerEncoder::new();
331        inner.integer_u64(0); // version (v1)
332        inner.sequence(&algo_bytes);
333        inner.octet_string(&sec1);
334        let content = inner.finish();
335        let mut outer = DerEncoder::new();
336        outer.sequence(&content);
337        outer.finish()
338    }
339
340    /// Encode as SEC1 PEM.
341    pub fn to_sec1_pem(&self, curve: EcCurve, public_key: Option<&EcPublicKey>) -> String {
342        pem_encode("EC PRIVATE KEY", &self.to_sec1_der(curve, public_key))
343    }
344
345    /// Encode as PKCS#8 PEM.
346    pub fn to_pkcs8_pem(&self, curve: EcCurve, public_key: Option<&EcPublicKey>) -> String {
347        pem_encode("PRIVATE KEY", &self.to_pkcs8_der(curve, public_key))
348    }
349}
350
351// ====================================================================
352// Ed25519 — SPKI (public) + PKCS#8 (private) per RFC 8037
353// ====================================================================
354
355impl Ed25519PublicKey {
356    /// Encode as SubjectPublicKeyInfo DER (RFC 8037).
357    pub fn to_spki_der(&self) -> Vec<u8> {
358        // AlgorithmIdentifier: SEQUENCE { id-Ed25519 } — no parameters
359        let mut algo = DerEncoder::new();
360        algo.oid(OID_ED25519);
361        let algo_bytes = algo.finish();
362        let mut inner = DerEncoder::new();
363        inner.sequence(&algo_bytes);
364        inner.bit_string(&self.0);
365        let content = inner.finish();
366        let mut outer = DerEncoder::new();
367        outer.sequence(&content);
368        outer.finish()
369    }
370
371    /// Parse from SPKI DER.
372    pub fn from_spki_der(der: &[u8]) -> Option<Self> {
373        let mut dec = DerDecoder::new(der);
374        let mut seq = dec.read_sequence()?;
375        let mut algo_seq = seq.read_sequence()?;
376        let oid = algo_seq.read_oid()?;
377        if oid != OID_ED25519 {
378            return None;
379        }
380        let pk_bits = seq.read_bit_string()?;
381        if pk_bits.len() != 32 {
382            return None;
383        }
384        let mut out = [0u8; 32];
385        out.copy_from_slice(pk_bits);
386        Some(Self(out))
387    }
388
389    /// Encode as SPKI PEM.
390    pub fn to_spki_pem(&self) -> String {
391        pem_encode("PUBLIC KEY", &self.to_spki_der())
392    }
393    /// Parse from SPKI PEM.
394    pub fn from_spki_pem(pem: &str) -> Option<Self> {
395        Self::from_spki_der(&pem_decode("PUBLIC KEY", pem)?)
396    }
397}
398
399impl Ed25519SecretKey {
400    /// Encode as PKCS#8 DER (RFC 8037).
401    pub fn to_pkcs8_der(&self) -> Vec<u8> {
402        // The "private key" in PKCS#8 for Ed25519 is an OCTET STRING
403        // containing the 32-byte seed, itself wrapped in an OCTET STRING.
404        let mut seed_enc = DerEncoder::new();
405        seed_enc.octet_string(&self.0);
406        let seed_der = seed_enc.finish();
407
408        let mut algo = DerEncoder::new();
409        algo.oid(OID_ED25519);
410        let algo_bytes = algo.finish();
411
412        let mut inner = DerEncoder::new();
413        inner.integer_u64(0); // version
414        inner.sequence(&algo_bytes);
415        inner.octet_string(&seed_der);
416        let content = inner.finish();
417        let mut outer = DerEncoder::new();
418        outer.sequence(&content);
419        outer.finish()
420    }
421
422    /// Parse from PKCS#8 DER.
423    pub fn from_pkcs8_der(der: &[u8]) -> Option<Self> {
424        let mut dec = DerDecoder::new(der);
425        let mut seq = dec.read_sequence()?;
426        let version = seq.read_integer_u64()?;
427        if version != 0 {
428            return None;
429        }
430        let mut algo_seq = seq.read_sequence()?;
431        let oid = algo_seq.read_oid()?;
432        if oid != OID_ED25519 {
433            return None;
434        }
435        let pk_octet = seq.read_octet_string()?;
436        // Inner OCTET STRING wrapping the 32-byte seed.
437        let mut inner = DerDecoder::new(pk_octet);
438        let seed = inner.read_octet_string()?;
439        if seed.len() != 32 {
440            return None;
441        }
442        let mut out = [0u8; 32];
443        out.copy_from_slice(seed);
444        Some(Self(out))
445    }
446
447    /// Encode as PKCS#8 PEM.
448    pub fn to_pkcs8_pem(&self) -> String {
449        pem_encode("PRIVATE KEY", &self.to_pkcs8_der())
450    }
451    /// Parse from PKCS#8 PEM.
452    pub fn from_pkcs8_pem(pem: &str) -> Option<Self> {
453        Self::from_pkcs8_der(&pem_decode("PRIVATE KEY", pem)?)
454    }
455}
456
457// ====================================================================
458// Tests
459// ====================================================================
460
461#[cfg(test)]
462mod tests {
463    use super::*;
464    use crate::ecc::eddsa::ed25519_keygen;
465
466    fn rng_fill(buf: &mut [u8]) {
467        static mut CTR: u64 = 0xdeadbeef;
468        for b in buf.iter_mut() {
469            unsafe {
470                CTR = CTR.wrapping_mul(6364136223846793005).wrapping_add(1);
471                *b = (CTR >> 33) as u8;
472            }
473        }
474    }
475
476    // ---------- RSA ----------
477
478    #[test]
479    fn rsa_pkcs1_roundtrip() {
480        let (pk, sk) = crate::rsa::rsa::rsa_keygen(1024, &mut rng_fill);
481
482        let pk_der = pk.to_pkcs1_der();
483        let pk_back = RsaPublicKey::from_pkcs1_der(&pk_der).unwrap();
484        assert_eq!(
485            pk_back.n.to_be_bytes(pk.n.byte_len()),
486            pk.n.to_be_bytes(pk.n.byte_len())
487        );
488        assert_eq!(
489            pk_back.e.to_be_bytes(pk.e.byte_len()),
490            pk.e.to_be_bytes(pk.e.byte_len())
491        );
492
493        let sk_der = sk.to_pkcs1_der();
494        let sk_back = RsaSecretKey::from_pkcs1_der(&sk_der).unwrap();
495        assert_eq!(
496            sk_back.n.to_be_bytes(sk.n.byte_len()),
497            sk.n.to_be_bytes(sk.n.byte_len())
498        );
499        assert_eq!(
500            sk_back.p.to_be_bytes(sk.p.byte_len()),
501            sk.p.to_be_bytes(sk.p.byte_len())
502        );
503    }
504
505    #[test]
506    fn rsa_spki_roundtrip() {
507        let (pk, _) = crate::rsa::rsa::rsa_keygen(1024, &mut rng_fill);
508        let der = pk.to_spki_der();
509        let pk_back = RsaPublicKey::from_spki_der(&der).unwrap();
510        assert_eq!(
511            pk_back.n.to_be_bytes(pk.n.byte_len()),
512            pk.n.to_be_bytes(pk.n.byte_len())
513        );
514    }
515
516    #[test]
517    fn rsa_pem_roundtrip() {
518        let (pk, sk) = crate::rsa::rsa::rsa_keygen(1024, &mut rng_fill);
519        let pk_pem = pk.to_pkcs1_pem();
520        assert!(pk_pem.contains("-----BEGIN RSA PUBLIC KEY-----"));
521        let pk_back = RsaPublicKey::from_pkcs1_pem(&pk_pem).unwrap();
522        assert_eq!(
523            pk_back.n.to_be_bytes(pk.n.byte_len()),
524            pk.n.to_be_bytes(pk.n.byte_len())
525        );
526
527        let sk_pem = sk.to_pkcs1_pem();
528        assert!(sk_pem.contains("-----BEGIN RSA PRIVATE KEY-----"));
529        let sk_back = RsaSecretKey::from_pkcs1_pem(&sk_pem).unwrap();
530        assert_eq!(
531            sk_back.p.to_be_bytes(sk.p.byte_len()),
532            sk.p.to_be_bytes(sk.p.byte_len())
533        );
534    }
535
536    // ---------- ECC P-256 ----------
537
538    #[test]
539    fn ec_spki_roundtrip() {
540        use crate::ecc::curves::{CryptoRng, Curve, P256};
541        struct Rng(u64);
542        impl CryptoRng for Rng {
543            fn fill_bytes(&mut self, dest: &mut [u8]) {
544                for b in dest {
545                    self.0 = self.0.wrapping_mul(6364136223846793005).wrapping_add(1);
546                    *b = (self.0 >> 33) as u8;
547                }
548            }
549        }
550        let (pk, _sk) = P256::keygen(&mut Rng(0xCAFE));
551        let der = pk.to_spki_der(EcCurve::P256);
552        let (pk_back, curve) = EcPublicKey::from_spki_der(&der).unwrap();
553        assert_eq!(curve, EcCurve::P256);
554        assert_eq!(pk_back.bytes, pk.bytes);
555    }
556
557    #[test]
558    fn ec_sec1_roundtrip() {
559        use crate::ecc::curves::{CryptoRng, Curve, P256};
560        struct Rng(u64);
561        impl CryptoRng for Rng {
562            fn fill_bytes(&mut self, dest: &mut [u8]) {
563                for b in dest {
564                    self.0 = self.0.wrapping_mul(6364136223846793005).wrapping_add(1);
565                    *b = (self.0 >> 33) as u8;
566                }
567            }
568        }
569        let (pk, sk) = P256::keygen(&mut Rng(0xBEEF));
570        let der = sk.to_sec1_der(EcCurve::P256, Some(&pk));
571        let (sk_back, curve, pk_back) = EcSecretKey::from_sec1_der(&der).unwrap();
572        assert_eq!(curve, EcCurve::P256);
573        assert_eq!(sk_back.bytes, sk.bytes);
574        assert_eq!(pk_back.unwrap().bytes, pk.bytes);
575    }
576
577    #[test]
578    fn ec_pem_roundtrip() {
579        use crate::ecc::curves::{CryptoRng, Curve, P256};
580        struct Rng(u64);
581        impl CryptoRng for Rng {
582            fn fill_bytes(&mut self, dest: &mut [u8]) {
583                for b in dest {
584                    self.0 = self.0.wrapping_mul(6364136223846793005).wrapping_add(1);
585                    *b = (self.0 >> 33) as u8;
586                }
587            }
588        }
589        let (pk, sk) = P256::keygen(&mut Rng(0xFACE));
590        let pem = pk.to_spki_pem(EcCurve::P256);
591        assert!(pem.contains("-----BEGIN PUBLIC KEY-----"));
592        let (pk_back, _) = EcPublicKey::from_spki_pem(&pem).unwrap();
593        assert_eq!(pk_back.bytes, pk.bytes);
594
595        let sk_pem = sk.to_sec1_pem(EcCurve::P256, None);
596        assert!(sk_pem.contains("-----BEGIN EC PRIVATE KEY-----"));
597    }
598
599    // ---------- Ed25519 ----------
600
601    #[test]
602    fn ed25519_spki_roundtrip() {
603        let seed = [0x42u8; 32];
604        let (pk, _sk) = ed25519_keygen(&seed);
605        let der = pk.to_spki_der();
606        let pk_back = Ed25519PublicKey::from_spki_der(&der).unwrap();
607        assert_eq!(pk_back.0, pk.0);
608    }
609
610    #[test]
611    fn ed25519_pkcs8_roundtrip() {
612        let seed = [0x42u8; 32];
613        let (_pk, sk) = ed25519_keygen(&seed);
614        let der = sk.to_pkcs8_der();
615        let sk_back = Ed25519SecretKey::from_pkcs8_der(&der).unwrap();
616        assert_eq!(sk_back.0, sk.0);
617    }
618
619    #[test]
620    fn ed25519_pem_roundtrip() {
621        let seed = [0x42u8; 32];
622        let (pk, sk) = ed25519_keygen(&seed);
623        let pem = pk.to_spki_pem();
624        assert!(pem.contains("-----BEGIN PUBLIC KEY-----"));
625        let pk_back = Ed25519PublicKey::from_spki_pem(&pem).unwrap();
626        assert_eq!(pk_back.0, pk.0);
627
628        let sk_pem = sk.to_pkcs8_pem();
629        assert!(sk_pem.contains("-----BEGIN PRIVATE KEY-----"));
630        let sk_back = Ed25519SecretKey::from_pkcs8_pem(&sk_pem).unwrap();
631        assert_eq!(sk_back.0, sk.0);
632    }
633}