encrypt and decrypt example tests work

testing
Avril 4 years ago
parent 0abd878df2
commit 89f706d07d
Signed by: flanchan
GPG Key ID: 284488987C31F630

150
Cargo.lock generated

@ -20,6 +20,15 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "block-buffer"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
dependencies = [
"generic-array",
]
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.67" version = "1.0.67"
@ -37,11 +46,27 @@ name = "chachaex"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"base64", "base64",
"getrandom", "getrandom 0.2.2",
"hex-literal", "hex-literal 0.3.1",
"khash",
"openssl", "openssl",
] ]
[[package]]
name = "cpuid-bool"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
[[package]]
name = "digest"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
"generic-array",
]
[[package]] [[package]]
name = "foreign-types" name = "foreign-types"
version = "0.3.2" version = "0.3.2"
@ -57,6 +82,27 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "generic-array"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
"cfg-if",
"libc",
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.2" version = "0.2.2"
@ -65,7 +111,17 @@ checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"wasi", "wasi 0.10.2+wasi-snapshot-preview1",
]
[[package]]
name = "hex-literal"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0"
dependencies = [
"hex-literal-impl",
"proc-macro-hack",
] ]
[[package]] [[package]]
@ -74,6 +130,27 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5af1f635ef1bc545d78392b136bfe1c9809e029023c84a3638a864a10b8819c8" checksum = "5af1f635ef1bc545d78392b136bfe1c9809e029023c84a3638a864a10b8819c8"
[[package]]
name = "hex-literal-impl"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "853f769599eb31de176303197b7ba4973299c38c7a7604a6bc88c3eef05b9b46"
dependencies = [
"proc-macro-hack",
]
[[package]]
name = "khash"
version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "193f6499a7299fa3f470fac8c79bbd148370f6085b0c2fa4f32a03f517f7a6e7"
dependencies = [
"getrandom 0.1.16",
"hex-literal 0.2.1",
"rustc_version",
"sha2",
]
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.90" version = "0.2.90"
@ -86,6 +163,12 @@ version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
[[package]]
name = "opaque-debug"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]] [[package]]
name = "openssl" name = "openssl"
version = "0.10.33" version = "0.10.33"
@ -119,12 +202,73 @@ version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
]
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "sha2"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de"
dependencies = [
"block-buffer",
"cfg-if",
"cpuid-bool",
"digest",
"opaque-debug",
]
[[package]]
name = "typenum"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
[[package]] [[package]]
name = "vcpkg" name = "vcpkg"
version = "0.2.11" version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
[[package]]
name = "version_check"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.10.2+wasi-snapshot-preview1" version = "0.10.2+wasi-snapshot-preview1"

@ -10,4 +10,5 @@ edition = "2018"
base64 = "0.13.0" base64 = "0.13.0"
getrandom = "0.2.2" getrandom = "0.2.2"
hex-literal = "0.3.1" hex-literal = "0.3.1"
khash = {version = "2.0.3", default-features=false}
openssl = "0.10.32" openssl = "0.10.32"

@ -1,25 +1,17 @@
use getrandom::getrandom;
use openssl::{ use openssl::{
symm::{ symm::{
Cipher, Crypter, Mode, Cipher, Crypter, Mode,
}, },
error::ErrorStack, error::ErrorStack,
}; };
use crate::key::{Key, IV};
pub const KEY_SIZE: usize = 32; pub const KEY_SIZE: usize = 32;
pub const IV_SIZE: usize = 12; pub const IV_SIZE: usize = 12;
static NEW_CIPHER: fn() -> Cipher = Cipher::chacha20_poly1305; static NEW_CIPHER: fn() -> Cipher = Cipher::chacha20_poly1305;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
#[repr(transparent)]
pub struct Key([u8; KEY_SIZE]);
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
#[repr(transparent)]
pub struct IV([u8; IV_SIZE]);
#[inline] pub fn decrypter(key: impl AsRef<Key>, iv: impl AsRef<IV>) -> Result<Crypter, ErrorStack> #[inline] pub fn decrypter(key: impl AsRef<Key>, iv: impl AsRef<IV>) -> Result<Crypter, ErrorStack>
{ {
Crypter::new( Crypter::new(
@ -39,74 +31,8 @@ pub struct IV([u8; IV_SIZE]);
) )
} }
impl Key /// Generate a random key and IV.
{
pub fn new() -> Self
{
let mut output = [0u8; KEY_SIZE];
getrandom(&mut output[..]).expect("rng fatal");
Self(output)
}
}
impl IV
{
pub fn new() -> Self
{
let mut output = [0u8; IV_SIZE];
getrandom(&mut output[..]).expect("rng fatal");
Self(output)
}
}
impl AsRef<[u8]> for Key
{
fn as_ref(&self) -> &[u8]
{
&self.0[..]
}
}
impl AsRef<[u8]> for IV
{
fn as_ref(&self) -> &[u8]
{
&self.0[..]
}
}
impl AsMut<[u8]> for Key
{
fn as_mut(&mut self) -> &mut [u8]
{
&mut self.0[..]
}
}
impl AsMut<[u8]> for IV
{
fn as_mut(&mut self) -> &mut [u8]
{
&mut self.0[..]
}
}
#[inline(always)] pub fn keygen() -> (Key, IV) #[inline(always)] pub fn keygen() -> (Key, IV)
{ {
(Key::new(), IV::new()) (Key::new(), IV::new())
} }
impl AsRef<Key> for Key
{
#[inline] fn as_ref(&self) -> &Key
{
self
}
}
impl AsRef<IV> for IV
{
#[inline] fn as_ref(&self) -> &IV
{
self
}
}

