use crate::{Buffer, CryptoRandom, CryptoResult, CryptoSignature, CryptoSystem};
pub struct FakeCryptoSystem {}
impl CryptoRandom for FakeCryptoSystem {
fn randombytes_buf<OutputBuffer: Buffer>(buffer: &mut OutputBuffer) -> CryptoResult<()> {
let mut buffer = buffer.write_lock();
for i in 0..buffer.len() {
buffer[i] = rand::random();
}
Ok(())
}
}
impl CryptoSignature for FakeCryptoSystem {
const SIGN_SEED_BYTES: usize = 8;
const SIGN_PUBLIC_KEY_BYTES: usize = 32;
const SIGN_SECRET_KEY_BYTES: usize = 8;
const SIGN_BYTES: usize = 8;
fn sign_seed_keypair<SeedBuffer: Buffer, PublicKeyBuffer: Buffer, SecretKeyBuffer: Buffer>(
seed: &SeedBuffer,
public_key: &mut PublicKeyBuffer,
secret_key: &mut SecretKeyBuffer,
) -> CryptoResult<()> {
public_key.write_lock().write(0, &seed.read_lock())?;
secret_key.write_lock().write(0, &seed.read_lock())?;
Ok(())
}
fn sign_keypair<PublicKeyBuffer: Buffer, SecretKeyBuffer: Buffer>(
public_key: &mut PublicKeyBuffer,
secret_key: &mut SecretKeyBuffer,
) -> CryptoResult<()> {
let mut rnd = vec![0; 8];
FakeCryptoSystem::randombytes_buf(&mut rnd)?;
public_key.write_lock().write(0, &rnd)?;
secret_key.write_lock().write(0, &rnd)?;
Ok(())
}
fn sign<SignatureBuffer: Buffer, MessageBuffer: Buffer, SecretKeyBuffer: Buffer>(
signature: &mut SignatureBuffer,
message: &MessageBuffer,
secret_key: &SecretKeyBuffer,
) -> CryptoResult<()> {
let mut signature = signature.write_lock();
signature[0] = secret_key.read_lock()[0];
signature[1] = message.read_lock()[0];
signature[2] = 0xff;
signature[3] = 0xff;
Ok(())
}
fn sign_verify<SignatureBuffer: Buffer, MessageBuffer: Buffer, PublicKeyBuffer: Buffer>(
signature: &SignatureBuffer,
message: &MessageBuffer,
public_key: &PublicKeyBuffer,
) -> CryptoResult<bool> {
let public_key = public_key.read_lock();
let message = message.read_lock();
let signature = signature.read_lock();
Ok(signature[0] == public_key[0]
&& signature[1] == message[0]
&& signature[2] == 0xff
&& signature[3] == 0xff)
}
}
impl CryptoSystem for FakeCryptoSystem {}
#[cfg(test)]
mod tests {
use super::*;
use crate::InsecureBuffer;
#[test]
fn it_should_randomize() {
let mut buf1 = InsecureBuffer::new(8).unwrap();
assert_eq!(
"InsecureBuffer { b: [0, 0, 0, 0, 0, 0, 0, 0], p: RefCell { value: NoAccess } }",
&format!("{:?}", buf1)
);
FakeCryptoSystem::randombytes_buf(&mut buf1).unwrap();
assert_ne!(
"InsecureBuffer { b: [0, 0, 0, 0, 0, 0, 0, 0], p: RefCell { value: NoAccess } }",
&format!("{:?}", buf1)
);
let mut buf2 = InsecureBuffer::new(8).unwrap();
FakeCryptoSystem::randombytes_buf(&mut buf2).unwrap();
assert_ne!(&format!("{:?}", buf1), &format!("{:?}", buf2));
}
#[test]
fn it_should_randomize_vec_u8() {
let mut buf1 = vec![0; 8];
assert_eq!("[0, 0, 0, 0, 0, 0, 0, 0]", &format!("{:?}", buf1));
FakeCryptoSystem::randombytes_buf(&mut buf1).unwrap();
assert_ne!("[0, 0, 0, 0, 0, 0, 0, 0]", &format!("{:?}", buf1));
let mut buf2 = vec![0; 8];
FakeCryptoSystem::randombytes_buf(&mut buf2).unwrap();
assert_ne!(&format!("{:?}", buf1), &format!("{:?}", buf2));
}
#[test]
fn it_should_sign_and_verify() {
let data = InsecureBuffer::new(8).unwrap();
let mut seed = InsecureBuffer::new(FakeCryptoSystem::SIGN_SEED_BYTES).unwrap();
FakeCryptoSystem::randombytes_buf(&mut seed).unwrap();
let mut pub_key = InsecureBuffer::new(FakeCryptoSystem::SIGN_PUBLIC_KEY_BYTES).unwrap();
let mut priv_key = InsecureBuffer::new(FakeCryptoSystem::SIGN_SECRET_KEY_BYTES).unwrap();
FakeCryptoSystem::sign_seed_keypair(&seed, &mut pub_key, &mut priv_key).unwrap();
let mut sig = InsecureBuffer::new(FakeCryptoSystem::SIGN_BYTES).unwrap();
assert!(!FakeCryptoSystem::sign_verify(&sig, &data, &pub_key).unwrap());
FakeCryptoSystem::sign(&mut sig, &data, &priv_key).unwrap();
assert!(FakeCryptoSystem::sign_verify(&sig, &data, &pub_key).unwrap());
}
}