aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack O'Connor <[email protected]>2022-01-07 15:51:35 -0500
committerJack O'Connor <[email protected]>2022-01-07 15:51:35 -0500
commit7d8c00507142b3716d0f606ab4e169e0936316a6 (patch)
tree56968b35dad743b982b839fc8acf474c1dd84d2d
parentc7b5881928715429857d0b3e1bee7a4315cbf415 (diff)
add blake3_hasher_reset to the C API
-rw-r--r--c/README.md15
-rw-r--r--c/blake3.c5
-rw-r--r--c/blake3.h1
-rw-r--r--c/blake3_c_rust_bindings/src/lib.rs7
-rw-r--r--c/blake3_c_rust_bindings/src/test.rs51
5 files changed, 79 insertions, 0 deletions
diff --git a/c/README.md b/c/README.md
index e3fca0c..5e35fe0 100644
--- a/c/README.md
+++ b/c/README.md
@@ -185,6 +185,21 @@ parameter for the starting byte position in the output stream. To
efficiently stream a large output without allocating memory, call this
function in a loop, incrementing `seek` by the output length each time.
+---
+
+```c
+void blake3_hasher_reset(
+ blake3_hasher *self);
+```
+
+Reset the hasher to its initial state, prior to any calls to
+`blake3_hasher_update`. Currently this is no different from calling
+`blake3_hasher_init` or similar again. However, if this implementation gains
+multithreading support in the future, and if `blake3_hasher` holds (optional)
+threading resources, this function will reuse those resources. Until then, this
+is mainly for feature compatibility with the Rust implementation.
+
+
# Building
This implementation is just C and assembly files. It doesn't include a
diff --git a/c/blake3.c b/c/blake3.c
index 20b6bd0..1239433 100644
--- a/c/blake3.c
+++ b/c/blake3.c
@@ -609,3 +609,8 @@ void blake3_hasher_finalize_seek(const blake3_hasher *self, uint64_t seek,
}
output_root_bytes(&output, seek, out, out_len);
}
+
+void blake3_hasher_reset(blake3_hasher *self) {
+ chunk_state_reset(&self->chunk, self->key, 0);
+ self->cv_stack_len = 0;
+}
diff --git a/c/blake3.h b/c/blake3.h
index c3ca22d..5cccc90 100644
--- a/c/blake3.h
+++ b/c/blake3.h
@@ -51,6 +51,7 @@ void blake3_hasher_finalize(const blake3_hasher *self, uint8_t *out,
size_t out_len);
void blake3_hasher_finalize_seek(const blake3_hasher *self, uint64_t seek,
uint8_t *out, size_t out_len);
+void blake3_hasher_reset(blake3_hasher *self);
#ifdef __cplusplus
}
diff --git a/c/blake3_c_rust_bindings/src/lib.rs b/c/blake3_c_rust_bindings/src/lib.rs
index f18fe12..41e4938 100644
--- a/c/blake3_c_rust_bindings/src/lib.rs
+++ b/c/blake3_c_rust_bindings/src/lib.rs
@@ -93,6 +93,12 @@ impl Hasher {
ffi::blake3_hasher_finalize_seek(&self.0, seek, output.as_mut_ptr(), output.len());
}
}
+
+ pub fn reset(&mut self) {
+ unsafe {
+ ffi::blake3_hasher_reset(&mut self.0);
+ }
+ }
}
pub mod ffi {
@@ -141,6 +147,7 @@ pub mod ffi {
out: *mut u8,
out_len: usize,
);
+ pub fn blake3_hasher_reset(self_: *mut blake3_hasher);
// portable low-level functions
pub fn blake3_compress_in_place_portable(
diff --git a/c/blake3_c_rust_bindings/src/test.rs b/c/blake3_c_rust_bindings/src/test.rs
index 3b3d8a7..f4d4810 100644
--- a/c/blake3_c_rust_bindings/src/test.rs
+++ b/c/blake3_c_rust_bindings/src/test.rs
@@ -509,3 +509,54 @@ fn test_finalize_seek() {
assert_eq!(&expected[seek..][..out.len()], &out[..]);
}
}
+
+#[test]
+fn test_reset() {
+ {
+ let mut hasher = crate::Hasher::new();
+ hasher.update(&[42; 3 * CHUNK_LEN + 7]);
+ hasher.reset();
+ hasher.update(&[42; CHUNK_LEN + 3]);
+ let mut output = [0; 32];
+ hasher.finalize(&mut output);
+
+ let mut reference_hasher = reference_impl::Hasher::new();
+ reference_hasher.update(&[42; CHUNK_LEN + 3]);
+ let mut reference_hash = [0; 32];
+ reference_hasher.finalize(&mut reference_hash);
+
+ assert_eq!(reference_hash, output);
+ }
+ {
+ let key = &[99; 32];
+ let mut hasher = crate::Hasher::new_keyed(key);
+ hasher.update(&[42; 3 * CHUNK_LEN + 7]);
+ hasher.reset();
+ hasher.update(&[42; CHUNK_LEN + 3]);
+ let mut output = [0; 32];
+ hasher.finalize(&mut output);
+
+ let mut reference_hasher = reference_impl::Hasher::new_keyed(key);
+ reference_hasher.update(&[42; CHUNK_LEN + 3]);
+ let mut reference_hash = [0; 32];
+ reference_hasher.finalize(&mut reference_hash);
+
+ assert_eq!(reference_hash, output);
+ }
+ {
+ let context = "BLAKE3 2020-02-12 10:20:58 reset test";
+ let mut hasher = crate::Hasher::new_derive_key(context);
+ hasher.update(&[42; 3 * CHUNK_LEN + 7]);
+ hasher.reset();
+ hasher.update(&[42; CHUNK_LEN + 3]);
+ let mut output = [0; 32];
+ hasher.finalize(&mut output);
+
+ let mut reference_hasher = reference_impl::Hasher::new_derive_key(context);
+ reference_hasher.update(&[42; CHUNK_LEN + 3]);
+ let mut reference_hash = [0; 32];
+ reference_hasher.finalize(&mut reference_hash);
+
+ assert_eq!(reference_hash, output);
+ }
+}