From c1920e3a1a1b88c27a4fe215f4a3c746350a12b2 Mon Sep 17 00:00:00 2001 From: Himess <95512809+Himess@users.noreply.github.com> Date: Fri, 9 May 2025 08:01:46 +0300 Subject: [PATCH] docs: add module and function documentation (#408) --- CHANGELOG.md | 1 + .../src/dsa/rpo_falcon512/keys/public_key.rs | 12 ++++++++++++ .../src/dsa/rpo_falcon512/math/polynomial.rs | 15 +++++++++++++++ miden-crypto/src/dsa/rpo_falcon512/signature.rs | 7 ++++++- miden-crypto/src/hash/mod.rs | 4 ++++ miden-crypto/src/hash/rescue/rpo/digest.rs | 9 +++++++++ 6 files changed, 47 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a7928b..30b2376 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## 0.15.0 (TBD) - Added default constructors to `MmrPeaks` and `PartialMmr` (#409). +- Add module and function documentation. (#408). ## 0.14.0 (2025-03-15) diff --git a/miden-crypto/src/dsa/rpo_falcon512/keys/public_key.rs b/miden-crypto/src/dsa/rpo_falcon512/keys/public_key.rs index 36eb849..7ad3f2f 100644 --- a/miden-crypto/src/dsa/rpo_falcon512/keys/public_key.rs +++ b/miden-crypto/src/dsa/rpo_falcon512/keys/public_key.rs @@ -1,3 +1,13 @@ +//! Public key types for the RPO Falcon 512 digital signature scheme used in Miden VM. +//! +//! This module defines two main types: +//! - `PublicKey`: A commitment to a polynomial, represented as a hash of the polynomial’s +//! coefficients. +//! - `PubKeyPoly`: A public key represented directly as a polynomial over FalconFelt coefficients. +//! +//! The `PublicKey` is used for signature verification. +//! The `PubKeyPoly` provides the raw polynomial form of a public key. + use alloc::string::ToString; use core::ops::Deref; @@ -50,6 +60,8 @@ impl From for Word { // PUBLIC KEY POLYNOMIAL // ================================================================================================ +/// Public key represented as a polynomial with coefficients over the Falcon prime field. +/// Used in the RPO Falcon 512 signature scheme. #[derive(Debug, Clone, PartialEq, Eq)] pub struct PubKeyPoly(pub Polynomial); diff --git a/miden-crypto/src/dsa/rpo_falcon512/math/polynomial.rs b/miden-crypto/src/dsa/rpo_falcon512/math/polynomial.rs index 5989ba1..7588458 100644 --- a/miden-crypto/src/dsa/rpo_falcon512/math/polynomial.rs +++ b/miden-crypto/src/dsa/rpo_falcon512/math/polynomial.rs @@ -1,3 +1,5 @@ +//! Generic polynomial type and operations used in Falcon. + use alloc::vec::Vec; use core::{ default::Default, @@ -13,8 +15,10 @@ use crate::{ dsa::rpo_falcon512::{MODULUS, N}, }; +/// Represents a polynomial with coefficients of type F. #[derive(Debug, Clone, Default)] pub struct Polynomial { + /// Coefficients of the polynomial, ordered from lowest to highest degree. pub coefficients: Vec, } @@ -22,6 +26,7 @@ impl Polynomial where F: Clone, { + /// Creates a new polynomial from the provided coefficients. pub fn new(coefficients: Vec) -> Self { Self { coefficients } } @@ -30,6 +35,7 @@ where impl + Sub + AddAssign + Zero + Div + Clone + Inverse> Polynomial { + /// Multiplies two polynomials coefficient-wise (Hadamard multiplication). pub fn hadamard_mul(&self, other: &Self) -> Self { Polynomial::new( self.coefficients @@ -39,6 +45,7 @@ impl + Sub + AddAssign + Zero + Div + .collect(), ) } + /// Divides two polynomials coefficient-wise (Hadamard division). pub fn hadamard_div(&self, other: &Self) -> Self { let other_coefficients_inverse = F::batch_inverse_or_zero(&other.coefficients); Polynomial::new( @@ -50,6 +57,7 @@ impl + Sub + AddAssign + Zero + Div + ) } + /// Computes the coefficient-wise inverse (Hadamard inverse). pub fn hadamard_inv(&self) -> Self { let coefficients_inverse = F::batch_inverse_or_zero(&self.coefficients); Polynomial::new(coefficients_inverse) @@ -57,6 +65,7 @@ impl + Sub + AddAssign + Zero + Div + } impl Polynomial { + /// Returns the degree of the polynomial. pub fn degree(&self) -> Option { if self.coefficients.is_empty() { return None; @@ -72,6 +81,7 @@ impl Polynomial { Some(max_index) } + /// Returns the leading coefficient of the polynomial. pub fn lc(&self) -> F { match self.degree() { Some(non_negative_degree) => self.coefficients[non_negative_degree].clone(), @@ -392,20 +402,24 @@ where } impl Polynomial { + /// Shifts the polynomial by the specified amount (adds leading zeros). pub fn shift(&self, shamt: usize) -> Self { Self { coefficients: [vec![F::zero(); shamt], self.coefficients.clone()].concat(), } } + /// Creates a constant polynomial with a single coefficient. pub fn constant(f: F) -> Self { Self { coefficients: vec![f] } } + /// Applies a function to each coefficient and returns a new polynomial. pub fn map G>(&self, closure: C) -> Polynomial { Polynomial::::new(self.coefficients.iter().map(closure).collect()) } + /// Folds the coefficients using the provided function and initial value. pub fn fold G + Clone>(&self, mut initial_value: G, closure: C) -> G { for c in self.coefficients.iter() { initial_value = (closure.clone())(initial_value, c); @@ -544,6 +558,7 @@ impl From<&Vec> for Polynomial { } impl Polynomial { + /// Computes the squared L2 norm of the polynomial. pub fn norm_squared(&self) -> u64 { self.coefficients .iter() diff --git a/miden-crypto/src/dsa/rpo_falcon512/signature.rs b/miden-crypto/src/dsa/rpo_falcon512/signature.rs index db35051..6011e98 100644 --- a/miden-crypto/src/dsa/rpo_falcon512/signature.rs +++ b/miden-crypto/src/dsa/rpo_falcon512/signature.rs @@ -56,6 +56,9 @@ pub struct Signature { impl Signature { // CONSTRUCTOR // -------------------------------------------------------------------------------------------- + + /// Creates a new signature from the given nonce, public key polynomial, and signature + /// polynomial. pub fn new(nonce: Nonce, h: PubKeyPoly, s2: SignaturePoly) -> Signature { Self { header: SignatureHeader::default(), @@ -73,7 +76,7 @@ impl Signature { &self.h } - // Returns the polynomial representation of the signature in Z_p[x]/(phi). + /// Returns the polynomial representation of the signature in Z_p\[x\]/(phi). pub fn sig_poly(&self) -> &Polynomial { &self.s2 } @@ -124,6 +127,7 @@ impl Deserializable for Signature { // SIGNATURE HEADER // ================================================================================================ +/// The header byte used to encode the signature metadata. #[derive(Debug, Clone, PartialEq, Eq)] pub struct SignatureHeader(u8); @@ -174,6 +178,7 @@ impl Deserializable for SignatureHeader { // SIGNATURE POLYNOMIAL // ================================================================================================ +/// A polynomial used as the `s2` component of the signature. #[derive(Debug, Clone, PartialEq, Eq)] pub struct SignaturePoly(pub Polynomial); diff --git a/miden-crypto/src/hash/mod.rs b/miden-crypto/src/hash/mod.rs index e7fd9c7..3fe9777 100644 --- a/miden-crypto/src/hash/mod.rs +++ b/miden-crypto/src/hash/mod.rs @@ -2,13 +2,17 @@ use super::{CubeExtension, Felt, FieldElement, StarkField, ZERO}; +/// Blake2s hash function. pub mod blake; mod rescue; + +/// Rescue Prime Optimized (RPO) hash function. pub mod rpo { pub use super::rescue::{Rpo256, RpoDigest, RpoDigestError}; } +/// Rescue Prime Extended (RPX) hash function. pub mod rpx { pub use super::rescue::{Rpx256, RpxDigest, RpxDigestError}; } diff --git a/miden-crypto/src/hash/rescue/rpo/digest.rs b/miden-crypto/src/hash/rescue/rpo/digest.rs index 47d09c6..961a104 100644 --- a/miden-crypto/src/hash/rescue/rpo/digest.rs +++ b/miden-crypto/src/hash/rescue/rpo/digest.rs @@ -21,6 +21,7 @@ use crate::{ // DIGEST TRAIT IMPLEMENTATIONS // ================================================================================================ +/// An RPO digest consisting of 4 field elements. #[derive(Debug, Default, Copy, Clone, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", serde(into = "String", try_from = "&str"))] @@ -30,18 +31,22 @@ impl RpoDigest { /// The serialized size of the digest in bytes. pub const SERIALIZED_SIZE: usize = DIGEST_BYTES; + /// Creates a new RpoDigest from the given field elements. pub const fn new(value: [Felt; DIGEST_SIZE]) -> Self { Self(value) } + /// Returns the digest as a slice of field elements. pub fn as_elements(&self) -> &[Felt] { self.as_ref() } + /// Returns the digest as a byte array. pub fn as_bytes(&self) -> [u8; DIGEST_BYTES] { ::as_bytes(self) } + /// Returns an iterator over the elements of multiple digests. pub fn digests_as_elements_iter<'a, I>(digests: I) -> impl Iterator where I: Iterator, @@ -49,6 +54,7 @@ impl RpoDigest { digests.flat_map(|d| d.0.iter()) } + /// Returns all elements of multiple digests as a slice. pub fn digests_as_elements(digests: &[Self]) -> &[Felt] { let p = digests.as_ptr(); let len = digests.len() * DIGEST_SIZE; @@ -141,10 +147,13 @@ impl Randomizable for RpoDigest { // CONVERSIONS: FROM RPO DIGEST // ================================================================================================ +/// Errors that can occur when working with RpoDigest. #[derive(Debug, Error)] pub enum RpoDigestError { + /// Failed to convert digest field element to the specified type. #[error("failed to convert digest field element to {0}")] TypeConversion(&'static str), + /// Field element conversion failed due to invalid value. #[error("failed to convert to field element: {0}")] InvalidFieldElement(String), }