Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3c82d58343 | |||
| 1f05e956fb | |||
| dbfe9a0b92 | |||
| eb3ed98f94 | |||
| 9d6a4ea99d | |||
| 5701ea5c02 | |||
| e3cd1f7eb7 | |||
| 080616a461 | |||
| 2a0ccf30f9 | |||
| cef9e17796 |
@@ -39,7 +39,7 @@ jobs:
|
|||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: test
|
command: test
|
||||||
args: --all
|
args: --all --all-features
|
||||||
|
|
||||||
- name: Check formatting
|
- name: Check formatting
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
|
|||||||
Generated
+751
-482
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,10 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
use crypto::generic_array::typenum::Unsigned;
|
||||||
use log::*;
|
use log::*;
|
||||||
use nymsphinx::anonymous_replies::{
|
use nymsphinx::anonymous_replies::{
|
||||||
encryption_key::EncryptionKeyDigest, encryption_key::Unsigned, SurbEncryptionKey,
|
encryption_key::EncryptionKeyDigest, SurbEncryptionKey, SurbEncryptionKeySize,
|
||||||
SurbEncryptionKeySize,
|
|
||||||
};
|
};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ impl ReplyKeyStorage {
|
|||||||
// if this fails it means we have some database corruption and we
|
// if this fails it means we have some database corruption and we
|
||||||
// absolutely can't continue
|
// absolutely can't continue
|
||||||
|
|
||||||
if key_bytes_ref.len() != SurbEncryptionKeySize::to_usize() {
|
if key_bytes_ref.len() != SurbEncryptionKeySize::USIZE {
|
||||||
error!("REPLY KEY STORAGE DATA CORRUPTION - ENCRYPTION KEY HAS INVALID LENGTH");
|
error!("REPLY KEY STORAGE DATA CORRUPTION - ENCRYPTION KEY HAS INVALID LENGTH");
|
||||||
panic!("REPLY KEY STORAGE DATA CORRUPTION - ENCRYPTION KEY HAS INVALID LENGTH");
|
panic!("REPLY KEY STORAGE DATA CORRUPTION - ENCRYPTION KEY HAS INVALID LENGTH");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,6 @@ url = "2.2"
|
|||||||
|
|
||||||
# I guess temporarily until we get serde support in coconut up and running
|
# I guess temporarily until we get serde support in coconut up and running
|
||||||
coconut-interface = { path = "../coconut-interface" }
|
coconut-interface = { path = "../coconut-interface" }
|
||||||
crypto = { path = "../crypto" }
|
crypto = { path = "../crypto", features = ["asymmetric"] }
|
||||||
network-defaults = { path = "../network-defaults" }
|
network-defaults = { path = "../network-defaults" }
|
||||||
validator-client = { path = "../client-libs/validator-client" }
|
validator-client = { path = "../client-libs/validator-client" }
|
||||||
|
|||||||
+19
-11
@@ -7,21 +7,29 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aes = { version = "0.7.4", features = ["ctr"] }
|
aes = { version = "0.8.1", optional = true }
|
||||||
bs58 = "0.4.0"
|
bs58 = "0.4.0"
|
||||||
blake3 = { version = "~1.2.0", features = ["traits-preview"] }
|
blake3 = { version = "1.3.1", features = ["traits-preview"], optional = true }
|
||||||
digest = "0.9.0"
|
ctr = { version = "0.9.1", optional = true }
|
||||||
generic-array = "0.14"
|
digest = { version = "0.10.3", optional = true }
|
||||||
hkdf = "0.11.0"
|
generic-array = { version = "0.14", optional = true }
|
||||||
hmac = "0.11.0"
|
hkdf = { version = "0.12.3", optional = true }
|
||||||
cipher = "0.3.0"
|
hmac = { version = "0.12.1", optional = true }
|
||||||
x25519-dalek = "1.1"
|
cipher = { version = "0.4.3", optional = true }
|
||||||
ed25519-dalek = "1.0"
|
x25519-dalek = { version = "1.1", optional = true }
|
||||||
log = "0.4"
|
ed25519-dalek = { version = "1.0", optional = true }
|
||||||
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
|
rand = { version = "0.7.3", features = ["wasm-bindgen"], optional = true }
|
||||||
subtle-encoding = { version = "0.5", features = ["bech32-preview"]}
|
subtle-encoding = { version = "0.5", features = ["bech32-preview"]}
|
||||||
|
|
||||||
# internal
|
# internal
|
||||||
nymsphinx-types = { path = "../nymsphinx/types" }
|
nymsphinx-types = { path = "../nymsphinx/types" }
|
||||||
pemstore = { path = "../../common/pemstore" }
|
pemstore = { path = "../../common/pemstore" }
|
||||||
config = { path="../../common/config" }
|
config = { path="../../common/config" }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
rand_chacha = "0.2"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
asymmetric = ["x25519-dalek", "ed25519-dalek"]
|
||||||
|
hashing = ["blake3", "digest", "hkdf", "hmac", "generic-array"]
|
||||||
|
symmetric = ["aes", "ctr", "cipher", "generic-array"]
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use pemstore::traits::{PemStorableKey, PemStorableKeyPair};
|
use pemstore::traits::{PemStorableKey, PemStorableKeyPair};
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
use rand::{CryptoRng, RngCore};
|
use rand::{CryptoRng, RngCore};
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
|
|
||||||
@@ -46,6 +47,7 @@ pub struct KeyPair {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl KeyPair {
|
impl KeyPair {
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
|
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
|
||||||
let private_key = x25519_dalek::StaticSecret::new(rng);
|
let private_key = x25519_dalek::StaticSecret::new(rng);
|
||||||
let public_key = (&private_key).into();
|
let public_key = (&private_key).into();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ pub use ed25519_dalek::SignatureError;
|
|||||||
pub use ed25519_dalek::{Verifier, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH};
|
pub use ed25519_dalek::{Verifier, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH};
|
||||||
use nymsphinx_types::{DestinationAddressBytes, DESTINATION_ADDRESS_LENGTH};
|
use nymsphinx_types::{DestinationAddressBytes, DESTINATION_ADDRESS_LENGTH};
|
||||||
use pemstore::traits::{PemStorableKey, PemStorableKeyPair};
|
use pemstore::traits::{PemStorableKey, PemStorableKeyPair};
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
use rand::{CryptoRng, RngCore};
|
use rand::{CryptoRng, RngCore};
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
|
|
||||||
@@ -45,6 +46,7 @@ pub struct KeyPair {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl KeyPair {
|
impl KeyPair {
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
|
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
|
||||||
let ed25519_keypair = ed25519_dalek::Keypair::generate(rng);
|
let ed25519_keypair = ed25519_dalek::Keypair::generate(rng);
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use digest::{BlockInput, Digest, FixedOutput, Reset, Update};
|
use digest::{Digest, Output};
|
||||||
use generic_array::{ArrayLength, GenericArray};
|
|
||||||
|
|
||||||
pub fn compute_digest<D>(data: &[u8]) -> GenericArray<u8, <D as Digest>::OutputSize>
|
pub fn compute_digest<D>(data: &[u8]) -> Output<D>
|
||||||
where
|
where
|
||||||
D: Update + BlockInput + FixedOutput + Reset + Default + Clone,
|
D: Digest,
|
||||||
D::BlockSize: ArrayLength<u8>,
|
|
||||||
D::OutputSize: ArrayLength<u8>,
|
|
||||||
{
|
{
|
||||||
D::digest(data)
|
D::digest(data)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use digest::{BlockInput, FixedOutput, Reset, Update};
|
use hkdf::{
|
||||||
use generic_array::ArrayLength;
|
hmac::{
|
||||||
use hkdf::Hkdf;
|
digest::{crypto_common::BlockSizeUser, Digest},
|
||||||
|
SimpleHmac,
|
||||||
|
},
|
||||||
|
Hkdf,
|
||||||
|
};
|
||||||
|
|
||||||
/// Perform HKDF `extract` then `expand` as a single step.
|
/// Perform HKDF `extract` then `expand` as a single step.
|
||||||
pub fn extract_then_expand<D>(
|
pub fn extract_then_expand<D>(
|
||||||
@@ -13,14 +17,12 @@ pub fn extract_then_expand<D>(
|
|||||||
okm_length: usize,
|
okm_length: usize,
|
||||||
) -> Result<Vec<u8>, hkdf::InvalidLength>
|
) -> Result<Vec<u8>, hkdf::InvalidLength>
|
||||||
where
|
where
|
||||||
D: Update + BlockInput + FixedOutput + Reset + Default + Clone,
|
D: Digest + BlockSizeUser + Clone,
|
||||||
D::BlockSize: ArrayLength<u8>,
|
|
||||||
D::OutputSize: ArrayLength<u8>,
|
|
||||||
{
|
{
|
||||||
// TODO: this would need to change if we ever needed the generated pseudorandom key, but
|
// TODO: this would need to change if we ever needed the generated pseudorandom key, but
|
||||||
// realistically I don't see any reasons why we might need it
|
// realistically I don't see any reasons why we might need it
|
||||||
|
|
||||||
let hkdf = Hkdf::<D>::new(salt, ikm);
|
let hkdf = Hkdf::<D, SimpleHmac<D>>::new(salt, ikm);
|
||||||
let mut okm = vec![0u8; okm_length];
|
let mut okm = vec![0u8; okm_length];
|
||||||
hkdf.expand(info.unwrap_or(&[]), &mut okm)?;
|
hkdf.expand(info.unwrap_or(&[]), &mut okm)?;
|
||||||
|
|
||||||
|
|||||||
+19
-24
@@ -1,24 +1,23 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use digest::{BlockInput, FixedOutput, Reset, Update};
|
use hmac::{
|
||||||
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};
|
digest::{crypto_common::BlockSizeUser, CtOutput, Digest, Output},
|
||||||
use hmac::{crypto_mac, Hmac, Mac, NewMac};
|
Mac, SimpleHmac,
|
||||||
|
};
|
||||||
|
|
||||||
pub use hmac;
|
pub use hmac;
|
||||||
|
|
||||||
// Type alias for ease of use so that it would not require explicit import of crypto_mac or Hmac
|
// TODO: We should probably change it to use some sealed trait to allow for both `Hmac` and `SimpleHmac`
|
||||||
pub type HmacOutput<D> = crypto_mac::Output<Hmac<D>>;
|
pub type HmacOutput<D> = CtOutput<SimpleHmac<D>>;
|
||||||
|
|
||||||
/// Compute keyed hmac
|
/// Compute keyed hmac
|
||||||
pub fn compute_keyed_hmac<D>(key: &[u8], data: &[u8]) -> HmacOutput<D>
|
pub fn compute_keyed_hmac<D>(key: &[u8], data: &[u8]) -> HmacOutput<D>
|
||||||
where
|
where
|
||||||
D: Update + BlockInput + FixedOutput + Reset + Default + Clone,
|
D: Digest + BlockSizeUser,
|
||||||
D::BlockSize: ArrayLength<u8>,
|
|
||||||
D::OutputSize: ArrayLength<u8>,
|
|
||||||
{
|
{
|
||||||
let mut hmac =
|
let mut hmac = SimpleHmac::<D>::new_from_slice(key)
|
||||||
Hmac::<D>::new_from_slice(key).expect("HMAC should be able to take key of any size!");
|
.expect("HMAC was instantiated with a key of an invalid size!");
|
||||||
hmac.update(data);
|
hmac.update(data);
|
||||||
hmac.finalize()
|
hmac.finalize()
|
||||||
}
|
}
|
||||||
@@ -26,32 +25,28 @@ where
|
|||||||
/// Compute keyed hmac and performs constant time equality check with the provided tag value.
|
/// Compute keyed hmac and performs constant time equality check with the provided tag value.
|
||||||
pub fn recompute_keyed_hmac_and_verify_tag<D>(key: &[u8], data: &[u8], tag: &[u8]) -> bool
|
pub fn recompute_keyed_hmac_and_verify_tag<D>(key: &[u8], data: &[u8], tag: &[u8]) -> bool
|
||||||
where
|
where
|
||||||
D: Update + BlockInput + FixedOutput + Reset + Default + Clone,
|
D: Digest + BlockSizeUser,
|
||||||
D::BlockSize: ArrayLength<u8>,
|
|
||||||
D::OutputSize: ArrayLength<u8>,
|
|
||||||
{
|
{
|
||||||
let mut hmac =
|
let mut hmac = SimpleHmac::<D>::new_from_slice(key)
|
||||||
Hmac::<D>::new_from_slice(key).expect("HMAC should be able to take key of any size!");
|
.expect("HMAC was instantiated with a key of an invalid size!");
|
||||||
hmac.update(data);
|
hmac.update(data);
|
||||||
|
|
||||||
|
let tag_arr = Output::<D>::from_slice(tag);
|
||||||
// note, under the hood ct_eq is called
|
// note, under the hood ct_eq is called
|
||||||
hmac.verify(tag).is_ok()
|
hmac.verify(tag_arr).is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verifies tag of an hmac output.
|
/// Verifies tag of an hmac output.
|
||||||
pub fn verify_tag<D>(tag: &[u8], out: HmacOutput<D>) -> bool
|
pub fn verify_tag<D>(tag: &[u8], out: HmacOutput<D>) -> bool
|
||||||
where
|
where
|
||||||
D: Update + BlockInput + FixedOutput + Reset + Default + Clone,
|
D: Digest + BlockSizeUser,
|
||||||
D::BlockSize: ArrayLength<u8>,
|
|
||||||
D::OutputSize: ArrayLength<u8>,
|
|
||||||
{
|
{
|
||||||
if tag.len() != D::OutputSize::to_usize() {
|
if tag.len() != <D as Digest>::output_size() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let tag_bytes = GenericArray::clone_from_slice(tag);
|
let tag_arr = Output::<D>::from_slice(tag);
|
||||||
let tag_out = HmacOutput::new(tag_bytes);
|
out == tag_arr.into()
|
||||||
// note, under the hood ct_eq is called
|
|
||||||
out == tag_out
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -1,21 +1,33 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
#[cfg(feature = "asymmetric")]
|
||||||
pub mod asymmetric;
|
pub mod asymmetric;
|
||||||
pub mod bech32_address_validation;
|
pub mod bech32_address_validation;
|
||||||
|
#[cfg(feature = "hashing")]
|
||||||
pub mod crypto_hash;
|
pub mod crypto_hash;
|
||||||
|
#[cfg(feature = "hashing")]
|
||||||
pub mod hkdf;
|
pub mod hkdf;
|
||||||
|
#[cfg(feature = "hashing")]
|
||||||
pub mod hmac;
|
pub mod hmac;
|
||||||
|
#[cfg(all(feature = "asymmetric", feature = "hashing", feature = "symmetric"))]
|
||||||
pub mod shared_key;
|
pub mod shared_key;
|
||||||
|
#[cfg(feature = "symmetric")]
|
||||||
pub mod symmetric;
|
pub mod symmetric;
|
||||||
|
|
||||||
pub use digest::Digest;
|
#[cfg(feature = "hashing")]
|
||||||
|
pub use digest::{Digest, OutputSizeUser};
|
||||||
|
#[cfg(any(feature = "hashing", feature = "symmetric"))]
|
||||||
pub use generic_array;
|
pub use generic_array;
|
||||||
|
|
||||||
// with the below my idea was to try to introduce having a single place of importing all hashing, encryption,
|
// with the below my idea was to try to introduce having a single place of importing all hashing, encryption,
|
||||||
// etc. algorithms and import them elsewhere as needed via common/crypto
|
// etc. algorithms and import them elsewhere as needed via common/crypto
|
||||||
|
#[cfg(feature = "symmetric")]
|
||||||
pub use aes;
|
pub use aes;
|
||||||
|
#[cfg(feature = "hashing")]
|
||||||
pub use blake3;
|
pub use blake3;
|
||||||
|
#[cfg(feature = "symmetric")]
|
||||||
|
pub use ctr;
|
||||||
|
|
||||||
// TODO: this function uses all three modules: asymmetric crypto, symmetric crypto and derives key...,
|
// TODO: this function uses all three modules: asymmetric crypto, symmetric crypto and derives key...,
|
||||||
// so I don't know where to put it...
|
// so I don't know where to put it...
|
||||||
|
|||||||
@@ -3,22 +3,22 @@
|
|||||||
|
|
||||||
use crate::asymmetric::encryption;
|
use crate::asymmetric::encryption;
|
||||||
use crate::hkdf;
|
use crate::hkdf;
|
||||||
use cipher::{CipherKey, NewCipher, StreamCipher};
|
use cipher::{Key, KeyIvInit, StreamCipher};
|
||||||
use digest::{BlockInput, FixedOutput, Reset, Update};
|
use digest::crypto_common::BlockSizeUser;
|
||||||
use generic_array::{typenum::Unsigned, ArrayLength};
|
use digest::Digest;
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
use rand::{CryptoRng, RngCore};
|
use rand::{CryptoRng, RngCore};
|
||||||
|
|
||||||
/// Generate an ephemeral encryption keypair and perform diffie-hellman to establish
|
/// Generate an ephemeral encryption keypair and perform diffie-hellman to establish
|
||||||
/// shared key with the remote.
|
/// shared key with the remote.
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
pub fn new_ephemeral_shared_key<C, D, R>(
|
pub fn new_ephemeral_shared_key<C, D, R>(
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
remote_key: &encryption::PublicKey,
|
remote_key: &encryption::PublicKey,
|
||||||
) -> (encryption::KeyPair, CipherKey<C>)
|
) -> (encryption::KeyPair, Key<C>)
|
||||||
where
|
where
|
||||||
C: StreamCipher + NewCipher,
|
C: StreamCipher + KeyIvInit,
|
||||||
D: Update + BlockInput + FixedOutput + Reset + Default + Clone,
|
D: Digest + BlockSizeUser + Clone,
|
||||||
D::BlockSize: ArrayLength<u8>,
|
|
||||||
D::OutputSize: ArrayLength<u8>,
|
|
||||||
R: RngCore + CryptoRng,
|
R: RngCore + CryptoRng,
|
||||||
{
|
{
|
||||||
let ephemeral_keypair = encryption::KeyPair::new(rng);
|
let ephemeral_keypair = encryption::KeyPair::new(rng);
|
||||||
@@ -27,11 +27,11 @@ where
|
|||||||
let dh_result = ephemeral_keypair.private_key().diffie_hellman(remote_key);
|
let dh_result = ephemeral_keypair.private_key().diffie_hellman(remote_key);
|
||||||
|
|
||||||
// there is no reason for this to fail as our okm is expected to be only C::KeySize bytes
|
// there is no reason for this to fail as our okm is expected to be only C::KeySize bytes
|
||||||
let okm = hkdf::extract_then_expand::<D>(None, &dh_result, None, C::KeySize::to_usize())
|
let okm = hkdf::extract_then_expand::<D>(None, &dh_result, None, C::key_size())
|
||||||
.expect("somehow too long okm was provided");
|
.expect("somehow too long okm was provided");
|
||||||
|
|
||||||
let derived_shared_key =
|
let derived_shared_key =
|
||||||
CipherKey::<C>::from_exact_iter(okm).expect("okm was expanded to incorrect length!");
|
Key::<C>::from_exact_iter(okm).expect("okm was expanded to incorrect length!");
|
||||||
|
|
||||||
(ephemeral_keypair, derived_shared_key)
|
(ephemeral_keypair, derived_shared_key)
|
||||||
}
|
}
|
||||||
@@ -40,18 +40,16 @@ where
|
|||||||
pub fn recompute_shared_key<C, D>(
|
pub fn recompute_shared_key<C, D>(
|
||||||
remote_key: &encryption::PublicKey,
|
remote_key: &encryption::PublicKey,
|
||||||
local_key: &encryption::PrivateKey,
|
local_key: &encryption::PrivateKey,
|
||||||
) -> CipherKey<C>
|
) -> Key<C>
|
||||||
where
|
where
|
||||||
C: StreamCipher + NewCipher,
|
C: StreamCipher + KeyIvInit,
|
||||||
D: Update + BlockInput + FixedOutput + Reset + Default + Clone,
|
D: Digest + BlockSizeUser + Clone,
|
||||||
D::BlockSize: ArrayLength<u8>,
|
|
||||||
D::OutputSize: ArrayLength<u8>,
|
|
||||||
{
|
{
|
||||||
let dh_result = local_key.diffie_hellman(remote_key);
|
let dh_result = local_key.diffie_hellman(remote_key);
|
||||||
|
|
||||||
// there is no reason for this to fail as our okm is expected to be only C::KeySize bytes
|
// there is no reason for this to fail as our okm is expected to be only C::KeySize bytes
|
||||||
let okm = hkdf::extract_then_expand::<D>(None, &dh_result, None, C::KeySize::to_usize())
|
let okm = hkdf::extract_then_expand::<D>(None, &dh_result, None, C::key_size())
|
||||||
.expect("somehow too long okm was provided");
|
.expect("somehow too long okm was provided");
|
||||||
|
|
||||||
CipherKey::<C>::from_exact_iter(okm).expect("okm was expanded to incorrect length!")
|
Key::<C>::from_exact_iter(okm).expect("okm was expanded to incorrect length!")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use cipher::{Nonce, StreamCipher};
|
use cipher::{Iv, StreamCipher};
|
||||||
use generic_array::{typenum::Unsigned, GenericArray};
|
pub use cipher::{IvSizeUser, KeyIvInit, KeySizeUser};
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
use rand::{CryptoRng, RngCore};
|
use rand::{CryptoRng, RngCore};
|
||||||
|
|
||||||
// re-export this for ease of use
|
// re-export this for ease of use
|
||||||
pub use cipher::{CipherKey, NewCipher};
|
pub use cipher::Key as CipherKey;
|
||||||
|
|
||||||
// SECURITY:
|
// SECURITY:
|
||||||
// TODO: note that this is not the most secure approach here
|
// TODO: note that this is not the most secure approach here
|
||||||
@@ -19,49 +20,51 @@ pub use cipher::{CipherKey, NewCipher};
|
|||||||
|
|
||||||
// I think 'IV' looks better than 'Iv', feel free to change that.
|
// I think 'IV' looks better than 'Iv', feel free to change that.
|
||||||
#[allow(clippy::upper_case_acronyms)]
|
#[allow(clippy::upper_case_acronyms)]
|
||||||
pub type IV<C> = Nonce<C>;
|
pub type IV<C> = Iv<C>;
|
||||||
|
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
pub fn generate_key<C, R>(rng: &mut R) -> CipherKey<C>
|
pub fn generate_key<C, R>(rng: &mut R) -> CipherKey<C>
|
||||||
where
|
where
|
||||||
C: NewCipher,
|
C: KeyIvInit,
|
||||||
R: RngCore + CryptoRng,
|
R: RngCore + CryptoRng,
|
||||||
{
|
{
|
||||||
let mut key = GenericArray::default();
|
let mut key = CipherKey::<C>::default();
|
||||||
rng.fill_bytes(&mut key);
|
rng.fill_bytes(&mut key);
|
||||||
key
|
key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "rand")]
|
||||||
pub fn random_iv<C, R>(rng: &mut R) -> IV<C>
|
pub fn random_iv<C, R>(rng: &mut R) -> IV<C>
|
||||||
where
|
where
|
||||||
C: NewCipher,
|
C: KeyIvInit,
|
||||||
R: RngCore + CryptoRng,
|
R: RngCore + CryptoRng,
|
||||||
{
|
{
|
||||||
let mut iv = GenericArray::default();
|
let mut iv = IV::<C>::default();
|
||||||
rng.fill_bytes(&mut iv);
|
rng.fill_bytes(&mut iv);
|
||||||
iv
|
iv
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn zero_iv<C>() -> IV<C>
|
pub fn zero_iv<C>() -> IV<C>
|
||||||
where
|
where
|
||||||
C: NewCipher,
|
C: KeyIvInit,
|
||||||
{
|
{
|
||||||
GenericArray::default()
|
Iv::<C>::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iv_from_slice<C>(b: &[u8]) -> &IV<C>
|
pub fn iv_from_slice<C>(b: &[u8]) -> &IV<C>
|
||||||
where
|
where
|
||||||
C: NewCipher,
|
C: KeyIvInit,
|
||||||
{
|
{
|
||||||
if b.len() != C::NonceSize::to_usize() {
|
if b.len() != C::iv_size() {
|
||||||
// `from_slice` would have caused a panic about this issue anyway.
|
// `from_slice` would have caused a panic about this issue anyway.
|
||||||
// Now we at least have slightly more information
|
// Now we at least have slightly more information
|
||||||
panic!(
|
panic!(
|
||||||
"Tried to convert {} bytes to IV. Expected {}",
|
"Tried to convert {} bytes to IV. Expected {}",
|
||||||
b.len(),
|
b.len(),
|
||||||
C::NonceSize::to_usize()
|
C::iv_size()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
GenericArray::from_slice(b)
|
IV::<C>::from_slice(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: there's really no way to use more parts of the keystream if it was required at some point.
|
// TODO: there's really no way to use more parts of the keystream if it was required at some point.
|
||||||
@@ -70,7 +73,7 @@ where
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn encrypt<C>(key: &CipherKey<C>, iv: &IV<C>, data: &[u8]) -> Vec<u8>
|
pub fn encrypt<C>(key: &CipherKey<C>, iv: &IV<C>, data: &[u8]) -> Vec<u8>
|
||||||
where
|
where
|
||||||
C: StreamCipher + NewCipher,
|
C: StreamCipher + KeyIvInit,
|
||||||
{
|
{
|
||||||
let mut ciphertext = data.to_vec();
|
let mut ciphertext = data.to_vec();
|
||||||
encrypt_in_place::<C>(key, iv, &mut ciphertext);
|
encrypt_in_place::<C>(key, iv, &mut ciphertext);
|
||||||
@@ -80,7 +83,7 @@ where
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn encrypt_in_place<C>(key: &CipherKey<C>, iv: &IV<C>, data: &mut [u8])
|
pub fn encrypt_in_place<C>(key: &CipherKey<C>, iv: &IV<C>, data: &mut [u8])
|
||||||
where
|
where
|
||||||
C: StreamCipher + NewCipher,
|
C: StreamCipher + KeyIvInit,
|
||||||
{
|
{
|
||||||
let mut cipher = C::new(key, iv);
|
let mut cipher = C::new(key, iv);
|
||||||
cipher.apply_keystream(data)
|
cipher.apply_keystream(data)
|
||||||
@@ -89,7 +92,7 @@ where
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn decrypt<C>(key: &CipherKey<C>, iv: &IV<C>, ciphertext: &[u8]) -> Vec<u8>
|
pub fn decrypt<C>(key: &CipherKey<C>, iv: &IV<C>, ciphertext: &[u8]) -> Vec<u8>
|
||||||
where
|
where
|
||||||
C: StreamCipher + NewCipher,
|
C: StreamCipher + KeyIvInit,
|
||||||
{
|
{
|
||||||
let mut data = ciphertext.to_vec();
|
let mut data = ciphertext.to_vec();
|
||||||
decrypt_in_place::<C>(key, iv, &mut data);
|
decrypt_in_place::<C>(key, iv, &mut data);
|
||||||
@@ -99,7 +102,7 @@ where
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn decrypt_in_place<C>(key: &CipherKey<C>, iv: &IV<C>, data: &mut [u8])
|
pub fn decrypt_in_place<C>(key: &CipherKey<C>, iv: &IV<C>, data: &mut [u8])
|
||||||
where
|
where
|
||||||
C: StreamCipher + NewCipher,
|
C: StreamCipher + KeyIvInit,
|
||||||
{
|
{
|
||||||
let mut cipher = C::new(key, iv);
|
let mut cipher = C::new(key, iv);
|
||||||
cipher.apply_keystream(data)
|
cipher.apply_keystream(data)
|
||||||
@@ -108,12 +111,12 @@ where
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use rand::rngs::OsRng;
|
use rand_chacha::rand_core::SeedableRng;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod aes_ctr128 {
|
mod aes_ctr128 {
|
||||||
use super::*;
|
use super::*;
|
||||||
use aes::Aes128Ctr;
|
type Aes128Ctr = ctr::Ctr64LE<aes::Aes128>;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn zero_iv_is_actually_zero() {
|
fn zero_iv_is_actually_zero() {
|
||||||
@@ -125,7 +128,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn decryption_is_reciprocal_to_encryption() {
|
fn decryption_is_reciprocal_to_encryption() {
|
||||||
let mut rng = OsRng;
|
let dummy_seed = [1u8; 32];
|
||||||
|
let mut rng = rand_chacha::ChaCha20Rng::from_seed(dummy_seed);
|
||||||
|
|
||||||
let arr_input = [42; 200];
|
let arr_input = [42; 200];
|
||||||
let vec_input = vec![123, 200];
|
let vec_input = vec![123, 200];
|
||||||
@@ -148,7 +152,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn in_place_variants_work_same_way() {
|
fn in_place_variants_work_same_way() {
|
||||||
let mut rng = OsRng;
|
let dummy_seed = [1u8; 32];
|
||||||
|
let mut rng = rand_chacha::ChaCha20Rng::from_seed(dummy_seed);
|
||||||
|
|
||||||
let mut data = [42; 200];
|
let mut data = [42; 200];
|
||||||
let original_data = data;
|
let original_data = data;
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rand = {version = "0.7.3", features = ["wasm-bindgen"]}
|
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
|
||||||
|
|
||||||
crypto = { path = "../../crypto" }
|
crypto = { path = "../../crypto", features = ["symmetric", "rand"] }
|
||||||
nymsphinx-addressing = { path = "../addressing" }
|
nymsphinx-addressing = { path = "../addressing" }
|
||||||
nymsphinx-params = { path = "../params" }
|
nymsphinx-params = { path = "../params" }
|
||||||
nymsphinx-types = { path = "../types" }
|
nymsphinx-types = { path = "../types" }
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::AckKey;
|
use crate::AckKey;
|
||||||
use crypto::generic_array::typenum::Unsigned;
|
use crypto::symmetric::stream_cipher::{self, encrypt, iv_from_slice, random_iv, IvSizeUser};
|
||||||
use crypto::symmetric::stream_cipher::{self, encrypt, iv_from_slice, random_iv, NewCipher};
|
|
||||||
use nymsphinx_params::{
|
use nymsphinx_params::{
|
||||||
packet_sizes::PacketSize, AckEncryptionAlgorithm, SerializedFragmentIdentifier, FRAG_ID_LEN,
|
packet_sizes::PacketSize, AckEncryptionAlgorithm, SerializedFragmentIdentifier, FRAG_ID_LEN,
|
||||||
};
|
};
|
||||||
@@ -33,7 +32,7 @@ pub fn recover_identifier(
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let iv_size = <AckEncryptionAlgorithm as NewCipher>::NonceSize::to_usize();
|
let iv_size = AckEncryptionAlgorithm::iv_size();
|
||||||
let iv = iv_from_slice::<AckEncryptionAlgorithm>(&iv_id_ciphertext[..iv_size]);
|
let iv = iv_from_slice::<AckEncryptionAlgorithm>(&iv_id_ciphertext[..iv_size]);
|
||||||
|
|
||||||
let id = stream_cipher::decrypt::<AckEncryptionAlgorithm>(
|
let id = stream_cipher::decrypt::<AckEncryptionAlgorithm>(
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crypto::generic_array::{typenum::Unsigned, GenericArray};
|
use crypto::symmetric::stream_cipher::{generate_key, CipherKey, KeySizeUser};
|
||||||
use crypto::symmetric::stream_cipher::{generate_key, CipherKey, NewCipher};
|
|
||||||
use nymsphinx_params::AckEncryptionAlgorithm;
|
use nymsphinx_params::AckEncryptionAlgorithm;
|
||||||
use pemstore::traits::PemStorableKey;
|
use pemstore::traits::PemStorableKey;
|
||||||
use rand::{CryptoRng, RngCore};
|
use rand::{CryptoRng, RngCore};
|
||||||
@@ -33,11 +32,14 @@ impl AckKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_from_bytes(bytes: &[u8]) -> Result<Self, AckKeyConversionError> {
|
pub fn try_from_bytes(bytes: &[u8]) -> Result<Self, AckKeyConversionError> {
|
||||||
if bytes.len() != <AckEncryptionAlgorithm as NewCipher>::KeySize::to_usize() {
|
if bytes.len() != AckEncryptionAlgorithm::key_size() {
|
||||||
return Err(AckKeyConversionError::BytesOfInvalidLengthError);
|
return Err(AckKeyConversionError::BytesOfInvalidLengthError);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(AckKey(GenericArray::clone_from_slice(bytes)))
|
// Ok(AckKey(GenericArray::clone_from_slice(bytes)))
|
||||||
|
Ok(AckKey(
|
||||||
|
CipherKey::<AckEncryptionAlgorithm>::clone_from_slice(bytes),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_bytes(&self) -> Vec<u8> {
|
pub fn to_bytes(&self) -> Vec<u8> {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
crypto = { path = "../../crypto" } # all addresses are expressed in terms on their crypto keys
|
crypto = { path = "../../crypto", features = ["asymmetric"] } # all addresses are expressed in terms on their crypto keys
|
||||||
nymsphinx-types = { path = "../types" } # we need to be able to refer to some types defined inside sphinx crate
|
nymsphinx-types = { path = "../types" } # we need to be able to refer to some types defined inside sphinx crate
|
||||||
serde = "1.0" # implementing serialization/deserialization for some types, like `Recipient`
|
serde = "1.0" # implementing serialization/deserialization for some types, like `Recipient`
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,20 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
pub use crypto::generic_array::typenum::Unsigned;
|
|
||||||
use crypto::{
|
use crypto::{
|
||||||
crypto_hash,
|
crypto_hash,
|
||||||
generic_array::GenericArray,
|
generic_array::{typenum::Unsigned, GenericArray},
|
||||||
symmetric::stream_cipher::{generate_key, CipherKey, NewCipher},
|
symmetric::stream_cipher::{generate_key, CipherKey, KeySizeUser},
|
||||||
Digest,
|
OutputSizeUser,
|
||||||
};
|
};
|
||||||
use nymsphinx_params::{ReplySurbEncryptionAlgorithm, ReplySurbKeyDigestAlgorithm};
|
use nymsphinx_params::{ReplySurbEncryptionAlgorithm, ReplySurbKeyDigestAlgorithm};
|
||||||
use rand::{CryptoRng, RngCore};
|
use rand::{CryptoRng, RngCore};
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
|
|
||||||
pub type EncryptionKeyDigest =
|
pub type EncryptionKeyDigest =
|
||||||
GenericArray<u8, <ReplySurbKeyDigestAlgorithm as Digest>::OutputSize>;
|
GenericArray<u8, <ReplySurbKeyDigestAlgorithm as OutputSizeUser>::OutputSize>;
|
||||||
|
|
||||||
pub type SurbEncryptionKeySize = <ReplySurbEncryptionAlgorithm as NewCipher>::KeySize;
|
pub type SurbEncryptionKeySize = <ReplySurbEncryptionAlgorithm as KeySizeUser>::KeySize;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SurbEncryptionKey(CipherKey<ReplySurbEncryptionAlgorithm>);
|
pub struct SurbEncryptionKey(CipherKey<ReplySurbEncryptionAlgorithm>);
|
||||||
@@ -45,7 +44,7 @@ impl SurbEncryptionKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_from_bytes(bytes: &[u8]) -> Result<Self, SurbEncryptionKeyError> {
|
pub fn try_from_bytes(bytes: &[u8]) -> Result<Self, SurbEncryptionKeyError> {
|
||||||
if bytes.len() != SurbEncryptionKeySize::to_usize() {
|
if bytes.len() != SurbEncryptionKeySize::USIZE {
|
||||||
return Err(SurbEncryptionKeyError::BytesOfInvalidLengthError);
|
return Err(SurbEncryptionKeyError::BytesOfInvalidLengthError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
pub mod encryption_key;
|
pub mod encryption_key;
|
||||||
pub mod reply_surb;
|
pub mod reply_surb;
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::encryption_key::{
|
use crate::encryption_key::{SurbEncryptionKey, SurbEncryptionKeyError, SurbEncryptionKeySize};
|
||||||
SurbEncryptionKey, SurbEncryptionKeyError, SurbEncryptionKeySize, Unsigned,
|
use crypto::{generic_array::typenum::Unsigned, Digest};
|
||||||
};
|
|
||||||
use crypto::Digest;
|
|
||||||
use nymsphinx_addressing::clients::Recipient;
|
use nymsphinx_addressing::clients::Recipient;
|
||||||
use nymsphinx_addressing::nodes::{NymNodeRoutingAddress, MAX_NODE_ADDRESS_UNPADDED_LEN};
|
use nymsphinx_addressing::nodes::{NymNodeRoutingAddress, MAX_NODE_ADDRESS_UNPADDED_LEN};
|
||||||
use nymsphinx_params::packet_sizes::PacketSize;
|
use nymsphinx_params::packet_sizes::PacketSize;
|
||||||
@@ -65,7 +63,7 @@ pub struct ReplySurb {
|
|||||||
// Serialize + Deserialize is not really used anymore (it was for a CBOR experiment)
|
// Serialize + Deserialize is not really used anymore (it was for a CBOR experiment)
|
||||||
// however, if we decided we needed it again, it's already here
|
// however, if we decided we needed it again, it's already here
|
||||||
impl Serialize for ReplySurb {
|
impl Serialize for ReplySurb {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
@@ -139,7 +137,7 @@ impl ReplySurb {
|
|||||||
|
|
||||||
// the SURB itself consists of SURB_header, first hop address and set of payload keys
|
// the SURB itself consists of SURB_header, first hop address and set of payload keys
|
||||||
// (note extra 1 for the gateway)
|
// (note extra 1 for the gateway)
|
||||||
SurbEncryptionKeySize::to_usize()
|
SurbEncryptionKeySize::USIZE
|
||||||
+ HEADER_SIZE
|
+ HEADER_SIZE
|
||||||
+ NODE_ADDRESS_LENGTH
|
+ NODE_ADDRESS_LENGTH
|
||||||
+ (1 + mix_hops as usize) * PAYLOAD_KEY_SIZE
|
+ (1 + mix_hops as usize) * PAYLOAD_KEY_SIZE
|
||||||
@@ -160,9 +158,9 @@ impl ReplySurb {
|
|||||||
|
|
||||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, ReplySurbError> {
|
pub fn from_bytes(bytes: &[u8]) -> Result<Self, ReplySurbError> {
|
||||||
let encryption_key =
|
let encryption_key =
|
||||||
SurbEncryptionKey::try_from_bytes(&bytes[..SurbEncryptionKeySize::to_usize()])?;
|
SurbEncryptionKey::try_from_bytes(&bytes[..SurbEncryptionKeySize::USIZE])?;
|
||||||
|
|
||||||
let surb = match SURB::from_bytes(&bytes[SurbEncryptionKeySize::to_usize()..]) {
|
let surb = match SURB::from_bytes(&bytes[SurbEncryptionKeySize::USIZE..]) {
|
||||||
Err(err) => return Err(ReplySurbError::RecoveryError(err)),
|
Err(err) => return Err(ReplySurbError::RecoveryError(err)),
|
||||||
Ok(surb) => surb,
|
Ok(surb) => surb,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,5 +7,5 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
crypto = { path = "../../crypto" }
|
crypto = { path = "../../crypto", features = ["hashing", "symmetric"] }
|
||||||
nymsphinx-types = { path = "../types" }
|
nymsphinx-types = { path = "../types" }
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crypto::aes::Aes128Ctr;
|
use crypto::aes::Aes128;
|
||||||
use crypto::blake3;
|
use crypto::blake3;
|
||||||
|
use crypto::ctr;
|
||||||
|
|
||||||
|
type Aes128Ctr = ctr::Ctr64LE<Aes128>;
|
||||||
|
|
||||||
// Re-export for ease of use
|
// Re-export for ease of use
|
||||||
pub use packet_modes::PacketMode;
|
pub use packet_modes::PacketMode;
|
||||||
|
|||||||
Generated
-99
@@ -27,12 +27,6 @@ version = "0.3.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "arrayvec"
|
|
||||||
version = "0.7.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
@@ -90,21 +84,6 @@ dependencies = [
|
|||||||
"opaque-debug 0.2.3",
|
"opaque-debug 0.2.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "blake3"
|
|
||||||
version = "1.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "526c210b4520e416420759af363083471656e819a75e831b8d2c9d5a584f2413"
|
|
||||||
dependencies = [
|
|
||||||
"arrayref",
|
|
||||||
"arrayvec",
|
|
||||||
"cc",
|
|
||||||
"cfg-if",
|
|
||||||
"constant_time_eq",
|
|
||||||
"crypto-mac 0.11.1",
|
|
||||||
"digest 0.9.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-buffer"
|
name = "block-buffer"
|
||||||
version = "0.7.3"
|
version = "0.7.3"
|
||||||
@@ -230,12 +209,6 @@ version = "0.6.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b"
|
checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "constant_time_eq"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "contracts-common"
|
name = "contracts-common"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -320,22 +293,11 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
|||||||
name = "crypto"
|
name = "crypto"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
|
||||||
"blake3",
|
|
||||||
"bs58",
|
"bs58",
|
||||||
"cipher",
|
|
||||||
"config",
|
"config",
|
||||||
"digest 0.9.0",
|
|
||||||
"ed25519-dalek",
|
|
||||||
"generic-array 0.14.5",
|
|
||||||
"hkdf",
|
|
||||||
"hmac",
|
|
||||||
"log",
|
|
||||||
"nymsphinx-types",
|
"nymsphinx-types",
|
||||||
"pemstore",
|
"pemstore",
|
||||||
"rand",
|
|
||||||
"subtle-encoding",
|
"subtle-encoding",
|
||||||
"x25519-dalek",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -448,29 +410,6 @@ dependencies = [
|
|||||||
"signature",
|
"signature",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ed25519"
|
|
||||||
version = "1.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "74e1069e39f1454367eb2de793ed062fac4c35c2934b76a81d90dd9abcd28816"
|
|
||||||
dependencies = [
|
|
||||||
"signature",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ed25519-dalek"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d"
|
|
||||||
dependencies = [
|
|
||||||
"curve25519-dalek",
|
|
||||||
"ed25519",
|
|
||||||
"rand",
|
|
||||||
"serde",
|
|
||||||
"sha2",
|
|
||||||
"zeroize",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ed25519-zebra"
|
name = "ed25519-zebra"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
@@ -1369,18 +1308,6 @@ dependencies = [
|
|||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "synstructure"
|
|
||||||
version = "0.12.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
"unicode-xid",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.30"
|
version = "1.0.30"
|
||||||
@@ -1653,34 +1580,8 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "x25519-dalek"
|
|
||||||
version = "1.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2392b6b94a576b4e2bf3c5b2757d63f10ada8020a2e4d08ac849ebcf6ea8e077"
|
|
||||||
dependencies = [
|
|
||||||
"curve25519-dalek",
|
|
||||||
"rand_core 0.5.1",
|
|
||||||
"zeroize",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zeroize"
|
name = "zeroize"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd"
|
checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd"
|
||||||
dependencies = [
|
|
||||||
"zeroize_derive",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zeroize_derive"
|
|
||||||
version = "1.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "65f1a51723ec88c66d5d1fe80c841f17f63587d6691901d66be9bec6c3b51f73"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
"synstructure",
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crypto::generic_array::{typenum::Unsigned, GenericArray};
|
use crypto::generic_array::{typenum::Unsigned, GenericArray};
|
||||||
use crypto::symmetric::stream_cipher::{random_iv, NewCipher, IV as CryptoIV};
|
use crypto::symmetric::stream_cipher::{random_iv, IvSizeUser, IV as CryptoIV};
|
||||||
use nymsphinx::params::GatewayEncryptionAlgorithm;
|
use nymsphinx::params::GatewayEncryptionAlgorithm;
|
||||||
use rand::{CryptoRng, RngCore};
|
use rand::{CryptoRng, RngCore};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
type NonceSize = <GatewayEncryptionAlgorithm as NewCipher>::NonceSize;
|
type NonceSize = <GatewayEncryptionAlgorithm as IvSizeUser>::IvSize;
|
||||||
|
|
||||||
// I think 'IV' looks better than 'Iv', feel free to change that.
|
// I think 'IV' looks better than 'Iv', feel free to change that.
|
||||||
#[allow(clippy::upper_case_acronyms)]
|
#[allow(clippy::upper_case_acronyms)]
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
pub use crypto::generic_array;
|
pub use crypto::generic_array;
|
||||||
use crypto::hmac::{hmac::Mac, HmacOutput};
|
use crypto::hmac::HmacOutput;
|
||||||
|
use crypto::OutputSizeUser;
|
||||||
use nymsphinx::params::GatewayIntegrityHmacAlgorithm;
|
use nymsphinx::params::GatewayIntegrityHmacAlgorithm;
|
||||||
pub use types::*;
|
pub use types::*;
|
||||||
|
|
||||||
@@ -15,4 +16,4 @@ pub type GatewayMac = HmacOutput<GatewayIntegrityHmacAlgorithm>;
|
|||||||
|
|
||||||
// TODO: could using `Mac` trait here for OutputSize backfire?
|
// TODO: could using `Mac` trait here for OutputSize backfire?
|
||||||
// Should hmac itself be exposed, imported and used instead?
|
// Should hmac itself be exposed, imported and used instead?
|
||||||
pub type GatewayMacSize = <GatewayIntegrityHmacAlgorithm as Mac>::OutputSize;
|
pub type GatewayMacSize = <GatewayIntegrityHmacAlgorithm as OutputSizeUser>::OutputSize;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use crypto::generic_array::{
|
|||||||
GenericArray,
|
GenericArray,
|
||||||
};
|
};
|
||||||
use crypto::hmac::{compute_keyed_hmac, recompute_keyed_hmac_and_verify_tag};
|
use crypto::hmac::{compute_keyed_hmac, recompute_keyed_hmac_and_verify_tag};
|
||||||
use crypto::symmetric::stream_cipher::{self, CipherKey, NewCipher, IV};
|
use crypto::symmetric::stream_cipher::{self, CipherKey, KeySizeUser, IV};
|
||||||
use nymsphinx::params::{GatewayEncryptionAlgorithm, GatewayIntegrityHmacAlgorithm};
|
use nymsphinx::params::{GatewayEncryptionAlgorithm, GatewayIntegrityHmacAlgorithm};
|
||||||
use pemstore::traits::PemStorableKey;
|
use pemstore::traits::PemStorableKey;
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
@@ -17,7 +17,7 @@ pub type SharedKeySize = Sum<EncryptionKeySize, MacKeySize>;
|
|||||||
|
|
||||||
// we're using 16 byte long key in sphinx, so let's use the same one here
|
// we're using 16 byte long key in sphinx, so let's use the same one here
|
||||||
type MacKeySize = U16;
|
type MacKeySize = U16;
|
||||||
type EncryptionKeySize = <GatewayEncryptionAlgorithm as NewCipher>::KeySize;
|
type EncryptionKeySize = <GatewayEncryptionAlgorithm as KeySizeUser>::KeySize;
|
||||||
|
|
||||||
/// Shared key used when computing MAC for messages exchanged between client and its gateway.
|
/// Shared key used when computing MAC for messages exchanged between client and its gateway.
|
||||||
pub type MacKey = GenericArray<u8, MacKeySize>;
|
pub type MacKey = GenericArray<u8, MacKeySize>;
|
||||||
|
|||||||
Generated
+590
-440
File diff suppressed because it is too large
Load Diff
@@ -13,13 +13,13 @@ rust-version = "1.56"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
tauri-build = { version = "1.0.0-beta.4" }
|
tauri-build = { version = "1.0.0-rc.3" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
strum = { version = "0.23", features = ["derive"] }
|
strum = { version = "0.23", features = ["derive"] }
|
||||||
tauri = { version = "1.0.0-beta.8", features = ["shell-open"] }
|
tauri = { version = "1.0.0-rc.3", features = ["shell-open"] }
|
||||||
tokio = { version = "1.10", features = ["sync"] }
|
tokio = { version = "1.10", features = ["sync"] }
|
||||||
dirs = "4.0"
|
dirs = "4.0"
|
||||||
bip39 = "1.0"
|
bip39 = "1.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user