From 5dca575b4806ee672549df63a52f764b465b9c1e Mon Sep 17 00:00:00 2001 From: hyunggilwoo Date: Sun, 8 Dec 2024 12:02:59 -0800 Subject: [PATCH 1/3] Added updated finalize feature. --- src/lib.rs | 4 ++++ src/ops.rs | 45 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index e792e09..16eab43 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -226,6 +226,10 @@ pub trait Signable { fn verify(&mut self, pub_key: &ExtendedPoint) -> Result<(), OperationError>; } +pub trait UpdateFinalize { + fn update(&mut self, data: &[u8]); + fn finalize(&mut self) -> Result<(), OperationError>; +} const RATE_IN_BYTES: usize = 136; // SHA3-256 r = 1088 / 8 = 136 #[cfg(test)] diff --git a/src/ops.rs b/src/ops.rs index c29b1d6..cbc4743 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -19,7 +19,7 @@ use crate::{ }, AesEncryptable, BitLength, Capacity, Hashable, KeyEncryptable, KeyPair, Message, OperationError, OutputLength, Rate, SecParam, Signable, Signature, SpongeEncryptable, - RATE_IN_BYTES, + UpdateFinalize, RATE_IN_BYTES, }; use rayon::prelude::*; use tiny_ed448_goldilocks::curve::{extended_edwards::ExtendedPoint, field::scalar::Scalar}; @@ -883,6 +883,30 @@ impl AesEncryptable for Message { } } +impl UpdateFinalize for Message { + fn update(&mut self, data: &[u8]) { + self.msg.append(&mut data.to_vec()); + } + /// # Finalizes the message by computing the keyed hash of the message. + /// ## Replaces: + /// ## Usage: + /// ``` + /// use capycrypt::{Message, SecParam,UpdateFinalize}; + /// let mut m = Message::new(vec![]); + /// m.d = &D256; + /// m.update("foo"); + /// m.update("bar"); + /// m.update("baz"); + /// assert_eq!(m.finalize(), vec!["foobarbaz"].compute_hash_sha3(&SecParam::D256)); + /// ``` + fn finalize(&mut self) -> Result<(), OperationError> { + + match self.d { + Some(d) => self.compute_hash_sha3(&d), + None => Err(OperationError::UnsupportedSecurityParameter) + } + } +} /// /// TESTS /// @@ -1165,3 +1189,22 @@ mod shake_tests { .unwrap_or(false)); } } + +#[cfg(test)] +mod updateFinalize_tests { + use crate::{ops::UpdateFinalize, Hashable, Message, SecParam::D256}; + #[test] + fn test_updated_message_256() { + let mut m = Message::new(vec![]); + m.d = Some(D256); + m.update(b"foo"); + m.update(b"bar"); + m.update(b"baz"); + + let mut expected = Message::new(b"foobarbaz".to_vec()); + expected.compute_hash_sha3(&D256); + + m.finalize(); + assert_eq!(m.finalize(), expected); + } +} \ No newline at end of file From 04ecc6af725640982b2d61e0a2f1d136b64b4f57 Mon Sep 17 00:00:00 2001 From: hyunggilwoo Date: Sun, 8 Dec 2024 15:23:53 -0800 Subject: [PATCH 2/3] Test case for finalize passes the D256 parameter. --- src/ops.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ops.rs b/src/ops.rs index cbc4743..0b7dc1d 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -903,8 +903,9 @@ impl UpdateFinalize for Message { match self.d { Some(d) => self.compute_hash_sha3(&d), - None => Err(OperationError::UnsupportedSecurityParameter) + None => Err(OperationError::UnsupportedSecurityParameter) } + } } /// @@ -1191,7 +1192,7 @@ mod shake_tests { } #[cfg(test)] -mod updateFinalize_tests { +mod update_finalize_tests { use crate::{ops::UpdateFinalize, Hashable, Message, SecParam::D256}; #[test] fn test_updated_message_256() { @@ -1202,9 +1203,7 @@ mod updateFinalize_tests { m.update(b"baz"); let mut expected = Message::new(b"foobarbaz".to_vec()); - expected.compute_hash_sha3(&D256); - m.finalize(); - assert_eq!(m.finalize(), expected); + assert_eq!(m.finalize(), expected.compute_hash_sha3(&D256)); } } \ No newline at end of file From 5697a664eaecfd46b799f999d735a19195986d0a Mon Sep 17 00:00:00 2001 From: hyunggilwoo Date: Mon, 9 Dec 2024 09:59:24 -0800 Subject: [PATCH 3/3] fn finalize has a single parameter of output_length. --- src/lib.rs | 2 +- src/ops.rs | 23 ++++++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 16eab43..8bff5d5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -228,7 +228,7 @@ pub trait Signable { pub trait UpdateFinalize { fn update(&mut self, data: &[u8]); - fn finalize(&mut self) -> Result<(), OperationError>; + fn finalize(&mut self, output_length: u64) -> Result<(), OperationError>; } const RATE_IN_BYTES: usize = 136; // SHA3-256 r = 1088 / 8 = 136 diff --git a/src/ops.rs b/src/ops.rs index 0b7dc1d..e34baf2 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -897,15 +897,20 @@ impl UpdateFinalize for Message { /// m.update("foo"); /// m.update("bar"); /// m.update("baz"); - /// assert_eq!(m.finalize(), vec!["foobarbaz"].compute_hash_sha3(&SecParam::D256)); + /// assert_eq!(m.finalize(m.len()), vec!["foobarbaz"].compute_hash_sha3(&SecParam::D256)); /// ``` - fn finalize(&mut self) -> Result<(), OperationError> { - + fn finalize(&mut self, output_length: u64) -> Result<(), OperationError> { match self.d { - Some(d) => self.compute_hash_sha3(&d), - None => Err(OperationError::UnsupportedSecurityParameter) - } - + Some(d) => { + // Compute the SHA3 hash of accumulated message + self.compute_hash_sha3(&d)?; + + self.digest = cshake(&self.msg , output_length, "", "", &d); + Ok(()) + }, + None => Err(OperationError::UnsupportedSecurityParameter) + } + } } /// @@ -1203,7 +1208,7 @@ mod update_finalize_tests { m.update(b"baz"); let mut expected = Message::new(b"foobarbaz".to_vec()); - - assert_eq!(m.finalize(), expected.compute_hash_sha3(&D256)); + let output_length = m.msg.len() as u64 * 8; + assert_eq!(m.finalize(output_length), expected.compute_hash_sha3(&D256)); } } \ No newline at end of file