Skip to content

Commit

Permalink
feat: Switch from SHA3-256 to BLAKE3-256 (#306)
Browse files Browse the repository at this point in the history
Release-As: 0.1.23

* feat: Switch from SHA3-256 to BLAKE3-256

* Also use Blake3 by default in `BlockStore::create_cid`

* Also use Blake3 in skip ratchet key derivation

* Make use of `blake3::derive_key` algorithm

* Un-expose temporal key bytes

* Update domain separation string

* Update prime hash fixture

* Fix block naming consistency

* Dedicated APIs for key structs & cleanup

* Store a `base_name` in `ExternalFileContent`

This ensures you can re-generate all block labels, even if you don't have access to the
 PrivateNodeHeader`, e.g. when you only have snapshot access.

* Lint

* Give tests more stack space

* Fix wasm-wnfs

* Make external file content encoding more spec-adhering

* Add a hiding segment to `base_name`

* Depend on released skip ratchet crate
  • Loading branch information
matheus23 authored Jul 21, 2023
1 parent c17f6bb commit e164a1f
Show file tree
Hide file tree
Showing 26 changed files with 276 additions and 190 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ jobs:
- name: Cache Project
uses: Swatinem/rust-cache@v2

- name: Run Tests
run: cargo test --all-features
- name: Run Tests # 3MB of stack space
run: RUST_MIN_STACK=3000000 cargo test --all-features

wasm-js-tests:
strategy:
Expand Down
2 changes: 1 addition & 1 deletion wnfs-bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ license = "Apache-2.0"

[dev-dependencies]
async-std = { version = "1.11", features = ["attributes"] }
blake3 = { version = "1.4", features = ["traits-preview"] }
chrono = { version = "0.4", default-features = false, features = ["clock", "std"] }
criterion = { version = "0.4", features = ["async_std"] }
proptest = "1.1"
rand = "0.8"
sha3 = "0.10"
wnfs = { path = "../wnfs" }
wnfs-common = { path = "../wnfs-common", features = ["test_utils"] }
wnfs-hamt = { path = "../wnfs-hamt", features = ["test_utils"] }
Expand Down
7 changes: 3 additions & 4 deletions wnfs-bench/nameaccumulator.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
use rand::{thread_rng, Rng};
use sha3::Digest;
use wnfs_nameaccumulator::{AccumulatorSetup, NameAccumulator, NameSegment};

fn name_segment_from_digest(c: &mut Criterion) {
c.bench_function("NameSegment::from_digest", |b| {
c.bench_function("NameSegment::new_hashed", |b| {
b.iter_batched(
|| sha3::Sha3_256::new().chain_update(thread_rng().gen::<[u8; 32]>()),
NameSegment::from_digest,
|| thread_rng().gen::<[u8; 32]>(),
|sth| NameSegment::new_hashed("wnfs benchmarks", sth),
BatchSize::SmallInput,
);
});
Expand Down
4 changes: 2 additions & 2 deletions wnfs-common/src/blockstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ pub trait BlockStore: Sized {
bail!(BlockStoreError::MaximumBlockSizeExceeded(bytes.len()))
}

// Compute the SHA256 hash of the bytes
let hash = Code::Sha2_256.digest(bytes);
// Compute the Blake3 hash of the bytes
let hash = Code::Blake3_256.digest(bytes);

// Represent the hash as a V1 CID
let cid = Cid::new(Version::V1, codec, hash)?;
Expand Down
2 changes: 1 addition & 1 deletion wnfs-hamt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ async-once-cell = "0.4"
async-recursion = "1.0"
async-trait = "0.1"
bitvec = { version = "1.0", features = ["serde"] }
blake3 = { version = "1.4", features = ["traits-preview"] }
chrono = { version = "0.4.23", default-features = false, features = ["clock", "std"] }
either = "1.8"
futures = "0.3"
Expand All @@ -33,7 +34,6 @@ proptest = { version = "1.1", optional = true }
rand_core = "0.6"
semver = { version = "1.0", features = ["serde"] }
serde = { version = "1.0", features = ["rc"] }
sha3 = "0.10"
thiserror = "1.0"
wnfs-common = { path = "../wnfs-common", version = "0.1.22" }

Expand Down
18 changes: 9 additions & 9 deletions wnfs-hamt/src/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ use wnfs_common::{BlockStore, Link};
//--------------------------------------------------------------------------------------------------

/// This type represents the different kinds of changes to a node.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum ChangeType {
Add,
Remove,
Modify,
}

/// Represents a change to some key-value pair of a HAMT node.
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct KeyValueChange<K, V> {
pub r#type: ChangeType,
pub key: K,
Expand Down Expand Up @@ -300,7 +300,7 @@ where
mod tests {
use super::{ChangeType::*, *};
use helper::*;
use std::rc::Rc;
use std::{collections::BTreeSet, rc::Rc};
use wnfs_common::MemoryBlockStore;

mod helper {
Expand Down Expand Up @@ -358,8 +358,8 @@ mod tests {
.unwrap();

assert_eq!(
changes,
vec![
changes.into_iter().collect::<BTreeSet<_>>(),
BTreeSet::from([
KeyValueChange {
r#type: Add,
key: [2, 0, 0, 0,],
Expand All @@ -372,7 +372,7 @@ mod tests {
value1: Some(String::from("1")),
value2: None,
},
]
])
);

let changes = diff(
Expand All @@ -384,8 +384,8 @@ mod tests {
.unwrap();

assert_eq!(
changes,
vec![
changes.into_iter().collect::<BTreeSet<_>>(),
BTreeSet::from([
KeyValueChange {
r#type: Remove,
key: [2, 0, 0, 0,],
Expand All @@ -398,7 +398,7 @@ mod tests {
value1: Some(String::from("1")),
value2: None,
},
]
])
);
}

Expand Down
3 changes: 1 addition & 2 deletions wnfs-hamt/src/hamt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use serde::{
ser::Error as SerError,
Deserialize, Deserializer, Serialize, Serializer,
};
use sha3::Sha3_256;
use std::{collections::BTreeMap, hash::Hash, rc::Rc, str::FromStr};
use wnfs_common::{AsyncSerialize, BlockStore, Link};

Expand All @@ -31,7 +30,7 @@ use wnfs_common::{AsyncSerialize, BlockStore, Link};
/// println!("HAMT: {:?}", hamt);
/// ```
#[derive(Debug, Clone)]
pub struct Hamt<K, V, H = Sha3_256>
pub struct Hamt<K, V, H = blake3::Hasher>
where
H: Hasher,
{
Expand Down
12 changes: 3 additions & 9 deletions wnfs-hamt/src/hash.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::error::HamtError;
use anyhow::{bail, Result};
use sha3::{Digest, Sha3_256};
use std::fmt::Debug;
use wnfs_common::{utils, HashOutput, HASH_BYTE_SIZE};

Expand All @@ -22,17 +21,14 @@ pub const MAX_HASH_NIBBLE_LENGTH: usize = HASH_BYTE_SIZE * 2;
/// # Examples
///
/// ```
/// use sha3::{Digest, Sha3_256};
/// use wnfs_hamt::Hasher;
/// use wnfs_common::HashOutput;
///
/// struct MyHasher;
///
/// impl Hasher for MyHasher {
/// fn hash<D: AsRef<[u8]>>(data: &D) -> HashOutput {
/// let mut hasher = Sha3_256::new();
/// hasher.update(data.as_ref());
/// hasher.finalize().into()
/// blake3::hash(data.as_ref()).into()
/// }
/// }
/// ```
Expand Down Expand Up @@ -152,11 +148,9 @@ impl Debug for HashNibbles<'_> {
}
}

