core_crypto/
block_cipher.rs1use anyhow::Result;
10use curve25519::edwards::CompressedEdwardsY;
11use curve25519::scalar::Scalar;
12use sha3::Digest;
13
14use super::{PrivateKey, PublicKey, SharedSecret, H256, KEY_BYTES_SIZE};
15
16pub trait BlockCipher: Sized {
19 fn encrypt_message(
20 signer_sk: &[u8; KEY_BYTES_SIZE],
21 receiver_pk: &[u8; KEY_BYTES_SIZE],
22 msg: &[u8],
23 ) -> Result<Vec<u8>>;
24
25 fn decrypt_message(
26 receiver_sk: &[u8; KEY_BYTES_SIZE],
27 signer_pk: &[u8; KEY_BYTES_SIZE],
28 enc_msg: &[u8],
29 ) -> Result<Vec<u8>>;
30}
31
32pub fn derive_shared_secret<D: Digest>(
34 secret_key: PrivateKey,
35 public_key: PublicKey,
36) -> SharedSecret {
37 let public = CompressedEdwardsY::from_slice(public_key.as_ref())
38 .decompress()
39 .unwrap();
40
41 let secret = scalar_from_sk::<D>(secret_key);
42
43 let shared_point = secret * &(public);
44 let shared_point_compressed = shared_point.compress();
45 SharedSecret::from(shared_point_compressed.as_bytes())
46}
47
48fn scalar_from_sk<D: Digest>(secret_key: PrivateKey) -> Scalar {
50 let sk_hash = D::digest(secret_key.as_bytes());
51
52 let mut sk_hash_fix: H256 = H256::default();
53 sk_hash_fix.assign_from_slice(&sk_hash.as_slice()[0..32]);
54
55 sk_hash_fix.0[0] &= 0xF8; sk_hash_fix.0[31] &= 0x7F; sk_hash_fix.0[31] |= 0x40; Scalar::from_bits(sk_hash_fix.into())
60}