use digest::Digest;
use tor_llcrypto as ll;
use tor_netdoc::doc::{
authcert::{AuthCert, AuthCertKeyIds},
netstatus::{Lifetime, MdConsensus, UnvalidatedMdConsensus},
};
use std::time::SystemTime;
#[derive(Debug, Clone)]
pub(crate) struct ConsensusMeta {
lifetime: Lifetime,
sha3_256_of_signed: [u8; 32],
sha3_256_of_whole: [u8; 32],
}
impl ConsensusMeta {
pub(crate) fn new(
lifetime: Lifetime,
sha3_256_of_signed: [u8; 32],
sha3_256_of_whole: [u8; 32],
) -> Self {
ConsensusMeta {
lifetime,
sha3_256_of_signed,
sha3_256_of_whole,
}
}
pub(crate) fn from_unvalidated(
signed_part: &str,
remainder: &str,
con: &UnvalidatedMdConsensus,
) -> Self {
let lifetime = con.peek_lifetime().clone();
let (sd, wd) = sha3_dual(signed_part, remainder);
ConsensusMeta::new(lifetime, sd, wd)
}
#[allow(unused)]
pub(crate) fn from_consensus(signed_part: &str, remainder: &str, con: &MdConsensus) -> Self {
let lifetime = con.lifetime().clone();
let (sd, wd) = sha3_dual(signed_part, remainder);
ConsensusMeta::new(lifetime, sd, wd)
}
pub(crate) fn lifetime(&self) -> &Lifetime {
&self.lifetime
}
pub(crate) fn sha3_256_of_signed(&self) -> &[u8; 32] {
&self.sha3_256_of_signed
}
pub(crate) fn sha3_256_of_whole(&self) -> &[u8; 32] {
&self.sha3_256_of_whole
}
}
fn sha3_dual(signed_part: impl AsRef<[u8]>, remainder: impl AsRef<[u8]>) -> ([u8; 32], [u8; 32]) {
let mut d = ll::d::Sha3_256::new();
d.update(signed_part.as_ref());
let sha3_of_signed = d.clone().finalize().into();
d.update(remainder.as_ref());
let sha3_of_whole = d.finalize().into();
(sha3_of_signed, sha3_of_whole)
}
#[derive(Clone, Debug)]
pub(crate) struct AuthCertMeta {
ids: AuthCertKeyIds,
published: SystemTime,
expires: SystemTime,
}
impl AuthCertMeta {
pub(crate) fn new(ids: AuthCertKeyIds, published: SystemTime, expires: SystemTime) -> Self {
AuthCertMeta {
ids,
published,
expires,
}
}
pub(crate) fn from_authcert(cert: &AuthCert) -> Self {
AuthCertMeta::new(*cert.key_ids(), cert.published(), cert.expires())
}
pub(crate) fn key_ids(&self) -> &AuthCertKeyIds {
&self.ids
}
pub(crate) fn published(&self) -> SystemTime {
self.published
}
pub(crate) fn expires(&self) -> SystemTime {
self.expires
}
}
#[cfg(test)]
mod test {
#![allow(clippy::bool_assert_comparison)]
#![allow(clippy::clone_on_copy)]
#![allow(clippy::dbg_macro)]
#![allow(clippy::mixed_attributes_style)]
#![allow(clippy::print_stderr)]
#![allow(clippy::print_stdout)]
#![allow(clippy::single_char_pattern)]
#![allow(clippy::unwrap_used)]
#![allow(clippy::unchecked_duration_subtraction)]
#![allow(clippy::useless_vec)]
#![allow(clippy::needless_pass_by_value)]
use super::*;
#[test]
fn t_sha3_dual() {
let s = b"Loarax ipsum gruvvulus thneed amet, snergelly once-ler lerkim, sed do barbaloot tempor gluppitus ut labore et truffula magna aliqua. Ut enim ad grickle-grass veniam, quis miff-muffered ga-zumpco laboris nisi ut cruffulus ex ea schloppity consequat. Duis aute snarggle in swomeeswans in voluptate axe-hacker esse rippulus crummii eu moof nulla snuvv.";
let sha3_of_whole: [u8; 32] = ll::d::Sha3_256::digest(s).into();
for idx in 0..s.len() {
let sha3_of_part: [u8; 32] = ll::d::Sha3_256::digest(&s[..idx]).into();
let (a, b) = sha3_dual(&s[..idx], &s[idx..]);
assert_eq!(a, sha3_of_part);
assert_eq!(b, sha3_of_whole);
}
}
}