Skip to content

Instantly share code, notes, and snippets.

@nickray
Created April 13, 2022 13:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nickray/b9e091c075f174abcf382bce684e0ba7 to your computer and use it in GitHub Desktop.
Save nickray/b9e091c075f174abcf382bce684e0ba7 to your computer and use it in GitHub Desktop.
/// Pretty dirty hack.
///
/// For security reasons, `signature::DigestSigner` doesn't want you to sign raw bytes.
/// However, we have a trusted client, and want it to be able to send the raw bytes for efficiency,
/// also because the blockchain messages internally calculate and independently use the hash.
///
/// So... we need to have a structure that
/// a) acts like a real Sha256 if initiated with Default and then updated + finalized
/// b) returns our desired pre-existing hash as final output if initiated from that
#[derive(Clone, Debug)]
enum Fake256 {
Real(sha2::Sha256),
Fake([u8; 32]),
}
impl Default for Fake256 {
fn default() -> Self {
Self::Real(sha2::Sha256::default())
}
}
impl From<&[u8; 32]> for Fake256 {
fn from(raw_digest: &[u8; 32]) -> Self {
Self::Fake(*raw_digest)
}
}
use generic_array::GenericArray;
use k256::ecdsa::signature::digest::{BlockInput, FixedOutput, Reset, Update};
impl BlockInput for Fake256 {
type BlockSize = <sha2::Sha256 as BlockInput>::BlockSize;
}
impl FixedOutput for Fake256 {
type OutputSize = <sha2::Sha256 as FixedOutput>::OutputSize;
fn finalize_into(self, out: &mut GenericArray<u8, Self::OutputSize>) {
println!("finalize_into");
match self {
Self::Real(sha2) => sha2.finalize_into(out),
Self::Fake(digest) => out.as_mut_slice().copy_from_slice(&digest),
}
}
fn finalize_into_reset(&mut self, out: &mut GenericArray<u8, Self::OutputSize>) {
println!("finalize_into_reset");
match self {
Self::Real(sha2) => sha2.finalize_into_reset(out),
Self::Fake(digest) => out.as_mut_slice().copy_from_slice(digest),
}
// self.reset();
}
}
impl Update for Fake256 {
fn update(&mut self, data: impl AsRef<[u8]>) {
println!("update");
match self {
Self::Real(sha2) => sha2.update(data),
Self::Fake(_) => panic!("this case should not occur"),
}
}
}
impl Reset for Fake256 {
fn reset(&mut self) {
println!("reset");
*self = Self::default();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment