70 lines
2.1 KiB
Rust
70 lines
2.1 KiB
Rust
use anyhow::Result;
|
|
use rs_merkle::{algorithms::Sha256, MerkleProof};
|
|
use sp_client::silentpayments::{
|
|
bitcoin_hashes::{sha256t_hash_newtype, Hash, HashEngine},
|
|
secp256k1::PublicKey,
|
|
};
|
|
|
|
use aes_gcm::aead::{Aead, Payload};
|
|
pub use aes_gcm::{AeadCore, Aes256Gcm, KeyInit};
|
|
use rand::{thread_rng, CryptoRng, RngCore};
|
|
|
|
pub const AAD: &[u8] = "4nk".as_bytes();
|
|
|
|
sha256t_hash_newtype! {
|
|
pub struct AnkSharedSecretTag = hash_str("4nk/AnkSharedSecret");
|
|
|
|
#[hash_newtype(forward)]
|
|
pub struct AnkSharedSecretHash(_);
|
|
}
|
|
|
|
impl AnkSharedSecretHash {
|
|
pub fn from_shared_point(shared_point: PublicKey) -> Self {
|
|
let mut eng = AnkSharedSecretHash::engine();
|
|
eng.input(&shared_point.serialize_uncompressed()[1..]);
|
|
AnkSharedSecretHash::from_engine(eng)
|
|
}
|
|
}
|
|
|
|
pub fn generate_key(rng: &mut (impl CryptoRng + RngCore)) -> [u8; 32] {
|
|
let key = Aes256Gcm::generate_key(rng);
|
|
key.into()
|
|
}
|
|
|
|
pub fn encrypt_with_key(key: &[u8; 32], plaintext: &[u8]) -> Result<Vec<u8>> {
|
|
let encryption_eng = Aes256Gcm::new(key.into());
|
|
let nonce = Aes256Gcm::generate_nonce(&mut thread_rng());
|
|
let payload = Payload {
|
|
msg: plaintext,
|
|
aad: AAD,
|
|
};
|
|
let ciphertext = encryption_eng
|
|
.encrypt(&nonce, payload)
|
|
.map_err(|e| anyhow::anyhow!(e))?;
|
|
|
|
let mut res: Vec<u8> = Vec::with_capacity(nonce.len() + ciphertext.len());
|
|
res.extend_from_slice(&nonce);
|
|
res.extend_from_slice(&ciphertext);
|
|
|
|
Ok(res)
|
|
}
|
|
|
|
pub fn decrypt_with_key(key: &[u8; 32], ciphertext: &[u8]) -> Result<Vec<u8>> {
|
|
let decryption_eng = Aes256Gcm::new(key.into());
|
|
let nonce = &ciphertext[..12];
|
|
let payload = Payload {
|
|
msg: &ciphertext[12..],
|
|
aad: AAD,
|
|
};
|
|
let plaintext = decryption_eng
|
|
.decrypt(nonce.into(), payload)
|
|
.map_err(|e| anyhow::anyhow!(e))?;
|
|
|
|
Ok(plaintext)
|
|
}
|
|
|
|
pub fn verify_merkle_proof(proof: &[u8], root: &[u8; 32], index: usize, hash: &[u8; 32], total_leaves_count: usize) -> Result<bool> {
|
|
let proof = MerkleProof::<Sha256>::from_bytes(proof)?;
|
|
Ok(proof.verify(*root, &[index], &[*hash], total_leaves_count))
|
|
}
|