provenance_mark/
rng_state.rs1use 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}