### 10 releases

0.4.0 | Jan 17, 2023 |
---|---|

0.4.0-alpha.7 | Dec 29, 2022 |

0.4.0-alpha.3 | Nov 5, 2022 |

0.4.0-alpha.1 | Oct 21, 2022 |

0.2.0 | Mar 24, 2021 |

#**14** in Cryptography

**94,156** downloads per month

Used in **674** crates
(82 directly)

**MIT/Apache**

315KB

7K
SLoC

# 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

under `arkworks -rs/curves`

`arkworks``-`rs`/`curves`/``<`your favourite curve`>``/`src`/`fields`/`

.This crate contains two types of traits:

traits: These define interfaces for manipulating field elements, such as addition, multiplication, inverses, square roots, and more.`Field`- Field

s: specifies the parameters defining the field in question. For extension fields, it also provides additional functionality required for the field, such as operations involving a (cubic or quadratic) non-residue used for constructing the field (`Config`

).`NONRESIDUE`

The available field traits are:

- Interface for a generic finite field.`Field`

- Exposes methods that allow for performing efficient FFTs on field elements.`FftField`

- Field with a prime`PrimeField`

number of elements, also referred to as`p`

.`Fp`

The models implemented are:

`Quadratic Extension`

- Struct representing a quadratic extension field, in this case holding two base field elements`QuadExtField`

- Trait defining the necessary parameters needed to instantiate a Quadratic Extension Field`QuadExtConfig`

`Cubic Extension`

- Struct representing a cubic extension field, holds three base field elements`CubicExtField`

- Trait defining the necessary parameters needed to instantiate a Cubic Extension Field`CubicExtConfig`

The above two models serve as abstractions for constructing the extension fields

directly (i.e. `Fp ^m`

`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.

- Quadratic extension directly on the prime field, i.e.`Fp2``BaseField``==`BasePrimeField

- Cubic extension directly on the prime field, i.e.`Fp3``BaseField``==`BasePrimeField

- Extension tower: quadratic extension on a cubic extension field, i.e.`Fp6_2over3`

, but`BaseField``=`Fp3

.`BasePrimeField``=`Fp

- Extension tower, similar to the above except that the towering order is reversed: it's a cubic extension on a quadratic extension field, i.e.`Fp6_3over2`

, but`BaseField``=`Fp2

. Only this latter one is exported by default as`BasePrimeField``=`Fp

.`Fp6`

- Extension tower: quadratic extension of`Fp12_2over3over2`

, i.e.`Fp6_3over2`

.`BaseField``=`Fp6

## Usage

There are two important traits when working with finite fields: [

],
and [`Field`

]. Let's explore these via examples.`PrimeField`

### [`Field`

]

`Field`

The [

] trait provides a generic interface for any finite field.
Types implementing [`Field`

] support common field operations
such as addition, subtraction, multiplication, and inverses.`Field`

`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-std` is a utility crate that enables `arkworks` libraries
`//` to easily support `std` and `no_std` workloads, and also re-exports
`//` useful crates that should be common across the entire ecosystem, such as `rand`.
`use` `ark_std``::``{`One`,` UniformRand`}``;`
`let` `mut` rng `=` `ark_std``::`test_rng`(``)``;`
`//` 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

-related methods for their field type. This method
is already implemented for prime fields (see below), and also for quadratic extension fields.`sqrt`

The

-related methods can be used as follows:`sqrt`

`use` `ark_ff``::`Field`;`
`//` As before, 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`;`
`use` `ark_std``::``{`One`,` UniformRand`}``;`
`let` `mut` rng `=` `ark_std``::`test_rng`(``)``;`
`let` a `=` `F``::`rand`(``&``mut` rng`)``;`
`//` We can check if a field element is a square by computing its Legendre symbol...
`if` a`.``legendre``(``)``.``is_qr``(``)` `{`
`//` ... and if it is, we can compute its square root.
`let` b `=` a`.``sqrt``(``)``.``unwrap``(``)``;`
`assert_eq!``(`b`.``square``(``)``,` a`)``;`
`}` `else` `{`
`//` Otherwise, we can check that the square root is `None`.
`assert_eq!``(`a`.``sqrt``(``)``,` `None``)``;`
`}`

### [`PrimeField`

]

`PrimeField`

If the field is of prime order, then users can choose
to implement the [

] trait for it. This provides access to the following
additional APIs:`PrimeField`

`use` `ark_ff``::``{`Field`,` PrimeField`,` FpConfig`,` BigInteger`}``;`
`//` Now we'll use the prime field underlying the BLS12-381 G1 curve.
`use` `ark_test_curves``::``bls12_381``::`Fq `as` F`;`
`use` `ark_std``::``{`One`,` Zero`,` UniformRand`}``;`
`let` `mut` rng `=` `ark_std``::`test_rng`(``)``;`
`let` a `=` `F``::`rand`(``&``mut` rng`)``;`
`//` We can access the prime modulus associated with `F`:
`let` modulus `=` `<`F `as` PrimeField`>``::``MODULUS``;`
`assert_eq!``(`a`.``pow``(``&`modulus`)``,` a`)``;`
`//` We can convert field elements to integers in the range [0, MODULUS - 1]:
`let` one`:` `num_bigint``::`BigUint `=` `F``::`one`(``)``.``into``(``)``;`
`assert_eq!``(`one`,` `num_bigint``::``BigUint``::`one`(``)``)``;`
`//` We can construct field elements from an arbitrary sequence of bytes:
`let` n `=` `F``::`from_le_bytes_mod_order`(``&`modulus`.``to_bytes_le``(``)``)``;`
`assert_eq!``(`n`,` `F``::`zero`(``)``)``;`

#### Dependencies

~1.7–2.7MB

~57K SLoC