cml_crypto/
lib.rs

1//use crate::byron::{AddrAttributes, AddressContent};
2use crate::chain_crypto::bech32::Bech32;
3pub use cml_core::{
4    error::{DeserializeError, DeserializeFailure},
5    serialization::{Deserialize, RawBytesEncoding, Serialize, StringEncoding},
6};
7use cryptoxide::blake2b::Blake2b;
8pub use derivative::Derivative;
9use impl_mockchain::key;
10use rand::rngs::OsRng;
11use std::convert::From;
12
13pub mod emip3;
14
15// brought over from old IOHK code
16pub mod chain_core;
17pub mod chain_crypto;
18pub mod impl_mockchain;
19pub mod typed_bytes;
20
21// used in chain_core / chain_crypto
22#[macro_use]
23extern crate cfg_if;
24
25#[derive(Debug, thiserror::Error)]
26pub enum CryptoError {
27    #[error("Bech32: {0}")]
28    Bech32(#[from] chain_crypto::bech32::Error),
29    #[error("ByronError: {0}")]
30    Hex(#[from] hex::FromHexError),
31    #[error("Deserialization: {0}")]
32    Deserialization(#[from] DeserializeError),
33    #[error("SecretKeyError: {0}")]
34    SecretKey(#[from] chain_crypto::SecretKeyError),
35    #[error("PublicKeyError: {0}")]
36    PublicKey(#[from] chain_crypto::PublicKeyError),
37    #[error("SignatureFromStr: {0}")]
38    SignatureFromStr(#[from] chain_crypto::SignatureFromStrError),
39    #[error("BootStrapCombine: {0}")]
40    BootstrapCombine(#[from] ed25519_bip32::PublicKeyError),
41    #[error("SignatureError: {0}")]
42    SignatureError(#[from] chain_crypto::SignatureError),
43}
44
45// otherwise with 2 Froms (bech32::Error -> chain_crypto::bech32::Error -> CryptoError)
46// this can be hard to use (type annotations needed) so we provide a direct one.
47impl From<bech32::Error> for CryptoError {
48    fn from(e: bech32::Error) -> Self {
49        chain_crypto::bech32::Error::Bech32Malformed(e).into()
50    }
51}
52
53pub fn blake2b224(data: &[u8]) -> [u8; 28] {
54    let mut out = [0; 28];
55    Blake2b::blake2b(&mut out, data, &[]);
56    out
57}
58
59pub fn blake2b256(data: &[u8]) -> [u8; 32] {
60    let mut out = [0; 32];
61    Blake2b::blake2b(&mut out, data, &[]);
62    out
63}
64
65// All key structs were adapted from js-chain-libs:
66// https://github.com/Emurgo/js-chain-libs
67
68pub struct Bip32PrivateKey(chain_crypto::SecretKey<chain_crypto::Ed25519Bip32>);
69
70impl Bip32PrivateKey {
71    /// derive this private key with the given index.
72    ///
73    /// # Security considerations
74    ///
75    /// * hard derivation index cannot be soft derived with the public key
76    ///
77    /// # Hard derivation vs Soft derivation
78    ///
79    /// If you pass an index below 0x80000000 then it is a soft derivation.
80    /// The advantage of soft derivation is that it is possible to derive the
81    /// public key too. I.e. derivation the private key with a soft derivation
82    /// index and then retrieving the associated public key is equivalent to
83    /// deriving the public key associated to the parent private key.
84    ///
85    /// Hard derivation index does not allow public key derivation.
86    ///
87    /// This is why deriving the private key should not fail while deriving
88    /// the public key may fail (if the derivation index is invalid).
89    ///
90    pub fn derive(&self, index: u32) -> Bip32PrivateKey {
91        Bip32PrivateKey(chain_crypto::derive::derive_sk_ed25519(&self.0, index))
92    }
93
94    /// 128-byte xprv a key format in Cardano that some software still uses or requires
95    /// the traditional 96-byte xprv is simply encoded as
96    /// prv | chaincode
97    /// however, because some software may not know how to compute a public key from a private key,
98    /// the 128-byte inlines the public key in the following format
99    /// prv | pub | chaincode
100    /// so be careful if you see the term "xprv" as it could refer to either one
101    /// our library does not require the pub (instead we compute the pub key when needed)
102    pub fn from_128_xprv(bytes: &[u8]) -> Result<Bip32PrivateKey, CryptoError> {
103        let mut buf = [0; 96];
104        buf[0..64].clone_from_slice(&bytes[0..64]);
105        buf[64..96].clone_from_slice(&bytes[96..128]);
106
107        Bip32PrivateKey::from_raw_bytes(&buf).map_err(Into::into)
108    }
109    /// see from_128_xprv
110    pub fn to_128_xprv(&self) -> Vec<u8> {
111        let raw_key = self.to_raw_key();
112        let prv_key = raw_key.to_raw_bytes();
113        let raw_pub_key = self.to_public().to_raw_key();
114        let pub_key = raw_pub_key.to_raw_bytes();
115        let cc = self.chaincode();
116
117        let mut buf = [0; 128];
118        buf[0..64].clone_from_slice(prv_key);
119        buf[64..96].clone_from_slice(pub_key);
120        buf[96..128].clone_from_slice(&cc);
121        buf.to_vec()
122    }
123
124    pub fn generate_ed25519_bip32() -> Bip32PrivateKey {
125        Bip32PrivateKey(chain_crypto::SecretKey::<chain_crypto::Ed25519Bip32>::generate(OsRng))
126    }
127
128    pub fn to_raw_key(&self) -> PrivateKey {
129        PrivateKey(key::EitherEd25519SecretKey::Extended(
130            chain_crypto::derive::to_raw_sk(&self.0),
131        ))
132    }
133
134    pub fn to_public(&self) -> Bip32PublicKey {
135        Bip32PublicKey(self.0.to_public())
136    }
137
138    pub fn from_bech32(bech32_str: &str) -> Result<Bip32PrivateKey, CryptoError> {
139        chain_crypto::SecretKey::try_from_bech32_str(bech32_str)
140            .map(Bip32PrivateKey)
141            .map_err(Into::into)
142    }
143
144    pub fn to_bech32(&self) -> String {
145        self.0.to_bech32_str()
146    }
147
148    pub fn from_bip39_entropy(entropy: &[u8], password: &[u8]) -> Bip32PrivateKey {
149        Bip32PrivateKey(chain_crypto::derive::from_bip39_entropy(entropy, password))
150    }
151
152    pub fn chaincode(&self) -> Vec<u8> {
153        const ED25519_PRIVATE_KEY_LENGTH: usize = 64;
154        const XPRV_SIZE: usize = 96;
155        self.0.as_ref()[ED25519_PRIVATE_KEY_LENGTH..XPRV_SIZE].to_vec()
156    }
157}
158
159impl RawBytesEncoding for Bip32PrivateKey {
160    fn to_raw_bytes(&self) -> &[u8] {
161        self.0.as_ref()
162    }
163
164    fn from_raw_bytes(bytes: &[u8]) -> Result<Self, DeserializeError> {
165        chain_crypto::SecretKey::<chain_crypto::Ed25519Bip32>::from_binary(bytes)
166            .map_err(|e| DeserializeFailure::InvalidStructure(Box::new(e)).into())
167            .map(Bip32PrivateKey)
168    }
169}
170
171#[derive(
172    Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
173)]
174pub struct Bip32PublicKey(pub chain_crypto::PublicKey<chain_crypto::Ed25519Bip32>);
175
176impl Bip32PublicKey {
177    /// derive this public key with the given index.
178    ///
179    /// # Errors
180    ///
181    /// If the index is not a soft derivation index (< 0x80000000) then
182    /// calling this method will fail.
183    ///
184    /// # Security considerations
185    ///
186    /// * hard derivation index cannot be soft derived with the public key
187    ///
188    /// # Hard derivation vs Soft derivation
189    ///
190    /// If you pass an index below 0x80000000 then it is a soft derivation.
191    /// The advantage of soft derivation is that it is possible to derive the
192    /// public key too. I.e. derivation the private key with a soft derivation
193    /// index and then retrieving the associated public key is equivalent to
194    /// deriving the public key associated to the parent private key.
195    ///
196    /// Hard derivation index does not allow public key derivation.
197    ///
198    /// This is why deriving the private key should not fail while deriving
199    /// the public key may fail (if the derivation index is invalid).
200    ///
201    pub fn derive(&self, index: u32) -> Result<Bip32PublicKey, ed25519_bip32::DerivationError> {
202        chain_crypto::derive::derive_pk_ed25519(&self.0, index).map(Bip32PublicKey)
203    }
204
205    pub fn to_raw_key(&self) -> PublicKey {
206        PublicKey(chain_crypto::derive::to_raw_pk(&self.0))
207    }
208
209    pub fn from_bech32(bech32_str: &str) -> Result<Bip32PublicKey, CryptoError> {
210        chain_crypto::PublicKey::try_from_bech32_str(bech32_str)
211            .map(Bip32PublicKey)
212            .map_err(Into::into)
213    }
214
215    pub fn to_bech32(&self) -> String {
216        self.0.to_bech32_str()
217    }
218
219    pub fn chaincode(&self) -> Vec<u8> {
220        const ED25519_PUBLIC_KEY_LENGTH: usize = 32;
221        const XPUB_SIZE: usize = 64;
222        self.0.as_ref()[ED25519_PUBLIC_KEY_LENGTH..XPUB_SIZE].to_vec()
223    }
224}
225
226impl RawBytesEncoding for Bip32PublicKey {
227    fn to_raw_bytes(&self) -> &[u8] {
228        self.0.as_ref()
229    }
230
231    fn from_raw_bytes(bytes: &[u8]) -> Result<Self, DeserializeError> {
232        chain_crypto::PublicKey::<chain_crypto::Ed25519Bip32>::from_binary(bytes)
233            .map_err(|e| DeserializeFailure::InvalidStructure(Box::new(e)).into())
234            .map(Bip32PublicKey)
235    }
236}
237
238impl From<chain_crypto::PublicKey<chain_crypto::Ed25519Bip32>> for Bip32PublicKey {
239    fn from(key: chain_crypto::PublicKey<chain_crypto::Ed25519Bip32>) -> Self {
240        Self(key)
241    }
242}
243
244pub struct PrivateKey(key::EitherEd25519SecretKey);
245
246impl From<key::EitherEd25519SecretKey> for PrivateKey {
247    fn from(secret_key: key::EitherEd25519SecretKey) -> PrivateKey {
248        PrivateKey(secret_key)
249    }
250}
251
252impl PrivateKey {
253    pub fn to_public(&self) -> PublicKey {
254        self.0.to_public().into()
255    }
256
257    pub fn generate_ed25519() -> PrivateKey {
258        let keypair = chain_crypto::SecretKey::<chain_crypto::Ed25519>::generate(OsRng);
259        PrivateKey(key::EitherEd25519SecretKey::Normal(keypair))
260    }
261
262    pub fn generate_ed25519extended() -> PrivateKey {
263        let keypair = chain_crypto::SecretKey::<chain_crypto::Ed25519Extended>::generate(OsRng);
264        PrivateKey(key::EitherEd25519SecretKey::Extended(keypair))
265    }
266
267    /// Get private key from its bech32 representation
268    /// ```rust
269    /// use cml_crypto::PrivateKey;
270    /// let key = PrivateKey::from_bech32("ed25519_sk1ahfetf02qwwg4dkq7mgp4a25lx5vh9920cr5wnxmpzz9906qvm8qwvlts0").unwrap();
271    /// ```
272    /// For an extended 25519 key
273    /// ```rust
274    /// use cml_crypto::PrivateKey;
275    /// let key = PrivateKey::from_bech32("ed25519e_sk1gqwl4szuwwh6d0yk3nsqcc6xxc3fpvjlevgwvt60df59v8zd8f8prazt8ln3lmz096ux3xvhhvm3ca9wj2yctdh3pnw0szrma07rt5gl748fp").unwrap();
276    /// ```
277    pub fn from_bech32(bech32_str: &str) -> Result<PrivateKey, CryptoError> {
278        chain_crypto::SecretKey::try_from_bech32_str(bech32_str)
279            .map(key::EitherEd25519SecretKey::Extended)
280            .or_else(|_| {
281                chain_crypto::SecretKey::try_from_bech32_str(bech32_str)
282                    .map(key::EitherEd25519SecretKey::Normal)
283            })
284            .map(PrivateKey)
285            .map_err(Into::into)
286    }
287
288    pub fn to_bech32(&self) -> String {
289        match self.0 {
290            key::EitherEd25519SecretKey::Normal(ref secret) => secret.to_bech32_str(),
291            key::EitherEd25519SecretKey::Extended(ref secret) => secret.to_bech32_str(),
292        }
293    }
294
295    pub fn from_extended_bytes(bytes: &[u8]) -> Result<PrivateKey, CryptoError> {
296        chain_crypto::SecretKey::from_binary(bytes)
297            .map(key::EitherEd25519SecretKey::Extended)
298            .map(PrivateKey)
299            .map_err(Into::into)
300    }
301
302    pub fn from_normal_bytes(bytes: &[u8]) -> Result<PrivateKey, CryptoError> {
303        chain_crypto::SecretKey::from_binary(bytes)
304            .map(key::EitherEd25519SecretKey::Normal)
305            .map(PrivateKey)
306            .map_err(Into::into)
307    }
308
309    pub fn sign(&self, message: &[u8]) -> Ed25519Signature {
310        Ed25519Signature::from(self.0.sign(&message.to_vec()))
311    }
312}
313
314impl RawBytesEncoding for PrivateKey {
315    fn to_raw_bytes(&self) -> &[u8] {
316        match self.0 {
317            key::EitherEd25519SecretKey::Normal(ref secret) => secret.as_ref(),
318            key::EitherEd25519SecretKey::Extended(ref secret) => secret.as_ref(),
319        }
320    }
321
322    fn from_raw_bytes(bytes: &[u8]) -> Result<Self, DeserializeError> {
323        Self::from_normal_bytes(bytes)
324            .or_else(|_| Self::from_extended_bytes(bytes))
325            .map_err(|e| DeserializeFailure::InvalidStructure(Box::new(e)).into())
326    }
327}
328
329/// ED25519 key used as public key
330#[derive(
331    Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
332)]
333pub struct PublicKey(pub chain_crypto::PublicKey<chain_crypto::Ed25519>);
334
335impl From<chain_crypto::PublicKey<chain_crypto::Ed25519>> for PublicKey {
336    fn from(key: chain_crypto::PublicKey<chain_crypto::Ed25519>) -> PublicKey {
337        PublicKey(key)
338    }
339}
340
341impl PublicKey {
342    /// Get public key from its bech32 representation
343    /// Example:
344    /// ```rust
345    /// use cml_crypto::PublicKey;
346    /// let key = PublicKey::from_bech32("ed25519_pk1dgaagyh470y66p899txcl3r0jaeaxu6yd7z2dxyk55qcycdml8gszkxze2").unwrap();
347    /// ```
348    pub fn from_bech32(bech32_str: &str) -> Result<PublicKey, CryptoError> {
349        chain_crypto::PublicKey::try_from_bech32_str(bech32_str)
350            .map(PublicKey)
351            .map_err(Into::into)
352    }
353
354    pub fn to_bech32(&self) -> String {
355        self.0.to_bech32_str()
356    }
357
358    pub fn verify(&self, data: &[u8], signature: &Ed25519Signature) -> bool {
359        signature.0.verify_slice(&self.0, data) == chain_crypto::Verification::Success
360    }
361
362    pub fn hash(&self) -> Ed25519KeyHash {
363        Ed25519KeyHash::from(blake2b224(self.to_raw_bytes()))
364    }
365}
366
367impl RawBytesEncoding for PublicKey {
368    fn to_raw_bytes(&self) -> &[u8] {
369        self.0.as_ref()
370    }
371
372    fn from_raw_bytes(bytes: &[u8]) -> Result<Self, DeserializeError> {
373        chain_crypto::PublicKey::from_binary(bytes)
374            .map_err(|e| DeserializeFailure::InvalidStructure(Box::new(e)).into())
375            .map(PublicKey)
376    }
377}
378
379macro_rules! impl_signature {
380    ($name:ident, $signee_type:ty, $verifier_type:ty) => {
381        #[derive(Debug, Clone, Eq, PartialEq)]
382        pub struct $name(chain_crypto::Signature<$signee_type, $verifier_type>);
383
384        impl $name {
385            pub fn to_bech32(&self) -> String {
386                use crate::chain_crypto::bech32::Bech32;
387                self.0.to_bech32_str()
388            }
389
390            pub fn to_hex(&self) -> String {
391                hex::encode(&self.0.as_ref())
392            }
393
394            pub fn from_bech32(bech32_str: &str) -> Result<Self, CryptoError> {
395                use crate::chain_crypto::bech32::Bech32;
396                chain_crypto::Signature::try_from_bech32_str(&bech32_str)
397                    .map(Self)
398                    .map_err(Into::into)
399            }
400
401            pub fn from_hex(input: &str) -> Result<Self, CryptoError> {
402                use crate::chain_core::property::FromStr;
403                chain_crypto::Signature::from_str(input)
404                    .map(Self)
405                    .map_err(Into::into)
406            }
407        }
408
409        impl RawBytesEncoding for $name {
410            fn to_raw_bytes(&self) -> &[u8] {
411                self.0.as_ref()
412            }
413
414            fn from_raw_bytes(bytes: &[u8]) -> Result<Self, DeserializeError> {
415                chain_crypto::Signature::from_binary(bytes.as_ref())
416                    .map(Self)
417                    .map_err(|e| DeserializeFailure::InvalidStructure(Box::new(e)).into())
418            }
419        }
420
421        impl serde::Serialize for $name {
422            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
423            where
424                S: serde::Serializer,
425            {
426                serializer.serialize_str(&self.to_hex())
427            }
428        }
429
430        impl<'de> serde::de::Deserialize<'de> for $name {
431            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
432            where
433                D: serde::de::Deserializer<'de>,
434            {
435                let s = <String as serde::de::Deserialize>::deserialize(deserializer)?;
436                $name::from_hex(&s).map_err(|_e| {
437                    serde::de::Error::invalid_value(
438                        serde::de::Unexpected::Str(&s),
439                        &"hex bytes for signature",
440                    )
441                })
442            }
443        }
444
445        impl schemars::JsonSchema for $name {
446            fn schema_name() -> String {
447                String::from(stringify!($name))
448            }
449            fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
450                String::json_schema(gen)
451            }
452            fn is_referenceable() -> bool {
453                String::is_referenceable()
454            }
455        }
456
457        impl Ord for $name {
458            fn cmp(&self, other: &Self) -> std::cmp::Ordering {
459                self.0.as_ref().cmp(other.0.as_ref())
460            }
461        }
462
463        impl PartialOrd for $name {
464            fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
465                Some(self.cmp(other))
466            }
467        }
468
469        // allow since both act on the raw bytes
470        #[allow(clippy::derived_hash_with_manual_eq)]
471        impl std::hash::Hash for $name {
472            fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
473                self.0.as_ref().hash(state)
474            }
475        }
476
477        impl From<chain_crypto::Signature<$signee_type, $verifier_type>> for $name {
478            fn from(sig: chain_crypto::Signature<$signee_type, $verifier_type>) -> Self {
479                Self(sig)
480            }
481        }
482    };
483}
484
485impl_signature!(Ed25519Signature, Vec<u8>, chain_crypto::Ed25519);
486
487#[macro_export]
488macro_rules! impl_hash_type {
489    ($name:ident, $byte_count:expr) => {
490        #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
491        pub struct $name([u8; $byte_count]);
492
493        impl $name {
494            pub const BYTE_COUNT: usize = $byte_count;
495
496            pub fn to_bech32(&self, prefix: &str) -> Result<String, CryptoError> {
497                use bech32::ToBase32;
498                bech32::encode(&prefix, self.0.as_ref().to_base32()).map_err(Into::into)
499            }
500
501            pub fn from_bech32(bech_str: &str) -> Result<$name, CryptoError> {
502                let (_hrp, u5data) = bech32::decode(bech_str)
503                    .map_err(chain_crypto::bech32::Error::Bech32Malformed)?;
504                let data: Vec<u8> = bech32::FromBase32::from_base32(&u5data)
505                    .map_err(chain_crypto::bech32::Error::Bech32Malformed)?;
506                Self::from_raw_bytes(&data).map_err(Into::into)
507            }
508
509            pub fn to_hex(&self) -> String {
510                hex::encode(&self.0.as_ref())
511            }
512
513            pub fn from_hex(input: &str) -> Result<Self, DeserializeError> {
514                let hex_bytes = hex::decode(input).map_err(|e| {
515                    DeserializeError::from(DeserializeFailure::InvalidStructure(Box::new(e)))
516                })?;
517                Self::from_raw_bytes(&hex_bytes)
518            }
519        }
520
521        impl std::fmt::Display for $name {
522            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
523                write!(f, "{}", self.to_raw_hex())
524            }
525        }
526
527        impl From<[u8; $byte_count]> for $name {
528            fn from(bytes: [u8; $byte_count]) -> Self {
529                Self(bytes)
530            }
531        }
532
533        impl From<$name> for [u8; $byte_count] {
534            fn from($name(bytes): $name) -> Self {
535                bytes
536            }
537        }
538
539        impl RawBytesEncoding for $name {
540            fn to_raw_bytes(&self) -> &[u8] {
541                self.0.as_ref()
542            }
543
544            fn from_raw_bytes(bytes: &[u8]) -> Result<Self, DeserializeError> {
545                use std::convert::TryInto;
546                match bytes.len() {
547                    $byte_count => Ok($name(bytes[..$byte_count].try_into().unwrap())),
548                    other_len => {
549                        let cbor_error = cbor_event::Error::WrongLen(
550                            $byte_count,
551                            cbor_event::Len::Len(other_len as u64),
552                            "hash length",
553                        );
554                        Err(DeserializeError::new(
555                            stringify!($name),
556                            DeserializeFailure::CBOR(cbor_error),
557                        ))
558                    }
559                }
560            }
561        }
562
563        impl serde::Serialize for $name {
564            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
565            where
566                S: serde::Serializer,
567            {
568                serializer.serialize_str(&self.to_hex())
569            }
570        }
571
572        impl<'de> serde::de::Deserialize<'de> for $name {
573            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
574            where
575                D: serde::de::Deserializer<'de>,
576            {
577                let s = <String as serde::de::Deserialize>::deserialize(deserializer)?;
578                $name::from_hex(&s).map_err(|_e| {
579                    serde::de::Error::invalid_value(
580                        serde::de::Unexpected::Str(&s),
581                        &"hex bytes for hash",
582                    )
583                })
584            }
585        }
586
587        impl schemars::JsonSchema for $name {
588            fn schema_name() -> String {
589                String::from(stringify!($name))
590            }
591            fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
592                String::json_schema(gen)
593            }
594            fn is_referenceable() -> bool {
595                String::is_referenceable()
596            }
597        }
598    };
599}
600
601impl_hash_type!(Ed25519KeyHash, 28);
602impl_hash_type!(ScriptHash, 28);
603// TransactionHash is either a hash of the tx CBOR or a hash of a redeem address (genesis)
604impl_hash_type!(TransactionHash, 32);
605impl_hash_type!(GenesisDelegateHash, 28);
606impl_hash_type!(GenesisHash, 28);
607impl_hash_type!(AuxiliaryDataHash, 32);
608impl_hash_type!(PoolMetadataHash, 32);
609impl_hash_type!(VRFKeyHash, 32);
610impl_hash_type!(BlockBodyHash, 32);
611impl_hash_type!(BlockHeaderHash, 32);
612impl_hash_type!(DatumHash, 32);
613impl_hash_type!(ScriptDataHash, 32);
614// We might want to make these two vkeys normal classes later but for now it's just arbitrary bytes for us (used in block parsing)
615impl_hash_type!(VRFVkey, 32);
616impl_hash_type!(KESVkey, 32);
617// same for this signature (but lots of traits aren't implemented for [u8; 448] so we can't)
618//impl_hash_type!(KESSignature, 448);
619impl_hash_type!(NonceHash, 32);
620impl_hash_type!(AnchorDocHash, 32);
621
622#[derive(Clone)]
623pub struct LegacyDaedalusPrivateKey(chain_crypto::SecretKey<chain_crypto::LegacyDaedalus>);
624
625impl LegacyDaedalusPrivateKey {
626    pub fn chaincode(&self) -> Vec<u8> {
627        const ED25519_PRIVATE_KEY_LENGTH: usize = 64;
628        const XPRV_SIZE: usize = 96;
629        self.0.as_ref()[ED25519_PRIVATE_KEY_LENGTH..XPRV_SIZE].to_vec()
630    }
631}
632
633impl RawBytesEncoding for LegacyDaedalusPrivateKey {
634    fn to_raw_bytes(&self) -> &[u8] {
635        self.0.as_ref()
636    }
637
638    fn from_raw_bytes(bytes: &[u8]) -> Result<LegacyDaedalusPrivateKey, DeserializeError> {
639        chain_crypto::SecretKey::<chain_crypto::LegacyDaedalus>::from_binary(bytes)
640            .map(LegacyDaedalusPrivateKey)
641            .map_err(|e| DeserializeFailure::InvalidStructure(Box::new(e)).into())
642    }
643}
644
645impl AsRef<chain_crypto::SecretKey<chain_crypto::LegacyDaedalus>> for LegacyDaedalusPrivateKey {
646    fn as_ref(&self) -> &chain_crypto::SecretKey<chain_crypto::LegacyDaedalus> {
647        &self.0
648    }
649}