#![allow(
clippy::print_stdout,
clippy::missing_assert_message,
clippy::panic_in_result_fn,
clippy::indexing_slicing,
clippy::uninlined_format_args,
clippy::useless_vec,
unused_crate_dependencies,
reason = "runnable demo: stdout output is the whole point, panic-on-failure is acceptable in a script-like context, and the binary inherits the lib's dep set"
)]
use nula_core::Keys;
use nula_core::limits::{NIP44_MAX_PLAINTEXT_BYTES, NIP44_MIN_PLAINTEXT_BYTES};
use nula_core::nips::nip44;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let alice = Keys::generate()?;
let bob = Keys::generate()?;
println!(
"plaintext bounds : {NIP44_MIN_PLAINTEXT_BYTES} ..= {NIP44_MAX_PLAINTEXT_BYTES} bytes"
);
println!("alice : {}", alice.public_key().to_hex());
println!("bob : {}", bob.public_key().to_hex());
let plaintext = "🌶 nip-44 v2 — authenticated, padded, secure.";
let payload = nip44::encrypt(alice.secret_key(), bob.public_key(), plaintext)?;
println!("payload bytes : {}", payload.len());
let recovered = nip44::decrypt(bob.secret_key(), alice.public_key(), &payload)?;
assert_eq!(
plaintext, recovered,
"round-trip MUST preserve the plaintext"
);
println!("round-trip : OK");
let twice = nip44::encrypt(alice.secret_key(), bob.public_key(), plaintext)?;
assert_ne!(payload, twice, "every NIP-44 payload MUST be unique");
println!("nonce uniqueness : OK");
let mallory = Keys::generate()?;
let err = nip44::decrypt(mallory.secret_key(), alice.public_key(), &payload);
println!("wrong-key error : {err:?}");
assert!(err.is_err(), "decryption MUST fail for a wrong recipient");
let empty = nip44::encrypt(alice.secret_key(), bob.public_key(), "");
println!("empty rejected : {empty:?}");
assert!(empty.is_err(), "empty plaintext MUST be rejected");
Ok(())
}