Created
April 30, 2025 01:42
-
-
Save oconnor663/e3e90d4578f62f439f8146e8ba38eca5 to your computer and use it in GitHub Desktop.
POC of absorbing, squeezing, and ratcheting with BLAKE3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use blake3::{Hasher, OutputReader}; | |
pub enum RatchetingHasher { | |
Absorbing(Hasher), | |
Squeezing(OutputReader), | |
} | |
use RatchetingHasher::{Absorbing, Squeezing}; | |
impl RatchetingHasher { | |
pub fn new(key: &[u8; 32]) -> Self { | |
Absorbing(Hasher::new_keyed(key)) | |
} | |
fn get_hasher(&mut self) -> &mut Hasher { | |
match self { | |
// already in the absorbing state | |
Absorbing(hasher) => hasher, | |
// in the squeezing state, switch to absorbing | |
Squeezing(reader) => { | |
let mut key = [0; 32]; | |
reader.fill(&mut key); | |
*self = Absorbing(Hasher::new_keyed(&key)); | |
match self { | |
Absorbing(hasher) => hasher, | |
_ => unreachable!(), | |
} | |
} | |
} | |
} | |
fn get_reader(&mut self) -> &mut OutputReader { | |
match self { | |
// in the absorbing state, switch to squeezing | |
Absorbing(hasher) => { | |
*self = Squeezing(hasher.finalize_xof()); | |
match self { | |
Squeezing(reader) => reader, | |
_ => unreachable!(), | |
} | |
} | |
// already in the squeezing state | |
Squeezing(reader) => reader, | |
} | |
} | |
pub fn absorb(&mut self, input: &[u8]) { | |
self.get_hasher().update(input); | |
} | |
pub fn squeeze(&mut self, output: &mut [u8]) { | |
self.get_reader().fill(output); | |
} | |
pub fn ratchet(&mut self) { | |
// Force a state switch. | |
match self { | |
Absorbing(_) => { | |
_ = self.get_reader(); | |
} | |
Squeezing(_) => { | |
_ = self.get_hasher(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note to self:
OutputReader
often contains the keyed hashkey
, soself.get_reader()
isn't sufficient to force "forgetting" the key.