docs: add module and function documentation (#408)
This commit is contained in:
parent
03647457d9
commit
c1920e3a1a
6 changed files with 47 additions and 1 deletions
|
@ -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)
|
||||
|
||||
|
|
|
@ -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<PublicKey> 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<FalconFelt>);
|
||||
|
||||
|
|
|
@ -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<F> {
|
||||
/// Coefficients of the polynomial, ordered from lowest to highest degree.
|
||||
pub coefficients: Vec<F>,
|
||||
}
|
||||
|
||||
|
@ -22,6 +26,7 @@ impl<F> Polynomial<F>
|
|||
where
|
||||
F: Clone,
|
||||
{
|
||||
/// Creates a new polynomial from the provided coefficients.
|
||||
pub fn new(coefficients: Vec<F>) -> Self {
|
||||
Self { coefficients }
|
||||
}
|
||||
|
@ -30,6 +35,7 @@ where
|
|||
impl<F: Mul<Output = F> + Sub<Output = F> + AddAssign + Zero + Div<Output = F> + Clone + Inverse>
|
||||
Polynomial<F>
|
||||
{
|
||||
/// Multiplies two polynomials coefficient-wise (Hadamard multiplication).
|
||||
pub fn hadamard_mul(&self, other: &Self) -> Self {
|
||||
Polynomial::new(
|
||||
self.coefficients
|
||||
|
@ -39,6 +45,7 @@ impl<F: Mul<Output = F> + Sub<Output = F> + AddAssign + Zero + Div<Output = F> +
|
|||
.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<F: Mul<Output = F> + Sub<Output = F> + AddAssign + Zero + Div<Output = F> +
|
|||
)
|
||||
}
|
||||
|
||||
/// 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<F: Mul<Output = F> + Sub<Output = F> + AddAssign + Zero + Div<Output = F> +
|
|||
}
|
||||
|
||||
impl<F: Zero + PartialEq + Clone> Polynomial<F> {
|
||||
/// Returns the degree of the polynomial.
|
||||
pub fn degree(&self) -> Option<usize> {
|
||||
if self.coefficients.is_empty() {
|
||||
return None;
|
||||
|
@ -72,6 +81,7 @@ impl<F: Zero + PartialEq + Clone> Polynomial<F> {
|
|||
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<F: Zero + Clone> Polynomial<F> {
|
||||
/// 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: Clone, C: FnMut(&F) -> G>(&self, closure: C) -> Polynomial<G> {
|
||||
Polynomial::<G>::new(self.coefficients.iter().map(closure).collect())
|
||||
}
|
||||
|
||||
/// Folds the coefficients using the provided function and initial value.
|
||||
pub fn fold<G, C: FnMut(G, &F) -> 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<i16>> for Polynomial<FalconFelt> {
|
|||
}
|
||||
|
||||
impl Polynomial<FalconFelt> {
|
||||
/// Computes the squared L2 norm of the polynomial.
|
||||
pub fn norm_squared(&self) -> u64 {
|
||||
self.coefficients
|
||||
.iter()
|
||||
|
|
|
@ -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<FalconFelt> {
|
||||
&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<FalconFelt>);
|
||||
|
||||
|
|
|
@ -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};
|
||||
}
|
||||
|
|
|
@ -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] {
|
||||
<Self as Digest>::as_bytes(self)
|
||||
}
|
||||
|
||||
/// Returns an iterator over the elements of multiple digests.
|
||||
pub fn digests_as_elements_iter<'a, I>(digests: I) -> impl Iterator<Item = &'a Felt>
|
||||
where
|
||||
I: Iterator<Item = &'a Self>,
|
||||
|
@ -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),
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue