Warning
This post was published 55 days ago. The information described in this article may have changed.
I'm trying to use the crate kyberlib
to implement quantum-resistant key exchange (for a school project). Unfortunately, cargo
doesn't like something about the traits implemented by my CSPRNG (ChaCha20
):
the trait bound `ChaCha20Rng: kyberlib::RngCore` is not satisfied
two types coming from two different versions of the same crate are different types even if they look the same
you can use `cargo tree` to explore your dependency treerustcClick for full compiler diagnostic
qsh_kyberlib.rs(41, 26): required by a bound introduced by this call
lib.rs(142, 1): there are multiple different versions of crate `rand_core` in the dependency graph
api.rs(37, 8): required by a bound in `kyberlib::keypair`
the trait bound `ChaCha20Rng: kyberlib::CryptoRng` is not satisfied
two types coming from two different versions of the same crate are different types even if they look the same
you can use `cargo tree` to explore your dependency treerustcClick for full compiler diagnostic
qsh_kyberlib.rs(41, 26): required by a bound introduced by this call
lib.rs(209, 1): there are multiple different versions of crate `rand_core` in the dependency graph
api.rs(37, 18): required by a bound in `kyberlib::keypair`
I have little idea what's going on, and I need this solved ASAP.
It seems that the maintainer wrote his own RandCore
and CryptoRng
..?
Code:
/*!
Implements the default key exchange method, kyberlib (CRYSTALS-Kyber).
Key exchange method 0.
*/
use std::array::TryFromSliceError;
// External dependancies go here:
use rand_chacha::ChaCha20Rng;
use rand_chacha::rand_core::SeedableRng;
use kyberlib::{keypair, Ake, AkeSendInit, AkeSendResponse, Keypair, KyberLibError, PublicKey};
// Internal dependancies go here:
use super::KeyExchanger;
pub struct KyberlibKeyExchanger {
// Generator for random numbers:
random: ChaCha20Rng,
// Stores the state for the key exchange:
state: Ake,
// Stores the keypair for this exchange:
keypair: Keypair,
// Stores the public key of the remote host:
remote_pubkey: Option<PublicKey>,
}
impl KeyExchanger for KyberlibKeyExchanger {
type Error = KyberLibError;
type ClientInit = AkeSendInit;
type ServerInit = AkeSendResponse;
fn new() -> Result<Self, Self::Error> {
let mut random: ChaCha20Rng = ChaCha20Rng::from_os_rng();
let state: Ake = Ake::new();
let keypair: Keypair = keypair(&mut random)?;
return Ok(Self {
random: random,
state: state,
keypair: keypair,
remote_pubkey: None,
});
}
fn get_local_pubkey(&self) -> &[u8] {
return &self.keypair.public;
}
fn set_remote_pubkey(&mut self, pubkey: &[u8]) -> Result<(), TryFromSliceError> {
self.remote_pubkey = Some(PublicKey::from(pubkey.try_into()?));
return Ok(());
}
fn client_init(&mut self) -> Result<Self::ClientInit, Self::Error> {
// Check if there's a public key stored here yet:
if let Some(pubkey) = self.remote_pubkey {
// If there is, run `client_init`, propagate any errors, and return the data as an owned Vec:
return Ok(self.state.client_init(&pubkey, &mut self.random)?);
} else {
// Or return this error (`MissingKey` would be more appropriate, but that doesn't exist๐):
return Err(KyberLibError::InvalidKey);
}
}
fn server_init(&mut self, client_init: Self::ClientInit) -> Result<Self::ServerInit, Self::Error> {
// Check if there's a public key:
if let Some(pubkey) = self.remote_pubkey {
// If yes, `server_init`:
return Ok(self.state.server_receive(client_init, &pubkey, &self.keypair.secret, &mut self.random)?);
} else {
// If not, error:
return Err(KyberLibError::InvalidKey);
}
}
fn client_confirm(&mut self, server_init: Self::ServerInit) -> Result<(), Self::Error> {
// Final step: propagate errors:
self.state.client_confirm(server_init, &self.keypair.secret)?;
// Or return `Ok`:
return Ok(());
}
fn shared_secret(&self) -> &[u8] {
return &self.state.shared_secret;
}
}
#[test]
fn test_kyberlib_key_exchanger() {
//let key_exchanger: KyberlibKeyExchanger = KyberlibKeyExchanger::new().expect("Failed to instantiate a `KyberlibKeyExchanger`"); // I know, not really a key. But what was I supposed to do? This is testing functionality, not security...
todo!() // Add the rest of the test, once we have the rest of the features.
}
6 posts - 4 participants
๐ท๏ธ rust_feed