Does it matter how big the thing you are signing is? Also what do you mean by "within" are you actually swapping out SHA-512 for BLAKE3 in the EdDSA algorithm or do you mean that you are signing BLAKE3 hashes with a standard EdDSA algorithm like ed25519?
Discussion
I swapped out SHA-512 *within* the EdDSA ed25519 construction, so it doesn't use SHA-512 internally anywhere.
Apparently I am only signing very short things. I just used the bench from ed25519-dalek. I should change that to see how much more difference I get.
Ok with empty messages I get:
Signing: SHA-512=13.5us BLAKE3=13.5us (no difference, message was empty, this makes sense)
Verificatin: SHA-512=30.1us BLAKE3=30.4us (within margin of error)
Strict Verif: SHA-512=31.6us BLAKE3=30.9us (within margin of error)
with 4416 bytes of data I instead get:
Signing: SHA-512=25.5us BLAKE3=19.0us (25% faster)
Verif: SHA-512=30.0us BLAKE3=26.5us (11.6% faster)
S. Verif: SHA-512=38.3 BLAKE3=31.9us (16.7% faster)
So I was wrong. Obviously with no data you aren't going to see a difference.
I'm not sure EdDSA with BLAKE3 has any solid implementations out there though, and the standard specifies only SHA-512 so I would be non-compliant.
Lemme think..... non-compliant..... how does that sound.... Hmmmmm.
Yes, sounds great.
For small payloads blake2 is faster than blake3, fyi. Blake3 is fastest for large payloads.
Thanks for doing that. I've wanted to try for awhile. I also don't care super much about compliance. If you are building something new and distributed that you want to compete with centralized services you have to do the optimal thing. There is a lot of headroom available to do more on smaller devices by being clever. Use a compressed byte format instead of json for instance. Prepackage all your data in packet sized chunks so you can route it instantly without processing etc.
Does your BLAKE3 version of Dalek exist anywhere that I can steal it?
// blake3 = "1.5"
// digest = "0.10"
// ed25519-dalek = { version = "2.1", features = [ "rand_core", "digest" ] }
use digest::generic_array::typenum::U64;
use digest::generic_array::GenericArray;
use digest::{FixedOutput, HashMarker, OutputSizeUser, Reset, Update};
/// This is a Blake3 Hasher implementing the traits required for use in
/// the ed25519 construction in place of SHA-512
#[derive(Clone)]
pub struct Blake3 {
pub(crate) h: blake3::Hasher,
}
impl Update for Blake3 {
#[inline]
fn update(&mut self, data: &[u8]) {
self.h.update(data.as_ref());
}
}
impl Reset for Blake3 {
#[inline]
fn reset(&mut self) {
self.h.reset();
}
}
impl Default for Blake3 {
#[inline]
fn default() -> Self {
Blake3 {
h: blake3::Hasher::new(),
}
}
}
impl FixedOutput for Blake3 {
#[inline]
fn finalize_into(self, out: &mut GenericArray
self.h.finalize_xof().fill(out);
}
}
impl OutputSizeUser for Blake3 {
type OutputSize = U64;
}
impl HashMarker for Blake3 {}
Thank you!! I haven't had a chance to try it yet. For some reason I assumed that you had to clone the whole Dalek repo and rip sha256 manually. This is much better.
Nope, it has a prehashed function: