algonaut_crypto/
lib.rs

1use algonaut_encoding::{deserialize_bytes32, SignatureVisitor, U8_32Visitor};
2use data_encoding::{BASE32_NOPAD, BASE64};
3use fmt::Debug;
4use ring::signature::UnparsedPublicKey;
5use serde::{Deserialize, Deserializer, Serialize, Serializer};
6use std::fmt::{self, Display, Formatter};
7use std::str::FromStr;
8
9/// Support for turning 32 byte keys into human-readable mnemonics and back
10pub mod mnemonic;
11
12///
13pub mod error;
14
15#[derive(Copy, Clone, Eq, Debug, PartialEq, Serialize, Deserialize)]
16pub enum HashType {
17    Sha512_256,
18    Sumhash,
19    Sha256,
20}
21
22/// A SHA512_256 hash
23#[derive(Copy, Clone, Eq, PartialEq)]
24pub struct HashDigest(pub [u8; 32]);
25
26impl FromStr for HashDigest {
27    type Err = String;
28    fn from_str(string: &str) -> Result<Self, Self::Err> {
29        let mut decoded = [0; 32];
30        decoded.copy_from_slice(
31            &BASE64
32                .decode(string.as_bytes())
33                .map_err(|e| e.to_string())?,
34        );
35        Ok(HashDigest(decoded))
36    }
37}
38
39impl Display for HashDigest {
40    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
41        write!(f, "{}", BASE64.encode(&self.0))
42    }
43}
44
45#[derive(Copy, Clone, Eq, PartialEq)]
46pub struct Ed25519PublicKey(pub [u8; 32]);
47
48impl Ed25519PublicKey {
49    pub fn verify(&self, message: &[u8], signature: &Signature) -> bool {
50        let peer_public_key = UnparsedPublicKey::new(&ring::signature::ED25519, self.0);
51        match peer_public_key.verify(message, signature.0.as_ref()) {
52            Ok(()) => true,
53            Err(_e) => {
54                println!("Signature verification failed");
55                false
56            }
57        }
58    }
59}
60
61#[derive(Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
62pub struct MasterDerivationKey(pub [u8; 32]);
63
64/// An Ed25519 Signature
65#[derive(Copy, Clone, PartialEq, Eq)]
66pub struct Signature(pub [u8; 64]);
67
68impl Debug for Signature {
69    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
70        write!(f, "{}", &BASE64.encode(&self.0))
71    }
72}
73
74impl Serialize for Signature {
75    fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
76    where
77        S: Serializer,
78    {
79        serializer.serialize_bytes(&self.0[..])
80    }
81}
82
83impl<'de> Deserialize<'de> for Signature {
84    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
85    where
86        D: Deserializer<'de>,
87    {
88        Ok(Signature(deserializer.deserialize_bytes(SignatureVisitor)?))
89    }
90}
91
92impl Serialize for HashDigest {
93    fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
94    where
95        S: Serializer,
96    {
97        serializer.serialize_bytes(&self.0[..])
98    }
99}
100
101impl<'de> Deserialize<'de> for HashDigest {
102    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
103    where
104        D: Deserializer<'de>,
105    {
106        Ok(HashDigest(deserializer.deserialize_bytes(U8_32Visitor)?))
107    }
108}
109
110impl Debug for HashDigest {
111    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
112        write!(f, "{}", BASE32_NOPAD.encode(&self.0))
113    }
114}
115
116impl AsRef<[u8]> for HashDigest {
117    fn as_ref(&self) -> &[u8] {
118        &self.0
119    }
120}
121
122impl Serialize for Ed25519PublicKey {
123    fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
124    where
125        S: Serializer,
126    {
127        serializer.serialize_bytes(&self.0[..])
128    }
129}
130
131impl<'de> Deserialize<'de> for Ed25519PublicKey {
132    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
133    where
134        D: Deserializer<'de>,
135    {
136        Ok(Ed25519PublicKey(
137            deserializer.deserialize_bytes(U8_32Visitor)?,
138        ))
139    }
140}
141
142impl Debug for Ed25519PublicKey {
143    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
144        write!(f, "{}", BASE32_NOPAD.encode(&self.0))
145    }
146}
147
148impl Debug for MasterDerivationKey {
149    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
150        write!(f, "{}", BASE32_NOPAD.encode(&self.0))
151    }
152}
153
154pub fn deserialize_hash<'de, D>(deserializer: D) -> Result<HashDigest, D::Error>
155where
156    D: Deserializer<'de>,
157{
158    Ok(HashDigest(deserialize_bytes32(deserializer)?))
159}
160
161pub fn deserialize_mdk<'de, D>(deserializer: D) -> Result<MasterDerivationKey, D::Error>
162where
163    D: Deserializer<'de>,
164{
165    Ok(MasterDerivationKey(deserialize_bytes32(deserializer)?))
166}
167
168pub fn deserialize_public_keys<'de, D>(deserializer: D) -> Result<Vec<Ed25519PublicKey>, D::Error>
169where
170    D: Deserializer<'de>,
171{
172    use serde::de::Error;
173    <Vec<String>>::deserialize(deserializer)?
174        .iter()
175        .map(|string| {
176            let mut decoded = [0; 32];
177            let bytes = BASE64.decode(string.as_bytes()).map_err(D::Error::custom)?;
178            decoded.copy_from_slice(&bytes);
179            Ok(Ed25519PublicKey(decoded))
180        })
181        .collect()
182}