provenance-mark 0.23.1

A cryptographically-secured system for establishing and verifying the authenticity of works
Documentation
use dcbor::prelude::*;
use serde::{Deserialize, Serialize};

use crate::util::{deserialize_block, serialize_block};

pub const RNG_STATE_LENGTH: usize = 32;

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct RngState(
    #[serde(
        serialize_with = "serialize_block",
        deserialize_with = "deserialize_block"
    )]
    [u8; RNG_STATE_LENGTH],
);

impl RngState {
    pub fn to_bytes(&self) -> [u8; RNG_STATE_LENGTH] { self.0 }

    pub fn from_bytes(bytes: [u8; RNG_STATE_LENGTH]) -> Self { Self(bytes) }

    pub fn from_slice(bytes: &[u8]) -> Result<Self, String> {
        if bytes.len() != RNG_STATE_LENGTH {
            return Err(format!(
                "invalid RNG state length: expected {} bytes, got {} bytes",
                RNG_STATE_LENGTH,
                bytes.len()
            ));
        }
        let mut state_bytes = [0u8; RNG_STATE_LENGTH];
        state_bytes.copy_from_slice(bytes);
        Ok(Self::from_bytes(state_bytes))
    }

    pub fn hex(&self) -> String { hex::encode(self.0) }
}

impl From<[u8; RNG_STATE_LENGTH]> for RngState {
    fn from(bytes: [u8; RNG_STATE_LENGTH]) -> Self { Self::from_bytes(bytes) }
}

impl From<RngState> for [u8; RNG_STATE_LENGTH] {
    fn from(state: RngState) -> Self { state.to_bytes() }
}

impl From<RngState> for CBOR {
    fn from(state: RngState) -> Self {
        CBOR::to_byte_string(state.to_bytes().as_ref())
    }
}

impl TryFrom<CBOR> for RngState {
    type Error = dcbor::Error;

    fn try_from(cbor: CBOR) -> dcbor::Result<Self> {
        let bytes: Vec<u8> = cbor.try_byte_string()?;
        RngState::from_slice(&bytes)
            .map_err(|e| dcbor::Error::Custom(e.to_string()))
    }
}