From 5dccfb9cc259a7812639db0be79e9c69b8f4f93a Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Mon, 26 Feb 2024 10:52:23 -0700 Subject: [PATCH 01/20] Implement to/fromBits in TS, and set max length to 254 bits --- src/lib/field.ts | 59 ++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/src/lib/field.ts b/src/lib/field.ts index 0e643cb2a5..2b373b0315 100644 --- a/src/lib/field.ts +++ b/src/lib/field.ts @@ -1,10 +1,11 @@ -import { Snarky, Provable } from '../snarky.js'; +import { Snarky } from '../snarky.js'; import { Field as Fp } from '../provable/field-bigint.js'; import { defineBinable } from '../bindings/lib/binable.js'; import type { NonNegativeInteger } from '../bindings/crypto/non-negative.js'; import { asProver, inCheckedComputation } from './provable-context.js'; import { Bool } from './bool.js'; import { assert } from './errors.js'; +import { Provable } from './provable.js'; // external API export { Field }; @@ -908,34 +909,34 @@ class Field { * Returns an array of {@link Bool} elements representing [little endian binary representation](https://en.wikipedia.org/wiki/Endianness) of this {@link Field} element. * * If you use the optional `length` argument, proves that the field element fits in `length` bits. - * The `length` has to be between 0 and 255 and the method throws if it isn't. + * The `length` has to be between 0 and 254 and the method throws if it isn't. * * **Warning**: The cost of this operation in a zk proof depends on the `length` you specify, - * which by default is 255 bits. Prefer to pass a smaller `length` if possible. + * which by default is 254 bits. Prefer to pass a smaller `length` if possible. * * @param length - the number of bits to fit the element. If the element does not fit in `length` bits, the functions throws an error. * * @return An array of {@link Bool} element representing little endian binary representation of this {@link Field}. */ - toBits(length?: number) { - if (length !== undefined) checkBitLength('Field.toBits()', length); - if (this.isConstant()) { - let bits = Fp.toBits(this.toBigInt()); - if (length !== undefined) { - if (bits.slice(length).some((bit) => bit)) - throw Error(`Field.toBits(): ${this} does not fit in ${length} bits`); - return bits.slice(0, length).map((b) => new Bool(b)); - } - return bits.map((b) => new Bool(b)); - } - let [, ...bits] = Snarky.field.toBits(length ?? Fp.sizeInBits, this.value); - return bits.map((b) => new Bool(b)); + toBits(length: number = 254) { + checkBitLength('Field.toBits()', length, 254); + let bits = Provable.witness(Provable.Array(Bool, length), () => { + let f = this.toBigInt(); + return Array.from( + { length }, + (_, k) => new Bool(!!((f >> BigInt(k)) & 0xffn)) + ); + }); + if (bits.slice(length).some((bit) => bit.toBoolean())) + throw Error(`Field.toBits(): ${this} does not fit in ${length} bits`); + Field.newFromBits(bits).assertEquals(this); + return bits; } /** * Convert a bit array into a {@link Field} element using [little endian binary representation](https://en.wikipedia.org/wiki/Endianness) * - * The method throws if the given bits do not fit in a single Field element. A Field element can be at most 255 bits. + * The method throws if the given bits do not fit in a single Field element. A Field element can be at most 254 bits. * * **Important**: If the given `bytes` array is an array of `booleans` or {@link Bool} elements that all are `constant`, the resulting {@link Field} element will be a constant as well. Or else, if the given array is a mixture of constants and variables of {@link Bool} type, the resulting {@link Field} will be a variable as well. * @@ -943,21 +944,15 @@ class Field { * * @return A {@link Field} element matching the [little endian binary representation](https://en.wikipedia.org/wiki/Endianness) of the given `bytes` array. */ - static fromBits(bits: (Bool | boolean)[]) { - let length = bits.length; - checkBitLength('Field.fromBits()', length); - if (bits.every((b) => typeof b === 'boolean' || b.toField().isConstant())) { - let bits_ = bits - .map((b) => (typeof b === 'boolean' ? b : b.toBoolean())) - .concat(Array(Fp.sizeInBits - length).fill(false)); - return new Field(Fp.fromBits(bits_)); - } - let bitsVars = bits.map((b): FieldVar => { - if (typeof b === 'boolean') return b ? FieldVar[1] : FieldVar[0]; - return b.toField().value; - }); - let x = Snarky.field.fromBits([0, ...bitsVars]); - return new Field(x); + static newFromBits(bits: (Bool | boolean)[]) { + const length = bits.length; + checkBitLength('Field.fromBits()', length, 254); + return bits + .map((b) => new Bool(b)) + .reduce((acc, bit, idx) => { + const shift = 1n << BigInt(idx); + return acc.add(bit.toField().mul(shift)); + }, Field.from(0)); } /** From fcf161385c982a469f38c20530f859d3c851840e Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Mon, 26 Feb 2024 10:58:43 -0700 Subject: [PATCH 02/20] Forgot to change name of fromBits --- src/lib/field.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/field.ts b/src/lib/field.ts index 2b373b0315..7f99545b98 100644 --- a/src/lib/field.ts +++ b/src/lib/field.ts @@ -929,7 +929,7 @@ class Field { }); if (bits.slice(length).some((bit) => bit.toBoolean())) throw Error(`Field.toBits(): ${this} does not fit in ${length} bits`); - Field.newFromBits(bits).assertEquals(this); + Field.fromBits(bits).assertEquals(this); return bits; } @@ -944,7 +944,7 @@ class Field { * * @return A {@link Field} element matching the [little endian binary representation](https://en.wikipedia.org/wiki/Endianness) of the given `bytes` array. */ - static newFromBits(bits: (Bool | boolean)[]) { + static fromBits(bits: (Bool | boolean)[]) { const length = bits.length; checkBitLength('Field.fromBits()', length, 254); return bits From 157edbffb4fec3a4cbee9817f32eb067ed83e8c7 Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Tue, 27 Feb 2024 13:55:30 +0000 Subject: [PATCH 03/20] Fixed mask --- src/lib/field.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lib/field.ts b/src/lib/field.ts index 7f99545b98..01b24aae4a 100644 --- a/src/lib/field.ts +++ b/src/lib/field.ts @@ -924,12 +924,13 @@ class Field { let f = this.toBigInt(); return Array.from( { length }, - (_, k) => new Bool(!!((f >> BigInt(k)) & 0xffn)) + (_, k) => new Bool(!!((f >> BigInt(k)) & 0x1n)) ); }); - if (bits.slice(length).some((bit) => bit.toBoolean())) - throw Error(`Field.toBits(): ${this} does not fit in ${length} bits`); - Field.fromBits(bits).assertEquals(this); + Field.fromBits(bits).assertEquals( + this, + `Field.toBits(): ${this} does not fit in ${length} bits` + ); return bits; } From 6e4ab729654dfdf192de1f0429ca3ad6ff8b0a1b Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Tue, 27 Feb 2024 15:13:30 +0000 Subject: [PATCH 04/20] Swtich import from core.js to prevent dependency cycle --- src/lib/provable.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lib/provable.ts b/src/lib/provable.ts index ea532b1c3a..0b0e919fa8 100644 --- a/src/lib/provable.ts +++ b/src/lib/provable.ts @@ -3,7 +3,8 @@ * - a namespace with tools for writing provable code * - the main interface for types that can be used in provable code */ -import { Field, Bool } from './core.js'; +import { Bool } from './bool.js'; +import { Field } from './field.js'; import { Provable as Provable_, Snarky } from '../snarky.js'; import type { FlexibleProvable, ProvableExtended } from './circuit-value.js'; import { Context } from './global-context.js'; @@ -239,7 +240,7 @@ function witness = FlexibleProvable>( // } return [0, ...fieldConstants]; }); - fields = fieldVars.map(Field); + fields = fieldVars.map((x) => new Field(x)); } finally { snarkContext.leave(id); } @@ -388,7 +389,7 @@ function switch_>( if (mask.every((b) => b.toField().isConstant())) checkMask(); else Provable.asProver(checkMask); let size = type.sizeInFields(); - let fields = Array(size).fill(Field(0)); + let fields = Array(size).fill(new Field(0)); for (let i = 0; i < nValues; i++) { let valueFields = type.toFields(values[i]); let maskField = mask[i].toField(); From d4c642f641eaf26a09a1f38396839e7d0a1a0e10 Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Tue, 27 Feb 2024 16:26:39 +0000 Subject: [PATCH 05/20] Fix Field.toBits error message --- src/lib/field.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/field.ts b/src/lib/field.ts index 01b24aae4a..9cc5990f1b 100644 --- a/src/lib/field.ts +++ b/src/lib/field.ts @@ -929,7 +929,9 @@ class Field { }); Field.fromBits(bits).assertEquals( this, - `Field.toBits(): ${this} does not fit in ${length} bits` + `Field.toBits(): ${Provable.asProver(() => { + this.toString(); + })} does not fit in ${length} bits` ); return bits; } From c3df5ecd2183c3851b6d970fee4df705ebb25867 Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Tue, 27 Feb 2024 16:28:09 +0000 Subject: [PATCH 06/20] Change field unit test to use 254bit values --- src/lib/field.unit-test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/field.unit-test.ts b/src/lib/field.unit-test.ts index 2b955dca85..0484017683 100644 --- a/src/lib/field.unit-test.ts +++ b/src/lib/field.unit-test.ts @@ -195,7 +195,8 @@ test(Random.field, Random.field, (x0, y0, assert) => { Provable.asProver(() => assert(z.toBigInt() === Fp.mul(x0, y0))); // toBits / fromBits - let bits = Fp.toBits(x0); + // Fp.toBits() returns 256 bits, but our new to/from impl only accepts <=254 + let bits = Fp.toBits(x0).slice(0, -1); let x1 = Provable.witness(Field, () => Field.fromBits(bits)); let bitsVars = x1.toBits(); Provable.asProver(() => From e63f421c6149b5c4bd5db1caec875eb5c826f579 Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Mon, 4 Mar 2024 13:47:42 +0000 Subject: [PATCH 07/20] Handle constant case manually like before --- src/lib/field.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/lib/field.ts b/src/lib/field.ts index 9cc5990f1b..305eec8bef 100644 --- a/src/lib/field.ts +++ b/src/lib/field.ts @@ -920,6 +920,15 @@ class Field { */ toBits(length: number = 254) { checkBitLength('Field.toBits()', length, 254); + if (this.isConstant()) { + let bits = Fp.toBits(this.toBigInt()); + if (length !== undefined) { + if (bits.slice(length).some((bit) => bit)) + throw Error(`Field.toBits(): ${this} does not fit in ${length} bits`); + return bits.slice(0, length).map((b) => new Bool(b)); + } + return bits.map((b) => new Bool(b)); + } let bits = Provable.witness(Provable.Array(Bool, length), () => { let f = this.toBigInt(); return Array.from( @@ -950,6 +959,16 @@ class Field { static fromBits(bits: (Bool | boolean)[]) { const length = bits.length; checkBitLength('Field.fromBits()', length, 254); + if (bits.every((b) => typeof b === 'boolean' || b.toField().isConstant())) { + let bits_ = bits + .map((b) => (typeof b === 'boolean' ? b : b.toBoolean())) + .concat(Array(Fp.sizeInBits - length).fill(false)); + return new Field(Fp.fromBits(bits_)); + } + let bitsVars = bits.map((b): FieldVar => { + if (typeof b === 'boolean') return b ? FieldVar[1] : FieldVar[0]; + return b.toField().value; + }); return bits .map((b) => new Bool(b)) .reduce((acc, bit, idx) => { From c14178afa92fb702734f41a88c0e9abc533084ef Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Mon, 4 Mar 2024 15:09:14 +0000 Subject: [PATCH 08/20] Add extra 0 to end of Bool.toBits so that Scalar.fromBits is happy --- src/lib/nullifier.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/lib/nullifier.ts b/src/lib/nullifier.ts index c8e84984ef..033187685d 100644 --- a/src/lib/nullifier.ts +++ b/src/lib/nullifier.ts @@ -5,6 +5,7 @@ import { Poseidon } from './hash.js'; import { MerkleMapWitness } from './merkle-map.js'; import { PrivateKey, PublicKey, scaleShifted } from './signature.js'; import { Provable } from './provable.js'; +import { Bool } from './bool.js'; export { Nullifier }; @@ -70,7 +71,10 @@ class Nullifier extends Struct({ // shifted scalar see https://github.com/o1-labs/o1js/blob/5333817a62890c43ac1b9cb345748984df271b62/src/lib/signature.ts#L220 // pk^c - let pk_c = scaleShifted(this.publicKey, Scalar.fromBits(c.toBits())); + let pk_c = scaleShifted( + this.publicKey, + Scalar.fromBits(c.toBits().concat(new Bool(false))) + ); // g^r = g^s / pk^c let g_r = G.scale(s).sub(pk_c); @@ -80,7 +84,10 @@ class Nullifier extends Struct({ // h_m_pk_r = h(m,pk)^s / nullifier^c let h_m_pk_s_div_nullifier_s = h_m_pk_s.sub( - scaleShifted(nullifier, Scalar.fromBits(c.toBits())) + scaleShifted( + nullifier, + Scalar.fromBits(c.toBits().concat(new Bool(false))) + ) ); // this is supposed to match the entries generated on "the other side" of the nullifier (mina-signer, in an wallet enclave) From e706b556b1730680d8f46f682d630c9d10a45c57 Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Mon, 4 Mar 2024 15:42:56 +0000 Subject: [PATCH 09/20] Fix typo --- src/lib/field.unit-test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/field.unit-test.ts b/src/lib/field.unit-test.ts index 0484017683..92703c5fb3 100644 --- a/src/lib/field.unit-test.ts +++ b/src/lib/field.unit-test.ts @@ -195,7 +195,7 @@ test(Random.field, Random.field, (x0, y0, assert) => { Provable.asProver(() => assert(z.toBigInt() === Fp.mul(x0, y0))); // toBits / fromBits - // Fp.toBits() returns 256 bits, but our new to/from impl only accepts <=254 + // Fp.toBits() returns 255 bits, but our new to/from impl only accepts <=254 let bits = Fp.toBits(x0).slice(0, -1); let x1 = Provable.witness(Field, () => Field.fromBits(bits)); let bitsVars = x1.toBits(); From 74fb4f3b951de5cee365134b9905c6938c7da36e Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Mon, 4 Mar 2024 17:11:15 +0000 Subject: [PATCH 10/20] Remove unreachable lines --- src/lib/field.ts | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/lib/field.ts b/src/lib/field.ts index 305eec8bef..886ee1f244 100644 --- a/src/lib/field.ts +++ b/src/lib/field.ts @@ -922,12 +922,9 @@ class Field { checkBitLength('Field.toBits()', length, 254); if (this.isConstant()) { let bits = Fp.toBits(this.toBigInt()); - if (length !== undefined) { - if (bits.slice(length).some((bit) => bit)) - throw Error(`Field.toBits(): ${this} does not fit in ${length} bits`); - return bits.slice(0, length).map((b) => new Bool(b)); - } - return bits.map((b) => new Bool(b)); + if (bits.slice(length).some((bit) => bit)) + throw Error(`Field.toBits(): ${this} does not fit in ${length} bits`); + return bits.slice(0, length).map((b) => new Bool(b)); } let bits = Provable.witness(Provable.Array(Bool, length), () => { let f = this.toBigInt(); @@ -965,10 +962,6 @@ class Field { .concat(Array(Fp.sizeInBits - length).fill(false)); return new Field(Fp.fromBits(bits_)); } - let bitsVars = bits.map((b): FieldVar => { - if (typeof b === 'boolean') return b ? FieldVar[1] : FieldVar[0]; - return b.toField().value; - }); return bits .map((b) => new Bool(b)) .reduce((acc, bit, idx) => { From f9acdbb5415ec4dbab5608b992133a90f8206c66 Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Mon, 4 Mar 2024 17:12:13 +0000 Subject: [PATCH 11/20] Dump vks --- tests/vk-regression/vk-regression.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/vk-regression/vk-regression.json b/tests/vk-regression/vk-regression.json index 691010dc38..4518da8c58 100644 --- a/tests/vk-regression/vk-regression.json +++ b/tests/vk-regression/vk-regression.json @@ -50,16 +50,16 @@ } }, "HelloWorld": { - "digest": "11c21044c0ab297f29b386d1d04d0318cff4effa75191371dd576282882c2a8d", + "digest": "103e8bd9af45de70a1b214377e71bd05ae464e932dbe48aeada70362fa38b05", "methods": { "update": { - "rows": 826, - "digest": "5215ab9c7474b26f3a9073d821aef59b" + "rows": 825, + "digest": "226ff56f432f39d8056bf7f1813669f5" } }, "verificationKey": { - "data": "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", - "hash": "12073693408844675717690269959590209616934536940765116494766700428390466839" + "data": "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", + "hash": "21868179330353774930881761197110482602042218337984430556708224781269131363222" } }, "TokenContract": { From 720a9fccd22994e3db9b1a123f5b5d69d09db7fe Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Mon, 4 Mar 2024 17:22:36 +0000 Subject: [PATCH 12/20] Add explanation for why only 254 bits are allowed in typedoc of fromBits --- src/lib/field.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/field.ts b/src/lib/field.ts index 886ee1f244..247404e753 100644 --- a/src/lib/field.ts +++ b/src/lib/field.ts @@ -945,7 +945,7 @@ class Field { /** * Convert a bit array into a {@link Field} element using [little endian binary representation](https://en.wikipedia.org/wiki/Endianness) * - * The method throws if the given bits do not fit in a single Field element. A Field element can be at most 254 bits. + * The method throws if the given bits do not fit in a single Field element. In this case, no more than 254 bits are allowed because some 255 bit integers do not fit into a single Field element. * * **Important**: If the given `bytes` array is an array of `booleans` or {@link Bool} elements that all are `constant`, the resulting {@link Field} element will be a constant as well. Or else, if the given array is a mixture of constants and variables of {@link Bool} type, the resulting {@link Field} will be a variable as well. * From d291e18d4411f30f3fafe4ed0bdd75b367636998 Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Mon, 4 Mar 2024 17:29:57 +0000 Subject: [PATCH 13/20] Better comment in Field unit test --- src/lib/field.unit-test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/field.unit-test.ts b/src/lib/field.unit-test.ts index 92703c5fb3..cee39ef0aa 100644 --- a/src/lib/field.unit-test.ts +++ b/src/lib/field.unit-test.ts @@ -196,6 +196,7 @@ test(Random.field, Random.field, (x0, y0, assert) => { // toBits / fromBits // Fp.toBits() returns 255 bits, but our new to/from impl only accepts <=254 + // https://github.com/o1-labs/o1js/pull/1461 let bits = Fp.toBits(x0).slice(0, -1); let x1 = Provable.witness(Field, () => Field.fromBits(bits)); let bitsVars = x1.toBits(); From 8509bdccae6644628054bbe35773c95e845ce523 Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Mon, 4 Mar 2024 21:30:16 +0000 Subject: [PATCH 14/20] Refactor Scalar.fromBits method to handle input of less than 255 bits --- src/lib/scalar.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/lib/scalar.ts b/src/lib/scalar.ts index 7439f3713a..055a7bbe0d 100644 --- a/src/lib/scalar.ts +++ b/src/lib/scalar.ts @@ -99,7 +99,10 @@ class Scalar { * **Warning**: The bits are interpreted as the bits of 2s + 1 + 2^255, where s is the Scalar. */ static fromBits(bits: Bool[]) { - return Scalar.fromFields(bits.map((b) => b.toField())); + return Scalar.fromFields([ + ...bits.map((b) => b.toField()), + ...Array(Fq.sizeInBits - bits.length).fill(new Bool(false)), + ]); } /** From bcf902991da36ef9b4e348c26c46c3ded8ca2d5a Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Mon, 4 Mar 2024 21:34:26 +0000 Subject: [PATCH 15/20] Revert "Add extra 0 to end of Bool.toBits so that Scalar.fromBits is happy" as this is handled in Scalar now This reverts commit c14178afa92fb702734f41a88c0e9abc533084ef. --- src/lib/nullifier.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/lib/nullifier.ts b/src/lib/nullifier.ts index 033187685d..c8e84984ef 100644 --- a/src/lib/nullifier.ts +++ b/src/lib/nullifier.ts @@ -5,7 +5,6 @@ import { Poseidon } from './hash.js'; import { MerkleMapWitness } from './merkle-map.js'; import { PrivateKey, PublicKey, scaleShifted } from './signature.js'; import { Provable } from './provable.js'; -import { Bool } from './bool.js'; export { Nullifier }; @@ -71,10 +70,7 @@ class Nullifier extends Struct({ // shifted scalar see https://github.com/o1-labs/o1js/blob/5333817a62890c43ac1b9cb345748984df271b62/src/lib/signature.ts#L220 // pk^c - let pk_c = scaleShifted( - this.publicKey, - Scalar.fromBits(c.toBits().concat(new Bool(false))) - ); + let pk_c = scaleShifted(this.publicKey, Scalar.fromBits(c.toBits())); // g^r = g^s / pk^c let g_r = G.scale(s).sub(pk_c); @@ -84,10 +80,7 @@ class Nullifier extends Struct({ // h_m_pk_r = h(m,pk)^s / nullifier^c let h_m_pk_s_div_nullifier_s = h_m_pk_s.sub( - scaleShifted( - nullifier, - Scalar.fromBits(c.toBits().concat(new Bool(false))) - ) + scaleShifted(nullifier, Scalar.fromBits(c.toBits())) ); // this is supposed to match the entries generated on "the other side" of the nullifier (mina-signer, in an wallet enclave) From da1a7a6953dc21fa3537a70bee18d513d6f46275 Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Thu, 7 Mar 2024 08:00:14 +0000 Subject: [PATCH 16/20] Seal Field.fromBits() return value to avoid proving AST each time return value is referenced --- src/lib/field.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/lib/field.ts b/src/lib/field.ts index 247404e753..a4cd6adf28 100644 --- a/src/lib/field.ts +++ b/src/lib/field.ts @@ -935,9 +935,7 @@ class Field { }); Field.fromBits(bits).assertEquals( this, - `Field.toBits(): ${Provable.asProver(() => { - this.toString(); - })} does not fit in ${length} bits` + `Field.toBits(): Input does not fit in ${length} bits` ); return bits; } @@ -967,7 +965,7 @@ class Field { .reduce((acc, bit, idx) => { const shift = 1n << BigInt(idx); return acc.add(bit.toField().mul(shift)); - }, Field.from(0)); + }, Field.from(0)).seal(); } /** From 266b9d146a26eb2c989fb5f218eb04e8cf68b1f7 Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Thu, 7 Mar 2024 08:00:56 +0000 Subject: [PATCH 17/20] Add CHANGELOG entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b04d1ea09e..fe67a89664 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Improved efficiency of computing `AccountUpdate.callData` by packing field elements into as few field elements as possible https://github.com/o1-labs/o1js/pull/1458 - This leads to a large reduction in the number of constraints used when inputs to a zkApp method are many field elements (e.g. a long list of `Bool`s) - Return events in the `LocalBlockchain` in reverse chronological order (latest events at the beginning) to match the behavior of the `Network` https://github.com/o1-labs/o1js/pull/1460 +- Fixed vulnerability in `Field.to/fromBits()` outlined in [#1023](https://github.com/o1-labs/o1js/issues/1023) by imposing a limit of 254 bits https://github.com/o1-labs/o1js/pull/1461 ### Added From 19a3e99be4f288817cb537e32660f959bebf4e7f Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Mon, 11 Mar 2024 15:56:35 +0000 Subject: [PATCH 18/20] Fix Field import --- src/lib/provable.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/provable.ts b/src/lib/provable.ts index 9d179a1ac7..ceff63ba68 100644 --- a/src/lib/provable.ts +++ b/src/lib/provable.ts @@ -292,7 +292,7 @@ async function witnessAsync< let fields = type.toFields(proverValue); return fields.map((x) => x.toBigInt()); }); - fields = fieldVars.map(Field); + fields = fieldVars.map((x) => new Field(x)); } finally { snarkContext.leave(id); } From e1daa57d9412d38ba6480f19c39afd4a8be77635 Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Mon, 11 Mar 2024 16:33:33 +0000 Subject: [PATCH 19/20] Dump vks --- tests/vk-regression/vk-regression.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/vk-regression/vk-regression.json b/tests/vk-regression/vk-regression.json index f135c32400..45eee51c92 100644 --- a/tests/vk-regression/vk-regression.json +++ b/tests/vk-regression/vk-regression.json @@ -251,7 +251,7 @@ } }, "diverse": { - "digest": "3822c67734f73c594779eab98899d2e4cc254b7b9d5261b2aada529f781c1234", + "digest": "384e7eb44f1ad3b899aae057c48a9eab8ad72c8120ef13a1e906c91b93028828", "methods": { "ecdsa": { "rows": 28186, @@ -262,8 +262,8 @@ "digest": "1496e5b8cc253c9909551a25c190ab85" }, "pallas": { - "rows": 1616, - "digest": "8a9ee7267139d6280971f9750a610713" + "rows": 1610, + "digest": "0ff5537aae21b4d47b8c901aa5e71007" }, "poseidon": { "rows": 947, @@ -279,8 +279,8 @@ } }, "verificationKey": { - "data": "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", - "hash": "16059383130523018273678724949684090892300714372032191113254352030711948582951" + "data": "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", + "hash": "25099125262785569464008872277824954042674175732318382315709475361977342159172" } } } \ No newline at end of file From e5cd92619a65f748c2a0a14f980d2d21280f0c3e Mon Sep 17 00:00:00 2001 From: jackryanservia <90076280+jackryanservia@users.noreply.github.com> Date: Mon, 11 Mar 2024 17:03:24 -0600 Subject: [PATCH 20/20] Move CHANGELOG entry to unreleased section --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b98d6e7d5..3b77842dbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm As a replacement, `UInt64.Unsafe.fromField()` was introduced - This prevents you from accidentally creating a `UInt64` without proving that it fits in 64 bits - Equivalent changes were made to `UInt32` +- Fixed vulnerability in `Field.to/fromBits()` outlined in [#1023](https://github.com/o1-labs/o1js/issues/1023) by imposing a limit of 254 bits https://github.com/o1-labs/o1js/pull/1461 ### Added @@ -58,7 +59,6 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Improved efficiency of computing `AccountUpdate.callData` by packing field elements into as few field elements as possible https://github.com/o1-labs/o1js/pull/1458 - This leads to a large reduction in the number of constraints used when inputs to a zkApp method are many field elements (e.g. a long list of `Bool`s) - Return events in the `LocalBlockchain` in reverse chronological order (latest events at the beginning) to match the behavior of the `Network` https://github.com/o1-labs/o1js/pull/1460 -- Fixed vulnerability in `Field.to/fromBits()` outlined in [#1023](https://github.com/o1-labs/o1js/issues/1023) by imposing a limit of 254 bits https://github.com/o1-labs/o1js/pull/1461 ### Added