@ -0,0 +1,116 @@
use std::{
mem,
iter::{
self,
ExactSizeIterator,
FusedIterator,
},
slice,
fmt,
};
#[derive(Debug, Clone)]
pub struct HexStringIter<I>(I, [u8; 2]);
impl<I: Iterator<Item = u8>> HexStringIter<I>
{
/// Write this hex string iterator to a formattable buffer
pub fn consume<F>(self, f: &mut F) -> fmt::Result
where F: std::fmt::Write
{
if self.1[0] != 0 {
write!(f, "{}", self.1[0] as char)?;
}
if self.1[1] != 0 {
write!(f, "{}", self.1[1] as char)?;
}
for x in self.0 {
write!(f, "{:02x}", x)?;
}
Ok(())
}
/// Consume into a string
pub fn into_string(self) -> String
{
let mut output = match self.size_hint() {
(0, None) => String::new(),
(_, Some(x)) |
(x, None) => String::with_capacity(x),
};
self.consume(&mut output).unwrap();
output
}
}
pub trait HexStringIterExt<I>: Sized
{
fn into_hex(self) -> HexStringIter<I>;
}
pub type HexStringSliceIter<'a> = HexStringIter<iter::Copied<slice::Iter<'a, u8>>>;
pub trait HexStringSliceIterExt
{
fn hex(&self) -> HexStringSliceIter<'_>;
}
impl<S> HexStringSliceIterExt for S
where S: AsRef<[u8]>
{
fn hex(&self) -> HexStringSliceIter<'_>
{
self.as_ref().iter().copied().into_hex()
}
}
impl<I: IntoIterator<Item=u8>> HexStringIterExt<I::IntoIter> for I
{
#[inline] fn into_hex(self) -> HexStringIter<I::IntoIter> {
HexStringIter(self.into_iter(), [0u8; 2])
}
}
impl<I: Iterator<Item = u8>> Iterator for HexStringIter<I>
{
type Item = char;
fn next(&mut self) -> Option<Self::Item>
{
match self.1 {
[_, 0] => {
use std::io::Write;
write!(&mut self.1[..], "{:02x}", self.0.next()?).unwrap();
Some(mem::replace(&mut self.1[0], 0) as char)
},
[0, _] => Some(mem::replace(&mut self.1[1], 0) as char),
_ => unreachable!(),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (l, h) = self.0.size_hint();
(l * 2, h.map(|x| x*2))
}
}
impl<I: Iterator<Item = u8> + ExactSizeIterator> ExactSizeIterator for HexStringIter<I>{}
impl<I: Iterator<Item = u8> + FusedIterator> FusedIterator for HexStringIter<I>{}
impl<I: Iterator<Item = u8>> From<HexStringIter<I>> for String
{
fn from(from: HexStringIter<I>) -> Self
{
from.into_string()
}
}
impl<I: Iterator<Item = u8> + Clone> fmt::Display for HexStringIter<I>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
self.clone().consume(f)
}
}

