Description
Hi,
@oli-obk You asked for use cases so this is on you ;)
I think that being able to hash in a const fn is a needed use case in production.
Domain separation between hashing different messages is good practice in cryptography [0],[1],[2]
so I'd want to do something along these lines:
const TaggedHashAppA: Sha256 = Sha256::new().input(b"AppA")
or even:
const TagAppA: [u8; 32] = Sha256::new().input("AppA").finalize();
const TaggedHashAppA: Sha256 = Sha256::new().input(&TagAppA).input(&TagAppA);
you'll then use it like that:
let mut hashing = TaggedHashAppA;
hashing.input(&msg);
let hash = hashing.finalize();
This is a naive implementation that manages to do everything under const eval (you can search for "Replacement" to see stuff I had to replace to make it work) except the input
function on line 60
https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=2a3be44298313834597b0e834a6050af
Had to replace:
W[..16].copy_from_slice(&block);
with:
unsafe {
let w16 = &mut W as *mut [u32] as *mut [u32; 16];
*w16 = block;
}
And unroll a couple of loops.
[0] https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-05#section-2.2.5
[1] https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf Section 2.3 "Domain Separation"
[2] https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki "Tagged Hashes"