Skip to content

Commit

Permalink
add IOPattern::from/to_bytes() for portability
Browse files Browse the repository at this point in the history
  • Loading branch information
alxiong committed Jan 9, 2025
1 parent 8a68d70 commit 480682b
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 4 deletions.
8 changes: 7 additions & 1 deletion nimue/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
/// An error to signal that the verification equation has failed. Destined for end users.
///
/// A [`core::Result::Result`] wrapper called [`ProofResult`] (having error fixed to [`ProofError`]) is also provided.
use std::{borrow::Borrow, error::Error, fmt::Display};
use std::{borrow::Borrow, error::Error, fmt::Display, string::FromUtf8Error};

/// Signals an invalid IO pattern.
///
Expand Down Expand Up @@ -82,3 +82,9 @@ impl From<std::io::Error> for IOPatternError {
IOPatternError(value.to_string())
}
}

impl From<FromUtf8Error> for IOPatternError {
fn from(value: FromUtf8Error) -> Self {
Self(value.to_string())
}
}
2 changes: 1 addition & 1 deletion nimue/src/hash/keccak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn transmute_state(st: &mut AlignedKeccakState) -> &mut [u64; 25] {
/// This is a wrapper around 200-byte buffer that's always 8-byte aligned
/// to make pointers to it safely convertible to pointers to [u64; 25]
/// (since u64 words must be 8-byte aligned)
#[derive(Clone, Zeroize, ZeroizeOnDrop)]
#[derive(Clone, Zeroize, ZeroizeOnDrop, PartialEq, Eq)]
#[repr(align(8))]
pub struct AlignedKeccakState([u8; 200]);

Expand Down
2 changes: 1 addition & 1 deletion nimue/src/hash/sponge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub trait Sponge: Zeroize + Default + Clone + AsRef<[Self::U]> + AsMut<[Self::U]
}

/// A cryptographic sponge.
#[derive(Clone, Default, Zeroize, ZeroizeOnDrop)]
#[derive(Clone, Default, Zeroize, ZeroizeOnDrop, PartialEq, Eq)]
pub struct DuplexSponge<C: Sponge> {
sponge: C,
absorb_pos: usize,
Expand Down
13 changes: 12 additions & 1 deletion nimue/src/iopattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const SEP_BYTE: &str = "\0";
/// The struct [`IOPattern`] guarantees the creation of a valid IO Pattern string, whose lengths are coherent with the types described in the protocol. No information about the types themselves is stored in an IO Pattern.
/// This means that [`Merlin`][`crate::Merlin`] or [`Arthur`][`crate::Arthur`] instances can generate successfully a protocol transcript respecting the length constraint but not the types. See [issue #6](https://github.com/arkworks-rs/nimue/issues/6) for a discussion on the topic.
#[derive(Clone)]
#[derive(Clone, PartialEq, Eq)]
pub struct IOPattern<H = crate::DefaultHash, U = u8>
where
U: Unit,
Expand Down Expand Up @@ -139,6 +139,17 @@ impl<H: DuplexHash<U>, U: Unit> IOPattern<H, U> {
self.io.as_bytes()
}

/// Return the IO Pattern as owned bytes.
pub fn to_bytes(&self) -> Vec<u8> {
self.io.clone().into_bytes()
}

/// Construct an IO Pattern from serialized bytes (usually output from `Self::to_bytes()`)
pub fn from_bytes(bytes: Vec<u8>) -> Result<Self, IOPatternError> {
let io = String::from_utf8(bytes)?;
Ok(Self::from_string(io))
}

/// Parse the givern IO Pattern into a sequence of [`Op`]'s.
pub(crate) fn finalize(&self) -> VecDeque<Op> {
// Guaranteed to succeed as instances are all valid iopatterns
Expand Down
2 changes: 2 additions & 0 deletions nimue/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ fn test_iopattern() {
// test that the byte separator is always added
let iop = IOPattern::<Keccak>::new("example.com");
assert!(iop.as_bytes().starts_with(b"example.com"));

assert_eq!(IOPattern::from_bytes(iop.to_bytes()).unwrap(), iop);
}

/// Test Merlin's rng is not doing completely stupid things.
Expand Down

0 comments on commit 480682b

Please sign in to comment.