litep2p/crypto/noise/
protocol.rs

1// Copyright 2019 Parity Technologies (UK) Ltd.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the "Software"),
5// to deal in the Software without restriction, including without limitation
6// the rights to use, copy, modify, merge, publish, distribute, sublicense,
7// and/or sell copies of the Software, and to permit persons to whom the
8// Software is furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19// DEALINGS IN THE SOFTWARE.
20
21use crate::crypto::noise::x25519_spec;
22
23use rand::SeedableRng;
24use zeroize::Zeroize;
25
26/// DH keypair.
27#[derive(Clone)]
28pub struct Keypair<T: Zeroize> {
29    pub secret: SecretKey<T>,
30    pub public: PublicKey<T>,
31}
32
33/// DH secret key.
34#[derive(Clone)]
35pub struct SecretKey<T: Zeroize>(pub T);
36
37impl<T: Zeroize> Drop for SecretKey<T> {
38    fn drop(&mut self) {
39        self.0.zeroize()
40    }
41}
42
43impl<T: AsRef<[u8]> + Zeroize> AsRef<[u8]> for SecretKey<T> {
44    fn as_ref(&self) -> &[u8] {
45        self.0.as_ref()
46    }
47}
48
49/// DH public key.
50#[derive(Clone)]
51pub struct PublicKey<T>(pub T);
52
53impl<T: AsRef<[u8]>> PartialEq for PublicKey<T> {
54    fn eq(&self, other: &PublicKey<T>) -> bool {
55        self.as_ref() == other.as_ref()
56    }
57}
58
59impl<T: AsRef<[u8]>> Eq for PublicKey<T> {}
60
61impl<T: AsRef<[u8]>> AsRef<[u8]> for PublicKey<T> {
62    fn as_ref(&self) -> &[u8] {
63        self.0.as_ref()
64    }
65}
66
67/// Custom `snow::CryptoResolver` which delegates to either the
68/// `RingResolver` on native or the `DefaultResolver` on wasm
69/// for hash functions and symmetric ciphers, while using x25519-dalek
70/// for Curve25519 DH.
71pub struct Resolver;
72
73impl snow::resolvers::CryptoResolver for Resolver {
74    fn resolve_rng(&self) -> Option<Box<dyn snow::types::Random>> {
75        Some(Box::new(Rng(rand::rngs::StdRng::from_entropy())))
76    }
77
78    fn resolve_dh(&self, choice: &snow::params::DHChoice) -> Option<Box<dyn snow::types::Dh>> {
79        if let snow::params::DHChoice::Curve25519 = choice {
80            Some(Box::new(Keypair::<x25519_spec::X25519Spec>::default()))
81        } else {
82            None
83        }
84    }
85
86    fn resolve_hash(
87        &self,
88        choice: &snow::params::HashChoice,
89    ) -> Option<Box<dyn snow::types::Hash>> {
90        snow::resolvers::RingResolver.resolve_hash(choice)
91    }
92
93    fn resolve_cipher(
94        &self,
95        choice: &snow::params::CipherChoice,
96    ) -> Option<Box<dyn snow::types::Cipher>> {
97        snow::resolvers::RingResolver.resolve_cipher(choice)
98    }
99}
100
101/// Wrapper around a CSPRNG to implement `snow::Random` trait for.
102struct Rng(rand::rngs::StdRng);
103
104impl rand::RngCore for Rng {
105    fn next_u32(&mut self) -> u32 {
106        self.0.next_u32()
107    }
108
109    fn next_u64(&mut self) -> u64 {
110        self.0.next_u64()
111    }
112
113    fn fill_bytes(&mut self, dest: &mut [u8]) {
114        self.0.fill_bytes(dest)
115    }
116
117    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
118        self.0.try_fill_bytes(dest)
119    }
120}
121
122impl rand::CryptoRng for Rng {}
123
124impl snow::types::Random for Rng {}