// Copyright 2018-2025 the Deno authors. MIT license. use std::marker::PhantomData; use digest::generic_array::ArrayLength; pub trait RingDigestAlgo { fn algorithm() -> &'static ring::digest::Algorithm; type OutputSize: ArrayLength + 'static; } pub struct RingDigest { context: ring::digest::Context, _phantom: PhantomData, } impl Clone for RingDigest { fn clone(&self) -> Self { Self { context: self.context.clone(), _phantom: self._phantom, } } } impl digest::HashMarker for RingDigest {} impl Default for RingDigest { fn default() -> Self { Self { context: ring::digest::Context::new(Algo::algorithm()), _phantom: PhantomData, } } } impl digest::Reset for RingDigest { fn reset(&mut self) { self.context = ring::digest::Context::new(Algo::algorithm()) } } impl digest::Update for RingDigest { fn update(&mut self, data: &[u8]) { self.context.update(data); } } impl digest::OutputSizeUser for RingDigest { type OutputSize = Algo::OutputSize; } impl digest::FixedOutput for RingDigest { fn finalize_into(self, out: &mut digest::Output) { let result = self.context.finish(); out.copy_from_slice(result.as_ref()); } } impl digest::FixedOutputReset for RingDigest { fn finalize_into_reset(&mut self, out: &mut digest::Output) { let context = std::mem::replace( &mut self.context, ring::digest::Context::new(Algo::algorithm()), ); out.copy_from_slice(context.finish().as_ref()); } } pub struct RingSha256Algo; impl RingDigestAlgo for RingSha256Algo { fn algorithm() -> &'static ring::digest::Algorithm { &ring::digest::SHA256 } type OutputSize = digest::typenum::U32; } pub struct RingSha512Algo; impl RingDigestAlgo for RingSha512Algo { fn algorithm() -> &'static ring::digest::Algorithm { &ring::digest::SHA512 } type OutputSize = digest::typenum::U64; } pub type RingSha256 = RingDigest; pub type RingSha512 = RingDigest;