pub use paste;
pub use serde;
pub use subtle;
mod types;
pub use types::*;
#[macro_export]
macro_rules! fixed_array_serialization {
($t:ty, $len:expr) => {
$crate::paste::paste! {
impl $crate::serde::ser::Serialize for $t {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: $crate::serde::ser::Serializer,
{
serializer.serialize_bytes(&self.0)
}
}
struct [<Visitor$t>];
impl<'de> $crate::serde::de::Visitor<'de> for [<Visitor$t>] {
type Value = [u8; $len];
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str(format!("a byte array of length {}", $len).as_str())
}
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
where
E: $crate::serde::de::Error,
{
if value.len() == $len {
let mut bytes = [0 as u8; $len];
bytes.clone_from_slice(value);
Ok(bytes)
} else {
let error_message = format!("{} bytes, got {} bytes", $len, value.len());
Err(E::invalid_value(
$crate::serde::de::Unexpected::Bytes(value),
&error_message.as_str(),
))
}
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: $crate::serde::de::SeqAccess<'de>,
{
let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or(0));
while let Some(b) = seq.next_element()? {
vec.push(b);
}
self.visit_bytes(&vec)
}
}
impl<'de> $crate::serde::de::Deserialize<'de> for $t {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: $crate::serde::de::Deserializer<'de>,
{
let bytes = deserializer.deserialize_bytes([<Visitor$t>])?;
Ok(Self(bytes))
}
}
}
};
}
#[macro_export]
macro_rules! secure_primitive {
($t:ty, $len:expr) => {
$crate::fixed_array_serialization!($t, $len);
impl PartialEq for $t {
fn eq(&self, other: &Self) -> bool {
use $crate::subtle::ConstantTimeEq;
self.0.ct_eq(&other.0).into()
}
}
impl Eq for $t {}
#[cfg(not(feature = "full"))]
impl std::fmt::Debug for $t {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(&self.0.to_vec(), f)
}
}
#[cfg(feature = "full")]
impl std::fmt::Debug for $t {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let str = String::from_utf8(subtle_encoding::hex::encode(self.0.to_vec()))
.unwrap_or_else(|_| "<unparseable signature>".into());
f.write_str(&str)
}
}
impl From<[u8; $len]> for $t {
fn from(b: [u8; $len]) -> Self {
Self(b)
}
}
impl core::convert::TryFrom<&[u8]> for $t {
type Error = $crate::SecurePrimitiveError;
fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
if slice.len() == $len {
let mut inner = [0; $len];
inner.copy_from_slice(slice);
Ok(inner.into())
} else {
Err($crate::SecurePrimitiveError::BadSize)
}
}
}
impl core::convert::TryFrom<Vec<u8>> for $t {
type Error = $crate::SecurePrimitiveError;
fn try_from(v: Vec<u8>) -> Result<Self, Self::Error> {
Self::try_from(v.as_ref())
}
}
impl AsRef<[u8]> for $t {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
};
}