copernica_packets/
identity.rs

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/// private identity, to keep close to you, privately and securely
24///
25/// From this root key multiple key may be generated depending on
26/// the needs and protocols.
27///
28#[derive(Debug, Eq, PartialEq, Hash, Clone)]
29struct PrivateIdentity(ed25519_hd::SecretKey);
30
31/// Public identity
32///
33/// Making this public (include the public key and the chain code)
34/// allows for anyone to derive the public key associated to the
35/// different schemes (signing or key exchange).
36///
37/// This key cannot be used for anything else, we restrict its usage
38/// to public derivation of different keys
39///
40#[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/// The Signing Key associated to your `PrivateIdentity`.
81///
82/// This key is derived from the `PrivateIdentity`. Anyone with
83/// the `PublicIdentity` key can derivate the associated `PublicVerifyKey`
84/// and verify any signature generated with this key.
85#[derive(Debug, Eq, PartialEq, Hash, Clone)]
86pub struct PrivateSigningKey(ed25519_extended::SecretKey);
87
88/// The Verify Key associated to the `PrivateSigningKey`.
89///
90/// Any signature generated by the `PrivateSigningKey` can be
91/// verified with this key. It is not necessary to share this
92/// key as it can be derived from the `PublicIdentity`.
93#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Clone)]
94pub struct PublicVerifyKey(ed25519::PublicKey);
95
96/// Secret key to use for key exchange
97///
98/// This key is derived from the `PrivateIdentity` and are used
99/// to established a key exchange (Diffie-Hellman) with a `PublicKey`.
100#[derive(Debug, Eq, PartialEq, Hash, Clone)]
101struct SecretKey(ed25519_extended::SecretKey);
102
103/// Public key to use for key exchange
104///
105/// This key is derived from the `PublicIdentity` and is meant for
106/// establishing a key exchange (Diffie-Hellman). It is not
107/// necessary to share this key as it can be derived from the
108/// `PublicIdentity` (assuming the derivation path is known by both
109/// party).
110#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Clone)]
111pub struct PublicKey(ed25519::PublicKey);
112
113impl PrivateIdentity {
114    /// build a private identity from the given `Seed`
115    ///
116    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        //PublicVerifyKey(self.0.derive(SIGNING_PATH_V1).unwrap().into_key())
143        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 {
193/*
194    pub fn public(&self) -> PublicKey {
195        PublicKey(self.0.public_key())
196    }
197*/
198    pub 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
207/* Formatter *************************************************************** */
208
209impl 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        // self.0.key().write_base32(&mut writer)?;
218        // self.0.chain_code().write_base32(&mut writer)?;
219        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
286/* Conversion ************************************************************** */
287
288impl 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