Skip to content

Commit

Permalink
Add documentation and improve source quality.
Browse files Browse the repository at this point in the history
  • Loading branch information
mmaker committed Jan 20, 2024
1 parent 619d2e7 commit 8f4f6a4
Show file tree
Hide file tree
Showing 17 changed files with 158 additions and 72 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.vscode
target/
82 changes: 38 additions & 44 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ ark-ff = {git = "https://github.com/arkworks-rs/algebra"}
ark-serialize = {git = "https://github.com/arkworks-rs/algebra"}
ark-serialize-derive = {git = "https://github.com/arkworks-rs/algebra"}
ark-bls12-381 = {git = "https://github.com/arkworks-rs/algebra"}
ark-algebra-test-templates = {git = "https://github.com/arkworks-rs/algebra"}

[dependencies]
zeroize = {version="1.6.0", features=["zeroize_derive"]}
Expand Down
5 changes: 3 additions & 2 deletions scripts/useful_bits_modp.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""
has a statistical distance from uniformly random given by:
Return the number of uniformly distributed bits in a little-endian representation of a
uniformly-random mod-p integer.
p is provided on stdin in any format that python can eval. For example,
The prime `p` is provided on stdin in any format that python can eval. For example,
$ python3 scripts/useful_bits_modp.py <<< 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab
"""
Expand Down
25 changes: 25 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
/// The [`nimue`] package has two types of errors:
/// [`IOPatternError`], which is the error exposed in the low-level interface for bytes and native elements,
/// which arises whenever the IO Pattern specified and the IO pattern exectuted mismatch.
/// [`ProofError`], which is the error exposed to high-level interfaces dealing with structured types and
/// for end-user applications.
/// Three types of errors can happen when dealing with [`ProofError`]:
///
/// - Serialization/Deseralization errors ([`ProofError::SerializationError`]):
/// This includes all potential problems when extracting a particular type from sequences of bytes.
///
/// - Invalid Proof format ([`ProofError::InvalidIO`]):
/// At a higher level, a proof object have to respect the same length and the same types as the protocol description.
/// This error is a wrapper under the [`IOPatternError`] and provides convenient dereference/conversion implementations for
/// moving from/to an [`IOPatternError`].
///
/// - Invalid Proof:
/// 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};

/// Signals an invalid IO pattern.
Expand All @@ -7,13 +26,19 @@ use std::{borrow::Borrow, error::Error, fmt::Display};
#[derive(Debug, Clone)]
pub struct IOPatternError(String);


/// An error happened when creating or verifying a proof.
#[derive(Debug, Clone)]
pub enum ProofError {
/// Signals the verification equation has failed.
InvalidProof,
/// The IO pattern specified mismatches the IO pattern used during the protocol execution.
InvalidIO(IOPatternError),
/// Serialization/Deserialization led to errors.
SerializationError,
}

/// The result type when trying to prove or verify a proof using Fiat-Shamir.
pub type ProofResult<T> = Result<T, ProofError>;

impl Display for IOPatternError {
Expand Down
5 changes: 5 additions & 0 deletions src/hash/anemoi.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
//! Work-in-progress (but working) implementation of the Anemoi hash function.
//!
//! The main reason for this code not being deployed is that [anemoi](https://anemoi-hash.github.io/)'s Rust implementation
//! is not published as a crate and thus `nimue` cannot publish it along with a new release.
use ark_ff::Field;
use std::ops::{Index, IndexMut, Range, RangeFrom, RangeTo};
use zeroize::Zeroize;
Expand Down
2 changes: 0 additions & 2 deletions src/hash/keccak.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//! A wrapper around the Keccak-f\[1600\] permutation.
//!
//! **Warning**: this function is not SHA3.
//! Despite internally we use the same permutation,
//! we build a duplex sponge in overwrite mode
Expand Down
2 changes: 0 additions & 2 deletions src/hash/legacy.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//! Legacy hash functions interface.
//!
//! This code is inspired from libsignal's poksho:
//! <https://github.com/signalapp/libsignal/blob/main/rust/poksho/src/shosha256.rs>.
//! With the following generalizations:
Expand Down
27 changes: 19 additions & 8 deletions src/hash/mod.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,44 @@
/// Hash functions traits and implmentations.
//! This module defines
//! [`DuplexHash`], the basic interface for hash function that can absorb and squeeze data.
//! Hashes in nume operate over some native elements satisfying the trait [`Unit`] which, roughly speaking, requires
//! the basic type to support cloning, size, read/write procedures, and secure deletion.
//!
//! Additionally, the module exports some utilities:
//! - [`sponge::DuplexSponge`] allows to implement a [`DuplexHash`] using a secure permutation function, specifying `RATE` and `CAPACITY`.
//! This is done using the standard duplex sponge cosntruction in overwrite mode (cf. [Wikipedia](https://en.wikipedia.org/wiki/Sponge_function#Duplex_construction)).
//! - [`legacy::DigestBridge`] takes as input any hash function implementing the NIST API via the standard [`digest::Digest`] trait and makes it suitable for usage in duplex mode for continuous absorb/squeeze.
/// SHA3 sponge function.

/// A wrapper around the Keccak-f\[1600\] permutation.
pub mod keccak;
/// Support for legacy hash functions (SHA2).
/// Legacy hash functions support (e.g. [`sha2`](https://crates.io/crates/sha2), [`blake2`](https://crates.io/crates/blake2)).
pub mod legacy;
/// Sponge functions.
pub mod sponge;

#[cfg(feature = "anemoi")]
pub mod anemoi;

// Re-export the supported hash functions.
pub use keccak::Keccak;

use std::io;

/// Basic units over which a sponge operates.
///
/// We require the units to have a precise size in memory, to be clonable,
/// and that we can zeroize them.
pub trait Unit: Clone + Sized + zeroize::Zeroize {
/// Write a bunch of units in the wire.
fn write(bunch: &[Self], w: &mut impl io::Write) -> Result<(), io::Error>;
fn write(bunch: &[Self], w: &mut impl std::io::Write) -> Result<(), std::io::Error>;
/// Read a bunch of units from the wire
fn read(r: &mut impl io::Read, bunch: &mut [Self]) -> Result<(), io::Error>;
fn read(r: &mut impl std::io::Read, bunch: &mut [Self]) -> Result<(), std::io::Error>;
}

/// A DuplexHash is an abstract interface for absorbing and squeezing data.
/// A [`DuplexHash`] is an abstract interface for absorbing and squeezing data.
/// The type parameter `U` represents basic unit that the sponge works with.
///
/// We require [`DuplexHash`] implementations to have a [`std::default::Default`] implementation, that initializes
/// to zero the hash function state, and a [`zeroize::Zeroize`] implementation for secure deletion.
///
/// **HAZARD**: Don't implement this trait unless you know what you are doing.
/// Consider using the sponges already provided by this library.
pub trait DuplexHash<U = u8>: Default + Clone + zeroize::Zeroize
Expand Down
Loading

0 comments on commit 8f4f6a4

Please sign in to comment.