ark-ff

This crate defines Finite Field traits and useful abstraction models that follow these traits. Implementations of concrete finite fields for some popular elliptic curves can be found in arkworks-rs/curves under arkworks-rs/curves/<your favourite curve>/src/fields/.

This crate contains two types of traits:

The available field traits are:

The models implemented are:

The above two models serve as abstractions for constructing the extension fields Fp^m directly (i.e. m equal 2 or 3) or for creating extension towers to arrive at higher m. The latter is done by applying the extensions iteratively, e.g. cubic extension over a quadratic extension field.

Usage

There are two important traits when working with finite fields: [Field], and [PrimeField]. Let's explore these via examples.

[Field]

The [Field] trait provides a generic interface for any finite field. Types implementing [Field] support common field operations such as addition, subtraction, multiplication, and inverses.

``rust use ark_ff::Field; // We'll use a field associated with the BLS12-381 pairing-friendly // group for this example. use ark_test_curves::bls12_381::Fq2 as F; //ark-stdis a utility crate that enablesarkworkslibraries // to easily supportstdandnostdworkloads, and also re-exports // useful crates that should be common across the entire ecosystem, such asrand`. use arkstd::{One, UniformRand};

let mut rng = arkstd::testrng(); // Let's sample uniformly random field elements: let a = F::rand(&mut rng); let b = F::rand(&mut rng);

// We can add... let c = a + b; // ... subtract ... let d = a - b; // ... double elements ... assert_eq!(c + d, a.double());

// ... multiply ... let e = c * d; // ... square elements ... assert_eq!(e, a.square() - b.square());

// ... and compute inverses ... assert_eq!(a.inverse().unwrap() * a, F::one()); // have to to unwrap, as a could be zero. ```

In some cases, it is useful to be able to compute square roots of field elements (e.g.: for point compression of elliptic curve elements). To support this, users can implement the sqrt-related methods for their field type. This method is already implemented for prime fields (see below), and also for quadratic extension fields.

The sqrt-related methods can be used as follows:

```rust use arkff::Field; // As before, we'll use a field associated with the BLS12-381 pairing-friendly // group for this example. use arktestcurves::bls12381::Fq2 as F; use ark_std::{One, UniformRand};

let mut rng = arkstd::testrng(); let a = F::rand(&mut rng);

// We can check if a field element is a square by computing its Legendre symbol... if a.legendre().isqr() { // ... and if it is, we can compute its square root. let b = a.sqrt().unwrap(); asserteq!(b.square(), a); } else { // Otherwise, we can check that the square root is None. assert_eq!(a.sqrt(), None); } ```

[PrimeField]

If the field is of prime order, then users can choose to implement the [PrimeField] trait for it. This provides access to the following additional APIs:

```rust use arkff::{Field, PrimeField, FpConfig, BigInteger}; // Now we'll use the prime field underlying the BLS12-381 G1 curve. use arktestcurves::bls12381::Fq as F; use ark_std::{One, Zero, UniformRand};

let mut rng = arkstd::testrng(); let a = F::rand(&mut rng); // We can access the prime modulus associated with F: let modulus = ::MODULUS; assert_eq!(a.pow(&modulus), a);

// We can convert field elements to integers in the range [0, MODULUS - 1]: let one: numbigint::BigUint = F::one().into(); asserteq!(one, num_bigint::BigUint::one());

// We can construct field elements from an arbitrary sequence of bytes: let n = F::fromlebytesmodorder(&modulus.tobytesle()); assert_eq!(n, F::zero()); ```