From 12a978797c97e3ed852bd61e02c39a1422c09322 Mon Sep 17 00:00:00 2001 From: Gregor Date: Thu, 7 Dec 2023 15:04:10 +0100 Subject: [PATCH 01/12] start section about foreign field kinds --- docs/zkapps/o1js/foreign-fields.mdx | 61 +++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/docs/zkapps/o1js/foreign-fields.mdx b/docs/zkapps/o1js/foreign-fields.mdx index a2700f8dc..bc60e3aae 100644 --- a/docs/zkapps/o1js/foreign-fields.mdx +++ b/docs/zkapps/o1js/foreign-fields.mdx @@ -111,3 +111,64 @@ y.toBigInt() === 5n; // convert to bigint As usual, you can find more information about each method in the [API reference](../o1js-reference/classes/Field). + +## The kinds of `ForeignField` + +If the basic usage examples look straightforward, here is where it gets a bit complicated. + +For each class created with `createForeignField()`, there are actually three different variants. We call them _unreduced_, _almost reduced_ and _canonical_. + +#### Unreduced fields + +Most arithmetic operations return unreduced fields: + +```ts +let z = x.add(x); +assert(z instanceof Field17.Unreduced); +``` + +In short, **unreduced** means that a value can be larger than the modulus. + +For example, if `x` has the value 16, it is valid for `x.add(x)` to contain the value 32. The addition is correct modulo 17, but doesn't guarantee a result smaller than 17. + +:::note + +Unreduced doesn't usually mean that the underlying witness is larger than the modulus. It just means that we have not _proved_ it to be smaller. +A malicious prover _could_ make it larger, by slightly modifying their local version of o1js and creating a proof with that. + +::: + +Unreduced fields can be added and subtracted, but not be used in multiplication or division: + +```ts +z.add(1).sub(x); // works + +assert((z as any).mul === undefined); // z.mul() is not defined +assert((z as any).inv === undefined); +assert((z as any).div === undefined); +``` + +#### Almost reduced fields + +To do multiplication, you need almost reduced fields. You can convert to that by using `.assertAlmostReduced()`: + +```ts +let zAlmost = z.assertAlmostReduced(); +assert(zAlmost instanceof SmallField.AlmostReduced); + +let zz = zAlmost.mul(zAlmost); // zAlmost.mul() is defined + +// but .mul() returns an unreduced field again: +assert(zz instanceof SmallField.Unreduced); + +// zAlmost.inv() is defined, and returns an almost reduced result! +assert(zAlmost.inv() instanceof SmallField.Unreduced); +``` + +The type common to all almost reduced fields is `AlmostReducedField`: + +```ts +import { AlmostReducedField } from 'o1js'; + +zAlmost satisfies AlmostReducedField; +``` From 1859d5d4f0f51da37f1d934b815e70d362e4b1ed Mon Sep 17 00:00:00 2001 From: Gregor Date: Thu, 7 Dec 2023 16:29:31 +0100 Subject: [PATCH 02/12] finish almost reduced --- docs/zkapps/o1js/foreign-fields.mdx | 41 +++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/docs/zkapps/o1js/foreign-fields.mdx b/docs/zkapps/o1js/foreign-fields.mdx index d207c69de..3695abf26 100644 --- a/docs/zkapps/o1js/foreign-fields.mdx +++ b/docs/zkapps/o1js/foreign-fields.mdx @@ -155,20 +155,57 @@ To do multiplication, you need almost reduced fields. You can convert to that by ```ts let zAlmost = z.assertAlmostReduced(); assert(zAlmost instanceof SmallField.AlmostReduced); +``` + +Now you can do multiplication and division: +```ts let zz = zAlmost.mul(zAlmost); // zAlmost.mul() is defined // but .mul() returns an unreduced field again: assert(zz instanceof SmallField.Unreduced); // zAlmost.inv() is defined, and returns an almost reduced result! -assert(zAlmost.inv() instanceof SmallField.Unreduced); +assert(zAlmost.inv() instanceof SmallField.AlmostReduced); ``` -The type common to all almost reduced fields is `AlmostReducedField`: +There is an exported base type common to all almost reduced fields: ```ts import { AlmostReducedField } from 'o1js'; zAlmost satisfies AlmostReducedField; ``` + +The definition of almost reduced is somewhat technical and we won't dwell on it for too long. The main motivation is to guarantee that the way we prove modular multiplication is sound. That is definitely true for field elements `< 2^259`. (Recall that we require the modulus to be `< 2^259`). + +However, we usually prove a stronger condition, which lets us save a few constraints in some places: + +`z` is **almost reduced** modulo `f`, if `z >> 176` is smaller or equal than `f >> 176`. (`>>` means a right shift.) + +:::note + +Example: Assume `x` is a `Field17` holding the value `1`. After computing `z = x.mul(1)`, it is valid for `z` to be `1*1 + 2^256 * 17`, which is larger than `2^260`. + +However, by calling `z.assertAlmostReduced()`, we prove that `z` is smaller than `2^259` and safe to use in another multiplication. According to our stronger definition, we even have `z < 2^176`. + +::: + +Why are we exposing `AlmostReducedField` as a separate type, and don't _always_ prove conditions necessary for multiplication? + +To allow you to use the minimum amount of constraints, in a way that is safely guided by the type system! + +Here is a trick to save constraints: It's most efficient to always reduce field elements in _batches of 3_. Do this when doing many multiplications in a row: + +```ts +let z1 = x.mul(7); +let z2 = x.add(11); +let z3 = x.sub(13); + +let [z1r, z2r, z3r] = Field17.assertAlmostReduced(z1, z2, z3); + +z1r.mul(z2r); +z2r.div(z3r); +``` + +`ForeignField.assertAlmostReduced()` takes any number of inputs, but is most efficient when called with a multiple of 3 inputs. From 0cb199ba28d0b9288228a49e4ba775b2a3ca7795 Mon Sep 17 00:00:00 2001 From: Gregor Date: Thu, 7 Dec 2023 17:01:44 +0100 Subject: [PATCH 03/12] minimize constraints section --- docs/zkapps/o1js/foreign-fields.mdx | 68 ++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 6 deletions(-) diff --git a/docs/zkapps/o1js/foreign-fields.mdx b/docs/zkapps/o1js/foreign-fields.mdx index 3695abf26..63cad3048 100644 --- a/docs/zkapps/o1js/foreign-fields.mdx +++ b/docs/zkapps/o1js/foreign-fields.mdx @@ -118,7 +118,7 @@ If the basic usage examples look straightforward, here is where it gets a bit co For each class created with `createForeignField()`, there are actually three different variants. We call them _unreduced_, _almost reduced_ and _canonical_. -#### Unreduced fields +### Unreduced fields Most arithmetic operations return unreduced fields: @@ -148,7 +148,7 @@ assert((z as any).inv === undefined); assert((z as any).div === undefined); ``` -#### Almost reduced fields +### Almost reduced fields To do multiplication, you need almost reduced fields. You can convert to that by using `.assertAlmostReduced()`: @@ -169,7 +169,22 @@ assert(zz instanceof SmallField.Unreduced); assert(zAlmost.inv() instanceof SmallField.AlmostReduced); ``` -There is an exported base type common to all almost reduced fields: +It can be convenient to require almost reduced fields as inputs to your smart contract. To do so, create a class which can also serve as a type, and use its `.provable` property when passing to the state decorator: + +```ts +class AlmostField17 extends Field17.AlmostReduced {} + +class MyContract extends SmartContract { + @state(AlmostField17.provable) x = State(); + + @method myMethod(y: AlmostField17) { + let x = y.mul(2); + this.x.set(x.assertAlmostReduced()); + } +} +``` + +There is also an exported type common to all almost reduced fields: ```ts import { AlmostReducedField } from 'o1js'; @@ -177,6 +192,8 @@ import { AlmostReducedField } from 'o1js'; zAlmost satisfies AlmostReducedField; ``` +#### What does almost reduced even mean? + The definition of almost reduced is somewhat technical and we won't dwell on it for too long. The main motivation is to guarantee that the way we prove modular multiplication is sound. That is definitely true for field elements `< 2^259`. (Recall that we require the modulus to be `< 2^259`). However, we usually prove a stronger condition, which lets us save a few constraints in some places: @@ -193,9 +210,15 @@ However, by calling `z.assertAlmostReduced()`, we prove that `z` is smaller than Why are we exposing `AlmostReducedField` as a separate type, and don't _always_ prove conditions necessary for multiplication? -To allow you to use the minimum amount of constraints, in a way that is safely guided by the type system! +To allow you to use the minimum amount of constraints, in a way that is safely guided by the type system! See the section below on [minimizing constraints](#minimizing-constraints) for all the details. -Here is a trick to save constraints: It's most efficient to always reduce field elements in _batches of 3_. Do this when doing many multiplications in a row: +## Minimizing constraints + +#### `ForeignField.assertAlmostReduced()` + +Here is a trick to save constraints when you need to "almost reduce" many field elements: Always reduce them in _batches of 3_. + +For example, do this when doing many multiplications in a row: ```ts let z1 = x.mul(7); @@ -208,4 +231,37 @@ z1r.mul(z2r); z2r.div(z3r); ``` -`ForeignField.assertAlmostReduced()` takes any number of inputs, but is most efficient when called with a multiple of 3 inputs. +`assertAlmostReduced()` takes any number of inputs, but is by far the most efficient with multiples of 3. For example: + +- 1 input takes 4.5 constraints +- 2 inputs take 5 constraints +- 3 inputs take 5.5 constraints + +#### `ForeignField.sum()` + +Another opportunity to save constraints is when doing many additions or subtractions in a row. Instead of doing something like `x.add(y).sub(z)`, you can use `ForeignField.sum()`: + +```ts +// u = x + y - z +let u = Field17.sum([x, y, z], [1, -1]); +``` + +The second argument is a list of signs: either 1 or -1, depending on whether you want to add or subtract the corresponding field element. + +- The 1 in this example means: "add x and y". +- The -1 means: "subtract z". + +To give a few more examples: + +```ts +// u = x - y - z +let u = Field17.sum([x, y, z], [-1, -1]); + +// u = 2*x + y +let u = Field17.sum([x, x, y], [1, 1]); + +// u = -3*z +let u = Field17.sum([0, z, z, z], [-1, -1, -1]); +``` + +Doing small multiplications like `-3*z` like this is more efficient than doing it with `mul()`. `sum()` only uses 1 additional constraint per summand. From 9b84e9e91ec0c11d472650cdfe2ff018fbfb8890 Mon Sep 17 00:00:00 2001 From: Gregor Date: Thu, 7 Dec 2023 17:12:25 +0100 Subject: [PATCH 04/12] tweaks --- docs/zkapps/o1js/foreign-fields.mdx | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/docs/zkapps/o1js/foreign-fields.mdx b/docs/zkapps/o1js/foreign-fields.mdx index 63cad3048..80b4d5395 100644 --- a/docs/zkapps/o1js/foreign-fields.mdx +++ b/docs/zkapps/o1js/foreign-fields.mdx @@ -118,6 +118,8 @@ If the basic usage examples look straightforward, here is where it gets a bit co For each class created with `createForeignField()`, there are actually three different variants. We call them _unreduced_, _almost reduced_ and _canonical_. +In the following, we explain when to use the different variants, and how to convert between them. You don't need to learn all of this, though: The type system will guide you to use the right variant in each situation. + ### Unreduced fields Most arithmetic operations return unreduced fields: @@ -150,7 +152,7 @@ assert((z as any).div === undefined); ### Almost reduced fields -To do multiplication, you need almost reduced fields. You can convert to that by using `.assertAlmostReduced()`: +To do multiplication, you need almost reduced fields. You can convert to them by using `.assertAlmostReduced()`: ```ts let zAlmost = z.assertAlmostReduced(); @@ -165,7 +167,7 @@ let zz = zAlmost.mul(zAlmost); // zAlmost.mul() is defined // but .mul() returns an unreduced field again: assert(zz instanceof SmallField.Unreduced); -// zAlmost.inv() is defined, and returns an almost reduced result! +// zAlmost.inv() is defined, and returns an almost reduced field: assert(zAlmost.inv() instanceof SmallField.AlmostReduced); ``` @@ -194,11 +196,11 @@ zAlmost satisfies AlmostReducedField; #### What does almost reduced even mean? -The definition of almost reduced is somewhat technical and we won't dwell on it for too long. The main motivation is to guarantee that the way we prove modular multiplication is sound. That is definitely true for field elements `< 2^259`. (Recall that we require the modulus to be `< 2^259`). +The definition of almost reduced is somewhat technical. The main motivation is to guarantee that the way we prove modular multiplication is sound. That is definitely true for field elements `< 2^259`. (Recall that we require the modulus to be `< 2^259`). -However, we usually prove a stronger condition, which lets us save a few constraints in some places: +However, we actually prove a stronger condition, which lets us save a few constraints in some places: -`z` is **almost reduced** modulo `f`, if `z >> 176` is smaller or equal than `f >> 176`. (`>>` means a right shift.) +`z` is **almost reduced** modulo `f`, if `z >> 176` is smaller or equal than `f >> 176`. (`>>` means a [right shift](https://en.wikipedia.org/wiki/Arithmetic_shift).) :::note @@ -214,7 +216,7 @@ To allow you to use the minimum amount of constraints, in a way that is safely g ## Minimizing constraints -#### `ForeignField.assertAlmostReduced()` +#### `assertAlmostReduced()` Here is a trick to save constraints when you need to "almost reduce" many field elements: Always reduce them in _batches of 3_. @@ -237,19 +239,16 @@ z2r.div(z3r); - 2 inputs take 5 constraints - 3 inputs take 5.5 constraints -#### `ForeignField.sum()` +#### `sum()` -Another opportunity to save constraints is when doing many additions or subtractions in a row. Instead of doing something like `x.add(y).sub(z)`, you can use `ForeignField.sum()`: +Another opportunity to save constraints is when doing many additions or subtractions in a row. Instead of doing something like `x.add(y).sub(z)`, use `ForeignField.sum()`: ```ts // u = x + y - z let u = Field17.sum([x, y, z], [1, -1]); ``` -The second argument is a list of signs: either 1 or -1, depending on whether you want to add or subtract the corresponding field element. - -- The 1 in this example means: "add x and y". -- The -1 means: "subtract z". +The second argument is a list of signs: either 1 or -1, depending on whether you want to add or subtract the corresponding value. So, the 1 in this example means "add x and y", and the -1 means "subtract z". To give a few more examples: @@ -264,4 +263,4 @@ let u = Field17.sum([x, x, y], [1, 1]); let u = Field17.sum([0, z, z, z], [-1, -1, -1]); ``` -Doing small multiplications like `-3*z` like this is more efficient than doing it with `mul()`. `sum()` only uses 1 additional constraint per summand. +Doing small multiplications like `-3*z` like this is more efficient than using `mul()` for the task. `sum()` uses 6 constraints for the first two summands but only 1 constraint per additional summand. From 6ea4210f288740fcf389c1d79a2f3e1211ae7bd0 Mon Sep 17 00:00:00 2001 From: Gregor Date: Thu, 7 Dec 2023 17:36:59 +0100 Subject: [PATCH 05/12] canonical --- docs/zkapps/o1js/foreign-fields.mdx | 88 ++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 15 deletions(-) diff --git a/docs/zkapps/o1js/foreign-fields.mdx b/docs/zkapps/o1js/foreign-fields.mdx index 80b4d5395..c2d6a01a4 100644 --- a/docs/zkapps/o1js/foreign-fields.mdx +++ b/docs/zkapps/o1js/foreign-fields.mdx @@ -112,19 +112,39 @@ y.toBigInt() === 5n; // convert to bigint As usual, you can find more information about each method in the [API reference](../o1js-reference/classes/Field). -## The kinds of `ForeignField` +## Three kinds of foreign field If the basic usage examples look straightforward, here is where it gets a bit complicated. -For each class created with `createForeignField()`, there are actually three different variants. We call them _unreduced_, _almost reduced_ and _canonical_. +For each `ForeignField` class created with `createForeignField()`, there are actually three different variants. We call them _unreduced_, _almost reduced_ and _canonical_. -In the following, we explain when to use the different variants, and how to convert between them. You don't need to learn all of this, though: The type system will guide you to use the right variant in each situation. +You find the variants as static properties on the class; they are themselves classes: + +```ts +let x = new Field17.Unreduced(0); +let y = new Field17.AlmostReduced(0); +let z = new Field17.Canonical(0); +``` + +And there are three base types that are common to each variant: + +```ts +import { UnreducedField, AlmostReducedField, CanonicalField } from 'o1js'; + +x satisfies UnreducedField; +y satisfies AlmostReducedField; +z satisfies CanonicalField; +``` + +In the following, we explain when to use the different variants, and how to convert between them. You don't need to learn all of it, though: The type system will guide you to use the right variant in each situation. ### Unreduced fields Most arithmetic operations return unreduced fields: ```ts +import assert from 'assert'; + let z = x.add(x); assert(z instanceof Field17.Unreduced); ``` @@ -140,7 +160,7 @@ A malicious prover _could_ make it larger, by slightly modifying their local ver ::: -Unreduced fields can be added and subtracted, but not be used in multiplication or division: +Unreduced fields can be added and subtracted, but not multiplied or divided: ```ts z.add(1).sub(x); // works @@ -186,15 +206,7 @@ class MyContract extends SmartContract { } ``` -There is also an exported type common to all almost reduced fields: - -```ts -import { AlmostReducedField } from 'o1js'; - -zAlmost satisfies AlmostReducedField; -``` - -#### What does almost reduced even mean? +#### What does almost reduced mean? The definition of almost reduced is somewhat technical. The main motivation is to guarantee that the way we prove modular multiplication is sound. That is definitely true for field elements `< 2^259`. (Recall that we require the modulus to be `< 2^259`). @@ -210,9 +222,55 @@ However, by calling `z.assertAlmostReduced()`, we prove that `z` is smaller than ::: -Why are we exposing `AlmostReducedField` as a separate type, and don't _always_ prove conditions necessary for multiplication? +Why are we exposing `AlmostReducedField` as a separate type, and don't _always_ prove conditions necessary for multiplication? Because that would take up additional constraints! + +`ForeignField` is built to allow you to use the minimum amount of constraints, in a way that is safely guided by the type system. See the section below on [minimizing constraints](#minimizing-constraints) for more details. + +### Canonical fields + +Canonical fields are the strictest variant. They are guaranteed to be smaller than the modulus. + +When you create fields from constants, they always get fully reduced. The type signature of `ForeignField.from()` reflects this and returns a canonical field: + +```ts +let constant = Field17.from(16); +assert(constant instanceof Field17.Canonical); + +// these also work, because `from()` takes the input mod 17: +Field17.from(100000000n) satisfies CanonicalForeignField; +Field17.from(-1) satisfies CanonicalForeignField; +``` + +You can convert any field to canonical by calling `.assertCanonical()`: + +```ts +let zCanonical = z.assertCanonical(); +assert(zCanonical instanceof Field17.Canonical); +``` + +Canonical fields are a special case of almost reduced fields at the type level: + +```ts +constant satisfies AlmostForeignField; +constant.mul(constant); // works +``` + +The cheapest way to prove that an existing field element is canonical is to show that it is equal to a constant: + +```ts +let zCanonical = z.assertEquals(3); +assert(uCanonical instanceof Field17.Canonical); +``` + +An operation that is only possible on canonical fields is the boolean equality check: + +```ts +let xCanonical = x.assertCanonical(); +let yCanonical = y.assertCanonical(); +let isEqual = xCanonical.equals(yCanonical); +``` -To allow you to use the minimum amount of constraints, in a way that is safely guided by the type system! See the section below on [minimizing constraints](#minimizing-constraints) for all the details. +We require inputs to be canonical for this because we check for strict equality, not equality modulo the field size. Note that being strictly unequal does not imply being unequal as field elements, so `equals()` on non-canonical fields would be error-prone. ## Minimizing constraints From 717bc2846d98ab42c02606c5515052b7527b0455 Mon Sep 17 00:00:00 2001 From: Gregor Date: Thu, 7 Dec 2023 20:32:15 +0100 Subject: [PATCH 06/12] minor fixes --- docs/zkapps/o1js/foreign-fields.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/zkapps/o1js/foreign-fields.mdx b/docs/zkapps/o1js/foreign-fields.mdx index c2d6a01a4..3456b5272 100644 --- a/docs/zkapps/o1js/foreign-fields.mdx +++ b/docs/zkapps/o1js/foreign-fields.mdx @@ -208,7 +208,7 @@ class MyContract extends SmartContract { #### What does almost reduced mean? -The definition of almost reduced is somewhat technical. The main motivation is to guarantee that the way we prove modular multiplication is sound. That is definitely true for field elements `< 2^259`. (Recall that we require the modulus to be `< 2^259`). +The definition of almost reduced is somewhat technical. The main motivation is to guarantee that the way we prove modular multiplication is sound. That is definitely true for field elements `< 2^259`. (Recall that we require the modulus to be `< 2^259`.) However, we actually prove a stronger condition, which lets us save a few constraints in some places: @@ -216,9 +216,9 @@ However, we actually prove a stronger condition, which lets us save a few constr :::note -Example: Assume `x` is a `Field17` holding the value `1`. After computing `z = x.mul(1)`, it is valid for `z` to be `1*1 + 2^256 * 17`, which is larger than `2^260`. +Example: Assume `x` is a `UInt256` holding the value `2^130`. After computing `z = x.mul(x)`, it is valid for `z` to be `2^260`. -However, by calling `z.assertAlmostReduced()`, we prove that `z` is smaller than `2^259` and safe to use in another multiplication. According to our stronger definition, we even have `z < 2^176`. +However, by calling `z.assertAlmostReduced()`, we prove that `z` is smaller than `2^259` and safe to use in another multiplication. According to our stronger definition, we even have `z < 2^256`. ::: @@ -259,7 +259,7 @@ The cheapest way to prove that an existing field element is canonical is to show ```ts let zCanonical = z.assertEquals(3); -assert(uCanonical instanceof Field17.Canonical); +assert(zCanonical instanceof Field17.Canonical); ``` An operation that is only possible on canonical fields is the boolean equality check: From fee5e5d3fd24ab949313657b261dce688cfca8c5 Mon Sep 17 00:00:00 2001 From: Gregor Date: Thu, 7 Dec 2023 21:04:09 +0100 Subject: [PATCH 07/12] manually update api reference --- .../classes/AlmostForeignField.md | 983 ++++++++++++++++++ .../classes/CanonicalForeignField.md | 983 ++++++++++++++++++ .../o1js-reference/classes/ForeignField.md | 745 +++++++++++++ .../o1js-reference/classes/Unconstrained.md | 195 ++++ docs/zkapps/o1js-reference/modules.md | 4 + sidebars.js | 20 + 6 files changed, 2930 insertions(+) create mode 100644 docs/zkapps/o1js-reference/classes/AlmostForeignField.md create mode 100644 docs/zkapps/o1js-reference/classes/CanonicalForeignField.md create mode 100644 docs/zkapps/o1js-reference/classes/ForeignField.md create mode 100644 docs/zkapps/o1js-reference/classes/Unconstrained.md diff --git a/docs/zkapps/o1js-reference/classes/AlmostForeignField.md b/docs/zkapps/o1js-reference/classes/AlmostForeignField.md new file mode 100644 index 000000000..c87f55785 --- /dev/null +++ b/docs/zkapps/o1js-reference/classes/AlmostForeignField.md @@ -0,0 +1,983 @@ +[o1js](../README.md) / [Exports](../modules.md) / AlmostForeignField + +# Class: AlmostForeignField + +## Hierarchy + +- `ForeignFieldWithMul` + + ↳ **`AlmostForeignField`** + +## Table of contents + +### Constructors + +- [constructor](AlmostForeignField.md#constructor) + +### Properties + +- [type](AlmostForeignField.md#type) +- [value](AlmostForeignField.md#value) +- [\_modulus](AlmostForeignField.md#_modulus) +- [\_provable](AlmostForeignField.md#_provable) +- [\_variants](AlmostForeignField.md#_variants) + +### Accessors + +- [Constructor](AlmostForeignField.md#constructor-1) +- [modulus](AlmostForeignField.md#modulus) +- [AlmostReduced](AlmostForeignField.md#almostreduced) +- [Canonical](AlmostForeignField.md#canonical) +- [Unreduced](AlmostForeignField.md#unreduced) +- [modulus](AlmostForeignField.md#modulus-1) +- [provable](AlmostForeignField.md#provable) +- [sizeInBits](AlmostForeignField.md#sizeinbits) + +### Methods + +- [add](AlmostForeignField.md#add) +- [assertAlmostReduced](AlmostForeignField.md#assertalmostreduced) +- [assertCanonical](AlmostForeignField.md#assertcanonical) +- [assertEquals](AlmostForeignField.md#assertequals) +- [assertLessThan](AlmostForeignField.md#assertlessthan) +- [div](AlmostForeignField.md#div) +- [equals](AlmostForeignField.md#equals) +- [inv](AlmostForeignField.md#inv) +- [isConstant](AlmostForeignField.md#isconstant) +- [mul](AlmostForeignField.md#mul) +- [neg](AlmostForeignField.md#neg) +- [sub](AlmostForeignField.md#sub) +- [toBigInt](AlmostForeignField.md#tobigint) +- [toBits](AlmostForeignField.md#tobits) +- [toConstant](AlmostForeignField.md#toconstant) +- [toFields](AlmostForeignField.md#tofields) +- [assertAlmostReduced](AlmostForeignField.md#assertalmostreduced-1) +- [check](AlmostForeignField.md#check) +- [from](AlmostForeignField.md#from) +- [fromBits](AlmostForeignField.md#frombits) +- [sum](AlmostForeignField.md#sum) +- [unsafeFrom](AlmostForeignField.md#unsafefrom) + +## Constructors + +### constructor + +• **new AlmostForeignField**(`x`) + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `x` | `string` \| `number` \| `bigint` \| `Field3` \| [`AlmostForeignField`](AlmostForeignField.md) | + +#### Overrides + +ForeignFieldWithMul.constructor + +#### Defined in + +[lib/foreign-field.ts:477](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L477) + +## Properties + +### type + +• **type**: ``"AlmostReduced"`` \| ``"FullyReduced"`` = `'AlmostReduced'` + +#### Defined in + +[lib/foreign-field.ts:475](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L475) + +___ + +### value + +• **value**: `Field3` + +The internal representation of a foreign field element, as a tuple of 3 limbs. + +#### Inherited from + +ForeignFieldWithMul.value + +#### Defined in + +[lib/foreign-field.ts:39](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L39) + +___ + +### \_modulus + +▪ `Static` **\_modulus**: `undefined` \| `bigint` = `undefined` + +#### Inherited from + +ForeignFieldWithMul.\_modulus + +#### Defined in + +[lib/foreign-field.ts:22](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L22) + +___ + +### \_provable + +▪ `Static` **\_provable**: `undefined` \| [`ProvablePure`](../interfaces/ProvablePure.md)<[`AlmostForeignField`](AlmostForeignField.md)\> = `undefined` + +#### Overrides + +ForeignFieldWithMul.\_provable + +#### Defined in + +[lib/foreign-field.ts:481](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L481) + +___ + +### \_variants + +▪ `Static` **\_variants**: `undefined` \| { `almostReduced`: typeof [`AlmostForeignField`](AlmostForeignField.md) ; `canonical`: typeof [`CanonicalForeignField`](CanonicalForeignField.md) ; `unreduced`: typeof `UnreducedForeignField` } = `undefined` + +Sibling classes that represent different ranges of field elements. + +#### Inherited from + +ForeignFieldWithMul.\_variants + +#### Defined in + +[lib/foreign-field.ts:48](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L48) + +## Accessors + +### Constructor + +• `get` **Constructor**(): typeof [`ForeignField`](ForeignField.md) + +#### Returns + +typeof [`ForeignField`](ForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.Constructor + +#### Defined in + +[lib/foreign-field.ts:41](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L41) + +___ + +### modulus + +• `get` **modulus**(): `bigint` + +#### Returns + +`bigint` + +#### Inherited from + +ForeignFieldWithMul.modulus + +#### Defined in + +[lib/foreign-field.ts:29](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L29) + +___ + +### AlmostReduced + +• `Static` `get` **AlmostReduced**(): typeof [`AlmostForeignField`](AlmostForeignField.md) + +Constructor for field elements that are "almost reduced", i.e. lie in the range [0, 2^ceil(log2(p))). + +#### Returns + +typeof [`AlmostForeignField`](AlmostForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.AlmostReduced + +#### Defined in + +[lib/foreign-field.ts:66](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L66) + +___ + +### Canonical + +• `Static` `get` **Canonical**(): typeof [`CanonicalForeignField`](CanonicalForeignField.md) + +Constructor for field elements that are fully reduced, i.e. lie in the range [0, p). + +#### Returns + +typeof [`CanonicalForeignField`](CanonicalForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.Canonical + +#### Defined in + +[lib/foreign-field.ts:73](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L73) + +___ + +### Unreduced + +• `Static` `get` **Unreduced**(): typeof `UnreducedForeignField` + +Constructor for unreduced field elements. + +#### Returns + +typeof `UnreducedForeignField` + +#### Inherited from + +ForeignFieldWithMul.Unreduced + +#### Defined in + +[lib/foreign-field.ts:59](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L59) + +___ + +### modulus + +• `Static` `get` **modulus**(): `bigint` + +#### Returns + +`bigint` + +#### Inherited from + +ForeignFieldWithMul.modulus + +#### Defined in + +[lib/foreign-field.ts:25](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L25) + +___ + +### provable + +• `Static` `get` **provable**(): [`ProvablePure`](../interfaces/ProvablePure.md)<[`AlmostForeignField`](AlmostForeignField.md)\> + +#### Returns + +[`ProvablePure`](../interfaces/ProvablePure.md)<[`AlmostForeignField`](AlmostForeignField.md)\> + +#### Overrides + +ForeignFieldWithMul.provable + +#### Defined in + +[lib/foreign-field.ts:482](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L482) + +___ + +### sizeInBits + +• `Static` `get` **sizeInBits**(): `number` + +#### Returns + +`number` + +#### Inherited from + +ForeignFieldWithMul.sizeInBits + +#### Defined in + +[lib/foreign-field.ts:32](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L32) + +## Methods + +### add + +▸ **add**(`y`): `UnreducedForeignField` + +Finite field addition + +**`Example`** + +```ts +x.add(2); // x + 2 mod p +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | `number` \| `bigint` \| [`ForeignField`](ForeignField.md) | + +#### Returns + +`UnreducedForeignField` + +#### Inherited from + +ForeignFieldWithMul.add + +#### Defined in + +[lib/foreign-field.ts:203](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L203) + +___ + +### assertAlmostReduced + +▸ **assertAlmostReduced**(): [`AlmostForeignField`](AlmostForeignField.md) + +Assert that this field element lies in the range [0, 2^k), +where k = ceil(log2(p)) and p is the foreign field modulus. + +Returns the field element as a [AlmostForeignField](AlmostForeignField.md). + +For a more efficient version of this for multiple field elements, see [assertAlmostReduced](ForeignField.md#assertalmostreduced-1). + +Note: this does not ensure that the field elements is in the canonical range [0, p). +To assert that stronger property, there is [assertCanonical](ForeignField.md#assertcanonical). +You should typically use [assertAlmostReduced](ForeignField.md#assertalmostreduced-1) though, because it is cheaper to prove and sufficient for +ensuring validity of all our non-native field arithmetic methods. + +#### Returns + +[`AlmostForeignField`](AlmostForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.assertAlmostReduced + +#### Defined in + +[lib/foreign-field.ts:156](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L156) + +___ + +### assertCanonical + +▸ **assertCanonical**(): [`CanonicalForeignField`](CanonicalForeignField.md) + +Assert that this field element is fully reduced, +i.e. lies in the range [0, p), where p is the foreign field modulus. + +Returns the field element as a [CanonicalForeignField](CanonicalForeignField.md). + +#### Returns + +[`CanonicalForeignField`](CanonicalForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.assertCanonical + +#### Defined in + +[lib/foreign-field.ts:189](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L189) + +___ + +### assertEquals + +▸ **assertEquals**(`y`, `message?`): [`CanonicalForeignField`](CanonicalForeignField.md) + +Assert equality with a ForeignField-like value + +**`Example`** + +```ts +x.assertEquals(0, "x is zero"); +``` + +Since asserting equality can also serve as a range check, +this method returns `x` with the appropriate type: + +**`Example`** + +```ts +let xChecked = x.assertEquals(1, "x is 1"); +xChecked satisfies CanonicalForeignField; +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | `number` \| `bigint` \| [`CanonicalForeignField`](CanonicalForeignField.md) | +| `message?` | `string` | + +#### Returns + +[`CanonicalForeignField`](CanonicalForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.assertEquals + +#### Defined in + +[lib/foreign-field.ts:278](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L278) + +▸ **assertEquals**(`y`, `message?`): [`AlmostForeignField`](AlmostForeignField.md) + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | [`AlmostForeignField`](AlmostForeignField.md) | +| `message?` | `string` | + +#### Returns + +[`AlmostForeignField`](AlmostForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.assertEquals + +#### Defined in + +[lib/foreign-field.ts:282](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L282) + +▸ **assertEquals**(`y`, `message?`): [`ForeignField`](ForeignField.md) + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | [`ForeignField`](ForeignField.md) | +| `message?` | `string` | + +#### Returns + +[`ForeignField`](ForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.assertEquals + +#### Defined in + +[lib/foreign-field.ts:283](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L283) + +___ + +### assertLessThan + +▸ **assertLessThan**(`c`, `message?`): `void` + +Assert that this field element is less than a constant c: `x < c`. + +The constant must satisfy `0 <= c < 2^264`, otherwise an error is thrown. + +**`Example`** + +```ts +x.assertLessThan(10); +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `c` | `number` \| `bigint` | +| `message?` | `string` | + +#### Returns + +`void` + +#### Inherited from + +ForeignFieldWithMul.assertLessThan + +#### Defined in + +[lib/foreign-field.ts:325](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L325) + +___ + +### div + +▸ **div**(`y`): [`AlmostForeignField`](AlmostForeignField.md) + +Division in the finite field, i.e. `x*y^(-1) mod p` where `y^(-1)` is the finite field inverse. + +**`Example`** + +```ts +let z = x.div(y); // x/y mod p +z.mul(y).assertEquals(x); +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | `number` \| `bigint` \| [`AlmostForeignField`](AlmostForeignField.md) | + +#### Returns + +[`AlmostForeignField`](AlmostForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.div + +#### Defined in + +[lib/foreign-field.ts:453](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L453) + +___ + +### equals + +▸ **equals**(`y`): `Bool` + +Check equality with a ForeignField-like value + +**`Example`** + +```ts +let isXZero = x.equals(0); +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | `number` \| `bigint` \| [`ForeignField`](ForeignField.md) | + +#### Returns + +`Bool` + +#### Inherited from + +ForeignFieldWithMul.equals + +#### Defined in + +[lib/foreign-field.ts:344](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L344) + +___ + +### inv + +▸ **inv**(): [`AlmostForeignField`](AlmostForeignField.md) + +Multiplicative inverse in the finite field + +**`Example`** + +```ts +let z = x.inv(); // 1/x mod p +z.mul(x).assertEquals(1); +``` + +#### Returns + +[`AlmostForeignField`](AlmostForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.inv + +#### Defined in + +[lib/foreign-field.ts:439](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L439) + +___ + +### isConstant + +▸ **isConstant**(): `boolean` + +Checks whether this field element is a constant. + +See FieldVar to understand constants vs variables. + +#### Returns + +`boolean` + +#### Inherited from + +ForeignFieldWithMul.isConstant + +#### Defined in + +[lib/foreign-field.ts:119](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L119) + +___ + +### mul + +▸ **mul**(`y`): `UnreducedForeignField` + +Finite field multiplication + +**`Example`** + +```ts +x.mul(y); // x*y mod p +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | `number` \| `bigint` \| [`AlmostForeignField`](AlmostForeignField.md) | + +#### Returns + +`UnreducedForeignField` + +#### Inherited from + +ForeignFieldWithMul.mul + +#### Defined in + +[lib/foreign-field.ts:425](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L425) + +___ + +### neg + +▸ **neg**(): `UnreducedForeignField` + +Finite field negation + +**`Example`** + +```ts +x.neg(); // -x mod p = p - x +``` + +#### Returns + +`UnreducedForeignField` + +#### Inherited from + +ForeignFieldWithMul.neg + +#### Defined in + +[lib/foreign-field.ts:214](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L214) + +___ + +### sub + +▸ **sub**(`y`): `UnreducedForeignField` + +Finite field subtraction + +**`Example`** + +```ts +x.sub(1); // x - 1 mod p +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | `number` \| `bigint` \| [`ForeignField`](ForeignField.md) | + +#### Returns + +`UnreducedForeignField` + +#### Inherited from + +ForeignFieldWithMul.sub + +#### Defined in + +[lib/foreign-field.ts:226](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L226) + +___ + +### toBigInt + +▸ **toBigInt**(): `bigint` + +Convert this field element to a bigint. + +#### Returns + +`bigint` + +#### Inherited from + +ForeignFieldWithMul.toBigInt + +#### Defined in + +[lib/foreign-field.ts:139](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L139) + +___ + +### toBits + +▸ **toBits**(`length?`): `Bool`[] + +Unpack a field element to its bits, as a [Bool](../modules.md#bool)[] array. + +This method is provable! + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `length?` | `number` | + +#### Returns + +`Bool`[] + +#### Inherited from + +ForeignFieldWithMul.toBits + +#### Defined in + +[lib/foreign-field.ts:363](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L363) + +___ + +### toConstant + +▸ **toConstant**(): [`ForeignField`](ForeignField.md) + +Convert this field element to a constant. + +See FieldVar to understand constants vs variables. + +**Warning**: This function is only useful in [witness](../modules.md#witness) or [asProver](../modules.md#asprover) blocks, +that is, in situations where the prover computes a value outside provable code. + +#### Returns + +[`ForeignField`](ForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.toConstant + +#### Defined in + +[lib/foreign-field.ts:131](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L131) + +___ + +### toFields + +▸ **toFields**(): `Field`[] + +Instance version of `Provable.toFields`, see [toFields](TokenSymbol.md#tofields) + +#### Returns + +`Field`[] + +#### Inherited from + +ForeignFieldWithMul.toFields + +#### Defined in + +[lib/foreign-field.ts:398](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L398) + +___ + +### assertAlmostReduced + +▸ `Static` **assertAlmostReduced**<`T`\>(`...xs`): [...{ [i in string \| number \| symbol]: AlmostForeignField }[]] + +Assert that one or more field elements lie in the range [0, 2^k), +where k = ceil(log2(p)) and p is the foreign field modulus. + +This is most efficient than when checking a multiple of 3 field elements at once. + +#### Type parameters + +| Name | Type | +| :------ | :------ | +| `T` | extends `Tuple`<[`ForeignField`](ForeignField.md)\> | + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `...xs` | `T` | + +#### Returns + +[...{ [i in string \| number \| symbol]: AlmostForeignField }[]] + +#### Inherited from + +ForeignFieldWithMul.assertAlmostReduced + +#### Defined in + +[lib/foreign-field.ts:172](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L172) + +___ + +### check + +▸ `Static` **check**(`x`): `void` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `x` | [`ForeignField`](ForeignField.md) | + +#### Returns + +`void` + +#### Overrides + +ForeignFieldWithMul.check + +#### Defined in + +[lib/foreign-field.ts:487](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L487) + +___ + +### from + +▸ `Static` **from**(`x`): [`CanonicalForeignField`](CanonicalForeignField.md) + +Coerce the input to a [ForeignField](ForeignField.md). + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `x` | `string` \| `number` \| `bigint` | + +#### Returns + +[`CanonicalForeignField`](CanonicalForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.from + +#### Defined in + +[lib/foreign-field.ts:108](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L108) + +___ + +### fromBits + +▸ `Static` **fromBits**(`bits`): [`AlmostForeignField`](AlmostForeignField.md) + +Create a field element from its bits, as a `Bool[]` array. + +This method is provable! + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `bits` | `Bool`[] | + +#### Returns + +[`AlmostForeignField`](AlmostForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.fromBits + +#### Defined in + +[lib/foreign-field.ts:384](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L384) + +___ + +### sum + +▸ `Static` **sum**(`xs`, `operations`): `UnreducedForeignField` + +Sum (or difference) of multiple finite field elements. + +**`Example`** + +```ts +let z = ForeignField.sum([3, 2, 1], [-1, 1]); // 3 - 2 + 1 +z.assertEquals(2); +``` + +This method expects a list of ForeignField-like values, `x0,...,xn`, +and a list of "operations" `op1,...,opn` where every op is 1 or -1 (plus or minus), +and returns + +`x0 + op1*x1 + ... + opn*xn` + +where the sum is computed in finite field arithmetic. + +**Important:** For more than two summands, this is significantly more efficient +than chaining calls to [add](ForeignField.md#add) and [sub](ForeignField.md#sub). + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `xs` | (`number` \| `bigint` \| [`ForeignField`](ForeignField.md))[] | +| `operations` | (``1`` \| ``-1``)[] | + +#### Returns + +`UnreducedForeignField` + +#### Inherited from + +ForeignFieldWithMul.sum + +#### Defined in + +[lib/foreign-field.ts:251](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L251) + +___ + +### unsafeFrom + +▸ `Static` **unsafeFrom**(`x`): [`AlmostForeignField`](AlmostForeignField.md) + +Coerce the input to an [AlmostForeignField](AlmostForeignField.md) without additional assertions. + +**Warning:** Only use if you know what you're doing. + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `x` | [`ForeignField`](ForeignField.md) | + +#### Returns + +[`AlmostForeignField`](AlmostForeignField.md) + +#### Defined in + +[lib/foreign-field.ts:497](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L497) diff --git a/docs/zkapps/o1js-reference/classes/CanonicalForeignField.md b/docs/zkapps/o1js-reference/classes/CanonicalForeignField.md new file mode 100644 index 000000000..33074a9b6 --- /dev/null +++ b/docs/zkapps/o1js-reference/classes/CanonicalForeignField.md @@ -0,0 +1,983 @@ +[o1js](../README.md) / [Exports](../modules.md) / CanonicalForeignField + +# Class: CanonicalForeignField + +## Hierarchy + +- `ForeignFieldWithMul` + + ↳ **`CanonicalForeignField`** + +## Table of contents + +### Constructors + +- [constructor](CanonicalForeignField.md#constructor) + +### Properties + +- [type](CanonicalForeignField.md#type) +- [value](CanonicalForeignField.md#value) +- [\_modulus](CanonicalForeignField.md#_modulus) +- [\_provable](CanonicalForeignField.md#_provable) +- [\_variants](CanonicalForeignField.md#_variants) + +### Accessors + +- [Constructor](CanonicalForeignField.md#constructor-1) +- [modulus](CanonicalForeignField.md#modulus) +- [AlmostReduced](CanonicalForeignField.md#almostreduced) +- [Canonical](CanonicalForeignField.md#canonical) +- [Unreduced](CanonicalForeignField.md#unreduced) +- [modulus](CanonicalForeignField.md#modulus-1) +- [provable](CanonicalForeignField.md#provable) +- [sizeInBits](CanonicalForeignField.md#sizeinbits) + +### Methods + +- [add](CanonicalForeignField.md#add) +- [assertAlmostReduced](CanonicalForeignField.md#assertalmostreduced) +- [assertCanonical](CanonicalForeignField.md#assertcanonical) +- [assertEquals](CanonicalForeignField.md#assertequals) +- [assertLessThan](CanonicalForeignField.md#assertlessthan) +- [div](CanonicalForeignField.md#div) +- [equals](CanonicalForeignField.md#equals) +- [inv](CanonicalForeignField.md#inv) +- [isConstant](CanonicalForeignField.md#isconstant) +- [mul](CanonicalForeignField.md#mul) +- [neg](CanonicalForeignField.md#neg) +- [sub](CanonicalForeignField.md#sub) +- [toBigInt](CanonicalForeignField.md#tobigint) +- [toBits](CanonicalForeignField.md#tobits) +- [toConstant](CanonicalForeignField.md#toconstant) +- [toFields](CanonicalForeignField.md#tofields) +- [assertAlmostReduced](CanonicalForeignField.md#assertalmostreduced-1) +- [check](CanonicalForeignField.md#check) +- [from](CanonicalForeignField.md#from) +- [fromBits](CanonicalForeignField.md#frombits) +- [sum](CanonicalForeignField.md#sum) +- [unsafeFrom](CanonicalForeignField.md#unsafefrom) + +## Constructors + +### constructor + +• **new CanonicalForeignField**(`x`) + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `x` | `string` \| `number` \| `bigint` \| `Field3` \| [`CanonicalForeignField`](CanonicalForeignField.md) | + +#### Overrides + +ForeignFieldWithMul.constructor + +#### Defined in + +[lib/foreign-field.ts:505](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L505) + +## Properties + +### type + +• **type**: ``"FullyReduced"`` + +#### Defined in + +[lib/foreign-field.ts:503](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L503) + +___ + +### value + +• **value**: `Field3` + +The internal representation of a foreign field element, as a tuple of 3 limbs. + +#### Inherited from + +ForeignFieldWithMul.value + +#### Defined in + +[lib/foreign-field.ts:39](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L39) + +___ + +### \_modulus + +▪ `Static` **\_modulus**: `undefined` \| `bigint` = `undefined` + +#### Inherited from + +ForeignFieldWithMul.\_modulus + +#### Defined in + +[lib/foreign-field.ts:22](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L22) + +___ + +### \_provable + +▪ `Static` **\_provable**: `undefined` \| [`ProvablePure`](../interfaces/ProvablePure.md)<[`CanonicalForeignField`](CanonicalForeignField.md)\> = `undefined` + +#### Overrides + +ForeignFieldWithMul.\_provable + +#### Defined in + +[lib/foreign-field.ts:509](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L509) + +___ + +### \_variants + +▪ `Static` **\_variants**: `undefined` \| { `almostReduced`: typeof [`AlmostForeignField`](AlmostForeignField.md) ; `canonical`: typeof [`CanonicalForeignField`](CanonicalForeignField.md) ; `unreduced`: typeof `UnreducedForeignField` } = `undefined` + +Sibling classes that represent different ranges of field elements. + +#### Inherited from + +ForeignFieldWithMul.\_variants + +#### Defined in + +[lib/foreign-field.ts:48](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L48) + +## Accessors + +### Constructor + +• `get` **Constructor**(): typeof [`ForeignField`](ForeignField.md) + +#### Returns + +typeof [`ForeignField`](ForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.Constructor + +#### Defined in + +[lib/foreign-field.ts:41](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L41) + +___ + +### modulus + +• `get` **modulus**(): `bigint` + +#### Returns + +`bigint` + +#### Inherited from + +ForeignFieldWithMul.modulus + +#### Defined in + +[lib/foreign-field.ts:29](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L29) + +___ + +### AlmostReduced + +• `Static` `get` **AlmostReduced**(): typeof [`AlmostForeignField`](AlmostForeignField.md) + +Constructor for field elements that are "almost reduced", i.e. lie in the range [0, 2^ceil(log2(p))). + +#### Returns + +typeof [`AlmostForeignField`](AlmostForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.AlmostReduced + +#### Defined in + +[lib/foreign-field.ts:66](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L66) + +___ + +### Canonical + +• `Static` `get` **Canonical**(): typeof [`CanonicalForeignField`](CanonicalForeignField.md) + +Constructor for field elements that are fully reduced, i.e. lie in the range [0, p). + +#### Returns + +typeof [`CanonicalForeignField`](CanonicalForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.Canonical + +#### Defined in + +[lib/foreign-field.ts:73](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L73) + +___ + +### Unreduced + +• `Static` `get` **Unreduced**(): typeof `UnreducedForeignField` + +Constructor for unreduced field elements. + +#### Returns + +typeof `UnreducedForeignField` + +#### Inherited from + +ForeignFieldWithMul.Unreduced + +#### Defined in + +[lib/foreign-field.ts:59](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L59) + +___ + +### modulus + +• `Static` `get` **modulus**(): `bigint` + +#### Returns + +`bigint` + +#### Inherited from + +ForeignFieldWithMul.modulus + +#### Defined in + +[lib/foreign-field.ts:25](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L25) + +___ + +### provable + +• `Static` `get` **provable**(): [`ProvablePure`](../interfaces/ProvablePure.md)<[`CanonicalForeignField`](CanonicalForeignField.md)\> + +#### Returns + +[`ProvablePure`](../interfaces/ProvablePure.md)<[`CanonicalForeignField`](CanonicalForeignField.md)\> + +#### Overrides + +ForeignFieldWithMul.provable + +#### Defined in + +[lib/foreign-field.ts:510](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L510) + +___ + +### sizeInBits + +• `Static` `get` **sizeInBits**(): `number` + +#### Returns + +`number` + +#### Inherited from + +ForeignFieldWithMul.sizeInBits + +#### Defined in + +[lib/foreign-field.ts:32](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L32) + +## Methods + +### add + +▸ **add**(`y`): `UnreducedForeignField` + +Finite field addition + +**`Example`** + +```ts +x.add(2); // x + 2 mod p +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | `number` \| `bigint` \| [`ForeignField`](ForeignField.md) | + +#### Returns + +`UnreducedForeignField` + +#### Inherited from + +ForeignFieldWithMul.add + +#### Defined in + +[lib/foreign-field.ts:203](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L203) + +___ + +### assertAlmostReduced + +▸ **assertAlmostReduced**(): [`AlmostForeignField`](AlmostForeignField.md) + +Assert that this field element lies in the range [0, 2^k), +where k = ceil(log2(p)) and p is the foreign field modulus. + +Returns the field element as a [AlmostForeignField](AlmostForeignField.md). + +For a more efficient version of this for multiple field elements, see [assertAlmostReduced](ForeignField.md#assertalmostreduced-1). + +Note: this does not ensure that the field elements is in the canonical range [0, p). +To assert that stronger property, there is [assertCanonical](ForeignField.md#assertcanonical). +You should typically use [assertAlmostReduced](ForeignField.md#assertalmostreduced-1) though, because it is cheaper to prove and sufficient for +ensuring validity of all our non-native field arithmetic methods. + +#### Returns + +[`AlmostForeignField`](AlmostForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.assertAlmostReduced + +#### Defined in + +[lib/foreign-field.ts:156](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L156) + +___ + +### assertCanonical + +▸ **assertCanonical**(): [`CanonicalForeignField`](CanonicalForeignField.md) + +Assert that this field element is fully reduced, +i.e. lies in the range [0, p), where p is the foreign field modulus. + +Returns the field element as a [CanonicalForeignField](CanonicalForeignField.md). + +#### Returns + +[`CanonicalForeignField`](CanonicalForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.assertCanonical + +#### Defined in + +[lib/foreign-field.ts:189](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L189) + +___ + +### assertEquals + +▸ **assertEquals**(`y`, `message?`): [`CanonicalForeignField`](CanonicalForeignField.md) + +Assert equality with a ForeignField-like value + +**`Example`** + +```ts +x.assertEquals(0, "x is zero"); +``` + +Since asserting equality can also serve as a range check, +this method returns `x` with the appropriate type: + +**`Example`** + +```ts +let xChecked = x.assertEquals(1, "x is 1"); +xChecked satisfies CanonicalForeignField; +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | `number` \| `bigint` \| [`CanonicalForeignField`](CanonicalForeignField.md) | +| `message?` | `string` | + +#### Returns + +[`CanonicalForeignField`](CanonicalForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.assertEquals + +#### Defined in + +[lib/foreign-field.ts:278](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L278) + +▸ **assertEquals**(`y`, `message?`): [`AlmostForeignField`](AlmostForeignField.md) + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | [`AlmostForeignField`](AlmostForeignField.md) | +| `message?` | `string` | + +#### Returns + +[`AlmostForeignField`](AlmostForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.assertEquals + +#### Defined in + +[lib/foreign-field.ts:282](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L282) + +▸ **assertEquals**(`y`, `message?`): [`ForeignField`](ForeignField.md) + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | [`ForeignField`](ForeignField.md) | +| `message?` | `string` | + +#### Returns + +[`ForeignField`](ForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.assertEquals + +#### Defined in + +[lib/foreign-field.ts:283](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L283) + +___ + +### assertLessThan + +▸ **assertLessThan**(`c`, `message?`): `void` + +Assert that this field element is less than a constant c: `x < c`. + +The constant must satisfy `0 <= c < 2^264`, otherwise an error is thrown. + +**`Example`** + +```ts +x.assertLessThan(10); +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `c` | `number` \| `bigint` | +| `message?` | `string` | + +#### Returns + +`void` + +#### Inherited from + +ForeignFieldWithMul.assertLessThan + +#### Defined in + +[lib/foreign-field.ts:325](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L325) + +___ + +### div + +▸ **div**(`y`): [`AlmostForeignField`](AlmostForeignField.md) + +Division in the finite field, i.e. `x*y^(-1) mod p` where `y^(-1)` is the finite field inverse. + +**`Example`** + +```ts +let z = x.div(y); // x/y mod p +z.mul(y).assertEquals(x); +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | `number` \| `bigint` \| [`AlmostForeignField`](AlmostForeignField.md) | + +#### Returns + +[`AlmostForeignField`](AlmostForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.div + +#### Defined in + +[lib/foreign-field.ts:453](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L453) + +___ + +### equals + +▸ **equals**(`y`): `Bool` + +Check equality with a ForeignField-like value + +**`Example`** + +```ts +let isXZero = x.equals(0); +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | `number` \| `bigint` \| [`ForeignField`](ForeignField.md) | + +#### Returns + +`Bool` + +#### Inherited from + +ForeignFieldWithMul.equals + +#### Defined in + +[lib/foreign-field.ts:344](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L344) + +___ + +### inv + +▸ **inv**(): [`AlmostForeignField`](AlmostForeignField.md) + +Multiplicative inverse in the finite field + +**`Example`** + +```ts +let z = x.inv(); // 1/x mod p +z.mul(x).assertEquals(1); +``` + +#### Returns + +[`AlmostForeignField`](AlmostForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.inv + +#### Defined in + +[lib/foreign-field.ts:439](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L439) + +___ + +### isConstant + +▸ **isConstant**(): `boolean` + +Checks whether this field element is a constant. + +See FieldVar to understand constants vs variables. + +#### Returns + +`boolean` + +#### Inherited from + +ForeignFieldWithMul.isConstant + +#### Defined in + +[lib/foreign-field.ts:119](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L119) + +___ + +### mul + +▸ **mul**(`y`): `UnreducedForeignField` + +Finite field multiplication + +**`Example`** + +```ts +x.mul(y); // x*y mod p +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | `number` \| `bigint` \| [`AlmostForeignField`](AlmostForeignField.md) | + +#### Returns + +`UnreducedForeignField` + +#### Inherited from + +ForeignFieldWithMul.mul + +#### Defined in + +[lib/foreign-field.ts:425](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L425) + +___ + +### neg + +▸ **neg**(): `UnreducedForeignField` + +Finite field negation + +**`Example`** + +```ts +x.neg(); // -x mod p = p - x +``` + +#### Returns + +`UnreducedForeignField` + +#### Inherited from + +ForeignFieldWithMul.neg + +#### Defined in + +[lib/foreign-field.ts:214](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L214) + +___ + +### sub + +▸ **sub**(`y`): `UnreducedForeignField` + +Finite field subtraction + +**`Example`** + +```ts +x.sub(1); // x - 1 mod p +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | `number` \| `bigint` \| [`ForeignField`](ForeignField.md) | + +#### Returns + +`UnreducedForeignField` + +#### Inherited from + +ForeignFieldWithMul.sub + +#### Defined in + +[lib/foreign-field.ts:226](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L226) + +___ + +### toBigInt + +▸ **toBigInt**(): `bigint` + +Convert this field element to a bigint. + +#### Returns + +`bigint` + +#### Inherited from + +ForeignFieldWithMul.toBigInt + +#### Defined in + +[lib/foreign-field.ts:139](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L139) + +___ + +### toBits + +▸ **toBits**(`length?`): `Bool`[] + +Unpack a field element to its bits, as a [Bool](../modules.md#bool)[] array. + +This method is provable! + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `length?` | `number` | + +#### Returns + +`Bool`[] + +#### Inherited from + +ForeignFieldWithMul.toBits + +#### Defined in + +[lib/foreign-field.ts:363](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L363) + +___ + +### toConstant + +▸ **toConstant**(): [`ForeignField`](ForeignField.md) + +Convert this field element to a constant. + +See FieldVar to understand constants vs variables. + +**Warning**: This function is only useful in [witness](../modules.md#witness) or [asProver](../modules.md#asprover) blocks, +that is, in situations where the prover computes a value outside provable code. + +#### Returns + +[`ForeignField`](ForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.toConstant + +#### Defined in + +[lib/foreign-field.ts:131](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L131) + +___ + +### toFields + +▸ **toFields**(): `Field`[] + +Instance version of `Provable.toFields`, see [toFields](TokenSymbol.md#tofields) + +#### Returns + +`Field`[] + +#### Inherited from + +ForeignFieldWithMul.toFields + +#### Defined in + +[lib/foreign-field.ts:398](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L398) + +___ + +### assertAlmostReduced + +▸ `Static` **assertAlmostReduced**<`T`\>(`...xs`): [...{ [i in string \| number \| symbol]: AlmostForeignField }[]] + +Assert that one or more field elements lie in the range [0, 2^k), +where k = ceil(log2(p)) and p is the foreign field modulus. + +This is most efficient than when checking a multiple of 3 field elements at once. + +#### Type parameters + +| Name | Type | +| :------ | :------ | +| `T` | extends `Tuple`<[`ForeignField`](ForeignField.md)\> | + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `...xs` | `T` | + +#### Returns + +[...{ [i in string \| number \| symbol]: AlmostForeignField }[]] + +#### Inherited from + +ForeignFieldWithMul.assertAlmostReduced + +#### Defined in + +[lib/foreign-field.ts:172](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L172) + +___ + +### check + +▸ `Static` **check**(`x`): `void` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `x` | [`ForeignField`](ForeignField.md) | + +#### Returns + +`void` + +#### Overrides + +ForeignFieldWithMul.check + +#### Defined in + +[lib/foreign-field.ts:515](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L515) + +___ + +### from + +▸ `Static` **from**(`x`): [`CanonicalForeignField`](CanonicalForeignField.md) + +Coerce the input to a [ForeignField](ForeignField.md). + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `x` | `string` \| `number` \| `bigint` | + +#### Returns + +[`CanonicalForeignField`](CanonicalForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.from + +#### Defined in + +[lib/foreign-field.ts:108](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L108) + +___ + +### fromBits + +▸ `Static` **fromBits**(`bits`): [`AlmostForeignField`](AlmostForeignField.md) + +Create a field element from its bits, as a `Bool[]` array. + +This method is provable! + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `bits` | `Bool`[] | + +#### Returns + +[`AlmostForeignField`](AlmostForeignField.md) + +#### Inherited from + +ForeignFieldWithMul.fromBits + +#### Defined in + +[lib/foreign-field.ts:384](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L384) + +___ + +### sum + +▸ `Static` **sum**(`xs`, `operations`): `UnreducedForeignField` + +Sum (or difference) of multiple finite field elements. + +**`Example`** + +```ts +let z = ForeignField.sum([3, 2, 1], [-1, 1]); // 3 - 2 + 1 +z.assertEquals(2); +``` + +This method expects a list of ForeignField-like values, `x0,...,xn`, +and a list of "operations" `op1,...,opn` where every op is 1 or -1 (plus or minus), +and returns + +`x0 + op1*x1 + ... + opn*xn` + +where the sum is computed in finite field arithmetic. + +**Important:** For more than two summands, this is significantly more efficient +than chaining calls to [add](ForeignField.md#add) and [sub](ForeignField.md#sub). + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `xs` | (`number` \| `bigint` \| [`ForeignField`](ForeignField.md))[] | +| `operations` | (``1`` \| ``-1``)[] | + +#### Returns + +`UnreducedForeignField` + +#### Inherited from + +ForeignFieldWithMul.sum + +#### Defined in + +[lib/foreign-field.ts:251](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L251) + +___ + +### unsafeFrom + +▸ `Static` **unsafeFrom**(`x`): [`CanonicalForeignField`](CanonicalForeignField.md) + +Coerce the input to a [CanonicalForeignField](CanonicalForeignField.md) without additional assertions. + +**Warning:** Only use if you know what you're doing. + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `x` | [`ForeignField`](ForeignField.md) | + +#### Returns + +[`CanonicalForeignField`](CanonicalForeignField.md) + +#### Defined in + +[lib/foreign-field.ts:525](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L525) diff --git a/docs/zkapps/o1js-reference/classes/ForeignField.md b/docs/zkapps/o1js-reference/classes/ForeignField.md new file mode 100644 index 000000000..51bf8200c --- /dev/null +++ b/docs/zkapps/o1js-reference/classes/ForeignField.md @@ -0,0 +1,745 @@ +[o1js](../README.md) / [Exports](../modules.md) / ForeignField + +# Class: ForeignField + +## Table of contents + +### Constructors + +- [constructor](ForeignField.md#constructor) + +### Properties + +- [value](ForeignField.md#value) +- [\_modulus](ForeignField.md#_modulus) +- [\_provable](ForeignField.md#_provable) +- [\_variants](ForeignField.md#_variants) + +### Accessors + +- [Constructor](ForeignField.md#constructor-1) +- [modulus](ForeignField.md#modulus) +- [AlmostReduced](ForeignField.md#almostreduced) +- [Canonical](ForeignField.md#canonical) +- [Unreduced](ForeignField.md#unreduced) +- [modulus](ForeignField.md#modulus-1) +- [provable](ForeignField.md#provable) +- [sizeInBits](ForeignField.md#sizeinbits) + +### Methods + +- [add](ForeignField.md#add) +- [assertAlmostReduced](ForeignField.md#assertalmostreduced) +- [assertCanonical](ForeignField.md#assertcanonical) +- [assertEquals](ForeignField.md#assertequals) +- [assertLessThan](ForeignField.md#assertlessthan) +- [equals](ForeignField.md#equals) +- [isConstant](ForeignField.md#isconstant) +- [neg](ForeignField.md#neg) +- [sub](ForeignField.md#sub) +- [toBigInt](ForeignField.md#tobigint) +- [toBits](ForeignField.md#tobits) +- [toConstant](ForeignField.md#toconstant) +- [toFields](ForeignField.md#tofields) +- [assertAlmostReduced](ForeignField.md#assertalmostreduced-1) +- [check](ForeignField.md#check) +- [from](ForeignField.md#from) +- [fromBits](ForeignField.md#frombits) +- [sum](ForeignField.md#sum) +- [toLimbs](ForeignField.md#tolimbs) + +## Constructors + +### constructor + +• **new ForeignField**(`x`) + +Create a new [ForeignField](ForeignField.md) from a bigint, number, string or another ForeignField. + +**`Example`** + +```ts +let x = new ForeignField(5); +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `x` | `string` \| `number` \| `bigint` \| `Field3` \| [`ForeignField`](ForeignField.md) | + +#### Defined in + +[lib/foreign-field.ts:85](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L85) + +## Properties + +### value + +• **value**: `Field3` + +The internal representation of a foreign field element, as a tuple of 3 limbs. + +#### Defined in + +[lib/foreign-field.ts:39](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L39) + +___ + +### \_modulus + +▪ `Static` **\_modulus**: `undefined` \| `bigint` = `undefined` + +#### Defined in + +[lib/foreign-field.ts:22](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L22) + +___ + +### \_provable + +▪ `Static` **\_provable**: `any` = `undefined` + +#### Defined in + +[lib/foreign-field.ts:406](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L406) + +___ + +### \_variants + +▪ `Static` **\_variants**: `undefined` \| { `almostReduced`: typeof [`AlmostForeignField`](AlmostForeignField.md) ; `canonical`: typeof [`CanonicalForeignField`](CanonicalForeignField.md) ; `unreduced`: typeof `UnreducedForeignField` } = `undefined` + +Sibling classes that represent different ranges of field elements. + +#### Defined in + +[lib/foreign-field.ts:48](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L48) + +## Accessors + +### Constructor + +• `get` **Constructor**(): typeof [`ForeignField`](ForeignField.md) + +#### Returns + +typeof [`ForeignField`](ForeignField.md) + +#### Defined in + +[lib/foreign-field.ts:41](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L41) + +___ + +### modulus + +• `get` **modulus**(): `bigint` + +#### Returns + +`bigint` + +#### Defined in + +[lib/foreign-field.ts:29](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L29) + +___ + +### AlmostReduced + +• `Static` `get` **AlmostReduced**(): typeof [`AlmostForeignField`](AlmostForeignField.md) + +Constructor for field elements that are "almost reduced", i.e. lie in the range [0, 2^ceil(log2(p))). + +#### Returns + +typeof [`AlmostForeignField`](AlmostForeignField.md) + +#### Defined in + +[lib/foreign-field.ts:66](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L66) + +___ + +### Canonical + +• `Static` `get` **Canonical**(): typeof [`CanonicalForeignField`](CanonicalForeignField.md) + +Constructor for field elements that are fully reduced, i.e. lie in the range [0, p). + +#### Returns + +typeof [`CanonicalForeignField`](CanonicalForeignField.md) + +#### Defined in + +[lib/foreign-field.ts:73](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L73) + +___ + +### Unreduced + +• `Static` `get` **Unreduced**(): typeof `UnreducedForeignField` + +Constructor for unreduced field elements. + +#### Returns + +typeof `UnreducedForeignField` + +#### Defined in + +[lib/foreign-field.ts:59](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L59) + +___ + +### modulus + +• `Static` `get` **modulus**(): `bigint` + +#### Returns + +`bigint` + +#### Defined in + +[lib/foreign-field.ts:25](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L25) + +___ + +### provable + +• `Static` `get` **provable**(): `any` + +`Provable`, see [Provable](../modules.md#provable-1) + +#### Returns + +`any` + +#### Defined in + +[lib/foreign-field.ts:411](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L411) + +___ + +### sizeInBits + +• `Static` `get` **sizeInBits**(): `number` + +#### Returns + +`number` + +#### Defined in + +[lib/foreign-field.ts:32](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L32) + +## Methods + +### add + +▸ **add**(`y`): `UnreducedForeignField` + +Finite field addition + +**`Example`** + +```ts +x.add(2); // x + 2 mod p +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | `number` \| `bigint` \| [`ForeignField`](ForeignField.md) | + +#### Returns + +`UnreducedForeignField` + +#### Defined in + +[lib/foreign-field.ts:203](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L203) + +___ + +### assertAlmostReduced + +▸ **assertAlmostReduced**(): [`AlmostForeignField`](AlmostForeignField.md) + +Assert that this field element lies in the range [0, 2^k), +where k = ceil(log2(p)) and p is the foreign field modulus. + +Returns the field element as a [AlmostForeignField](AlmostForeignField.md). + +For a more efficient version of this for multiple field elements, see [assertAlmostReduced](ForeignField.md#assertalmostreduced-1). + +Note: this does not ensure that the field elements is in the canonical range [0, p). +To assert that stronger property, there is [assertCanonical](ForeignField.md#assertcanonical). +You should typically use [assertAlmostReduced](ForeignField.md#assertalmostreduced-1) though, because it is cheaper to prove and sufficient for +ensuring validity of all our non-native field arithmetic methods. + +#### Returns + +[`AlmostForeignField`](AlmostForeignField.md) + +#### Defined in + +[lib/foreign-field.ts:156](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L156) + +___ + +### assertCanonical + +▸ **assertCanonical**(): [`CanonicalForeignField`](CanonicalForeignField.md) + +Assert that this field element is fully reduced, +i.e. lies in the range [0, p), where p is the foreign field modulus. + +Returns the field element as a [CanonicalForeignField](CanonicalForeignField.md). + +#### Returns + +[`CanonicalForeignField`](CanonicalForeignField.md) + +#### Defined in + +[lib/foreign-field.ts:189](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L189) + +___ + +### assertEquals + +▸ **assertEquals**(`y`, `message?`): [`CanonicalForeignField`](CanonicalForeignField.md) + +Assert equality with a ForeignField-like value + +**`Example`** + +```ts +x.assertEquals(0, "x is zero"); +``` + +Since asserting equality can also serve as a range check, +this method returns `x` with the appropriate type: + +**`Example`** + +```ts +let xChecked = x.assertEquals(1, "x is 1"); +xChecked satisfies CanonicalForeignField; +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | `number` \| `bigint` \| [`CanonicalForeignField`](CanonicalForeignField.md) | +| `message?` | `string` | + +#### Returns + +[`CanonicalForeignField`](CanonicalForeignField.md) + +#### Defined in + +[lib/foreign-field.ts:278](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L278) + +▸ **assertEquals**(`y`, `message?`): [`AlmostForeignField`](AlmostForeignField.md) + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | [`AlmostForeignField`](AlmostForeignField.md) | +| `message?` | `string` | + +#### Returns + +[`AlmostForeignField`](AlmostForeignField.md) + +#### Defined in + +[lib/foreign-field.ts:282](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L282) + +▸ **assertEquals**(`y`, `message?`): [`ForeignField`](ForeignField.md) + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | [`ForeignField`](ForeignField.md) | +| `message?` | `string` | + +#### Returns + +[`ForeignField`](ForeignField.md) + +#### Defined in + +[lib/foreign-field.ts:283](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L283) + +___ + +### assertLessThan + +▸ **assertLessThan**(`c`, `message?`): `void` + +Assert that this field element is less than a constant c: `x < c`. + +The constant must satisfy `0 <= c < 2^264`, otherwise an error is thrown. + +**`Example`** + +```ts +x.assertLessThan(10); +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `c` | `number` \| `bigint` | +| `message?` | `string` | + +#### Returns + +`void` + +#### Defined in + +[lib/foreign-field.ts:325](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L325) + +___ + +### equals + +▸ **equals**(`y`): `Bool` + +Check equality with a ForeignField-like value + +**`Example`** + +```ts +let isXZero = x.equals(0); +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | `number` \| `bigint` \| [`ForeignField`](ForeignField.md) | + +#### Returns + +`Bool` + +#### Defined in + +[lib/foreign-field.ts:344](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L344) + +___ + +### isConstant + +▸ **isConstant**(): `boolean` + +Checks whether this field element is a constant. + +See FieldVar to understand constants vs variables. + +#### Returns + +`boolean` + +#### Defined in + +[lib/foreign-field.ts:119](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L119) + +___ + +### neg + +▸ **neg**(): `UnreducedForeignField` + +Finite field negation + +**`Example`** + +```ts +x.neg(); // -x mod p = p - x +``` + +#### Returns + +`UnreducedForeignField` + +#### Defined in + +[lib/foreign-field.ts:214](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L214) + +___ + +### sub + +▸ **sub**(`y`): `UnreducedForeignField` + +Finite field subtraction + +**`Example`** + +```ts +x.sub(1); // x - 1 mod p +``` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `y` | `number` \| `bigint` \| [`ForeignField`](ForeignField.md) | + +#### Returns + +`UnreducedForeignField` + +#### Defined in + +[lib/foreign-field.ts:226](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L226) + +___ + +### toBigInt + +▸ **toBigInt**(): `bigint` + +Convert this field element to a bigint. + +#### Returns + +`bigint` + +#### Defined in + +[lib/foreign-field.ts:139](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L139) + +___ + +### toBits + +▸ **toBits**(`length?`): `Bool`[] + +Unpack a field element to its bits, as a [Bool](../modules.md#bool)[] array. + +This method is provable! + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `length?` | `number` | + +#### Returns + +`Bool`[] + +#### Defined in + +[lib/foreign-field.ts:363](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L363) + +___ + +### toConstant + +▸ **toConstant**(): [`ForeignField`](ForeignField.md) + +Convert this field element to a constant. + +See FieldVar to understand constants vs variables. + +**Warning**: This function is only useful in [witness](../modules.md#witness) or [asProver](../modules.md#asprover) blocks, +that is, in situations where the prover computes a value outside provable code. + +#### Returns + +[`ForeignField`](ForeignField.md) + +#### Defined in + +[lib/foreign-field.ts:131](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L131) + +___ + +### toFields + +▸ **toFields**(): `Field`[] + +Instance version of `Provable.toFields`, see [toFields](TokenSymbol.md#tofields) + +#### Returns + +`Field`[] + +#### Defined in + +[lib/foreign-field.ts:398](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L398) + +___ + +### assertAlmostReduced + +▸ `Static` **assertAlmostReduced**<`T`\>(`...xs`): [...{ [i in string \| number \| symbol]: AlmostForeignField }[]] + +Assert that one or more field elements lie in the range [0, 2^k), +where k = ceil(log2(p)) and p is the foreign field modulus. + +This is most efficient than when checking a multiple of 3 field elements at once. + +#### Type parameters + +| Name | Type | +| :------ | :------ | +| `T` | extends `Tuple`<[`ForeignField`](ForeignField.md)\> | + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `...xs` | `T` | + +#### Returns + +[...{ [i in string \| number \| symbol]: AlmostForeignField }[]] + +#### Defined in + +[lib/foreign-field.ts:172](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L172) + +___ + +### check + +▸ `Static` **check**(`_`): `void` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `_` | [`ForeignField`](ForeignField.md) | + +#### Returns + +`void` + +#### Defined in + +[lib/foreign-field.ts:402](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L402) + +___ + +### from + +▸ `Static` **from**(`x`): [`CanonicalForeignField`](CanonicalForeignField.md) + +Coerce the input to a [ForeignField](ForeignField.md). + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `x` | `string` \| `number` \| `bigint` | + +#### Returns + +[`CanonicalForeignField`](CanonicalForeignField.md) + +#### Defined in + +[lib/foreign-field.ts:108](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L108) + +___ + +### fromBits + +▸ `Static` **fromBits**(`bits`): [`AlmostForeignField`](AlmostForeignField.md) + +Create a field element from its bits, as a `Bool[]` array. + +This method is provable! + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `bits` | `Bool`[] | + +#### Returns + +[`AlmostForeignField`](AlmostForeignField.md) + +#### Defined in + +[lib/foreign-field.ts:384](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L384) + +___ + +### sum + +▸ `Static` **sum**(`xs`, `operations`): `UnreducedForeignField` + +Sum (or difference) of multiple finite field elements. + +**`Example`** + +```ts +let z = ForeignField.sum([3, 2, 1], [-1, 1]); // 3 - 2 + 1 +z.assertEquals(2); +``` + +This method expects a list of ForeignField-like values, `x0,...,xn`, +and a list of "operations" `op1,...,opn` where every op is 1 or -1 (plus or minus), +and returns + +`x0 + op1*x1 + ... + opn*xn` + +where the sum is computed in finite field arithmetic. + +**Important:** For more than two summands, this is significantly more efficient +than chaining calls to [add](ForeignField.md#add) and [sub](ForeignField.md#sub). + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `xs` | (`number` \| `bigint` \| [`ForeignField`](ForeignField.md))[] | +| `operations` | (``1`` \| ``-1``)[] | + +#### Returns + +`UnreducedForeignField` + +#### Defined in + +[lib/foreign-field.ts:251](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L251) + +___ + +### toLimbs + +▸ `Static` `Private` **toLimbs**(`x`): `Field3` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `x` | `string` \| `number` \| `bigint` \| [`ForeignField`](ForeignField.md) | + +#### Returns + +`Field3` + +#### Defined in + +[lib/foreign-field.ts:100](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/foreign-field.ts#L100) diff --git a/docs/zkapps/o1js-reference/classes/Unconstrained.md b/docs/zkapps/o1js-reference/classes/Unconstrained.md new file mode 100644 index 000000000..4193447f1 --- /dev/null +++ b/docs/zkapps/o1js-reference/classes/Unconstrained.md @@ -0,0 +1,195 @@ +[o1js](../README.md) / [Exports](../modules.md) / Unconstrained + +# Class: Unconstrained + +Container which holds an unconstrained value. This can be used to pass values +between the out-of-circuit blocks in provable code. + +Invariants: +- An `Unconstrained`'s value can only be accessed in auxiliary contexts. +- An `Unconstrained` can be empty when compiling, but never empty when running as the prover. + (there is no way to create an empty `Unconstrained` in the prover) + +**`Example`** + +```ts +let x = Unconstrained.from(0n); + +class MyContract extends SmartContract { + `@method` myMethod(x: Unconstrained) { + + Provable.witness(Field, () => { + // we can access and modify `x` here + let newValue = x.get() + otherField.toBigInt(); + x.set(newValue); + + // ... + }); + + // throws an error! + x.get(); + } +``` + +## Type parameters + +| Name | +| :------ | +| `T` | + +## Table of contents + +### Constructors + +- [constructor](Unconstrained.md#constructor) + +### Properties + +- [option](Unconstrained.md#option) +- [provable](Unconstrained.md#provable) + +### Methods + +- [get](Unconstrained.md#get) +- [set](Unconstrained.md#set) +- [from](Unconstrained.md#from) +- [witness](Unconstrained.md#witness) + +## Constructors + +### constructor + +• `Private` **new Unconstrained**<`T`\>(`isSome`, `value?`) + +#### Type parameters + +| Name | +| :------ | +| `T` | + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `isSome` | `boolean` | +| `value?` | `T` | + +#### Defined in + +[lib/circuit_value.ts:514](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/circuit_value.ts#L514) + +## Properties + +### option + +• `Private` **option**: { `isSome`: ``true`` ; `value`: `T` } \| { `isSome`: ``false`` ; `value`: `undefined` } + +#### Defined in + +[lib/circuit_value.ts:510](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/circuit_value.ts#L510) + +___ + +### provable + +▪ `Static` **provable**: [`Provable`](../modules.md#provable-1)<[`Unconstrained`](Unconstrained.md)<`any`\>\> + +#### Defined in + +[lib/circuit_value.ts:558](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/circuit_value.ts#L558) + +## Methods + +### get + +▸ **get**(): `T` + +Read an unconstrained value. + +Note: Can only be called outside provable code. + +#### Returns + +`T` + +#### Defined in + +[lib/circuit_value.ts:523](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/circuit_value.ts#L523) + +___ + +### set + +▸ **set**(`value`): `void` + +Modify the unconstrained value. + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `value` | `T` | + +#### Returns + +`void` + +#### Defined in + +[lib/circuit_value.ts:537](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/circuit_value.ts#L537) + +___ + +### from + +▸ `Static` **from**<`T`\>(`value`): [`Unconstrained`](Unconstrained.md)<`T`\> + +Create an `Unconstrained` with the given `value`. + +#### Type parameters + +| Name | +| :------ | +| `T` | + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `value` | `T` | + +#### Returns + +[`Unconstrained`](Unconstrained.md)<`T`\> + +#### Defined in + +[lib/circuit_value.ts:544](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/circuit_value.ts#L544) + +___ + +### witness + +▸ `Static` **witness**<`T`\>(`compute`): [`Unconstrained`](Unconstrained.md)<`T`\> + +Create an `Unconstrained` from a witness computation. + +#### Type parameters + +| Name | +| :------ | +| `T` | + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `compute` | () => `T` | + +#### Returns + +[`Unconstrained`](Unconstrained.md)<`T`\> + +#### Defined in + +[lib/circuit_value.ts:551](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/circuit_value.ts#L551) diff --git a/docs/zkapps/o1js-reference/modules.md b/docs/zkapps/o1js-reference/modules.md index 7dd24bc7a..26f89f86c 100644 --- a/docs/zkapps/o1js-reference/modules.md +++ b/docs/zkapps/o1js-reference/modules.md @@ -23,11 +23,14 @@ ### Classes - [AccountUpdate](classes/AccountUpdate.md) +- [AlmostForeignField](classes/AlmostForeignField.md) +- [CanonicalForeignField](classes/CanonicalForeignField.md) - [Bool](classes/Bool.md) - [Character](classes/Character.md) - [Circuit](classes/Circuit.md) - [CircuitString](classes/CircuitString.md) - [CircuitValue](classes/CircuitValue.md) +- [ForeignField](classes/ForeignField.md) - [Field](classes/Field.md) - [Group](classes/Group.md) - [Int64](classes/Int64.md) @@ -48,6 +51,7 @@ - [TokenSymbol](classes/TokenSymbol.md) - [UInt32](classes/UInt32.md) - [UInt64](classes/UInt64.md) +- [Unconstrained](classes/Unconstrained.md) - [VerificationKey](classes/VerificationKey.md) ### Interfaces diff --git a/sidebars.js b/sidebars.js index 631067008..8728adefc 100644 --- a/sidebars.js +++ b/sidebars.js @@ -109,11 +109,21 @@ module.exports = { id: 'zkapps/o1js-reference/classes/AccountUpdate', label: 'AccountUpdate', }, + { + type: 'doc', + id: 'zkapps/o1js-reference/classes/AlmostForeignField', + label: 'AlmostForeignField', + }, { type: 'doc', id: 'zkapps/o1js-reference/classes/Bool', label: 'Bool', }, + { + type: 'doc', + id: 'zkapps/o1js-reference/classes/CanonicalForeignField', + label: 'CanonicalForeignField', + }, { type: 'doc', id: 'zkapps/o1js-reference/classes/Character', @@ -139,6 +149,11 @@ module.exports = { id: 'zkapps/o1js-reference/classes/Field', label: 'Field', }, + { + type: 'doc', + id: 'zkapps/o1js-reference/classes/ForeignField', + label: 'ForeignField', + }, { type: 'doc', id: 'zkapps/o1js-reference/classes/Group', @@ -239,6 +254,11 @@ module.exports = { id: 'zkapps/o1js-reference/classes/UInt64', label: 'UInt64', }, + { + type: 'doc', + id: 'zkapps/o1js-reference/classes/Unconstrained', + label: 'Unconstrained', + }, { type: 'doc', id: 'zkapps/o1js-reference/classes/VerificationKey', From 9186ef384dedc0bc1b806ada9bba194aea750f02 Mon Sep 17 00:00:00 2001 From: Gregor Date: Thu, 7 Dec 2023 21:04:20 +0100 Subject: [PATCH 08/12] remove link todos --- docs/zkapps/o1js/foreign-fields.mdx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/docs/zkapps/o1js/foreign-fields.mdx b/docs/zkapps/o1js/foreign-fields.mdx index 3456b5272..664b7570a 100644 --- a/docs/zkapps/o1js/foreign-fields.mdx +++ b/docs/zkapps/o1js/foreign-fields.mdx @@ -34,9 +34,7 @@ Here is where foreign fields come in: They let you perform algorithms that conne ## Basic usage - - -What follows is a brief overview of how to use foreign fields. For more details, refer to the [API reference](../o1js-reference/classes/Field) or the doccomments on each method. +What follows is a brief overview of how to use foreign fields. For more details, refer to the [API reference](../o1js-reference/classes/ForeignField) or the doccomments on each method. The entry point for using foreign fields is the `createForeignField()` function: @@ -108,9 +106,7 @@ let y = SmallField.from(5n); // convert from bigint or number y.toBigInt() === 5n; // convert to bigint ``` - - -As usual, you can find more information about each method in the [API reference](../o1js-reference/classes/Field). +As usual, you can find more information about each method in the [API reference](../o1js-reference/classes/ForeignField). ## Three kinds of foreign field From b9bb92def7ffa01a955183762709a1dc84054302 Mon Sep 17 00:00:00 2001 From: Gregor Date: Thu, 7 Dec 2023 21:07:37 +0100 Subject: [PATCH 09/12] actually unreduced is not exported --- docs/zkapps/o1js/foreign-fields.mdx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/zkapps/o1js/foreign-fields.mdx b/docs/zkapps/o1js/foreign-fields.mdx index 664b7570a..a3c3c5d64 100644 --- a/docs/zkapps/o1js/foreign-fields.mdx +++ b/docs/zkapps/o1js/foreign-fields.mdx @@ -122,12 +122,11 @@ let y = new Field17.AlmostReduced(0); let z = new Field17.Canonical(0); ``` -And there are three base types that are common to each variant: +Unreduced field elements just have the `ForeignField` type. For the other two variants, there are narrower base types that are common to each variant: ```ts -import { UnreducedField, AlmostReducedField, CanonicalField } from 'o1js'; +import { AlmostReducedField, CanonicalField } from 'o1js'; -x satisfies UnreducedField; y satisfies AlmostReducedField; z satisfies CanonicalField; ``` From 23ab1997e01c043fde249f82544cceb249850dbb Mon Sep 17 00:00:00 2001 From: Barrie Byron Date: Thu, 7 Dec 2023 15:19:35 -0500 Subject: [PATCH 10/12] snarkyjs to o1js for code links --- docs/zkapps/o1js-reference/classes/Unconstrained.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/zkapps/o1js-reference/classes/Unconstrained.md b/docs/zkapps/o1js-reference/classes/Unconstrained.md index 4193447f1..0ca19ccf0 100644 --- a/docs/zkapps/o1js-reference/classes/Unconstrained.md +++ b/docs/zkapps/o1js-reference/classes/Unconstrained.md @@ -6,8 +6,8 @@ Container which holds an unconstrained value. This can be used to pass values between the out-of-circuit blocks in provable code. Invariants: -- An `Unconstrained`'s value can only be accessed in auxiliary contexts. -- An `Unconstrained` can be empty when compiling, but never empty when running as the prover. +- An `Unconstrained`'s value can be accessed only in auxiliary contexts. +- An `Unconstrained` container can be empty when compiling, but never empty when running as the prover. (there is no way to create an empty `Unconstrained` in the prover) **`Example`** @@ -76,7 +76,7 @@ class MyContract extends SmartContract { #### Defined in -[lib/circuit_value.ts:514](https://github.com/o1-labs/snarkyjs/blob/9d34c7fcf/src/lib/circuit_value.ts#L514) +[lib/circuit_value.ts:514](https://github.com/o1-labs/o1js/blob/9d34c7fcf/src/lib/circuit_value.ts#L514) ## Properties From ee1b851a2eacc95a05056aad436c479195ef87e1 Mon Sep 17 00:00:00 2001 From: Gregor Mitscha-Baude Date: Fri, 8 Dec 2023 09:12:08 +0100 Subject: [PATCH 11/12] Apply suggestions from code review Co-authored-by: Barrie Byron --- docs/zkapps/o1js/foreign-fields.mdx | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/zkapps/o1js/foreign-fields.mdx b/docs/zkapps/o1js/foreign-fields.mdx index 329966216..b920842f5 100644 --- a/docs/zkapps/o1js/foreign-fields.mdx +++ b/docs/zkapps/o1js/foreign-fields.mdx @@ -106,11 +106,11 @@ y.toBigInt() === 5n; // convert to bigint As usual, you can find more information about each method in the [API reference](../o1js-reference/classes/ForeignField). -## Three kinds of foreign field +## Three kinds of foreign fields If the basic usage examples look straightforward, here is where it gets a bit complicated. -For each `ForeignField` class created with `createForeignField()`, there are actually three different variants. We call them _unreduced_, _almost reduced_ and _canonical_. +For each `ForeignField` class created with `createForeignField()`, there are actually three different variants: _unreduced_, _almost reduced_, and _canonical_. You find the variants as static properties on the class; they are themselves classes: @@ -129,7 +129,7 @@ y satisfies AlmostReducedField; z satisfies CanonicalField; ``` -In the following, we explain when to use the different variants, and how to convert between them. You don't need to learn all of it, though: The type system will guide you to use the right variant in each situation. +In the following section, you learn when to use the different variants, and how to convert between them. You don't need to remember all of it, though: The type system guides you to use the right variant in each situation. ### Unreduced fields @@ -148,8 +148,8 @@ For example, if `x` has the value 16, it is valid for `x.add(x)` to contain the :::note -Unreduced doesn't usually mean that the underlying witness is larger than the modulus. It just means that we have not _proved_ it to be smaller. -A malicious prover _could_ make it larger, by slightly modifying their local version of o1js and creating a proof with that. +Unreduced doesn't usually mean that the underlying witness is larger than the modulus. It just means that it is not _proved_ to be smaller. +A malicious prover _could_ make it larger by slightly modifying their local version of o1js and creating a proof with that version. ::: @@ -184,7 +184,7 @@ assert(zz instanceof SmallField.Unreduced); assert(zAlmost.inv() instanceof SmallField.AlmostReduced); ``` -It can be convenient to require almost reduced fields as inputs to your smart contract. To do so, create a class which can also serve as a type, and use its `.provable` property when passing to the state decorator: +It can be convenient to require almost reduced fields as inputs to your smart contract. To do that, create a class that can also serve as a type and use its `.provable` property when passing to the state decorator: ```ts class AlmostField17 extends Field17.AlmostReduced {} @@ -201,9 +201,9 @@ class MyContract extends SmartContract { #### What does almost reduced mean? -The definition of almost reduced is somewhat technical. The main motivation is to guarantee that the way we prove modular multiplication is sound. That is definitely true for field elements `< 2^259`. (Recall that we require the modulus to be `< 2^259`.) +The definition of almost reduced is somewhat technical. The main motivation is to guarantee that the way you prove modular multiplication is sound. That is definitely true for field elements `< 2^259`. (Recall that the modulus is required to be `< 2^259`.) -However, we actually prove a stronger condition, which lets us save a few constraints in some places: +However, you actually prove a stronger condition, which saves a few constraints in some places: `z` is **almost reduced** modulo `f`, if `z >> 176` is smaller or equal than `f >> 176`. (`>>` means a [right shift](https://en.wikipedia.org/wiki/Arithmetic_shift).) @@ -217,7 +217,7 @@ However, by calling `z.assertAlmostReduced()`, we prove that `z` is smaller than Why are we exposing `AlmostReducedField` as a separate type, and don't _always_ prove conditions necessary for multiplication? Because that would take up additional constraints! -`ForeignField` is built to allow you to use the minimum amount of constraints, in a way that is safely guided by the type system. See the section below on [minimizing constraints](#minimizing-constraints) for more details. +`ForeignField` is built to allow you to use the minimum amount of constraints in a way that is safely guided by the type system. See [minimizing constraints](#minimizing-constraints) for more details. ### Canonical fields @@ -263,7 +263,7 @@ let yCanonical = y.assertCanonical(); let isEqual = xCanonical.equals(yCanonical); ``` -We require inputs to be canonical for this because we check for strict equality, not equality modulo the field size. Note that being strictly unequal does not imply being unequal as field elements, so `equals()` on non-canonical fields would be error-prone. +Inputs must be canonical for `equals()` because the operation checks for strict equality, not equality modulo the field size. Note that being strictly unequal does not imply being unequal as field elements, so `equals()` on non-canonical fields would be error-prone. ## Minimizing constraints @@ -292,7 +292,7 @@ z2r.div(z3r); #### `sum()` -Another opportunity to save constraints is when doing many additions or subtractions in a row. Instead of doing something like `x.add(y).sub(z)`, use `ForeignField.sum()`: +Another opportunity to save constraints is when many additions or subtractions are performed in a row. Instead of doing something like `x.add(y).sub(z)`, use `ForeignField.sum()`: ```ts // u = x + y - z From 98cfff16cd0c03c243e7f2c4992143705c31317c Mon Sep 17 00:00:00 2001 From: Gregor Mitscha-Baude Date: Fri, 8 Dec 2023 09:20:18 +0100 Subject: [PATCH 12/12] Apply suggestions from code review --- docs/zkapps/o1js/foreign-fields.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/zkapps/o1js/foreign-fields.mdx b/docs/zkapps/o1js/foreign-fields.mdx index b920842f5..20d9a96fd 100644 --- a/docs/zkapps/o1js/foreign-fields.mdx +++ b/docs/zkapps/o1js/foreign-fields.mdx @@ -211,11 +211,11 @@ However, you actually prove a stronger condition, which saves a few constraints Example: Assume `x` is a `UInt256` holding the value `2^130`. After computing `z = x.mul(x)`, it is valid for `z` to be `2^260`. -However, by calling `z.assertAlmostReduced()`, we prove that `z` is smaller than `2^259` and safe to use in another multiplication. According to our stronger definition, we even have `z < 2^256`. +However, by calling `z.assertAlmostReduced()`, you prove that `z` is smaller than `2^259` and safe to use in another multiplication. According to the stronger definition, you even have `z < 2^256`. ::: -Why are we exposing `AlmostReducedField` as a separate type, and don't _always_ prove conditions necessary for multiplication? Because that would take up additional constraints! +Why is `AlmostReducedField` exposed as a separate type, instead of _always_ proving conditions necessary for multiplication? Because that would take up additional constraints! `ForeignField` is built to allow you to use the minimum amount of constraints in a way that is safely guided by the type system. See [minimizing constraints](#minimizing-constraints) for more details.