///|
/// Polynomial vector operations for the Dilithium signature scheme.
///
/// This module implements operations on vectors of polynomials, which are
/// fundamental data structures in the Dilithium signature scheme. These vectors
/// represent elements in the module lattice used by the underlying cryptographic
/// construction.
///
/// # Mathematical Structure
///
/// The module implements two types of polynomial vectors:
/// - `Polyvecl`: Vectors of length l (typically l = k or l = k+1)
/// - `Polyveck`: Vectors of length k
///
/// Both types operate in the polynomial ring Z_q[X]/(X^N + 1) where:
/// - q = 8380417 (the modulus)
/// - N = 256 (the polynomial degree)
///
/// # Vector Operations
///
/// The module provides essential operations including:
/// - Vector addition and subtraction
/// - Pointwise polynomial multiplication
/// - Norm checking for security bounds
/// - NTT transformations for efficient multiplication
/// - Specialized packing/unpacking for keys and signatures
///
/// # Examples
///
/// ```moonbit
/// // Create polynomial vectors
/// let v1 = @ruifeng/moondsa.Polyveck::default()
/// let v2 = @ruifeng/moondsa.Polyveck::default()
///
/// // Vector operations
/// v1.add(v2) // v1 = v1 + v2
/// let norm = v1.chknorm(1000) // Check if coefficients are within bounds
/// ```
///|
/// Vector of polynomials with length k, where k is determined by the Dilithium
/// parameter set.
///
/// This structure represents one of the core data types in the Dilithium
/// post-quantum cryptographic scheme. The length k corresponds to the security
/// parameter that defines the dimensions of the underlying lattice problem.
/// Each polynomial in the vector operates in the ring Z\_q\[X]/(X^256 + 1)
/// where q is the modulus used in Dilithium.
///
/// Fields:
///
/// * `vec` : Array containing k polynomials, where each polynomial represents a
/// vector component in the lattice-based operations.
pub struct Polyveck {
vec : Array[Poly]
} derive(Show)
///|
/// Creates a deep copy of the polynomial vector.
///
/// Parameters:
///
/// * `self` : The polynomial vector to copy.
///
/// Returns a new `Polyveck` instance with deeply copied polynomials, ensuring
/// that modifications to the returned vector or its polynomials do not affect
/// the original.
///
pub fn Polyveck::copy(self : Polyveck) -> Polyveck {
let new_vec = Array::new()
for poly in self.vec {
new_vec.push(poly.copy())
}
{ vec: new_vec }
}
///|
/// Creates a default `Polyveck` instance with a vector of `k` polynomials,
/// where `k` is determined by the current Dilithium parameter set.
///
/// Returns a new `Polyveck` with each polynomial initialized using
/// `Poly::new()`.
///
/// Example:
///
/// ```moonbit
/// let polyveck = Polyveck::default()
/// println(polyveck.vec.length()) // prints the value of k from current parameter set
/// ```
///
pub impl Default for Polyveck with default() -> Polyveck {
let k = dilithium_context.get_params_set().k
let vec = Array::new()
for _i in 0.. Polyvecl {
let new_vec = Array::new()
for poly in self.vec {
new_vec.push(poly.copy())
}
{ vec: new_vec }
}
///|
/// Creates a default `Polyvecl` instance with polynomials initialized to zero.
///
/// Returns a new `Polyvecl` containing `l` zero-initialized polynomials, where
/// `l` is obtained from the current Dilithium parameter set.
///
pub impl Default for Polyvecl with default() -> Polyvecl {
let l = dilithium_context.get_params_set().l
let vec = Array::new()
for _i in 0.. Unit {
let k = dilithium_context.get_params_set().k
let l = dilithium_context.get_params_set().l
for i in 0.. Unit {
let k = dilithium_context.get_params_set().k
for i in 0.. Unit {
let l = dilithium_context.get_params_set().l
let mut nonce = nonce
for i in 0.. Unit {
let l = dilithium_context.get_params_set().l
let l_u16 = l.to_uint16()
for i in 0.. Unit {
let l = dilithium_context.get_params_set().l
for i in 0.. Unit {
let l = dilithium_context.get_params_set().l
for i in 0.. Unit {
let l = dilithium_context.get_params_set().l
for i in 0.. Unit {
let l = dilithium_context.get_params_set().l
for i in 0.. Unit {
let l = dilithium_context.get_params_set().l
for i in 0.. Unit {
let l = dilithium_context.get_params_set().l
let t = Poly::default()
w.pointwise_montgomery(u.vec[0], v.vec[0])
for i in 1.. Byte {
let l = dilithium_context.get_params_set().l
for i in 0.. 0 {
return 1
}
}
return 0
}
//*********** Vectors of polynomials of length K ****************************
///|
/// Generates uniform random polynomials with coefficients in the range \[-eta,
/// eta] for all polynomials in the vector.
///
/// Parameters:
///
/// * `v` : The polynomial vector of length K to be filled with uniform random
/// coefficients.
/// * `seed` : The random seed bytes used for generating the uniform
/// distribution.
/// * `nonce` : The starting nonce value used for randomness generation,
/// incremented for each polynomial.
pub fn Polyveck::uniform_eta(
v : Polyveck,
seed : Array[Byte],
nonce : UInt16,
) -> Unit {
let k = dilithium_context.get_params_set().k
let mut nonce = nonce
for i in 0.. Unit {
let k = dilithium_context.get_params_set().k
for i in 0.. Unit {
let k = dilithium_context.get_params_set().k
for i in 0.. Unit {
let k = dilithium_context.get_params_set().k
for i in 0.. Unit {
let k = dilithium_context.get_params_set().k
for i in 0.. Unit {
let k = dilithium_context.get_params_set().k
for i in 0.. Unit {
let k = dilithium_context.get_params_set().k
for i in 0.. Unit {
let k = dilithium_context.get_params_set().k
for i in 0.. Unit {
let k = dilithium_context.get_params_set().k
for i in 0.. Byte {
let k = dilithium_context.get_params_set().k
for i in 0.. 0 {
return 1
}
}
return 0
}
///| For all coefficients a of polynomials in vector of length K,
/// compute a0, a1 such that a mod Q = a1*2^D + a0
/// with -2^{D-1} < a0 <= 2^{D-1}. Assumes coefficients to be
/// standard representatives.
pub fn Polyveck::power2round(v1 : Polyveck, v0 : Polyveck) -> Unit {
let k = dilithium_context.get_params_set().k
for i in 0.. Unit {
let k = dilithium_context.get_params_set().k
for i in 0.. Int {
let k = dilithium_context.get_params_set().k
let mut s = 0
for i in 0.. Unit {
let k = dilithium_context.get_params_set().k
for i in 0.. Unit {
let k = dilithium_context.get_params_set().k
let mut idx = 0
for i in 0..