Skip to main content

provenance_mark/
rng_state.rs

1use dcbor::prelude::*;
2use serde::{Deserialize, Serialize};
3
4use crate::util::{deserialize_block, serialize_block};
5
6pub const RNG_STATE_LENGTH: usize = 32;
7
8#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
9pub struct RngState(
10    #[serde(
11        serialize_with = "serialize_block",
12        deserialize_with = "deserialize_block"
13    )]
14    [u8; RNG_STATE_LENGTH],
15);
16
17impl RngState {
18    pub fn to_bytes(&self) -> [u8; RNG_STATE_LENGTH] { self.0 }
19
20    pub fn from_bytes(bytes: [u8; RNG_STATE_LENGTH]) -> Self { Self(bytes) }
21
22    pub fn from_slice(bytes: &[u8]) -> Result<Self, String> {
23        if bytes.len() != RNG_STATE_LENGTH {
24            return Err(format!(
25                "invalid RNG state length: expected {} bytes, got {} bytes",
26                RNG_STATE_LENGTH,
27                bytes.len()
28            ));
29        }
30        let mut state_bytes = [0u8; RNG_STATE_LENGTH];
31        state_bytes.copy_from_slice(bytes);
32        Ok(Self::from_bytes(state_bytes))
33    }
34
35    pub fn hex(&self) -> String { hex::encode(self.0) }
36}
37
38impl From<[u8; RNG_STATE_LENGTH]> for RngState {
39    fn from(bytes: [u8; RNG_STATE_LENGTH]) -> Self { Self::from_bytes(bytes) }
40}
41
42impl From<RngState> for [u8; RNG_STATE_LENGTH] {
43    fn from(state: RngState) -> Self { state.to_bytes() }
44}
45
46impl From<RngState> for CBOR {
47    fn from(state: RngState) -> Self {
48        CBOR::to_byte_string(state.to_bytes().as_ref())
49    }
50}
51
52impl TryFrom<CBOR> for RngState {
53    type Error = dcbor::Error;
54
55    fn try_from(cbor: CBOR) -> dcbor::Result<Self> {
56        let bytes: Vec<u8> = cbor.try_byte_string()?;
57        RngState::from_slice(&bytes)
58            .map_err(|e| dcbor::Error::Custom(e.to_string()))
59    }
60}