createForeignField
function createForeignField(modulus: bigint): typeof UnreducedForeignField
Create a class representing a prime order finite field, which is different from the native Field.
const SmallField = createForeignField(17n); // the finite field F_17
createForeignField(p)
takes the prime modulus p
of the finite field as input, as a bigint.
We support prime moduli up to a size of 259 bits.
The returned ForeignField class supports arithmetic modulo p
(addition and multiplication),
as well as helper methods like assertEquals()
and equals()
.
Advanced details:
Internally, a foreign field element is represented as three native field elements, each of which represents a limb of 88 bits. Therefore, being a valid foreign field element means that all 3 limbs fit in 88 bits, and the foreign field element altogether is smaller than the modulus p.
Since the full x < p
check is expensive, by default we only prove a weaker assertion, x < 2^ceil(log2(p))
,
see ForeignField.assertAlmostReduced for more details.
This weaker assumption is what we call "almost reduced", and it is represented by the AlmostForeignField class. Note that only AlmostForeignField supports multiplication and inversion, while UnreducedForeignField only supports addition and subtraction.
This function returns the Unreduced
class, which will cause the minimum amount of range checks to be created by default.
If you want to do multiplication, you have two options:
- create your field elements using the ForeignField.AlmostReduced constructor.
let x = Provable.witness(ForeignField.AlmostReduced, () => 5n);
- create your field elements normally and convert them using
x.assertAlmostReduced()
.
let xChecked = x.assertAlmostReduced(); // asserts x < 2^ceil(log2(p)); returns `AlmostForeignField`
Similarly, there is a separate class CanonicalForeignField which represents fully reduced, "canonical" field elements.
To convert to a canonical field element, use ForeignField.assertCanonical()
:
x.assertCanonical(); // asserts x < p; returns `CanonicalForeignField`
You will likely not need canonical fields most of the time.
Base types for all of these classes are separately exported as UnreducedForeignField, AlmostForeignField and CanonicalForeignField.,
Parameters
• modulus: bigint
the modulus of the finite field you are instantiating
Returns
typeof UnreducedForeignField