diff --git a/fp/src/fp_ext.rs b/fp/src/fp_ext.rs index 8a56c91..875df5e 100644 --- a/fp/src/fp_ext.rs +++ b/fp/src/fp_ext.rs @@ -97,7 +97,7 @@ use std::marker::PhantomData; use crate::field_ops::{FieldFromRepr, FieldOps, FieldRandom}; use crate::fp_element::FpElement; -use crypto_bigint::{Uint, modular::ConstPrimeMontyParams}; +use crypto_bigint::{modular::ConstPrimeMontyParams, Uint}; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; // =========================================================================== @@ -429,6 +429,61 @@ where Self::new(coeffs_fp) } + /// Returns an element $\sum_{i=0}^{M-1} c_i x^i \in + /// \mathbb{F}\_{p^M} = \mathbb{F}\_{p}\[x\] / (f(x))$ from a + /// coefficient array $[c_0, ..., c_{M-1}]$ of `Uint` + /// integers. + /// + /// # Arguments + /// + /// * `coeffs` - The coefficient array (type: `[Uint; M]`). + /// + /// # Returns + /// + /// The element $\sum_{i=0}^{M-1} c_i x^i \in \mathbb{F}\_{p^M}$ + /// (type: `Self`). + /// + /// # Examples + /// + /// ``` + /// # use crypto_bigint::{const_prime_monty_params, Uint}; + /// # use fp::field_ops::{FieldOps, FieldRandom}; + /// # use fp::fp_element::FpElement; + /// # use fp::fp_ext::{FpExt, IrreduciblePoly, TonelliShanksConstants}; + /// # const_prime_monty_params!(Fp19Mod, Uint<1>, "0000000000000013", 2); + /// # type Fp19 = FpElement; + /// # + /// # struct QuadPoly; + /// # struct TSQuad; + /// # + /// # impl IrreduciblePoly for QuadPoly { + /// # fn modulus() -> [Fp19; 2] { + /// # [Fp19::one(), Fp19::zero()] + /// # } + /// # } + /// # + /// # impl TonelliShanksConstants for TSQuad { + /// # const ORDER: Uint<1> = Uint::<1>::from_u64(360); + /// # const HALF_ORDER: Uint<1> = Uint::<1>::from_u64(180); + /// # const S: u64 = 3; + /// # const T: Uint<1> = Uint::<1>::from_u64(45); + /// # const PROJENATOR_EXP: Uint<1> = Uint::<1>::from_u64(22); + /// # const TWOSM1: Uint<1> = Uint::<1>::from_u64(4); + /// # fn root_of_unity() -> [FpElement; 2] { + /// # [Fp19::from_u64(3), Fp19::from_u64(3)] + /// # } + /// # } + /// # + /// # type F19_2 = FpExt; + /// let a = F19_2::from_u64([3, 5]); + /// let b = F19_2::from_uint([Uint::<1>::from_u64(3), Uint::<1>::from_u64(5)]); + /// assert_eq!(a, b); + /// ``` + pub fn from_uint(coeffs: [Uint; M]) -> Self { + let coeffs_fp = std::array::from_fn(|i| FpElement::from_uint(coeffs[i])); + Self::new(coeffs_fp) + } + /// Embed an element of the base-field $\mathbb{F}\_p$ as $a + 0x + /// \dots + 0x^{M-1} \in \mathbb{F}\_{p^M}$. ///