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..0ca19ccf0 --- /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 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`** + +```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/o1js/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/docs/zkapps/o1js/foreign-fields.mdx b/docs/zkapps/o1js/foreign-fields.mdx index 5d0266ed5..20d9a96fd 100644 --- a/docs/zkapps/o1js/foreign-fields.mdx +++ b/docs/zkapps/o1js/foreign-fields.mdx @@ -32,9 +32,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 o1js [API reference](../o1js-reference/classes/Field) or the doccomments on each method. +This section provides 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: @@ -106,6 +104,214 @@ 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/ForeignField). + +## 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: _unreduced_, _almost reduced_, and _canonical_. + +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); +``` + +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 { AlmostReducedField, CanonicalField } from 'o1js'; + +y satisfies AlmostReducedField; +z satisfies CanonicalField; +``` + +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 + +Most arithmetic operations return unreduced fields: + +```ts +import assert from 'assert'; + +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 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. + +::: + +Unreduced fields can be added and subtracted, but not multiplied or divided: + +```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 them by using `.assertAlmostReduced()`: + +```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 field: +assert(zAlmost.inv() instanceof SmallField.AlmostReduced); +``` + +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 {} + +class MyContract extends SmartContract { + @state(AlmostField17.provable) x = State(); + + @method myMethod(y: AlmostField17) { + let x = y.mul(2); + this.x.set(x.assertAlmostReduced()); + } +} +``` + +#### What does almost reduced mean? + +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, 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).) + +:::note + +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()`, 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 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. + +### 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(zCanonical 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); +``` + +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 + +#### `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); +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); +``` + +`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 + +#### `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 +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 value. So, the 1 in this example means "add x and y", and 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]); +``` -As usual, you can find more information about each method in the o1js [API reference](../o1js-reference/classes/Field). +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. 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',