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 const MAGIC_BYTES: [u8; 10] = [205, 198, 59, 175, 94, 82, 224, 9, 114, 173];
18
19pub fn argon2_hash(input: &[u8]) -> [u8; 32] {
20 let params = Params::new(8 * 1024, 1, 2, Some(32)).unwrap();
22 let argon2 = Argon2::new(argon2::Algorithm::Argon2id, argon2::Version::V0x13, params);
23 let mut hash = [0u8; 32];
24 argon2
25 .hash_password_into(input, &MAGIC_BYTES, &mut hash)
26 .unwrap();
27 hash
28}
29
30#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, std::hash::Hash)]
33pub struct Hash([u8; 32]);
34
35impl Hash {
36 pub fn new(data: &[u8]) -> Self {
38 Hash(argon2_hash(data))
39 }
40
41 pub const fn new_from_buf(hash_buf: [u8; 32]) -> Self {
43 Hash(hash_buf)
44 }
45
46 pub fn compare_with_data(&self, other_data: &[u8]) -> bool {
48 let computed = argon2_hash(other_data);
49 computed == self.0
50 }
51
52 pub fn new_from_base36(s: &str) -> Option<Self> {
54 let big_int = BigUint::parse_bytes(s.as_bytes(), 36)?;
56 let mut buf = big_int.to_bytes_be();
57
58 if buf.len() > 32 {
60 return None;
61 } else if buf.len() < 32 {
62 let mut padded = vec![0u8; 32 - buf.len()];
64 padded.extend(buf);
65 buf = padded;
66 }
67
68 let buf: [u8; 32] = buf.try_into().ok()?;
70
71 Some(Hash(buf))
72 }
73
74 pub fn dump_base36(&self) -> String {
75 let big_int = BigUint::from_bytes_be(&self.0);
76 big_int.to_str_radix(36)
77 }
78}
79
80impl Serialize for Hash {
81 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
82 where
83 S: serde::Serializer,
84 {
85 serializer.serialize_str(&self.dump_base36())
86 }
87}
88
89impl<'de> Deserialize<'de> for Hash {
90 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
91 where
92 D: serde::Deserializer<'de>,
93 {
94 let s = String::deserialize(deserializer)?;
95 Self::new_from_base36(&s).ok_or_else(|| serde::de::Error::custom("Invalid base36 hash"))
96 }
97}
98
99impl Deref for Hash {
100 type Target = [u8; 32];
101 fn deref(&self) -> &Self::Target {
102 &self.0
103 }
104}
105
106impl fmt::Debug for Hash {
107 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
108 write!(f, "Hash: {}", self.dump_base36())
109 }
110}
111
112#[derive(Clone, PartialEq, Eq, Encode, Decode, Copy, Hash)]
114pub struct Signature([u8; 64]);
115
116impl Signature {
117 pub fn new_signature(private: &mut Private, data: &[u8]) -> Self {
119 let mut key = SigningKey::from_bytes(private.dump_buf());
120 let signature = key.sign(data);
121 Signature(signature.to_bytes()) }
123
124 pub fn new_from_buf(signature: &[u8; 64]) -> Self {
126 Signature(signature.clone())
127 }
128
129 pub fn validate_with_public(&self, public: &Public, data: &[u8]) -> Result<bool, Error> {
131 let key = VerifyingKey::from_bytes(public.dump_buf())?;
132 Ok(key
133 .verify_strict(data, &DalekSignature::from_bytes(&self.0))
134 .is_ok())
135 }
136
137 pub fn validate_with_private(&self, private: &Private, data: &[u8]) -> Result<bool, Error> {
139 let key = SigningKey::from_bytes(private.dump_buf());
140 Ok(key
141 .verify_strict(data, &DalekSignature::from_bytes(&self.0))
142 .is_ok())
143 }
144
145 pub fn new_from_base36(s: &str) -> Option<Self> {
147 let big_int = BigUint::parse_bytes(s.as_bytes(), 36)?;
149 let mut buf = big_int.to_bytes_be();
150
151 if buf.len() > 64 {
153 return None;
154 } else if buf.len() < 64 {
155 let mut padded = vec![0u8; 64 - buf.len()];
157 padded.extend(buf);
158 buf = padded;
159 }
160
161 let buf: [u8; 64] = buf.try_into().ok()?;
163
164 Some(Self(buf))
165 }
166
167 pub fn dump_base36(&self) -> String {
168 let big_int = BigUint::from_bytes_be(&self.0);
169 big_int.to_str_radix(36)
170 }
171}
172
173impl Serialize for Signature {
174 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
175 where
176 S: serde::Serializer,
177 {
178 serializer.serialize_str(&self.dump_base36())
179 }
180}
181
182impl<'de> Deserialize<'de> for Signature {
183 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
184 where
185 D: serde::Deserializer<'de>,
186 {
187 let s = String::deserialize(deserializer)?;
188 Self::new_from_base36(&s).ok_or_else(|| serde::de::Error::custom("Invalid base36 signature"))
189 }
190}
191
192impl Deref for Signature {
193 type Target = [u8; 64]; fn deref(&self) -> &Self::Target {
195 &self.0
196 }
197}
198
199impl fmt::Debug for Signature {
200 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
201 write!(f, "Signature: {}", self.dump_base36())
202 }
203}