impl Hasher for Sha3_256 {
impl Hasher for blake3::Hasher {
fn hash<D: AsRef<[u8]>>(data: &D) -> HashOutput {
let mut hasher = Self::default();
hasher.update(data.as_ref());
hasher.finalize().into()
blake3::hash(data.as_ref()).into()
}
}

Expand Down
11 changes: 3 additions & 8 deletions wnfs-hamt/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use serde::{
ser::Error as SerError,
Deserializer, Serialize, Serializer,
};
use sha3::Sha3_256;
use std::{
collections::HashMap,
fmt::{self, Debug, Formatter},
Expand Down Expand Up @@ -50,7 +49,7 @@ pub type BitMaskType = [u8; HAMT_BITMASK_BYTE_SIZE];
///
/// assert!(node.is_empty());
/// ```
pub struct Node<K, V, H = Sha3_256>
pub struct Node<K, V, H = blake3::Hasher>
where
H: Hasher,
{
Expand Down Expand Up @@ -223,7 +222,6 @@ where
///
/// ```
/// use std::rc::Rc;
/// use sha3::Sha3_256;
/// use wnfs_hamt::{Node, Hasher};
/// use wnfs_common::MemoryBlockStore;
///
Expand All @@ -234,7 +232,7 @@ where
///
/// node.set("key".into(), 42, store).await.unwrap();
///
/// let key_hash = &Sha3_256::hash(&String::from("key"));
/// let key_hash = &blake3::Hasher::hash(&String::from("key"));
/// assert_eq!(node.get_by_hash(key_hash, store).await.unwrap(), Some(&42));
/// }
/// ```
Expand Down Expand Up @@ -262,7 +260,6 @@ where
///
/// ```
/// use std::rc::Rc;
/// use sha3::Sha3_256;
/// use wnfs_hamt::{Node, Hasher, Pair};
/// use wnfs_common::MemoryBlockStore;
///
Expand All @@ -274,7 +271,7 @@ where
/// node.set("key".into(), 42, store).await.unwrap();
/// assert_eq!(node.get(&String::from("key"), store).await.unwrap(), Some(&42));
///
/// let key_hash = &Sha3_256::hash(&String::from("key"));
/// let key_hash = &blake3::Hasher::hash(&String::from("key"));
/// let value = node.remove_by_hash(key_hash, store).await.unwrap();
///
/// assert_eq!(value, Some(Pair::new("key".into(), 42)));
Expand Down Expand Up @@ -613,7 +610,6 @@ where
///
/// ```
/// use std::rc::Rc;
/// use sha3::Sha3_256;
/// use wnfs_hamt::{Node, HashPrefix, Hasher};
/// use wnfs_common::{MemoryBlockStore, utils};
///
Expand Down Expand Up @@ -694,7 +690,6 @@ where
///
/// ```
/// use std::rc::Rc;
/// use sha3::Sha3_256;
/// use wnfs_hamt::{Node, Hasher};
/// use wnfs_common::MemoryBlockStore;
///
Expand Down
6 changes: 3 additions & 3 deletions wnfs-hamt/src/pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,12 @@ where
#[cfg(test)]
mod tests {
use super::*;
use sha3::Sha3_256;
use wnfs_common::{dagcbor, MemoryBlockStore};

#[async_std::test]
async fn pointer_can_encode_decode_as_cbor() {
let store = &MemoryBlockStore::default();
let pointer: Pointer<String, i32, Sha3_256> = Pointer::Values(vec![
let pointer: Pointer<String, i32, blake3::Hasher> = Pointer::Values(vec![
Pair {
key: "James".into(),
value: 4500,
Expand All @@ -267,7 +266,8 @@ mod tests {

let encoded_pointer = dagcbor::async_encode(&pointer, store).await.unwrap();
let decoded_pointer =
dagcbor::decode::<Pointer<String, i32, Sha3_256>>(encoded_pointer.as_ref()).unwrap();
dagcbor::decode::<Pointer<String, i32, blake3::Hasher>>(encoded_pointer.as_ref())
.unwrap();

assert_eq!(pointer, decoded_pointer);
}
Expand Down
2 changes: 1 addition & 1 deletion wnfs-nameaccumulator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ authors = ["The Fission Authors"]

[dependencies]
anyhow = "1.0"
blake3 = { version = "1.4", features = ["traits-preview"] }
libipld = { version = "0.16", features = ["dag-cbor", "derive", "serde-codec"] }
num-bigint-dig = { version = "0.8.2", features = ["prime", "zeroize"] }
num-integer = "0.1.45"
Expand All @@ -26,7 +27,6 @@ once_cell = "1.0"
rand_core = "0.6"
serde = { version = "1.0", features = ["rc"] }
serde_bytes = "0.11.9"
sha3 = "0.10"
thiserror = "1.0"
zeroize = "1.6"

Expand Down
Loading

0 comments on commit e164a1f

Please sign in to comment.