1use {
2 keynesis::{
3 key::{
4 ed25519_hd,
5 ed25519_extended,
6 ed25519,
7 ed25519::Signature, SharedSecret
8 },
9 Seed,
10 },
11 crate::{ Nonce, bloom_filter_index, BFI},
12 anyhow::{Result, anyhow},
13 std::{
14 convert::{TryFrom, TryInto as _},
15 fmt::{self, Display, Formatter},
16 str::FromStr,
17 },
18 thiserror::Error,
19};
20const SIGNING_PATH_V1: &[u8] = b"/copernica/v1/signing";
21const EXCHANGE_PATH_ROOT_V1: &[u8] = b"/copernica/v1/exchange";
22
23#[derive(Debug, Eq, PartialEq, Hash, Clone)]
29struct PrivateIdentity(ed25519_hd::SecretKey);
30
31#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Clone)]
41pub struct PublicIdentity(ed25519_hd::PublicKey);
42
43#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
44pub enum PublicIdentityInterface {
45 Present { public_identity: PublicIdentity },
46 Absent,
47}
48impl PublicIdentityInterface {
49 pub fn new(public_identity: PublicIdentity) -> Self {
50 Self::Present { public_identity }
51 }
52 pub fn bloom_filter_index(&self) -> Result<BFI> {
53 match self {
54 PublicIdentityInterface::Present { public_identity } => Ok(bloom_filter_index(&format!("{}", public_identity))?),
55 PublicIdentityInterface::Absent => Ok(BFI::new()),
56 }
57 }
58 pub fn public_identity(&self) -> Result<PublicIdentity> {
59 match self {
60 PublicIdentityInterface::Present { public_identity } => Ok(public_identity.clone()),
61 PublicIdentityInterface::Absent => Err(anyhow!("PublicIdentity is Absent")),
62 }
63 }
64}
65
66impl fmt::Display for PublicIdentityInterface {
67 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
68 let out = match self {
69 PublicIdentityInterface::Present { public_identity } => {
70 format!("{}", public_identity)
71 }
72 PublicIdentityInterface::Absent => {
73 format!("Absent_Key")
74 }
75 };
76 write!(f, "{}", out)
77 }
78}
79
80#[derive(Debug, Eq, PartialEq, Hash, Clone)]
86pub struct PrivateSigningKey(ed25519_extended::SecretKey);
87
88#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Clone)]
94pub struct PublicVerifyKey(ed25519::PublicKey);
95
96#[derive(Debug, Eq, PartialEq, Hash, Clone)]
101struct SecretKey(ed25519_extended::SecretKey);
102
103#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Clone)]
111pub struct PublicKey(ed25519::PublicKey);
112
113impl PrivateIdentity {
114 pub fn from_seed(seed: Seed) -> Self {
117 let mut rng = seed.into_rand_chacha();
118 Self(ed25519_hd::SecretKey::new(&mut rng))
119 }
120 pub fn public_id(&self) -> PublicIdentity {
121 PublicIdentity(self.0.public_key())
122 }
123
124 pub fn signing_key(&self) -> PrivateSigningKey {
125 PrivateSigningKey(self.0.derive(SIGNING_PATH_V1).into_key())
126 }
127
128 pub fn derive<P>(&self, purpose: P) -> SecretKey
129 where
130 P: AsRef<[u8]>,
131 {
132 let mut path = EXCHANGE_PATH_ROOT_V1.to_vec();
133 path.extend_from_slice(purpose.as_ref());
134 SecretKey(self.0.derive(path).into_key())
135 }
136}
137
138impl PublicIdentity {
139 pub const SIZE: usize = ed25519_hd::PublicKey::SIZE;
140
141 pub fn verify_key(&self) -> anyhow::Result<PublicVerifyKey> {
142 if let Some(derived) = self.0.derive(SIGNING_PATH_V1) {
144 return Ok(PublicVerifyKey(derived.into_key()))
145 } else {
146 return Err(anyhow!("PublicKey Derive returned None"))
147 }
148 }
149
150 pub fn derive<P>(&self, purpose: P) -> PublicKey
151 where
152 P: AsRef<[u8]>,
153 {
154 let mut path = EXCHANGE_PATH_ROOT_V1.to_vec();
155 path.extend_from_slice(purpose.as_ref());
156 PublicKey(self.0.derive(path).unwrap().into_key())
157 }
158
159 pub fn key(&self) -> &ed25519_extended::PublicKey {
160 self.0.key()
161 }
162
163 pub fn chain_code(&self) -> &ed25519_hd::ChainCode {
164 self.0.chain_code()
165 }
166}
167
168impl PrivateSigningKey {
169 pub fn public(&self) -> PublicVerifyKey {
170 PublicVerifyKey(self.0.public_key())
171 }
172
173 pub fn sign<M>(&self, message: M) -> Signature
174 where
175 M: AsRef<[u8]>,
176 {
177 self.0.sign(message)
178 }
179}
180
181impl PublicVerifyKey {
182 pub const SIZE: usize = ed25519::PublicKey::SIZE;
183
184 pub fn verify<M>(&self, signature: &Signature, message: M) -> bool
185 where
186 M: AsRef<[u8]>,
187 {
188 self.0.verify(message, signature)
189 }
190}
191
192impl SecretKey {
193pub fn exchange(&self, key: &PublicKey) -> SharedSecret {
199 self.0.exchange(&key.0)
200 }
201}
202
203impl PublicKey {
204 pub const SIZE: usize = ed25519::PublicKey::SIZE;
205}
206
207impl Display for PublicIdentity {
210 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
211 use bech32::ToBase32 as _;
212 let mut writer = bech32::Bech32Writer::new("id", f)?;
213
214 let mut bytes = self.0.key().as_ref().to_vec();
215 bytes.extend_from_slice(self.0.chain_code().as_ref());
216
217 bytes.write_base32(&mut writer)?;
220
221 writer.finalize()
222 }
223}
224
225impl Display for PublicKey {
226 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
227 self.0.fmt(f)
228 }
229}
230
231impl Display for PublicVerifyKey {
232 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
233 self.0.fmt(f)
234 }
235}
236
237#[derive(Debug, Error)]
238pub enum PublicIdentityError {
239 #[error("Not a valid bech32 encoded PublicIdentity")]
240 InvalidBech32(
241 #[source]
242 #[from]
243 bech32::Error,
244 ),
245
246 #[error("Invalid key type prefix, expected 'id' but received {hrp}")]
247 InvalidHRP { hrp: String },
248
249 #[error("Invalid public key")]
250 InvalidKey(
251 #[source]
252 #[from]
253 ed25519_hd::PublicKeyError,
254 ),
255}
256
257impl FromStr for PublicIdentity {
258 type Err = PublicIdentityError;
259 fn from_str(s: &str) -> Result<Self, Self::Err> {
260 use bech32::FromBase32 as _;
261
262 let (hrp, data) = bech32::decode(s)?;
263 if hrp != "id" {
264 return Err(Self::Err::InvalidHRP { hrp });
265 }
266 let data = Vec::<u8>::from_base32(&data)?;
267 let pid = ed25519_hd::PublicKey::try_from(data.as_slice()).map(Self)?;
268 Ok(pid)
269 }
270}
271
272impl FromStr for PublicVerifyKey {
273 type Err = hex::FromHexError;
274 fn from_str(s: &str) -> Result<Self, Self::Err> {
275 s.parse().map(Self)
276 }
277}
278
279impl FromStr for PublicKey {
280 type Err = hex::FromHexError;
281 fn from_str(s: &str) -> Result<Self, Self::Err> {
282 s.parse().map(Self)
283 }
284}
285
286impl From<PublicIdentity> for String {
289 fn from(pid: PublicIdentity) -> Self {
290 pid.to_string()
291 }
292}
293
294impl From<[u8; Self::SIZE]> for PublicIdentity {
295 fn from(bytes: [u8; Self::SIZE]) -> Self {
296 Self(bytes.into())
297 }
298}
299
300impl From<[u8; Self::SIZE]> for PublicVerifyKey {
301 fn from(bytes: [u8; Self::SIZE]) -> Self {
302 Self(bytes.into())
303 }
304}
305
306impl From<[u8; Self::SIZE]> for PublicKey {
307 fn from(bytes: [u8; Self::SIZE]) -> Self {
308 Self(bytes.into())
309 }
310}
311
312impl TryFrom<String> for PublicIdentity {
313 type Error = <Self as FromStr>::Err;
314
315 fn try_from(value: String) -> Result<Self, Self::Error> {
316 value.parse()
317 }
318}
319impl<'a> TryFrom<&'a str> for PublicIdentity {
320 type Error = <Self as FromStr>::Err;
321
322 fn try_from(value: &'a str) -> Result<Self, Self::Error> {
323 value.parse()
324 }
325}
326
327impl<'a> TryFrom<&'a [u8]> for PublicIdentity {
328 type Error = ed25519_hd::PublicKeyError;
329
330 fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
331 value.try_into().map(Self)
332 }
333}
334
335impl<'a> TryFrom<&'a [u8]> for PublicVerifyKey {
336 type Error = ed25519::PublicKeyError;
337
338 fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
339 value.try_into().map(Self)
340 }
341}
342
343impl<'a> TryFrom<&'a [u8]> for PublicKey {
344 type Error = ed25519::PublicKeyError;
345
346 fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
347 value.try_into().map(Self)
348 }
349}
350
351#[derive(Clone, Eq, PartialEq, Hash, Debug)]
352enum PrivateIdentityState {
353 SentinelOne { key: PrivateIdentity },
354 FileSystem { key: PrivateIdentity },
355 Key { key: PrivateIdentity },
356}
357#[derive(Clone, Eq, PartialEq, Hash, Debug)]
358pub struct PrivateIdentityInterface {
359 inner: PrivateIdentityState,
360}
361impl PrivateIdentityInterface {
362 pub fn new_key() -> Self {
363 let mut rng = rand::thread_rng();
364 let key = PrivateIdentity::from_seed(Seed::generate(&mut rng));
365 Self { inner: PrivateIdentityState::Key { key } }
366 }
367 pub fn new_fs() -> Self {
368 let mut rng = rand::thread_rng();
369 let key = PrivateIdentity::from_seed(Seed::generate(&mut rng));
370 Self { inner: PrivateIdentityState::FileSystem { key } }
371 }
372 pub fn new_sentinel() -> Self {
373 let mut rng = rand::thread_rng();
374 let key = PrivateIdentity::from_seed(Seed::generate(&mut rng));
375 Self { inner: PrivateIdentityState::SentinelOne { key } }
376 }
377 pub fn public_id(&self) -> PublicIdentity {
378 match &self.inner {
379 PrivateIdentityState::Key { key } => {
380 key.public_id()
381 },
382 PrivateIdentityState::FileSystem { key } => {
383 key.public_id()
384 },
385 PrivateIdentityState::SentinelOne { key } => {
386 key.public_id()
387 },
388 }
389 }
390 pub fn shared_secret(&self, nonce: Nonce, rx_pid: PublicIdentity) -> SharedSecret {
391 let rx_pk = rx_pid.derive(&nonce.0);
392 match &self.inner {
393 PrivateIdentityState::Key { key } => {
394 let tx_sk = key.derive(&nonce.0);
395 let shared_secret = tx_sk.exchange(&rx_pk);
396 shared_secret
397 },
398 PrivateIdentityState::FileSystem { key } => {
399 let tx_sk = key.derive(&nonce.0);
400 let shared_secret = tx_sk.exchange(&rx_pk);
401 shared_secret
402 },
403 PrivateIdentityState::SentinelOne { key } => {
404 let tx_sk = key.derive(&nonce.0);
405 let shared_secret = tx_sk.exchange(&rx_pk);
406 shared_secret
407 },
408 }
409 }
410 pub fn signing_key(&self) -> PrivateSigningKey {
411 match &self.inner {
412 PrivateIdentityState::Key { key } => {
413 key.signing_key()
414 },
415 PrivateIdentityState::FileSystem { key } => {
416 key.signing_key()
417 },
418 PrivateIdentityState::SentinelOne { key } => {
419 key.signing_key()
420 },
421 }
422 }
423}
424
425
426