#![allow(non_snake_case)]
use std::sync::Arc;
use async_trait::async_trait;
use tokio::sync::RwLock;
use ring::{aead, digest, rand, signature, agreement};
use ring::rand::{SecureRandom, SystemRandom};
use data_encoding::{BASE64, HEX};
use std::collections::HashMap as FxHashMap;
use crate::core::{RiResult, RiError};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CryptoError {
InvalidKey,
EncryptionError(String),
DecryptionError(String),
SigningError(String),
VerificationError(String),
}
impl std::fmt::Display for CryptoError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
CryptoError::InvalidKey => write!(f, "Invalid cryptographic key"),
CryptoError::EncryptionError(msg) => write!(f, "Encryption error: {}", msg),
CryptoError::DecryptionError(msg) => write!(f, "Decryption error: {}", msg),
CryptoError::SigningError(msg) => write!(f, "Signing error: {}", msg),
CryptoError::VerificationError(msg) => write!(f, "Verification error: {}", msg),
}
}
}
impl std::error::Error for CryptoError {}
pub struct AES256GCM {
key: [u8; 32],
rng: Arc<SystemRandom>,
}
impl AES256GCM {
pub fn new() -> RiResult<Self> {
let rng = Arc::new(SystemRandom::new());
let mut key = [0u8; 32];
rng.fill(&mut key)
.map_err(|e| RiError::CryptoError(format!("Failed to generate AES key: {}", e)))?;
Ok(Self { key, rng })
}
pub fn with_key(key: [u8; 32]) -> Self {
let rng = Arc::new(SystemRandom::new());
Self { key, rng }
}
pub fn encrypt(&self, plaintext: &[u8], additional_data: Option<&[u8]>) -> RiResult<Vec<u8>> {
let key = aead::UnboundKey::new(&aead::AES_256_GCM, &self.key)
.map_err(|e| RiError::CryptoError(format!("Failed to create AES key: {}", e)))?;
let key = aead::LessSafeKey::new(key);
let nonce = self.generate_nonce()?;
let mut ciphertext = plaintext.to_vec();
ciphertext.extend_from_slice(&nonce);
key.seal_in_place_append_tag(
aead::Nonce::try_assume_unique_for_key(&nonce)
.map_err(|e| RiError::CryptoError(format!("Invalid nonce: {}", e)))?,
aead::Aad::from(additional_data.unwrap_or(&[])),
&mut ciphertext,
).map_err(|e| RiError::CryptoError(format!("Encryption failed: {}", e)))?;
Ok(ciphertext)
}
pub fn decrypt(&self, ciphertext: &[u8], additional_data: Option<&[u8]>) -> RiResult<Vec<u8>> {
if ciphertext.len() < 12 + 16 { return Err(RiError::CryptoError("Invalid ciphertext length".to_string()));
}
let nonce = &ciphertext[ciphertext.len() - 12..];
let tag = &ciphertext[ciphertext.len() - 28..ciphertext.len() - 12];
let data = &ciphertext[..ciphertext.len() - 28];
let key = aead::UnboundKey::new(&aead::AES_256_GCM, &self.key)
.map_err(|e| RiError::CryptoError(format!("Failed to create AES key: {}", e)))?;
let key = aead::LessSafeKey::new(key);
let mut plaintext = data.to_vec();
plaintext.extend_from_slice(tag);
let decrypted_len = key.open_in_place(
aead::Nonce::try_assume_unique_for_key(nonce)
.map_err(|e| RiError::CryptoError(format!("Invalid nonce: {}", e)))?,
aead::Aad::from(additional_data.unwrap_or(&[])),
&mut plaintext,
).map_err(|e| RiError::CryptoError(format!("Decryption failed: {}", e)))?;
plaintext.truncate(decrypted_len.len());
Ok(plaintext)
}
fn generate_nonce(&self) -> RiResult<[u8; 12]> {
let mut nonce = [0u8; 12];
self.rng.fill(&mut nonce)
.map_err(|e| RiError::CryptoError(format!("Failed to generate nonce: {}", e)))?;
Ok(nonce)
}
pub fn get_key(&self) -> &[u8; 32] {
&self.key
}
}
pub struct ChaCha20Poly1305 {
key: [u8; 32],
rng: Arc<SystemRandom>,
}
impl ChaCha20Poly1305 {
pub fn new() -> RiResult<Self> {
let rng = Arc::new(SystemRandom::new());
let mut key = [0u8; 32];
rng.fill(&mut key)
.map_err(|e| RiError::CryptoError(format!("Failed to generate ChaCha20 key: {}", e)))?;
Ok(Self { key, rng })
}
pub fn encrypt(&self, plaintext: &[u8], additional_data: Option<&[u8]>) -> RiResult<Vec<u8>> {
let key = aead::UnboundKey::new(&aead::CHACHA20_POLY1305, &self.key)
.map_err(|e| RiError::CryptoError(format!("Failed to create ChaCha20 key: {}", e)))?;
let key = aead::LessSafeKey::new(key);
let mut nonce = [0u8; 12];
self.rng.fill(&mut nonce)
.map_err(|e| RiError::CryptoError(format!("Failed to generate nonce: {}", e)))?;
let mut ciphertext = plaintext.to_vec();
key.seal_in_place_append_tag(
aead::Nonce::try_assume_unique_for_key(&nonce)
.map_err(|e| RiError::CryptoError(format!("Invalid nonce: {}", e)))?,
aead::Aad::from(additional_data.unwrap_or(&[])),
&mut ciphertext,
).map_err(|e| RiError::CryptoError(format!("Encryption failed: {}", e)))?;
let mut result = nonce.to_vec();
result.extend_from_slice(&ciphertext);
Ok(result)
}
pub fn decrypt(&self, ciphertext: &[u8], additional_data: Option<&[u8]>) -> RiResult<Vec<u8>> {
if ciphertext.len() < 12 {
return Err(RiError::CryptoError("Invalid ciphertext length".to_string()));
}
let (nonce, encrypted_data) = ciphertext.split_at(12);
let key = aead::UnboundKey::new(&aead::CHACHA20_POLY1305, &self.key)
.map_err(|e| RiError::CryptoError(format!("Failed to create ChaCha20 key: {}", e)))?;
let key = aead::LessSafeKey::new(key);
let mut plaintext = encrypted_data.to_vec();
let decrypted_len = key.open_in_place(
aead::Nonce::try_assume_unique_for_key(nonce)
.map_err(|e| RiError::CryptoError(format!("Invalid nonce: {}", e)))?,
aead::Aad::from(additional_data.unwrap_or(&[])),
&mut plaintext,
).map_err(|e| RiError::CryptoError(format!("Decryption failed: {}", e)))?;
plaintext.truncate(decrypted_len.len());
Ok(plaintext)
}
pub fn sign_ecdsa(&self, data: &[u8], private_key: &[u8]) -> RiResult<Vec<u8>> {
let rng = SystemRandom::new();
let key_pair = signature::EcdsaKeyPair::from_pkcs8(
&signature::ECDSA_P256_SHA256_FIXED_SIGNING,
private_key,
&rng
).map_err(|e| RiError::CryptoError(format!("Failed to create ECDSA key: {}", e)))?;
let signature = key_pair.sign(&rng, data)
.map_err(|e| RiError::CryptoError(format!("Failed to sign: {}", e)))?;
Ok(signature.as_ref().to_vec())
}
pub fn verify_ecdsa(&self, data: &[u8], signature: &[u8], public_key: &[u8]) -> RiResult<bool> {
let public_key = signature::UnparsedPublicKey::new(
&signature::ECDSA_P256_SHA256_FIXED,
public_key
);
match public_key.verify(data, signature) {
Ok(()) => Ok(true),
Err(_) => Ok(false),
}
}
pub fn sign_ed25519(&self, data: &[u8], private_key: &[u8]) -> RiResult<Vec<u8>> {
let key_pair = Ed25519KeyPair::from_pkcs8(private_key)
.map_err(|_| CryptoError::InvalidKey)?;
let signature = key_pair.sign(data);
Ok(signature.as_ref().to_vec())
}
pub fn verify_ed25519(&self, data: &[u8], signature: &[u8], public_key: &[u8]) -> RiResult<bool> {
let public_key = signature::UnparsedPublicKey::new(
&signature::ED25519,
public_key
);
match public_key.verify(data, signature) {
Ok(()) => Ok(true),
Err(_) => Ok(false),
}
}
pub fn generate_ed25519_keypair(&self) -> RiResult<(Vec<u8>, Vec<u8>)> {
let rng = SystemRandom::new();
let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng)
.map_err(|e| RiError::CryptoError(format!("Failed to generate Ed25519 key: {}", e)))?;
let key_pair = signature::Ed25519KeyPair::from_pkcs8(pkcs8_bytes.as_ref())
.map_err(|e| RiError::CryptoError(format!("Failed to parse Ed25519 key: {}", e)))?;
let public_key = key_pair.public_key().as_ref().to_vec();
let private_key = pkcs8_bytes.as_ref().to_vec();
Ok((private_key, public_key))
}
pub fn generate_ecdsa_keypair(&self) -> RiResult<(Vec<u8>, Vec<u8>)> {
let rng = SystemRandom::new();
let pkcs8_bytes = signature::EcdsaKeyPair::generate_pkcs8(
&signature::ECDSA_P256_SHA256_FIXED_SIGNING,
&rng
).map_err(|e| RiError::CryptoError(format!("Failed to generate ECDSA key: {}", e)))?;
let key_pair = signature::EcdsaKeyPair::from_pkcs8(
&signature::ECDSA_P256_SHA256_FIXED_SIGNING,
pkcs8_bytes.as_ref(),
&rng
).map_err(|e| RiError::CryptoError(format!("Failed to parse ECDSA key: {}", e)))?;
let public_key = key_pair.public_key().as_ref().to_vec();
let private_key = pkcs8_bytes.as_ref().to_vec();
Ok((private_key, public_key))
}
}
pub struct SM4Cipher {
key: [u8; 16],
rng: Arc<SystemRandom>,
}
impl SM4Cipher {
pub fn new() -> RiResult<Self> {
let rng = Arc::new(SystemRandom::new());
let mut key = [0u8; 16];
rng.fill(&mut key)
.map_err(|e| RiError::CryptoError(format!("Failed to generate SM4 key: {}", e)))?;
Ok(Self { key, rng })
}
pub fn encrypt_cbc(&self, plaintext: &[u8], iv: Option<&[u8; 16]>) -> RiResult<Vec<u8>> {
let mut iv = if let Some(iv) = iv {
*iv
} else {
let mut new_iv = [0u8; 16];
self.rng.fill(&mut new_iv)
.map_err(|e| RiError::CryptoError(format!("Failed to generate IV: {}", e)))?;
new_iv
};
let mut ciphertext = iv.to_vec();
let padded_plaintext = self.pkcs7_pad(plaintext);
for chunk in padded_plaintext.chunks(16) {
let mut block = [0u8; 16];
block.copy_from_slice(chunk);
for i in 0..16 {
block[i] ^= iv[i];
}
let encrypted_block = self.sm4_encrypt_block(&block)?;
ciphertext.extend_from_slice(&encrypted_block);
iv = encrypted_block;
}
Ok(ciphertext)
}
pub fn decrypt_cbc(&self, ciphertext: &[u8]) -> RiResult<Vec<u8>> {
if ciphertext.len() < 32 || ciphertext.len() % 16 != 0 {
return Err(RiError::CryptoError("Invalid ciphertext length".to_string()));
}
let (iv, encrypted_data) = ciphertext.split_at(16);
let mut iv = [0u8; 16];
iv.copy_from_slice(iv);
let mut plaintext = Vec::with_capacity(128);
let mut previous_iv = iv;
for chunk in encrypted_data.chunks(16) {
let mut block = [0u8; 16];
block.copy_from_slice(chunk);
let decrypted_block = self.sm4_decrypt_block(&block)?;
for i in 0..16 {
decrypted_block[i] ^= previous_iv[i];
}
plaintext.extend_from_slice(&decrypted_block);
previous_iv = block;
}
self.pkcs7_unpad(&plaintext)
}
fn sm4_encrypt_block(&self, block: &[u8; 16]) -> RiResult<[u8; 16]> {
let rk = self.expand_key();
let mut x = [
u32::from_be_bytes([block[0], block[1], block[2], block[3]]),
u32::from_be_bytes([block[4], block[5], block[6], block[7]]),
u32::from_be_bytes([block[8], block[9], block[10], block[11]]),
u32::from_be_bytes([block[12], block[13], block[14], block[15]]),
];
for i in 0..32 {
let tmp = x[0] ^ self.f_func(x[1] ^ x[2] ^ x[3] ^ rk[i]);
x[0] = x[1];
x[1] = x[2];
x[2] = x[3];
x[3] = tmp;
}
let mut result = [0u8; 16];
let final_x = [x[3], x[2], x[1], x[0]];
for (i, word) in final_x.iter().enumerate() {
let bytes = word.to_be_bytes();
result[i*4..(i+1)*4].copy_from_slice(&bytes);
}
Ok(result)
}
fn sm4_decrypt_block(&self, block: &[u8; 16]) -> RiResult<[u8; 16]> {
let rk = self.expand_key();
let mut x = [
u32::from_be_bytes([block[0], block[1], block[2], block[3]]),
u32::from_be_bytes([block[4], block[5], block[6], block[7]]),
u32::from_be_bytes([block[8], block[9], block[10], block[11]]),
u32::from_be_bytes([block[12], block[13], block[14], block[15]]),
];
for i in (0..32).rev() {
let tmp = x[3] ^ self.f_func(x[0] ^ x[1] ^ x[2] ^ rk[i]);
x[3] = x[2];
x[2] = x[1];
x[1] = x[0];
x[0] = tmp;
}
let mut result = [0u8; 16];
let final_x = [x[3], x[2], x[1], x[0]];
for (i, word) in final_x.iter().enumerate() {
let bytes = word.to_be_bytes();
result[i*4..(i+1)*4].copy_from_slice(&bytes);
}
Ok(result)
}
fn expand_key(&self) -> [u32; 32] {
let mut rk = [0u32; 32];
let mut mk = [0u32; 4];
for i in 0..4 {
mk[i] = u32::from_be_bytes([
self.key[i*4], self.key[i*4+1],
self.key[i*4+2], self.key[i*4+3]
]);
}
let fk = [0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc];
let ck = [
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279,
];
let mut k = [0u32; 36];
for i in 0..4 {
k[i] = mk[i] ^ fk[i];
}
for i in 0..32 {
k[i+4] = k[i] ^ self.f_func(k[i+1] ^ k[i+2] ^ k[i+3] ^ ck[i]);
rk[i] = k[i+4];
}
rk
}
fn f_func(&self, x: u32) -> u32 {
let sbox = [
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
];
let mut result = 0u32;
for i in 0..4 {
let byte = ((x >> (i * 8)) & 0xff) as usize;
result |= (sbox[byte] as u32) << (i * 8);
}
result ^ x.rotate_left(2) ^ x.rotate_left(10) ^ x.rotate_left(18) ^ x.rotate_left(24)
}
fn pkcs7_pad(&self, data: &[u8]) -> Vec<u8> {
let pad_len = 16 - (data.len() % 16);
let mut result = data.to_vec();
result.extend(std::iter::repeat(pad_len as u8).take(pad_len));
result
}
fn pkcs7_unpad(&self, data: &[u8]) -> RiResult<Vec<u8>> {
if data.is_empty() {
return Err(RiError::CryptoError("Empty data".to_string()));
}
let pad_len = data[data.len() - 1] as usize;
if pad_len > 16 || pad_len == 0 {
return Err(RiError::CryptoError("Invalid padding".to_string()));
}
if pad_len > data.len() {
return Err(RiError::CryptoError("Invalid padding length: padding exceeds data length".to_string()));
}
let data_len = data.len() - pad_len;
for i in 0..pad_len {
if data[data.len() - 1 - i] != pad_len as u8 {
return Err(RiError::CryptoError("Invalid padding".to_string()));
}
}
Ok(data[..data_len].to_vec())
}
}
pub struct SHA256;
impl SHA256 {
pub fn hash(data: &[u8]) -> [u8; 32] {
let mut ctx = digest::Context::new(&digest::SHA256);
ctx.update(data);
let result = ctx.finish();
let mut hash = [0u8; 32];
hash.copy_from_slice(result.as_ref());
hash
}
pub fn hmac(key: &[u8], data: &[u8]) -> [u8; 32] {
use ring::hmac;
let key = hmac::Key::new(hmac::HMAC_SHA256, key);
let tag = hmac::sign(&key, data);
let mut result = [0u8; 32];
result.copy_from_slice(tag.as_ref());
result
}
}
pub struct SHA3;
impl SHA3 {
pub fn hash256(data: &[u8]) -> [u8; 32] {
let mut ctx = digest::Context::new(&digest::SHA256);
ctx.update(data);
let result = ctx.finish();
let mut hash = [0u8; 32];
hash.copy_from_slice(result.as_ref());
hash
}
pub fn hash512(data: &[u8]) -> [u8; 64] {
let mut ctx = digest::Context::new(&digest::SHA512);
ctx.update(data);
let result = ctx.finish();
let mut hash = [0u8; 64];
hash.copy_from_slice(result.as_ref());
hash
}
}
pub struct SM3;
impl SM3 {
pub fn hash(data: &[u8]) -> [u8; 32] {
let iv = [
0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600,
0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e
];
fn sm3_compress(v: &mut [u32; 8], block: &[u8]) {
let mut w = [0u32; 68];
let mut w1 = [0u32; 64];
for i in 0..16 {
w[i] = u32::from_be_bytes([
block[i * 4], block[i * 4 + 1],
block[i * 4 + 2], block[i * 4 + 3]
]);
}
for i in 16..68 {
w[i] = w[i-16] ^ w[i-9] ^ (w[i-3].rotate_left(15)) ^ (w[i-13].rotate_left(7)) ^ (w[i-6].rotate_left(6));
}
for i in 0..64 {
w1[i] = w[i] ^ w[i+4];
}
let mut a = v[0];
let mut b = v[1];
let mut c = v[2];
let mut d = v[3];
let mut e = v[4];
let mut f = v[5];
let mut g = v[6];
let mut h = v[7];
for j in 0..64 {
let ss1 = ((a.rotate_left(12)).wrapping_add(e).wrapping_add((0x79cc4519).rotate_left(j as u32))) & 0xffffffff;
let ss1 = ss1.rotate_left(7);
let ss2 = ss1 ^ (a.rotate_left(12));
let tt1 = (ff(a, b, c, j)).wrapping_add(ss2).wrapping_add(w1[j]) & 0xffffffff;
let tt2 = (gg(e, f, g, j)).wrapping_add(ss1).wrapping_add(w[j]) & 0xffffffff;
d = c;
c = b.rotate_left(9);
b = a;
a = tt1;
h = g;
g = f.rotate_left(19);
f = e;
e = p0(tt2);
}
v[0] ^= a;
v[1] ^= b;
v[2] ^= c;
v[3] ^= d;
v[4] ^= e;
v[5] ^= f;
v[6] ^= g;
v[7] ^= h;
fn ff(x: u32, y: u32, z: u32, j: usize) -> u32 {
if j < 16 {
x ^ y ^ z
} else {
(x & y) | (x & z) | (y & z)
}
}
fn gg(x: u32, y: u32, z: u32, j: usize) -> u32 {
if j < 16 {
x ^ y ^ z
} else {
(x & y) | (!x & z)
}
}
fn p0(x: u32) -> u32 {
x ^ (x.rotate_left(9)) ^ (x.rotate_left(17))
}
}
let mut padded_data = data.to_vec();
let original_len = data.len() * 8;
padded_data.push(0x80);
while (padded_data.len() % 64) != 56 {
padded_data.push(0x00);
}
padded_data.extend_from_slice(&(original_len as u64).to_be_bytes());
let mut hash_value = iv;
for chunk in padded_data.chunks(64) {
sm3_compress(&mut hash_value, chunk);
}
let mut result = [0u8; 32];
for i in 0..8 {
let bytes = hash_value[i].to_be_bytes();
result[i * 4..(i + 1) * 4].copy_from_slice(&bytes);
}
result
}
}
pub struct ECDSASigner {
key_pair: signature::EcdsaKeyPair,
}
impl ECDSASigner {
pub fn generate() -> RiResult<Self> {
let rng = SystemRandom::new();
let pkcs8_bytes = signature::EcdsaKeyPair::generate_pkcs8(
&signature::ECDSA_P256_SHA256_FIXED_SIGNING,
&rng,
).map_err(|e| RiError::CryptoError(format!("Failed to generate ECDSA key: {}", e)))?;
let key_pair = signature::EcdsaKeyPair::from_pkcs8(
&signature::ECDSA_P256_SHA256_FIXED_SIGNING,
pkcs8_bytes.as_ref(),
).map_err(|e| RiError::CryptoError(format!("Failed to parse ECDSA key: {}", e)))?;
Ok(Self { key_pair })
}
pub fn sign(&self, message: &[u8]) -> RiResult<Vec<u8>> {
let rng = SystemRandom::new();
let signature = self.key_pair.sign(&rng, message)
.map_err(|e| RiError::CryptoError(format!("Failed to sign message: {}", e)))?;
Ok(signature.as_ref().to_vec())
}
pub fn public_key(&self) -> Vec<u8> {
self.key_pair.public_key().as_ref().to_vec()
}
}
pub struct ECDSAVerifier;
impl ECDSAVerifier {
pub fn verify(public_key: &[u8], message: &[u8], signature: &[u8]) -> RiResult<bool> {
let public_key = signature::UnparsedPublicKey::new(
&signature::ECDSA_P256_SHA256_FIXED,
public_key,
);
match public_key.verify(message, signature) {
Ok(_) => Ok(true),
Err(_) => Ok(false),
}
}
}
pub struct Ed25519Signer {
key_pair: signature::Ed25519KeyPair,
}
impl Ed25519Signer {
pub fn generate() -> RiResult<Self> {
let rng = SystemRandom::new();
let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng)
.map_err(|e| RiError::CryptoError(format!("Failed to generate Ed25519 key: {}", e)))?;
let key_pair = signature::Ed25519KeyPair::from_pkcs8(pkcs8_bytes.as_ref())
.map_err(|e| RiError::CryptoError(format!("Failed to parse Ed25519 key: {}", e)))?;
Ok(Self { key_pair })
}
pub fn sign(&self, message: &[u8]) -> RiResult<Vec<u8>> {
let signature = self.key_pair.sign(message);
Ok(signature.as_ref().to_vec())
}
pub fn public_key(&self) -> Vec<u8> {
self.key_pair.public_key().as_ref().to_vec()
}
}
pub struct ECDHKeyExchange {
private_key: agreement::EphemeralPrivateKey,
}
impl ECDHKeyExchange {
pub fn generate() -> RiResult<Self> {
let rng = SystemRandom::new();
let private_key = agreement::EphemeralPrivateKey::generate(&agreement::ECDH_P256, &rng)
.map_err(|e| RiError::CryptoError(format!("Failed to generate ECDH key: {}", e)))?;
Ok(Self { private_key })
}
pub fn compute_shared_secret(self, peer_public_key: &[u8]) -> RiResult<Vec<u8>> {
let public_key = agreement::UnparsedPublicKey::new(&agreement::ECDH_P256, peer_public_key);
agreement::agree_ephemeral(
self.private_key,
&public_key,
RiError::CryptoError("Invalid peer public key".to_string()),
|shared_secret| Ok(shared_secret.to_vec()),
).map_err(|e| RiError::CryptoError(format!("Key exchange failed: {}", e)))
}
pub fn public_key(&self) -> Vec<u8> {
self.private_key.compute_public_key()
.map_err(|e| RiError::CryptoError(format!("Failed to compute public key: {}", e)))
.unwrap_or_else(|_| Vec::new())
}
}
pub struct X25519KeyExchange {
private_key: agreement::EphemeralPrivateKey,
}
impl X25519KeyExchange {
pub fn generate() -> RiResult<Self> {
let rng = SystemRandom::new();
let private_key = agreement::EphemeralPrivateKey::generate(&agreement::X25519, &rng)
.map_err(|e| RiError::CryptoError(format!("Failed to generate X25519 key: {}", e)))?;
Ok(Self { private_key })
}
pub fn compute_shared_secret(self, peer_public_key: &[u8]) -> RiResult<Vec<u8>> {
let public_key = agreement::UnparsedPublicKey::new(&agreement::X25519, peer_public_key);
agreement::agree_ephemeral(
self.private_key,
&public_key,
RiError::CryptoError("Invalid peer public key".to_string()),
|shared_secret| Ok(shared_secret.to_vec()),
).map_err(|e| RiError::CryptoError(format!("Key exchange failed: {}", e)))
}
pub fn public_key(&self) -> Vec<u8> {
self.private_key.compute_public_key()
.map_err(|e| RiError::CryptoError(format!("Failed to compute public key: {}", e)))
.unwrap_or_else(|_| Vec::new())
}
}
pub struct SecureRNG {
rng: SystemRandom,
}
impl SecureRNG {
pub fn new() -> Self {
Self {
rng: SystemRandom::new(),
}
}
pub fn generate(&self, len: usize) -> RiResult<Vec<u8>> {
let mut bytes = vec![0u8; len];
self.rng.fill(&mut bytes)
.map_err(|e| RiError::CryptoError(format!("Failed to generate random bytes: {}", e)))?;
Ok(bytes)
}
pub fn generate_u32(&self) -> RiResult<u32> {
let mut bytes = [0u8; 4];
self.rng.fill(&mut bytes)
.map_err(|e| RiError::CryptoError(format!("Failed to generate random u32: {}", e)))?;
Ok(u32::from_le_bytes(bytes))
}
pub fn generate_u64(&self) -> RiResult<u64> {
let mut bytes = [0u8; 8];
self.rng.fill(&mut bytes)
.map_err(|e| RiError::CryptoError(format!("Failed to generate random u64: {}", e)))?;
Ok(u64::from_le_bytes(bytes))
}
}
#[cfg(test)]
mod crypto_tests {
use super::*;
#[test]
fn test_aes256_gcm_encrypt_decrypt() {
let key = [0u8; 32];
let nonce = [0u8; 12];
let cipher = DMSAes256Gcm::new(&key, &nonce);
let plaintext = b"Hello, World!";
let ciphertext = cipher.encrypt(plaintext, None).unwrap();
assert_ne!(ciphertext[..12], plaintext);
let decrypted = cipher.decrypt(&ciphertext[12..], None).unwrap();
assert_eq!(&decrypted, plaintext);
}
#[test]
fn test_aes256_gcm_with_aad() {
let key = [0u8; 32];
let nonce = [0u8; 12];
let aad = b"additional data";
let cipher = DMSAes256Gcm::new(&key, &nonce);
let plaintext = b"Secret message";
let ciphertext = cipher.encrypt(plaintext, Some(aad)).unwrap();
let decrypted = cipher.decrypt(&ciphertext[12..], Some(aad)).unwrap();
assert_eq!(&decrypted, plaintext);
}
#[test]
fn test_aes256_gcm_different_keys() {
let key1 = [0u8; 32];
let key2 = [1u8; 32];
let nonce = [0u8; 12];
let cipher1 = DMSAes256Gcm::new(&key1, &nonce);
let cipher2 = DMSAes256Gcm::new(&key2, &nonce);
let plaintext = b"Test message";
let ciphertext1 = cipher1.encrypt(plaintext, None).unwrap();
let ciphertext2 = cipher2.encrypt(plaintext, None).unwrap();
assert_ne!(ciphertext1, ciphertext2);
}
#[test]
fn test_chacha20_poly1305_encrypt_decrypt() {
let key = [0u8; 32];
let nonce = [0u8; 12];
let cipher = RiChacha20Poly1305::new(&key, &nonce);
let plaintext = b"ChaCha20 Poly1305 test";
let ciphertext = cipher.encrypt(plaintext, None).unwrap();
assert_ne!(ciphertext[..12], plaintext);
let decrypted = cipher.decrypt(&ciphertext[12..], None).unwrap();
assert_eq!(&decrypted, plaintext);
}
#[test]
fn test_sm4_cbc_encrypt_decrypt() {
let key = [0u8; 16];
let cipher = RiSM4Cbc::new(&key);
let plaintext = b"SM4 CBC test message with padding";
let ciphertext = cipher.encrypt(plaintext).unwrap();
let decrypted = cipher.decrypt(&ciphertext).unwrap();
assert_eq!(&decrypted, plaintext);
}
#[test]
fn test_sm4_cbc_padding() {
let key = [0u8; 16];
let cipher = RiSM4Cbc::new(&key);
let plaintext = b"Exactly16bytes!!";
let ciphertext = cipher.encrypt(plaintext).unwrap();
let decrypted = cipher.decrypt(&ciphertext).unwrap();
assert_eq!(&decrypted, plaintext);
let plaintext = b"Exactly15bytes";
let ciphertext = cipher.encrypt(plaintext).unwrap();
let decrypted = cipher.decrypt(&ciphertext).unwrap();
assert_eq!(&decrypted, plaintext);
}
#[test]
fn test_hmac_sha256() {
let key = b"test_key";
let data = b"test_data";
let hmac = RiHmac::hmac_sha256(key, data);
assert_eq!(hmac.len(), 32);
let hmac2 = RiHmac::hmac_sha256(key, data);
assert_eq!(hmac, hmac2);
let hmac3 = RiHmac::hmac_sha256(b"different_key", data);
assert_ne!(hmac, hmac3);
}
#[test]
fn test_pbkdf2_derivation() {
let password = "test_password";
let salt = b"unique_salt";
let iterations = 1000;
let output_len = 32;
let derived = RiPbkdf2::derive_key(password, salt, iterations, output_len);
assert_eq!(derived.len(), output_len);
let derived2 = RiPbkdf2::derive_key(password, salt, iterations, output_len);
assert_eq!(derived, derived2);
let derived3 = RiPbkdf2::derive_key(password, salt, iterations + 1, output_len);
assert_ne!(derived, derived3);
}
#[test]
fn test_scrypt_derivation() {
let password = "test_password";
let salt = b"unique_salt";
let params = RiSCRYPTParams::standard();
let derived = RiScrypt::derive_key(password, salt, ¶ms);
assert_eq!(derived.len(), 64);
let derived2 = RiScrypt::derive_key(password, salt, ¶ms);
assert_eq!(derived, derived2);
}
#[test]
fn test_x25519_key_exchange() {
let alice_private = RiPrivateKey::generate_x25519();
let bob_private = RiPrivateKey::generate_x25519();
let alice_public = alice_private.public_key_x25519();
let bob_public = bob_private.public_key_x25519();
let alice_shared = alice_private.x25519_agree(&bob_public).unwrap();
let bob_shared = bob_private.x25519_agree(&alice_public).unwrap();
assert_eq!(alice_shared, bob_shared);
}
#[test]
fn test_random_bytes_generation() {
let rng = RiRandom::new();
let bytes1 = rng.generate(32).unwrap();
let bytes2 = rng.generate(32).unwrap();
assert_ne!(bytes1, bytes2);
assert_ne!(bytes1, vec![0u8; 32]);
}
}
pub use self::crypto::RiCryptoEngine;
pub use self::crypto::CryptoError;