From 335d18bfbc63bf366137fb4a35959d15cc26885b Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Tue, 22 Nov 2022 15:29:04 +0100 Subject: [PATCH] Simplified hashing and signing API --- src/crypto/mod.rs | 18 ++++++++++++++++++ src/dec/mod.rs | 4 ++-- src/lib.rs | 21 +++++++++++---------- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/crypto/mod.rs b/src/crypto/mod.rs index 01d9afa..82b726b 100644 --- a/src/crypto/mod.rs +++ b/src/crypto/mod.rs @@ -19,3 +19,21 @@ impl enc::Encode for sign::SigningKeyPair { Ok(enc::bytes(self.secret_key.as_slice())) } } + + +// ---- helpers ---- + +/// Compute the hash of a payload with default dryoc parameters and optionnal key +pub fn compute_hash(bytes: &[u8], key: Option<&[u8; 32]>) -> generichash::Hash { + generichash::GenericHash::hash_with_defaults(bytes, key).unwrap() +} + +/// Compute the ed25519 signature of a message using a secret key +pub fn compute_signature(message: &[u8], secret_key: &sign::SecretKey) -> sign::Signature { + SigningKeyPair::from_secret_key(secret_key.clone()).sign_with_defaults(message).unwrap().into_parts().0 +} + +/// Verify the ed25519 signature of a message using a public key +pub fn verify_signature(signature: &sign::Signature, message: &[u8], public_key: &sign::PublicKey) -> bool { + sign::SignedMessage::from_parts(signature.clone(), message).verify(public_key).is_ok() +} diff --git a/src/dec/mod.rs b/src/dec/mod.rs index a45793a..827c268 100644 --- a/src/dec/mod.rs +++ b/src/dec/mod.rs @@ -458,9 +458,9 @@ impl<'a, 'b> Term<'a, 'b> { /// }").unwrap(); /// let [msg, hash] = term.dict_of(["message", "hash"], false).unwrap(); /// let expected_hash = GenericHash::hash_with_defaults(msg.raw(), None::<&Vec>).unwrap(); - /// assert_eq!(hash.b2sum().unwrap(), expected_hash); + /// assert_eq!(hash.hash().unwrap(), expected_hash); /// ``` - pub fn b2sum(&self) -> Result { + pub fn hash(&self) -> Result { Ok(crypto::generichash::Hash::from(self.bytes_exact()?)) } diff --git a/src/lib.rs b/src/lib.rs index 0fed495..6dd26fc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,7 @@ //! ``` //! use nettext::enc::*; //! use nettext::dec::*; -//! use nettext::crypto::{SigningKeyPair, generichash::{Hash, GenericHash}, sign::{Signature, SignedMessage}}; +//! use nettext::crypto::*; //! //! let final_payload = { //! let keypair = SigningKeyPair::gen_with_defaults(); @@ -22,8 +22,8 @@ //! ]).unwrap().encode(); //! eprintln!("{}", std::str::from_utf8(&signed_payload).unwrap()); //! -//! let hash: Hash = GenericHash::hash_with_defaults(&signed_payload, None::<&Vec>).unwrap(); -//! let (sign, _) = keypair.sign_with_defaults(&signed_payload[..]).unwrap().into_parts(); +//! let hash = compute_hash(&signed_payload, None); +//! let sign = compute_signature(&signed_payload[..], &keypair.secret_key); //! //! // Encode a second object that represents the signed and hashed payload //! dict([ @@ -37,16 +37,16 @@ //! // Decode and check everything is fine //! let signed_object = decode(&final_payload).unwrap(); //! let [hash, signature, payload] = signed_object.dict_of(["hash", "signature", "payload"], false).unwrap(); -//! let hash = hash.b2sum().unwrap(); +//! let hash = hash.hash().unwrap(); //! let signature = signature.signature().unwrap(); -//! let expected_hash = GenericHash::hash_with_defaults(payload.raw(), None::<&Vec>).unwrap(); +//! let expected_hash = compute_hash(payload.raw(), None); //! assert_eq!(hash, expected_hash); //! //! let object2 = decode(payload.raw()).unwrap(); //! //! let [verb, arg1, arg2, pubkey] = object2.list_of().unwrap(); //! let pubkey = pubkey.public_key().unwrap(); -//! assert!(SignedMessage::from_parts(signature, payload.raw()).verify(&pubkey).is_ok()); +//! assert!(verify_signature(&signature, payload.raw(), &pubkey)); //! //! assert_eq!(verb.string().unwrap(), "CALL"); //! assert_eq!(arg1.string().unwrap(), "myfunction"); @@ -55,6 +55,7 @@ //! The value of `text1` would be as follows: //! //! ```raw +//! //! CALL myfunction { //! a = hello, //! b = world, @@ -62,13 +63,13 @@ //! d = AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4v //! MDEyMzQ1Njc4OTo7PD0-P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5f //! YGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8, -//! } 1hUAS2C0lzHXHWIvXqwuhUYVPlu3BbZ7ANLUMH_OYjo +//! } M3_to5OQ5TvIVyoRXTSK4Jz-zvSqsuh3a68haud_8Vs //! ``` //! //! And the value of `text2` would be as follows: //! ```raw //! { -//! hash = Se6Wmbh3fbFQ9_ilE6zGbxNaEd9v5CHAb30p46Fxpi74iblRb9fXmGAiMkXnSe4DePTwb16zGAz_Ux4ZAG9s3w, +//! hash = Hxpas10VnFIq8WIWGmQk7YLbxT-OMIkg0-sKSBJnUuo, //! payload = CALL myfunction { //! a = hello, //! b = world, @@ -76,8 +77,8 @@ //! d = AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4v //! MDEyMzQ1Njc4OTo7PD0-P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5f //! YGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8, -//! } 1hUAS2C0lzHXHWIvXqwuhUYVPlu3BbZ7ANLUMH_OYjo, -//! signature = 8mo3aeQD7JAdqbDcm7oVdaU0XamDwg03JtC3mfsWhEy_ZkNmWBFZefIDlzBR3XpnF0szTzEwtoPFfnR1fz6fAA, +//! } M3_to5OQ5TvIVyoRXTSK4Jz-zvSqsuh3a68haud_8Vs, +//! signature = DAgQDqxi6rDEkGVoUmfHexWUCFYKNbQR0Fgp3_EiaMxiFLeQdy3w3If_lsYqDDmWHYR51whfaNGQZ6PxVthMAA, //! } //! ``` //!