use bitcoin::secp256k1::{PublicKey, SecretKey};
pub fn encrypt_ecies(public_key: &PublicKey, message: &[u8]) -> Result<Vec<u8>, &'static str> {
let pk_bytes = public_key.serialize();
ecies::encrypt(&pk_bytes, message).map_err(|_| "ECIES encryption failed")
}
pub fn decrypt_ecies(secret_key: SecretKey, ciphertext: &[u8]) -> Result<Vec<u8>, &'static str> {
let sk_bytes = secret_key.secret_bytes();
::ecies::decrypt(&sk_bytes, ciphertext).map_err(|_| "ECIES decryption failed")
}
#[cfg(test)]
mod tests {
use super::*;
use bitcoin::secp256k1::rand::rngs::OsRng;
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
use rand::RngCore;
#[test]
fn test_encrypt_decrypt() {
let secp = Secp256k1::new();
let mut rng = OsRng;
let receiver_secret_key = SecretKey::new(&mut rng);
let receiver_public_key = PublicKey::from_secret_key(&secp, &receiver_secret_key);
let plaintext = b"This is a test message for ECIES encryption";
let ciphertext = encrypt_ecies(&receiver_public_key, plaintext).unwrap();
let decrypted = decrypt_ecies(receiver_secret_key, &ciphertext).unwrap();
assert_eq!(plaintext.to_vec(), decrypted);
}
#[test]
fn test_decrypt_secret_key() {
let secp = Secp256k1::new();
let mut rng = OsRng;
let identity_secret_key = SecretKey::new(&mut rng);
let identity_public_key = PublicKey::from_secret_key(&secp, &identity_secret_key);
let new_secret_key = SecretKey::new(&mut rng);
let ciphertext =
encrypt_ecies(&identity_public_key, &new_secret_key.secret_bytes()).unwrap();
let decrypted_bytes = decrypt_ecies(identity_secret_key, &ciphertext).unwrap();
let decrypted_secret_key = SecretKey::from_slice(&decrypted_bytes).unwrap();
assert_eq!(new_secret_key, decrypted_secret_key);
}
#[test]
fn test_empty_message() {
let secp = Secp256k1::new();
let mut rng = OsRng;
let secret_key = SecretKey::new(&mut rng);
let public_key = PublicKey::from_secret_key(&secp, &secret_key);
let empty_message = b"";
let ciphertext = encrypt_ecies(&public_key, empty_message).unwrap();
let decrypted = decrypt_ecies(secret_key, &ciphertext).unwrap();
assert_eq!(empty_message.to_vec(), decrypted);
}
#[test]
fn test_large_message() {
let secp = Secp256k1::new();
let mut rng = OsRng;
let secret_key = SecretKey::new(&mut rng);
let public_key = PublicKey::from_secret_key(&secp, &secret_key);
let large_message = vec![0xAA; 100 * 1024];
let ciphertext = encrypt_ecies(&public_key, &large_message).unwrap();
let decrypted = decrypt_ecies(secret_key, &ciphertext).unwrap();
assert_eq!(large_message, decrypted);
}
#[test]
fn test_binary_data() {
let secp = Secp256k1::new();
let mut rng = OsRng;
let secret_key = SecretKey::new(&mut rng);
let public_key = PublicKey::from_secret_key(&secp, &secret_key);
let binary_data: Vec<u8> = (0..=255).collect();
let ciphertext = encrypt_ecies(&public_key, &binary_data).unwrap();
let decrypted = decrypt_ecies(secret_key, &ciphertext).unwrap();
assert_eq!(binary_data, decrypted);
}
#[test]
fn test_different_key_fails() {
let secp = Secp256k1::new();
let mut rng = OsRng;
let secret_key1 = SecretKey::new(&mut rng);
let public_key1 = PublicKey::from_secret_key(&secp, &secret_key1);
let secret_key2 = SecretKey::new(&mut rng);
let message = b"This message should not be decryptable with the wrong key";
let ciphertext = encrypt_ecies(&public_key1, message).unwrap();
let decrypted = decrypt_ecies(secret_key2, &ciphertext);
assert!(decrypted.is_err());
}
#[test]
fn test_invalid_ciphertext() {
let mut rng = OsRng;
let secret_key = SecretKey::new(&mut rng);
let result = decrypt_ecies(secret_key, &[1, 2, 3]);
assert!(result.is_err());
let mut invalid_ciphertext = vec![0; 33 + 10]; rng.fill_bytes(&mut invalid_ciphertext); let result = decrypt_ecies(secret_key, &invalid_ciphertext);
assert!(result.is_err());
}
#[test]
fn test_tampered_ciphertext() {
let secp = Secp256k1::new();
let mut rng = OsRng;
let secret_key = SecretKey::new(&mut rng);
let public_key = PublicKey::from_secret_key(&secp, &secret_key);
let message = b"This is a secret message";
let mut ciphertext = encrypt_ecies(&public_key, message).unwrap();
if ciphertext.len() > 40 {
ciphertext[40] ^= 0xFF;
}
let decrypted = decrypt_ecies(secret_key, &ciphertext);
assert!(decrypted.is_err());
}
}