[Fix] Hopefully Iota - Omikron comms work now.

[todo] fix Omikron - Omega comms
This commit is contained in:
Alex Emmet 2026-03-26 02:03:13 +01:00
commit 60c980ba9a
9 changed files with 493 additions and 89 deletions

View file

@ -4,12 +4,12 @@ use aes_gcm::{
};
use base64::{Engine as _, engine::general_purpose::STANDARD as BASE64_STD};
use hkdf::Hkdf;
use sha2::{Digest, Sha256};
type HkdfSha256 = sha2::Sha256;
use sha2::{Digest, Sha256 as HashSha256};
use x448::{PublicKey, Secret};
// --- Custom Errors ---
#[allow(dead_code)]
#[derive(Debug)]
#[allow(dead_code)]
pub enum SecurePayloadError {
InvalidBase64,
InvalidHex,
@ -18,9 +18,8 @@ pub enum SecurePayloadError {
InvalidKeyLength,
}
// --- Data Format Enum ---
#[allow(dead_code)]
#[derive(Clone, Copy, Debug)]
#[allow(dead_code)]
pub enum DataFormat {
Raw,
Base64,
@ -41,8 +40,8 @@ impl Clone for SecurePayload {
}
}
#[allow(dead_code)]
impl SecurePayload {
/// Clear Constructor: Takes data in any format and the user's private key.
pub fn new<S, T: AsRef<[u8]>>(
data: T,
format: DataFormat,
@ -67,13 +66,10 @@ impl SecurePayload {
})
}
/// Helper to get the public key associated with this instance's private key.
#[allow(dead_code)]
pub fn get_public_key(&self) -> [u8; 56] {
*PublicKey::from(&self.private_key).as_bytes()
}
/// Exports the internal data to the requested format
pub fn export(&self, format: DataFormat) -> String {
match format.into() {
DataFormat::Raw => String::from_utf8_lossy(&self.inner_data).to_string(),
@ -82,16 +78,12 @@ impl SecurePayload {
}
}
/// Access raw bytes directly
#[allow(dead_code)]
pub fn get_bytes(&self) -> &[u8] {
&self.inner_data
}
/// Returns the SHA-256 Hash of the data in the requested format
#[allow(dead_code)]
pub fn get_hash(&self, format: DataFormat) -> String {
let mut hasher = Sha256::new();
let mut hasher = HashSha256::new();
hasher.update(&self.inner_data);
let result = hasher.finalize();
@ -102,8 +94,6 @@ impl SecurePayload {
}
}
/// Encrypts the held data for a specific recipient using AES-256-GCM.
/// The message will contain ONLY the ciphertext.
pub fn encrypt_x448<S>(&self, public_key: S) -> Result<SecurePayload, SecurePayloadError>
where
S: Into<PublicKey>,
@ -111,8 +101,9 @@ impl SecurePayload {
let peer_pub = public_key.into();
let shared_secret = self.private_key.as_diffie_hellman(&peer_pub).unwrap();
let hkdf = Hkdf::<Sha256>::new(None, shared_secret.as_bytes());
let hkdf = Hkdf::<HkdfSha256>::new(None, shared_secret.as_bytes());
let mut okm = [0u8; 44];
hkdf.expand(b"x448-aes-gcm-no-overhead", &mut okm)
.map_err(|_| SecurePayloadError::EncryptionError)?;
@ -138,26 +129,27 @@ impl SecurePayload {
})
}
/// Decrypts the held data providing the sender's public key manually.
#[allow(dead_code)]
pub fn decrypt_to_format(
&self,
peer_public_key_bytes: &[u8; 56],
output_format: DataFormat,
) -> Result<String, SecurePayloadError> {
let decrypted_instance = self.decrypt_x448(peer_public_key_bytes)?;
let decrypted_instance =
self.decrypt_x448(PublicKey::from_bytes(peer_public_key_bytes).unwrap())?;
Ok(decrypted_instance.export(output_format))
}
/// Decrypts the held data using the internal Private Key and the provided Peer Public Key.
pub fn decrypt_x448(
pub fn decrypt_x448<S>(
&self,
peer_public_key_bytes: &[u8; 56],
) -> Result<SecurePayload, SecurePayloadError> {
let peer_pub = PublicKey::from_bytes(peer_public_key_bytes).unwrap();
peer_public_key_bytes: S,
) -> Result<SecurePayload, SecurePayloadError>
where
S: Into<PublicKey>,
{
let peer_pub = peer_public_key_bytes.into();
let shared_secret = self.private_key.as_diffie_hellman(&peer_pub).unwrap();
let hkdf = Hkdf::<Sha256>::new(None, shared_secret.as_bytes());
let hkdf = Hkdf::<HkdfSha256>::new(None, shared_secret.as_bytes());
let mut okm = [0u8; 44];
hkdf.expand(b"x448-aes-gcm-no-overhead", &mut okm)
.map_err(|_| SecurePayloadError::DecryptionError)?;