@ -0,0 +1,98 @@
use getrandom::getrandom;
use std::fmt;
use crate::cha::{
KEY_SIZE,
IV_SIZE,
};
use crate::ext::*;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
#[repr(transparent)]
pub struct Key([u8; KEY_SIZE]);
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
#[repr(transparent)]
pub struct IV([u8; IV_SIZE]);
impl Key
{
pub fn new() -> Self
{
let mut output = [0u8; KEY_SIZE];
getrandom(&mut output[..]).expect("rng fatal");
Self(output)
}
}
impl IV
{
pub fn new() -> Self
{
let mut output = [0u8; IV_SIZE];
getrandom(&mut output[..]).expect("rng fatal");
Self(output)
}
}
impl AsRef<[u8]> for Key
{
fn as_ref(&self) -> &[u8]
{
&self.0[..]
}
}
impl AsRef<[u8]> for IV
{
fn as_ref(&self) -> &[u8]
{
&self.0[..]
}
}
impl AsMut<[u8]> for Key
{
fn as_mut(&mut self) -> &mut [u8]
{
&mut self.0[..]
}
}
impl AsMut<[u8]> for IV
{
fn as_mut(&mut self) -> &mut [u8]
{
&mut self.0[..]
}
}
impl AsRef<Key> for Key
{
#[inline] fn as_ref(&self) -> &Key
{
self
}
}
impl AsRef<IV> for IV
{
#[inline] fn as_ref(&self) -> &IV
{
self
}
}
impl fmt::Display for Key
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "Key({})", self.0.iter().copied().into_hex())
}
}
impl fmt::Display for IV
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "Key({})", self.0.iter().copied().into_hex())
}
}

@ -1,16 +1,19 @@
#[macro_use] extern crate hex_literal; #[macro_use] extern crate hex_literal;
mod ext; use ext::*;
mod key;
mod cha; mod cha;
use cha::{Key, IV}; use key::{Key, IV};
fn encrypt((key, iv): &(Key, IV), input: impl Into<Vec<u8>>) -> Result<String, openssl::error::ErrorStack> fn encrypt((key, iv): &(Key, IV), input: impl AsRef<[u8]>) -> Result<String, openssl::error::ErrorStack>
{ {
let input = input.into();//.into(); let input = input.as_ref();
let mut output = vec![0u8; input.len()]; let mut output = vec![0u8; input.len()];
eprintln!("(enc) Key: {:?}, IV: {:?}, Input: ({}, {:?})", key, iv, input.len(), input); eprintln!("(enc) Key: {}, IV: {}, Input: ({}, {})", key, iv, input.len(), input.hex());
let mut enc = cha::encrypter(key, iv)?; let mut enc = cha::encrypter(key, iv)?;
@ -21,12 +24,12 @@ fn encrypt((key, iv): &(Key, IV), input: impl Into<Vec<u8>>) -> Result<String, o
Ok(base64::encode(&output[..n])) Ok(base64::encode(&output[..n]))
} }
fn decrypt((key, iv): &(Key, IV), input: impl Into<String>) -> Result<Vec<u8>, openssl::error::ErrorStack> fn decrypt((key, iv): &(Key, IV), input: impl AsRef<str>) -> Result<Vec<u8>, openssl::error::ErrorStack>
{ {
let input = base64::decode(input.into()).expect("invalid base64"); let input = base64::decode(input.as_ref()).expect("invalid base64");
let mut output = vec![0u8; input.len()]; let mut output = vec![0u8; input.len()];
eprintln!("(dec) Key: {:?}, IV: {:?}, Input: ({}, {:?})", key, iv, input.len(), input); eprintln!("(dec) Key: {}, IV: {}, Input: ({}, {})", key, iv, input.len(), input.hex());
let mut dec = cha::decrypter(key, iv)?; let mut dec = cha::decrypter(key, iv)?;
@ -39,10 +42,19 @@ fn decrypt((key, iv): &(Key, IV), input: impl Into<String>) -> Result<Vec<u8>, o
} }
fn main() { fn main() {
let input = std::env::args().nth(1).unwrap_or({
let mut input = [0u8; 16];
getrandom::getrandom(&mut input[..]).expect("rng fatal");
khash::generate(&Default::default(), input).expect("kana-hash fatal")
//input.hex().into()
});
let key = cha::keygen(); let key = cha::keygen();
let enc = encrypt(&key, std::env::args().nth(1).unwrap()).expect("encrypt"); let enc = encrypt(&key, &input).expect("encrypt");
println!("{}", enc); println!("{}", enc);
let dec = decrypt(&key, enc).expect("decrypt"); let dec = decrypt(&key, enc).expect("decrypt");
println!("{:?}", std::str::from_utf8(&dec[..]).unwrap()); let output = std::str::from_utf8(&dec[..]).unwrap();
println!("{:?}", output);
assert_eq!(output, &input[..]);
} }

Loading…
Cancel
Save