use p256::ecdsa::{SigningKey, VerifyingKey}; use rand::thread_rng; use super::event::{Changed, Event}; use crate::{clock::DateTime, event::Instant}; #[derive(Debug)] pub struct History { pub key: VerifyingKey, pub changed: Instant, } // Lifecycle interface impl History { pub fn begin(changed: &Instant) -> (Self, SigningKey) { let key = SigningKey::random(&mut thread_rng()); ( Self { key: VerifyingKey::from(&key), changed: *changed, }, key, ) } // `self` _is_ unused here, clippy is right about that. This choice is deliberate, however - it // makes it harder to inadvertently reuse a rotated key via its history, and it makes the // lifecycle interface more obviously consistent between this and other History types. #[allow(clippy::unused_self)] pub fn rotate(self, changed: &Instant) -> (Self, SigningKey) { Self::begin(changed) } } // State interface impl History { pub fn older_than(&self, when: DateTime) -> bool { self.changed.at < when } } // Events interface impl History { pub fn events(&self) -> impl Iterator + Clone { [self.changed()].into_iter() } fn changed(&self) -> Event { Changed { key: self.key, instant: self.changed, } .into() } }