Improvements (#24)
* Remove manual `Debug` impl for `InternalError` * Remove unnecessary `#[macro_use]` * Remove unnecessary `tuple` handling in macro * Improve serialization macro impl * Improve `impl_traits_for` macro * Re-direct `Drop` implementation * Improve macro readability * Fix rustdoc warnings * Rust 1.51 has no support for `rustdoc` lints * Change `i2osp` output to `GenericArray` from `Vec` * Reduce calls to `to_vec()` and simplify conversion * Adding zeroize tests Co-authored-by: Kevin Lewi <[email protected]>
This commit is contained in:
+37
-41
@@ -19,7 +19,7 @@ use crate::{
|
||||
use alloc::vec::Vec;
|
||||
use core::marker::PhantomData;
|
||||
use digest::{BlockInput, Digest};
|
||||
use generic_array::{typenum::Unsigned, GenericArray};
|
||||
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// Serialization and Deserialization for High-Level API //
|
||||
@@ -29,7 +29,7 @@ use generic_array::{typenum::Unsigned, GenericArray};
|
||||
impl<G: Group, H: BlockInput + Digest> NonVerifiableClient<G, H> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
[G::scalar_as_bytes(self.blind).to_vec(), self.data.clone()].concat()
|
||||
[G::scalar_as_bytes(self.blind).as_slice(), &self.data].concat()
|
||||
}
|
||||
|
||||
/// Deserialization from bytes
|
||||
@@ -39,7 +39,7 @@ impl<G: Group, H: BlockInput + Digest> NonVerifiableClient<G, H> {
|
||||
return Err(InternalError::SizeError);
|
||||
}
|
||||
|
||||
let blind = G::from_scalar_slice(GenericArray::from_slice(&input[..scalar_len]))?;
|
||||
let blind = G::from_scalar_slice(&input[..scalar_len])?;
|
||||
let data = input[scalar_len..].to_vec();
|
||||
|
||||
Ok(Self {
|
||||
@@ -54,9 +54,9 @@ impl<G: Group, H: BlockInput + Digest> VerifiableClient<G, H> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
[
|
||||
G::scalar_as_bytes(self.blind).to_vec(),
|
||||
self.blinded_element.to_arr().to_vec(),
|
||||
self.data.clone(),
|
||||
G::scalar_as_bytes(self.blind).as_slice(),
|
||||
&self.blinded_element.to_arr(),
|
||||
&self.data,
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
@@ -69,10 +69,8 @@ impl<G: Group, H: BlockInput + Digest> VerifiableClient<G, H> {
|
||||
return Err(InternalError::SizeError);
|
||||
}
|
||||
|
||||
let blind = G::from_scalar_slice(GenericArray::from_slice(&input[..scalar_len]))?;
|
||||
let blinded_element = G::from_element_slice(GenericArray::from_slice(
|
||||
&input[scalar_len..scalar_len + elem_len],
|
||||
))?;
|
||||
let blind = G::from_scalar_slice(&input[..scalar_len])?;
|
||||
let blinded_element = G::from_element_slice(&input[scalar_len..scalar_len + elem_len])?;
|
||||
let data = input[scalar_len + elem_len..].to_vec();
|
||||
|
||||
Ok(Self {
|
||||
@@ -97,7 +95,7 @@ impl<G: Group, H: BlockInput + Digest> NonVerifiableServer<G, H> {
|
||||
return Err(InternalError::SizeError);
|
||||
}
|
||||
|
||||
let sk = G::from_scalar_slice(GenericArray::from_slice(input))?;
|
||||
let sk = G::from_scalar_slice(input)?;
|
||||
|
||||
Ok(Self {
|
||||
sk,
|
||||
@@ -109,11 +107,7 @@ impl<G: Group, H: BlockInput + Digest> NonVerifiableServer<G, H> {
|
||||
impl<G: Group, H: BlockInput + Digest> VerifiableServer<G, H> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
[
|
||||
G::scalar_as_bytes(self.sk).to_vec(),
|
||||
self.pk.to_arr().to_vec(),
|
||||
]
|
||||
.concat()
|
||||
[G::scalar_as_bytes(self.sk).as_slice(), &self.pk.to_arr()].concat()
|
||||
}
|
||||
|
||||
/// Deserialization from bytes
|
||||
@@ -124,8 +118,8 @@ impl<G: Group, H: BlockInput + Digest> VerifiableServer<G, H> {
|
||||
return Err(InternalError::SizeError);
|
||||
}
|
||||
|
||||
let sk = G::from_scalar_slice(GenericArray::from_slice(&input[..scalar_len]))?;
|
||||
let pk = G::from_element_slice(GenericArray::from_slice(&input[scalar_len..]))?;
|
||||
let sk = G::from_scalar_slice(&input[..scalar_len])?;
|
||||
let pk = G::from_element_slice(&input[scalar_len..])?;
|
||||
|
||||
Ok(Self {
|
||||
sk,
|
||||
@@ -152,8 +146,8 @@ impl<G: Group, H: BlockInput + Digest> Proof<G, H> {
|
||||
return Err(InternalError::SizeError);
|
||||
}
|
||||
Ok(Proof {
|
||||
c_scalar: G::from_scalar_slice(GenericArray::from_slice(&input[..scalar_len]))?,
|
||||
s_scalar: G::from_scalar_slice(GenericArray::from_slice(&input[scalar_len..]))?,
|
||||
c_scalar: G::from_scalar_slice(&input[..scalar_len])?,
|
||||
s_scalar: G::from_scalar_slice(&input[scalar_len..])?,
|
||||
hash: PhantomData,
|
||||
})
|
||||
}
|
||||
@@ -168,7 +162,7 @@ impl<G: Group, H: BlockInput + Digest> BlindedElement<G, H> {
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
|
||||
Ok(Self {
|
||||
value: G::from_element_slice(GenericArray::from_slice(input))?,
|
||||
value: G::from_element_slice(input)?,
|
||||
hash: PhantomData,
|
||||
})
|
||||
}
|
||||
@@ -183,7 +177,7 @@ impl<G: Group, H: BlockInput + Digest> EvaluationElement<G, H> {
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
|
||||
Ok(Self {
|
||||
value: G::from_element_slice(GenericArray::from_slice(input))?,
|
||||
value: G::from_element_slice(input)?,
|
||||
hash: PhantomData,
|
||||
})
|
||||
}
|
||||
@@ -195,46 +189,48 @@ impl<G: Group, H: BlockInput + Digest> EvaluationElement<G, H> {
|
||||
//////////////////////
|
||||
|
||||
// Corresponds to the I2OSP() function from RFC8017
|
||||
pub(crate) fn i2osp(input: usize, length: usize) -> Result<alloc::vec::Vec<u8>, InternalError> {
|
||||
let sizeof_usize = core::mem::size_of::<usize>();
|
||||
pub(crate) fn i2osp<L: ArrayLength<u8>>(
|
||||
input: usize,
|
||||
) -> Result<GenericArray<u8, L>, InternalError> {
|
||||
const SIZEOF_USIZE: usize = core::mem::size_of::<usize>();
|
||||
|
||||
// Check if input >= 256^length
|
||||
if (sizeof_usize as u32 - input.leading_zeros() / 8) > length as u32 {
|
||||
if (SIZEOF_USIZE as u32 - input.leading_zeros() / 8) > L::U32 {
|
||||
return Err(InternalError::SerializationError);
|
||||
}
|
||||
|
||||
if length <= sizeof_usize {
|
||||
return Ok((&input.to_be_bytes()[sizeof_usize - length..]).to_vec());
|
||||
if L::USIZE <= SIZEOF_USIZE {
|
||||
return Ok(GenericArray::clone_from_slice(
|
||||
&input.to_be_bytes()[SIZEOF_USIZE - L::USIZE..],
|
||||
));
|
||||
}
|
||||
|
||||
let mut output = alloc::vec![0u8; length];
|
||||
output.splice(
|
||||
length - sizeof_usize..length,
|
||||
input.to_be_bytes().iter().cloned(),
|
||||
);
|
||||
let mut output = GenericArray::default();
|
||||
output[L::USIZE - SIZEOF_USIZE..L::USIZE].copy_from_slice(&input.to_be_bytes());
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
// Computes I2OSP(len(input), max_bytes) || input
|
||||
pub(crate) fn serialize(input: &[u8], max_bytes: usize) -> Result<Vec<u8>, InternalError> {
|
||||
Ok([&i2osp(input.len(), max_bytes)?, input].concat())
|
||||
pub(crate) fn serialize<L: ArrayLength<u8>>(input: &[u8]) -> Result<Vec<u8>, InternalError> {
|
||||
Ok([&i2osp::<L>(input.len())?, input].concat())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod unit_tests {
|
||||
use super::*;
|
||||
use generic_array::typenum::{U1, U2};
|
||||
|
||||
// Test the error condition for I2OSP
|
||||
#[test]
|
||||
fn test_i2osp_err_check() {
|
||||
assert!(i2osp(0, 1).is_ok());
|
||||
assert!(i2osp::<U1>(0).is_ok());
|
||||
|
||||
assert!(i2osp(255, 1).is_ok());
|
||||
assert!(i2osp(256, 1).is_err());
|
||||
assert!(i2osp(257, 1).is_err());
|
||||
assert!(i2osp::<U1>(255).is_ok());
|
||||
assert!(i2osp::<U1>(256).is_err());
|
||||
assert!(i2osp::<U1>(257).is_err());
|
||||
|
||||
assert!(i2osp(256 * 256 - 1, 2).is_ok());
|
||||
assert!(i2osp(256 * 256, 2).is_err());
|
||||
assert!(i2osp(256 * 256 + 1, 2).is_err());
|
||||
assert!(i2osp::<U2>(256 * 256 - 1).is_ok());
|
||||
assert!(i2osp::<U2>(256 * 256).is_err());
|
||||
assert!(i2osp::<U2>(256 * 256 + 1).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user