1use argon2::{Argon2, Params};
2use bincode::{Decode, Encode};
3use ed25519_dalek::SigningKey;
4use ed25519_dalek::ed25519::Error;
5use ed25519_dalek::ed25519::signature::SignerMut;
6use ed25519_dalek::{Signature as DalekSignature, VerifyingKey};
7use num_bigint::BigUint;
8use serde::{Deserialize, Serialize};
9use std::fmt;
10use std::ops::Deref;
11
12use keys::{Private, Public};
13
14pub mod keys;
16
17pub struct Argon2Config {
19 pub memory_cost: u32,
20 pub time_cost: u32,
21 pub parallelism: u32,
22 pub output_length: Option<usize>,
23 pub algorithm: argon2::Algorithm,
24 pub version: argon2::Version,
25 pub magic_bytes: [u8; 10]
26}
27
28pub const ARGON2_CONFIG: Argon2Config = Argon2Config {
30 memory_cost: 8 * 1024,
31 time_cost: 1,
32 parallelism: 2,
33 output_length: Some(32),
34 algorithm: argon2::Algorithm::Argon2id,
35 version: argon2::Version::V0x13,
36 magic_bytes: [0xCD, 0xC6, 0x3B, 0xAF, 0x5E, 0x52, 0xE0, 0x9, 0x72, 0xAD]
37};
38
39pub fn argon2_hash(input: &[u8]) -> [u8; 32] {
41 let params = Params::new(ARGON2_CONFIG.memory_cost, ARGON2_CONFIG.time_cost, ARGON2_CONFIG.parallelism, ARGON2_CONFIG.output_length).unwrap();
42 let argon2 = Argon2::new(ARGON2_CONFIG.algorithm, ARGON2_CONFIG.version, params);
43 let mut hash = [0u8; 32];
44 argon2
45 .hash_password_into(input, &ARGON2_CONFIG.magic_bytes, &mut hash)
46 .unwrap();
47 hash
48}
49
50#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, std::hash::Hash)]
53pub struct Hash([u8; 32]);
54
55impl Hash {
56 pub fn new(data: &[u8]) -> Self {
59 Hash(argon2_hash(data))
60 }
61
62 pub const fn new_from_buf(hash_buf: [u8; 32]) -> Self {
64 Hash(hash_buf)
65 }
66
67 pub fn compare_with_data(&self, other_data: &[u8]) -> bool {
69 let computed = argon2_hash(other_data);
70 computed == self.0
71 }
72
73 pub fn new_from_base36(s: &str) -> Option<Self> {
75 let big_int = BigUint::parse_bytes(s.as_bytes(), 36)?;
77 let mut buf = big_int.to_bytes_be();
78
79 if buf.len() > 32 {
81 return None;
82 } else if buf.len() < 32 {
83 let mut padded = vec![0u8; 32 - buf.len()];
85 padded.extend(buf);
86 buf = padded;
87 }
88
89 let buf: [u8; 32] = buf.try_into().ok()?;
91
92 Some(Hash(buf))
93 }
94
95 pub fn dump_base36(&self) -> String {
96 let big_int = BigUint::from_bytes_be(&self.0);
97 big_int.to_str_radix(36)
98 }
99
100 pub fn dump_buf(&self) -> [u8; 32] {
101 self.0
102 }
103}
104
105impl Serialize for Hash {
106 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
107 where
108 S: serde::Serializer,
109 {
110 serializer.serialize_str(&self.dump_base36())
111 }
112}
113
114impl<'de> Deserialize<'de> for Hash {
115 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
116 where
117 D: serde::Deserializer<'de>,
118 {
119 let s = String::deserialize(deserializer)?;
120 Self::new_from_base36(&s).ok_or_else(|| serde::de::Error::custom("Invalid base36 hash"))
121 }
122}
123
124impl Deref for Hash {
125 type Target = [u8; 32];
126 fn deref(&self) -> &Self::Target {
127 &self.0
128 }
129}
130
131impl fmt::Debug for Hash {
132 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
133 write!(f, "Hash: {}", self.dump_base36())
134 }
135}
136
137#[derive(Clone, PartialEq, Eq, Encode, Decode, Copy, Hash)]
139pub struct Signature([u8; 64]);
140
141impl Signature {
142 pub fn new_signature(private: &mut Private, data: &[u8]) -> Self {
144 let mut key = SigningKey::from_bytes(private.dump_buf());
145 let signature = key.sign(data);
146 Signature(signature.to_bytes()) }
148
149 pub fn new_from_buf(signature: &[u8; 64]) -> Self {
151 Signature(signature.clone())
152 }
153
154 pub fn validate_with_public(&self, public: &Public, data: &[u8]) -> Result<bool, Error> {
156 let key = VerifyingKey::from_bytes(public.dump_buf())?;
157 Ok(key
158 .verify_strict(data, &DalekSignature::from_bytes(&self.0))
159 .is_ok())
160 }
161
162 pub fn validate_with_private(&self, private: &Private, data: &[u8]) -> Result<bool, Error> {
164 let key = SigningKey::from_bytes(private.dump_buf());
165 Ok(key
166 .verify_strict(data, &DalekSignature::from_bytes(&self.0))
167 .is_ok())
168 }
169
170 pub fn new_from_base36(s: &str) -> Option<Self> {
172 let big_int = BigUint::parse_bytes(s.as_bytes(), 36)?;
174 let mut buf = big_int.to_bytes_be();
175
176 if buf.len() > 64 {
178 return None;
179 } else if buf.len() < 64 {
180 let mut padded = vec![0u8; 64 - buf.len()];
182 padded.extend(buf);
183 buf = padded;
184 }
185
186 let buf: [u8; 64] = buf.try_into().ok()?;
188
189 Some(Self(buf))
190 }
191
192 pub fn dump_base36(&self) -> String {
193 let big_int = BigUint::from_bytes_be(&self.0);
194 big_int.to_str_radix(36)
195 }
196
197 pub fn dump_buf(&self) -> [u8; 64] {
198 self.0
199 }
200}
201
202impl Serialize for Signature {
203 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
204 where
205 S: serde::Serializer,
206 {
207 serializer.serialize_str(&self.dump_base36())
208 }
209}
210
211impl<'de> Deserialize<'de> for Signature {
212 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
213 where
214 D: serde::Deserializer<'de>,
215 {
216 let s = String::deserialize(deserializer)?;
217 Self::new_from_base36(&s).ok_or_else(|| serde::de::Error::custom("Invalid base36 signature"))
218 }
219}
220
221impl Deref for Signature {
222 type Target = [u8; 64]; fn deref(&self) -> &Self::Target {
224 &self.0
225 }
226}
227
228impl fmt::Debug for Signature {
229 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
230 write!(f, "Signature: {}", self.dump_base36())
231 }
232}