From a9712cd992e0fa81c82bcab12953c1444f53946c Mon Sep 17 00:00:00 2001 From: Sam Frengley Date: Fri, 17 Apr 2026 10:27:49 +0200 Subject: [PATCH 1/2] fixed some broken docs --- .cargo/config.toml | 2 +- fp/src/f2_element.rs | 5 +- fp/src/f2_ext.rs | 15 +++--- fp/src/field_ops.rs | 121 +++++++++++++++++++++---------------------- fp/src/fp_ext.rs | 10 ++-- fp/src/lib.rs | 2 +- 6 files changed, 76 insertions(+), 79 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 8e5e901..1c0361a 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,5 +1,5 @@ [build] -rustdocflags = ["--html-in-header", "katex-header.html", "-D", "missing_docs"] +rustdocflags = ["--html-in-header", "katex-header.html", "-Dmissing_docs", "-Dwarnings"] [alias] ourdoc = [ diff --git a/fp/src/f2_element.rs b/fp/src/f2_element.rs index cbc41b4..75918b2 100644 --- a/fp/src/f2_element.rs +++ b/fp/src/f2_element.rs @@ -1,7 +1,6 @@ //! Base binary field element $\mathbb{F}_2 = \mathbb{Z} / //! 2\mathbb{Z}$ - use crate::field_ops::FieldFromRepr; use crate::field_ops::{FieldOps, FieldRandom}; use core::ops::{Add, Mul, Neg, Sub}; @@ -216,12 +215,10 @@ impl FieldRandom for F2Element { } } - - impl FieldFromRepr for F2Element { type Repr = Uint<1>; fn from_repr(x: Self::Repr) -> Self { Self::new(x) } -} \ No newline at end of file +} diff --git a/fp/src/f2_ext.rs b/fp/src/f2_ext.rs index 7e387e4..2d9513b 100644 --- a/fp/src/f2_ext.rs +++ b/fp/src/f2_ext.rs @@ -1,4 +1,4 @@ -//! Generic finary fields $F_{2^m} = F_2\[x\] / (f(x))$ +//! Generic binary fields $\mathbb{F}\_{2^m} = \mathbb{F}\_2\[x\] / (f(x))$ use crate::field_ops::{FieldFromRepr, FieldOps, FieldRandom}; use core::ops::{Add, Mul, Neg, Sub}; @@ -146,7 +146,6 @@ where } } - // --------------------------------------------------------------------------- // CtOption functionalities // --------------------------------------------------------------------------- @@ -405,7 +404,9 @@ where Self::from_uint(Uint::::ONE) } - fn from_u64(x: u64) -> Self { Self::from_u64(x) } + fn from_u64(x: u64) -> Self { + Self::from_u64(x) + } fn is_zero(&self) -> Choice { Self::ct_eq(self, &Self::zero()) @@ -493,7 +494,6 @@ where fn degree() -> u32 { P::degree() as u32 } - } // --------------------------------------------------------------------------- @@ -509,7 +509,6 @@ where /// Fills a `Uint` with random bytes, masks to `m` bits, /// and wraps via `F2Ext::new` (which reduces mod the irreducible). fn random(rng: &mut (impl rand::CryptoRng + rand::Rng)) -> Self { - let m = P::degree(); let mut words = [0u64; LIMBS]; for w in words.iter_mut() { @@ -521,7 +520,10 @@ where let leftover = m % 64; // Zero out limbs beyond the ones we need. - for w in words.iter_mut().skip(full_limbs + if leftover > 0 { 1 } else { 0 }) { + for w in words + .iter_mut() + .skip(full_limbs + if leftover > 0 { 1 } else { 0 }) + { *w = 0; } // Mask the partial top limb. @@ -533,7 +535,6 @@ where } } - impl FieldFromRepr for F2Ext where P: BinaryIrreducible, diff --git a/fp/src/field_ops.rs b/fp/src/field_ops.rs index 45b6c20..5be1002 100644 --- a/fp/src/field_ops.rs +++ b/fp/src/field_ops.rs @@ -82,31 +82,40 @@ pub trait FieldOps: /// `self^exp` using square-and multiply (litte-endian bit order) /// - /// It is constant time for fixed `exp` - /// /// # Arguments /// - /// * `&self` - Finite field element (type: self) + /// * `&self` - Finite field element (type: `Self`) /// * `exp` - Exponent (type: &[u64]) /// /// # Returns /// - /// `&self^exp` (type: Self) - /// - /// # Why `::mul` instead of `result.mul(&base)` - /// - /// `FieldOps` requires `Mul` as a supertrait, so `Self` - /// exposes **two** methods named `mul`: - /// - /// - `::mul(self, rhs: Self) -> Self` ← operator, takes by value - /// - `::mul(&self, rhs: &Self) -> Self` ← ours, takes by ref - /// - /// Writing `result.mul(&base)` triggers method resolution, which picks - /// `Mul::mul` (the operator) because it was declared first in the supertrait - /// list. `Mul::mul` expects `Self`, not `&Self` → E0308. - /// - /// Fully-qualified syntax `::mul(...)` bypasses method - /// resolution entirely and calls exactly the trait method we want. + /// `&self^exp` (type: `Self`) + /// + /// # Warnings + /// + /// This function is constant time only if two exponents `exp1` + /// and `exp2` are equal as [u64] (i.e., they are the same number + /// AND the same number of limbs) + // + // # Notes + // + // `::mul` is used instead of + // `result.mul(&base)` because `FieldOps` requires `Mul` as a supertrait, so `Self` exposes **two** methods + // named `mul`: + // + // - `::mul(self, rhs: Self) -> Self` ← operator, + // takes by value - `::mul(&self, rhs: &Self) + // -> Self` ← ours, takes by ref + // + // Writing `result.mul(&base)` triggers method resolution, which + // picks `Mul::mul` (the operator) because it was declared first + // in the supertrait list. `Mul::mul` expects `Self`, not `&Self` + // → E0308. + // + // Fully-qualified syntax `::mul(...)` bypasses + // method resolution entirely and calls exactly the trait method + // we want. fn pow_vartime(&self, exp: &[u64]) -> Self { let mut result = Self::one(); let mut base = self.clone(); @@ -127,21 +136,21 @@ pub trait FieldOps: /// `self^pow` in constant time using a Montgomery ladder /// /// Uses a Montgomery ladder to compute `self^exp` - /// WARNING: Only constant time if the number of limbs of exp is - /// constant /// /// # Arguments /// - /// * `&self` - Element of $\mathbb{F}_p$ (type: self) + /// * `&self` - Element of $\mathbb{F}\_{p^M}$ (type: `Self`) /// * `exp` - Exponent (type: &[u64]) /// /// # Returns /// - /// The value `self^pow` (type: Self) + /// The value `self^pow` (type: `Self`) /// - /// # Todo + /// # Warning /// - /// Use `subtle` and `conditional_swap` to make true constant time + /// This function is only constant time if the number of limbs of + /// `exp` is fixed (so `[1,0]` would run in different time to + /// `[1]`) fn pow(&self, exp: &[u64]) -> Self { let mut result = Self::one(); let mut base = self.clone(); @@ -172,45 +181,38 @@ pub trait FieldOps: result } - /// compute the norm of `self` down to $\mathbb{F}_p$ (as an + /// Compute the norm of `self` down to $\mathbb{F}_p$ (as an /// element of type `Self`) fn norm(&self) -> Self; - /// compute the trace of `self` down to $\mathbb{F}_p$ (as an + /// Compute the trace of `self` down to $\mathbb{F}_p$ (as an /// element of type `Self`) fn trace(&self) -> Self; /// Returns a squareroot if it exists /// - /// Returns a squareroof of `self` if it exists in the finite - /// field $\mathbb{F}_{p^M}$. The return type is `CtOption` - /// and it is not none if and only if the squareroot exists. This - /// is an implementation fo the Tonelli--Shanks algorithm in the - /// multiplicative group $\mathbb{F}_{p^M}^*$ - /// /// # Arguments /// - /// * `&self` - Element of $\mathbb{F}_{p^M}$ (type: self) + /// * `&self` - Element of $\mathbb{F}_{p^M}$ (type: `Self`) /// /// # Returns /// - /// The square root of `self` (type: `CtOption`) + /// * $\sqrt{\texttt{self}}$ which is not `none` if and only if + /// the square root of `self` exists (type: `CtOption`) fn sqrt(&self) -> CtOption; /// Computes the inverse and square root of `self` /// - /// Computes simulaineously the inverse and square root of `self`. - /// /// # Arguments /// - /// * `&self` - Element of $\mathbb{F}_{p^M}$ (type: self) + /// * `&self` - Element of $\mathbb{F}_{p^M}$ (type: `Self`) /// /// # Returns /// - /// The inverse and square root of `self`. The former is none if - /// and only if nonzero and the latter is not none if and only if - /// there exists a squareroot in $\mathbb{F}_{p^M}$ - /// (type: `(CtOption, CtOption)`) + /// * `(inv, sqrt)` the inverse and the square root of `self`. The + /// former is none if and only if nonzero and the latter is not + /// none if and only if there exists a squareroot in + /// $\mathbb{F}_{p^M}$ (type: `(CtOption, CtOption)`) fn inverse_and_sqrt(&self) -> (CtOption, CtOption) { (self.invert(), self.sqrt()) } @@ -219,33 +221,31 @@ pub trait FieldOps: /// /// # Arguments /// - /// * `&self` - Element of $\mathbb{F}_{p^M}$ (type: self) + /// * `&self` - Element of $\mathbb{F}_{p^M}$ (type: `Self`) /// /// # Returns /// - /// The square root of the inverse of `self`. The former is not - /// none if and only if it is both nonzero there exists a - /// squareroot in $\mathbb{F}_{p^M}$ (type: `CtOption`) + /// * $1 / \sqrt{\texttt{self}}$. The is not none if and only if + /// `self` is both nonzero there exists a squareroot in + /// $\mathbb{F}_{p^M}$ (type: `CtOption`) fn inv_sqrt(&self) -> CtOption { self.sqrt().and_then(|s| s.invert()) } /// Computes the inverse of `self` and square root of `rhs` /// - /// Computes simulaineously the inverse of `self` and square root - /// of `rhs`. - /// /// # Arguments /// - /// * `&self` - Element of $\mathbb{F}_{p^M}$ (type: self) + /// * `&self` - Element of $\mathbb{F}_{p^M}$ (type: `Self`) /// * `rhs` - Element of $\mathbb{F}_{p^M}$ (type: &Self) /// /// # Returns /// - /// The inverse of `self` and square root fo `rhs`. Theq former is - /// none if and only if `self` is nonzero and the latter is not - /// none if and only if there exists a squareroot of `rhs` in $\mathbb{F}_{p^M}$ - /// (type: `(CtOption, CtOption)`) + /// * `(inv, sqrt)` where `inv` is the inverse of `self` `sqrt` is + /// the square root fo `rhs`. `inv` is `none` if and only if + /// `self` is zero and the `sqrt` is not none if and only if + /// there exists a squareroot of `rhs` in $\mathbb{F}_{p^M}$ + /// (type: `(CtOption, CtOption)`) fn invertme_sqrtother(&self, rhs: &Self) -> (CtOption, CtOption) { (self.invert(), rhs.sqrt()) } @@ -254,14 +254,14 @@ pub trait FieldOps: /// /// # Arguments /// - /// * `&self` - Element of $\mathbb{F}_{p^M}$ (type: self) - /// * `rhs` - Element of $\mathbb{F}_{p^M}$ (type: &Self) + /// * `&self` - Element of $\mathbb{F}_{p^M}$ (type: `Self`) + /// * `rhs` - Element of $\mathbb{F}_{p^M}$ (type: `&Self`) /// /// # Returns /// - /// The squareroot of the ratio `self/rhs` is not none if and only - /// if `rhs` is invertible and the ratio has an $\mathbb{F}_{p^M}$ squareroot - /// (type: `(CtOption, CtOption))` + /// * $\sqrt{\texttt{self} / \texttt{rhs}}$ which is not `none` if and only + /// both `rhs` is invertible and the ratio has a rational squareroot + /// (type: `(CtOption, CtOption))` fn sqrt_ratio(&self, rhs: &Self) -> CtOption { rhs.invert().and_then(|inv_rhs| self.mul(&inv_rhs).sqrt()) } @@ -278,7 +278,6 @@ pub trait FieldOps: /// Convert u64 to the field. fn from_u64(x: u64) -> Self; - } /// Trait for field types that can be constructed from a field-specific /// representation. @@ -288,4 +287,4 @@ pub trait FieldFromRepr: FieldOps { /// Constructs a field element from the given representation. fn from_repr(x: Self::Repr) -> Self; -} \ No newline at end of file +} diff --git a/fp/src/fp_ext.rs b/fp/src/fp_ext.rs index 9061dcf..7f3c5b5 100644 --- a/fp/src/fp_ext.rs +++ b/fp/src/fp_ext.rs @@ -9,9 +9,9 @@ //! modulo $f$. //! //! This module provides a single generic type [`FpExt`] that covers *any* such extension. The -//! irreducible polynomial is supplied via the zero-size marker trait -//! [`IrreduciblePoly`]. +//! N, P, TSCONSTS>`](self::fp_ext::FpExt) that covers *any* such +//! extension. The irreducible polynomial is supplied via the +//! zero-size marker trait [`IrreduciblePoly`](self::fp_ext::FpExt). //! //! # Example //! @@ -1161,8 +1161,8 @@ where } } -impl -FieldFromRepr for FpExt +impl FieldFromRepr + for FpExt where MOD: ConstPrimeMontyParams, P: IrreduciblePoly, diff --git a/fp/src/lib.rs b/fp/src/lib.rs index febbf4b..6993b6e 100644 --- a/fp/src/lib.rs +++ b/fp/src/lib.rs @@ -11,7 +11,7 @@ /// Binary base field $\mathbb{F}_2$ and its arithmetic. pub mod f2_element; -/// Binary extension fields $\mathbb{F}_{2^m}$ built from irreducible polynomials. +/// Binary extension fields $\mathbb{F}\_{2^m}$ built from irreducible polynomials. pub mod f2_ext; /// Core field traits shared by prime and binary fields. pub mod field_ops; From 5875e03061bc09bf3ec90687c3b3589baa1e6745 Mon Sep 17 00:00:00 2001 From: Sam Frengley Date: Wed, 22 Apr 2026 09:41:11 +0200 Subject: [PATCH 2/2] Doc edits --- fp/src/lib.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fp/src/lib.rs b/fp/src/lib.rs index 6993b6e..c787936 100644 --- a/fp/src/lib.rs +++ b/fp/src/lib.rs @@ -4,9 +4,12 @@ //! //! ```text //! fp -//! ├── field_ops - FieldOps trait (the algebraic contract) -//! ├── fp_element - Base prime field Fp element -//! └── fp_ext - Extension prime field Elements +//! ├── f2_element.rs +//! ├── f2_ext.rs +//! ├── field_ops.rs +//! ├── fp_element.rs +//! ├── fp_ext.rs +//! └── lib.rs //! ``` /// Binary base field $\mathbb{F}_2$ and its arithmetic.