cardano_serialization_lib/chain_crypto/algorithms/
ed25519_extended.rs1use crate::chain_crypto::key::{
2 AsymmetricKey, AsymmetricPublicKey, SecretKeyError, SecretKeySizeStatic,
3};
4use crate::chain_crypto::sign::SigningAlgorithm;
5
6use super::ed25519 as ei;
7
8use cryptoxide::ed25519;
9use rand_os::rand_core::{CryptoRng, RngCore};
10
11use ed25519_bip32::{XPrv, XPRV_SIZE};
12
13pub struct Ed25519Extended;
15
16#[derive(Clone)]
17pub struct ExtendedPriv([u8; ed25519::EXTENDED_KEY_LENGTH]);
18
19impl AsRef<[u8]> for ExtendedPriv {
20 fn as_ref(&self) -> &[u8] {
21 &self.0[..]
22 }
23}
24
25impl ExtendedPriv {
26 pub fn from_xprv(xprv: &XPrv) -> Self {
27 let mut buf = [0; ed25519::EXTENDED_KEY_LENGTH];
28 xprv.get_extended_mut(&mut buf);
29 ExtendedPriv(buf)
30 }
31}
32
33impl AsymmetricKey for Ed25519Extended {
34 type Secret = ExtendedPriv;
35 type PubAlg = ei::Ed25519;
36
37 const SECRET_BECH32_HRP: &'static str = "ed25519e_sk";
38
39 fn generate<T: RngCore + CryptoRng>(mut rng: T) -> Self::Secret {
40 let mut priv_bytes = [0u8; XPRV_SIZE];
41 rng.fill_bytes(&mut priv_bytes);
42 let xprv = XPrv::normalize_bytes_force3rd(priv_bytes);
43
44 let mut out = [0u8; ed25519::EXTENDED_KEY_LENGTH];
45 xprv.get_extended_mut(&mut out);
46 ExtendedPriv(out)
47 }
48
49 fn compute_public(key: &Self::Secret) -> <Self::PubAlg as AsymmetricPublicKey>::Public {
50 let pk = ed25519::extended_to_public(&key.0);
51 ei::Pub(pk)
52 }
53
54 fn secret_from_binary(data: &[u8]) -> Result<Self::Secret, SecretKeyError> {
55 if data.len() != ed25519::EXTENDED_KEY_LENGTH {
56 return Err(SecretKeyError::SizeInvalid);
57 }
58 let mut buf = [0; ed25519::EXTENDED_KEY_LENGTH];
59 buf.clone_from_slice(data);
60 Ok(ExtendedPriv(buf))
62 }
63}
64
65impl SecretKeySizeStatic for Ed25519Extended {
66 const SECRET_KEY_SIZE: usize = ed25519::PRIVATE_KEY_LENGTH;
67}
68
69impl SigningAlgorithm for Ed25519Extended {
70 fn sign(key: &Self::Secret, msg: &[u8]) -> ei::Sig {
71 ei::Sig(ed25519::signature_extended(msg, &key.0))
72 }
73}
74
75#[cfg(test)]
76mod test {
77 use super::*;
78
79 use crate::chain_crypto::key::KeyPair;
80 use crate::chain_crypto::sign::test::{keypair_signing_ko, keypair_signing_ok};
81
82 #[quickcheck]
83 fn sign_ok(input: (KeyPair<Ed25519Extended>, Vec<u8>)) -> bool {
84 keypair_signing_ok(input)
85 }
86
87 #[quickcheck]
88 fn sign_ko(input: (KeyPair<Ed25519Extended>, KeyPair<Ed25519Extended>, Vec<u8>)) -> bool {
89 keypair_signing_ko(input)
90 }
91}