From ed623bfcb1c3794b24893e6c39c229148e0ead4a Mon Sep 17 00:00:00 2001 From: julio4 Date: Fri, 16 Feb 2024 17:41:15 +0900 Subject: [PATCH 01/11] Move `Uint.from(Field)` to `Uint.Unsafe.fromField(Field)` --- src/lib/int.ts | 148 ++++++++++++++++++++++++++++++------------------- 1 file changed, 92 insertions(+), 56 deletions(-) diff --git a/src/lib/int.ts b/src/lib/int.ts index 99c0d04e29..8bf4373584 100644 --- a/src/lib/int.ts +++ b/src/lib/int.ts @@ -19,23 +19,41 @@ class UInt64 extends CircuitValue { @prop value: Field; static NUM_BITS = 64; - constructor(x: UInt64 | UInt32 | Field | number | string | bigint) { - if (x instanceof UInt64 || x instanceof UInt32) x = x.value; - else if (!(x instanceof Field)) x = Field(x); - super(x); + /** + * Create a {@link UInt64}. + * The max value of a {@link UInt64} is `2^64 - 1 = UInt64.MAXINT()`. + * + * **Warning**: Cannot overflow, an error is thrown if the result is greater than UInt64.MAXINT() + */ + constructor(x: UInt64 | UInt32 | FieldVar | number | string | bigint) { + if (x instanceof UInt64 || x instanceof UInt32) x = x.value.value; + super({ value: Field(x) }); + UInt64.checkConstant(this.value); } + static Unsafe = { + /** + * Create a {@link UInt64} from a {@link Field} without constraining its range. + * + * **Warning**: This is unsafe, because it does not prove that the input {@link Field} actually fits in 64 bits.\ + * Only use this if you know what you are doing, otherwise use the safe {@link UInt64.from}. + */ + fromField(x: Field) { + return new UInt64(x.value); + }, + }; + /** * Static method to create a {@link UInt64} with value `0`. */ static get zero() { - return new UInt64(Field(0)); + return new UInt64(0); } /** * Static method to create a {@link UInt64} with value `1`. */ static get one() { - return new UInt64(Field(1)); + return new UInt64(1); } /** * Turns the {@link UInt64} into a string. @@ -56,7 +74,7 @@ class UInt64 extends CircuitValue { * Turns the {@link UInt64} into a {@link UInt32}, asserting that it fits in 32 bits. */ toUInt32() { - let uint32 = new UInt32(this.value); + let uint32 = new UInt32(this.value.value); UInt32.check(uint32); return uint32; } @@ -72,7 +90,7 @@ class UInt64 extends CircuitValue { return Provable.if( this.greaterThan(UInt64.from(max)), UInt32.from(max), - new UInt32(this.value) + new UInt32(this.value.value) ); } @@ -113,16 +131,16 @@ class UInt64 extends CircuitValue { /** * Creates a new {@link UInt64}. */ - static from(x: UInt64 | UInt32 | Field | number | string | bigint) { - if (x instanceof UInt64 || x instanceof UInt32) x = x.value; - return new this(this.checkConstant(Field(x))); + static from(x: UInt64 | UInt32 | number | string | bigint) { + let _x = (x instanceof UInt64 || x instanceof UInt32) ? x.value : Field(x); + return new this(this.checkConstant(_x).value); } /** * Creates a {@link UInt64} with a value of 18,446,744,073,709,551,615. */ static MAXINT() { - return new UInt64(Field((1n << 64n) - 1n)); + return new UInt64((1n << 64n) - 1n); } /** @@ -140,8 +158,8 @@ class UInt64 extends CircuitValue { let q = xn / yn; let r = xn - q * yn; return { - quotient: new UInt64(Field(q)), - rest: new UInt64(Field(r)), + quotient: new UInt64(q), + rest: new UInt64(r), }; } @@ -158,10 +176,10 @@ class UInt64 extends CircuitValue { let r = x.sub(q.mul(y_)).seal(); RangeCheck.rangeCheckN(UInt64.NUM_BITS, r); - let r_ = new UInt64(r); - let q_ = new UInt64(q); + let r_ = new UInt64(r.value); + let q_ = new UInt64(q.value); - r_.assertLessThan(new UInt64(y_)); + r_.assertLessThan(new UInt64(y_.value)); return { quotient: q_, rest: r_ }; } @@ -193,7 +211,7 @@ class UInt64 extends CircuitValue { mul(y: UInt64 | number) { let z = this.value.mul(UInt64.from(y).value); RangeCheck.rangeCheckN(UInt64.NUM_BITS, z); - return new UInt64(z); + return new UInt64(z.value); } /** @@ -202,7 +220,7 @@ class UInt64 extends CircuitValue { add(y: UInt64 | number) { let z = this.value.add(UInt64.from(y).value); RangeCheck.rangeCheckN(UInt64.NUM_BITS, z); - return new UInt64(z); + return new UInt64(z.value); } /** @@ -211,7 +229,7 @@ class UInt64 extends CircuitValue { sub(y: UInt64 | number) { let z = this.value.sub(UInt64.from(y).value); RangeCheck.rangeCheckN(UInt64.NUM_BITS, z); - return new UInt64(z); + return new UInt64(z.value); } /** @@ -234,7 +252,7 @@ class UInt64 extends CircuitValue { * ``` */ xor(x: UInt64) { - return new UInt64(Bitwise.xor(this.value, x.value, UInt64.NUM_BITS)); + return new UInt64(Bitwise.xor(this.value, x.value, UInt64.NUM_BITS).value); } /** @@ -267,7 +285,7 @@ class UInt64 extends CircuitValue { * */ not() { - return new UInt64(Bitwise.not(this.value, UInt64.NUM_BITS, false)); + return new UInt64(Bitwise.not(this.value, UInt64.NUM_BITS, false).value); } /** @@ -299,7 +317,7 @@ class UInt64 extends CircuitValue { * ``` */ rotate(bits: number, direction: 'left' | 'right' = 'left') { - return new UInt64(Bitwise.rotate64(this.value, bits, direction)); + return new UInt64(Bitwise.rotate64(this.value, bits, direction).value); } /** @@ -320,7 +338,7 @@ class UInt64 extends CircuitValue { * ``` */ leftShift(bits: number) { - return new UInt64(Bitwise.leftShift64(this.value, bits)); + return new UInt64(Bitwise.leftShift64(this.value, bits).value); } /** @@ -341,7 +359,7 @@ class UInt64 extends CircuitValue { * ``` */ rightShift(bits: number) { - return new UInt64(Bitwise.leftShift64(this.value, bits)); + return new UInt64(Bitwise.leftShift64(this.value, bits).value); } /** @@ -370,7 +388,7 @@ class UInt64 extends CircuitValue { * ``` */ and(x: UInt64) { - return new UInt64(Bitwise.and(this.value, x.value, UInt64.NUM_BITS)); + return new UInt64(Bitwise.and(this.value, x.value, UInt64.NUM_BITS).value); } /** @@ -546,24 +564,42 @@ class UInt32 extends CircuitValue { @prop value: Field; static NUM_BITS = 32; - constructor(x: UInt32 | Field | number | string | bigint) { - if (x instanceof UInt32) x = x.value; - else if (!(x instanceof Field)) x = Field(x); - super(x); + /** + * Create a {@link UInt32}. + * The max value of a {@link UInt32} is `2^32 - 1 = UInt32.MAXINT()`. + * + * **Warning**: Cannot overflow, an error is thrown if the result is greater than UInt32.MAXINT() + */ + constructor(x: UInt32 | FieldVar | number | string | bigint) { + if (x instanceof UInt32) x = x.value.value; + super({ value: Field(x) }); + UInt32.checkConstant(this.value); } + static Unsafe = { + /** + * Create a {@link UInt32} from a {@link Field} without constraining its range. + * + * **Warning**: This is unsafe, because it does not prove that the input {@link Field} actually fits in 32 bits.\ + * Only use this if you know what you are doing, otherwise use the safe {@link UInt32.from}. + */ + fromField(x: Field) { + return new UInt32(x.value); + }, + }; + /** * Static method to create a {@link UInt32} with value `0`. */ static get zero(): UInt32 { - return new UInt32(Field(0)); + return new UInt32(0); } /** * Static method to create a {@link UInt32} with value `0`. */ static get one(): UInt32 { - return new UInt32(Field(1)); + return new UInt32(1); } /** * Turns the {@link UInt32} into a string. @@ -582,7 +618,7 @@ class UInt32 extends CircuitValue { */ toUInt64(): UInt64 { // this is safe, because the UInt32 range is included in the UInt64 range - return new UInt64(this.value); + return new UInt64(this.value.value); } static check(x: UInt32) { @@ -620,23 +656,23 @@ class UInt32 extends CircuitValue { /** * Creates a new {@link UInt32}. */ - static from(x: UInt32 | Field | number | string | bigint) { - if (x instanceof UInt32) x = x.value; - return new this(this.checkConstant(Field(x))); + static from(x: UInt32 | number | string | bigint) { + let _x = x instanceof UInt32 ? x.value : Field(x); + return new this(this.checkConstant(_x).value); } /** * Creates a {@link UInt32} with a value of 4,294,967,295. */ static MAXINT() { - return new UInt32(Field((1n << 32n) - 1n)); + return new UInt32((1n << 32n) - 1n); } /** * Addition modulo 2^32. Check {@link Gadgets.addMod32} for a detailed description. */ addMod32(y: UInt32) { - return new UInt32(addMod32(this.value, y.value)); + return new UInt32(addMod32(this.value, y.value).value); } /** @@ -654,8 +690,8 @@ class UInt32 extends CircuitValue { let q = xn / yn; let r = xn - q * yn; return { - quotient: new UInt32(new Field(q.toString())), - rest: new UInt32(new Field(r.toString())), + quotient: new UInt32(new Field(q.toString()).value), + rest: new UInt32(new Field(r.toString()).value), }; } @@ -672,10 +708,10 @@ class UInt32 extends CircuitValue { let r = x.sub(q.mul(y_)).seal(); RangeCheck.rangeCheck32(r); - let r_ = new UInt32(r); - let q_ = new UInt32(q); + let r_ = new UInt32(r.value); + let q_ = new UInt32(q.value); - r_.assertLessThan(new UInt32(y_)); + r_.assertLessThan(new UInt32(y_.value)); return { quotient: q_, rest: r_ }; } @@ -704,7 +740,7 @@ class UInt32 extends CircuitValue { mul(y: UInt32 | number) { let z = this.value.mul(UInt32.from(y).value); RangeCheck.rangeCheck32(z); - return new UInt32(z); + return new UInt32(z.value); } /** * Addition with overflow checking. @@ -712,7 +748,7 @@ class UInt32 extends CircuitValue { add(y: UInt32 | number) { let z = this.value.add(UInt32.from(y).value); RangeCheck.rangeCheck32(z); - return new UInt32(z); + return new UInt32(z.value); } /** * Subtraction with underflow checking. @@ -720,7 +756,7 @@ class UInt32 extends CircuitValue { sub(y: UInt32 | number) { let z = this.value.sub(UInt32.from(y).value); RangeCheck.rangeCheck32(z); - return new UInt32(z); + return new UInt32(z.value); } /** @@ -743,7 +779,7 @@ class UInt32 extends CircuitValue { * ``` */ xor(x: UInt32) { - return new UInt32(Bitwise.xor(this.value, x.value, UInt32.NUM_BITS)); + return new UInt32(Bitwise.xor(this.value, x.value, UInt32.NUM_BITS).value); } /** @@ -774,7 +810,7 @@ class UInt32 extends CircuitValue { * @param a - The value to apply NOT to. */ not() { - return new UInt32(Bitwise.not(this.value, UInt32.NUM_BITS, false)); + return new UInt32(Bitwise.not(this.value, UInt32.NUM_BITS, false).value); } /** @@ -806,7 +842,7 @@ class UInt32 extends CircuitValue { * ``` */ rotate(bits: number, direction: 'left' | 'right' = 'left') { - return new UInt32(Bitwise.rotate32(this.value, bits, direction)); + return new UInt32(Bitwise.rotate32(this.value, bits, direction).value); } /** @@ -829,7 +865,7 @@ class UInt32 extends CircuitValue { * ``` */ leftShift(bits: number) { - return new UInt32(Bitwise.leftShift32(this.value, bits)); + return new UInt32(Bitwise.leftShift32(this.value, bits).value); } /** @@ -852,7 +888,7 @@ class UInt32 extends CircuitValue { * ``` */ rightShift(bits: number) { - return new UInt32(Bitwise.rightShift64(this.value, bits)); + return new UInt32(Bitwise.rightShift64(this.value, bits).value); } /** @@ -881,7 +917,7 @@ class UInt32 extends CircuitValue { * ``` */ and(x: UInt32) { - return new UInt32(Bitwise.and(this.value, x.value, UInt32.NUM_BITS)); + return new UInt32(Bitwise.and(this.value, x.value, UInt32.NUM_BITS).value); } /** @@ -1137,7 +1173,7 @@ class Int64 extends CircuitValue implements BalanceChange { throw Error(`Int64: Expected a value between (-2^64, 2^64), got ${x}`); let magnitude = Field(isValidPositive ? x.toString() : x.neg().toString()); let sign = isValidPositive ? Sign.one : Sign.minusOne; - return new Int64(new UInt64(magnitude), sign); + return new Int64(new UInt64(magnitude.value), sign); } // this doesn't check ranges because we assume they're already checked on UInts @@ -1269,7 +1305,7 @@ class Int64 extends CircuitValue implements BalanceChange { let y_ = UInt64.from(y); let rest = this.magnitude.divMod(y_).rest.value; rest = Provable.if(this.isPositive(), rest, y_.value.sub(rest)); - return new Int64(new UInt64(rest)); + return new Int64(new UInt64(rest.value)); } /** @@ -1644,14 +1680,14 @@ class UInt8 extends Struct({ * Turns a {@link UInt8} into a {@link UInt32}. */ toUInt32(): UInt32 { - return new UInt32(this.value); + return new UInt32(this.value.value); } /** * Turns a {@link UInt8} into a {@link UInt64}. */ toUInt64(): UInt64 { - return new UInt64(this.value); + return new UInt64(this.value.value); } /** From 37d619e2dddddd04e5b6779baead5812df82bd5a Mon Sep 17 00:00:00 2001 From: julio4 Date: Fri, 16 Feb 2024 17:41:55 +0900 Subject: [PATCH 02/11] Update tests to create Uint from number only --- src/lib/circuit-value.unit-test.ts | 2 +- src/lib/int.test.ts | 594 ++++++++++++++--------------- 2 files changed, 298 insertions(+), 298 deletions(-) diff --git a/src/lib/circuit-value.unit-test.ts b/src/lib/circuit-value.unit-test.ts index 4c7b194f6e..c4633d9020 100644 --- a/src/lib/circuit-value.unit-test.ts +++ b/src/lib/circuit-value.unit-test.ts @@ -72,7 +72,7 @@ expect(() => uint: [ UInt32.zero, // invalid Uint32 - new UInt32(Field(-1)), + new UInt32(-1), ], })); }) diff --git a/src/lib/int.test.ts b/src/lib/int.test.ts index 1914a9fede..2d53e826df 100644 --- a/src/lib/int.test.ts +++ b/src/lib/int.test.ts @@ -97,7 +97,7 @@ describe('int', () => { Int64.from(100).sub('1180591620717411303424'); }).toThrow(); expect(() => { - Int64.from(100).mul(UInt64.from(Field(1n << 100n))); + Int64.from(100).mul(UInt64.from(1n << 100n)); }).toThrow(); }); @@ -108,16 +108,16 @@ describe('int', () => { // which breaks out current practice of having a dumb constructor that only stores variables it.skip('operations should throw on overflow of any input', () => { expect(() => { - new Int64(new UInt64(Field(1n << 64n))).sub(1); + new Int64(new UInt64(1n << 64n)).sub(1); }).toThrow(); expect(() => { - new Int64(new UInt64(Field(-(1n << 64n)))).add(5); + new Int64(new UInt64(-(1n << 64n))).add(5); }).toThrow(); expect(() => { - Int64.from(20).sub(new UInt64(Field((1n << 64n) + 10n))); + Int64.from(20).sub(new UInt64((1n << 64n) + 10n)); }).toThrow(); expect(() => { - Int64.from(6).add(new UInt64(Field(-(1n << 64n) - 5n))); + Int64.from(6).add(new UInt64(-(1n << 64n) - 5n)); }).toThrow(); }); @@ -214,9 +214,9 @@ describe('int', () => { it('1+1=2', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1))); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); - x.add(y).assertEquals(new UInt64(Field(2))); + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(1)); + x.add(y).assertEquals(new UInt64(2)); }); }).not.toThrow(); }); @@ -224,15 +224,15 @@ describe('int', () => { it('5000+5000=10000', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(5000))); - const y = Provable.witness(UInt64, () => new UInt64(Field(5000))); - x.add(y).assertEquals(new UInt64(Field(10000))); + const x = Provable.witness(UInt64, () => new UInt64(5000)); + const y = Provable.witness(UInt64, () => new UInt64(5000)); + x.add(y).assertEquals(new UInt64(10000)); }); }).not.toThrow(); }); it('(MAXINT/2+MAXINT/2) adds to MAXINT', () => { - const n = Field((((1n << 64n) - 2n) / 2n).toString()); + const n = ((1n << 64n) - 2n) / 2n; expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt64, () => new UInt64(n)); @@ -246,7 +246,7 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt64, () => UInt64.MAXINT()); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); + const y = Provable.witness(UInt64, () => new UInt64(1)); x.add(y); }); }).toThrow(); @@ -257,9 +257,9 @@ describe('int', () => { it('1-1=0', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1))); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); - x.sub(y).assertEquals(new UInt64(Field(0))); + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(1)); + x.sub(y).assertEquals(new UInt64(0)); }); }).not.toThrow(); }); @@ -269,10 +269,10 @@ describe('int', () => { Provable.runAndCheck(() => { const x = Provable.witness( UInt64, - () => new UInt64(Field(10000)) + () => new UInt64(10000) ); - const y = Provable.witness(UInt64, () => new UInt64(Field(5000))); - x.sub(y).assertEquals(new UInt64(Field(5000))); + const y = Provable.witness(UInt64, () => new UInt64(5000)); + x.sub(y).assertEquals(new UInt64(5000)); }); }).not.toThrow(); }); @@ -280,8 +280,8 @@ describe('int', () => { it('should throw on sub if results in negative number', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(0))); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); + const x = Provable.witness(UInt64, () => new UInt64(0)); + const y = Provable.witness(UInt64, () => new UInt64(1)); x.sub(y); }); }).toThrow(); @@ -292,9 +292,9 @@ describe('int', () => { it('1x2=2', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1))); - const y = Provable.witness(UInt64, () => new UInt64(Field(2))); - x.mul(y).assertEquals(new UInt64(Field(2))); + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(2)); + x.mul(y).assertEquals(new UInt64(2)); }); }).not.toThrow(); }); @@ -302,9 +302,9 @@ describe('int', () => { it('1x0=0', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1))); - const y = Provable.witness(UInt64, () => new UInt64(Field(0))); - x.mul(y).assertEquals(new UInt64(Field(0))); + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(0)); + x.mul(y).assertEquals(new UInt64(0)); }); }).not.toThrow(); }); @@ -312,9 +312,9 @@ describe('int', () => { it('1000x1000=1000000', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1000))); - const y = Provable.witness(UInt64, () => new UInt64(Field(1000))); - x.mul(y).assertEquals(new UInt64(Field(1000000))); + const x = Provable.witness(UInt64, () => new UInt64(1000)); + const y = Provable.witness(UInt64, () => new UInt64(1000)); + x.mul(y).assertEquals(new UInt64(1000000)); }); }).not.toThrow(); }); @@ -323,7 +323,7 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt64, () => UInt64.MAXINT()); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); + const y = Provable.witness(UInt64, () => new UInt64(1)); x.mul(y).assertEquals(UInt64.MAXINT()); }); }).not.toThrow(); @@ -333,7 +333,7 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt64, () => UInt64.MAXINT()); - const y = Provable.witness(UInt64, () => new UInt64(Field(2))); + const y = Provable.witness(UInt64, () => new UInt64(2)); x.mul(y); }); }).toThrow(); @@ -344,9 +344,9 @@ describe('int', () => { it('2/1=2', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(2))); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); - x.div(y).assertEquals(new UInt64(Field(2))); + const x = Provable.witness(UInt64, () => new UInt64(2)); + const y = Provable.witness(UInt64, () => new UInt64(1)); + x.div(y).assertEquals(new UInt64(2)); }); }).not.toThrow(); }); @@ -354,9 +354,9 @@ describe('int', () => { it('0/1=0', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(0))); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); - x.div(y).assertEquals(new UInt64(Field(0))); + const x = Provable.witness(UInt64, () => new UInt64(0)); + const y = Provable.witness(UInt64, () => new UInt64(1)); + x.div(y).assertEquals(new UInt64(0)); }); }).not.toThrow(); }); @@ -364,9 +364,9 @@ describe('int', () => { it('2000/1000=2', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(2000))); - const y = Provable.witness(UInt64, () => new UInt64(Field(1000))); - x.div(y).assertEquals(new UInt64(Field(2))); + const x = Provable.witness(UInt64, () => new UInt64(2000)); + const y = Provable.witness(UInt64, () => new UInt64(1000)); + x.div(y).assertEquals(new UInt64(2)); }); }).not.toThrow(); }); @@ -375,7 +375,7 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt64, () => UInt64.MAXINT()); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); + const y = Provable.witness(UInt64, () => new UInt64(1)); x.div(y).assertEquals(UInt64.MAXINT()); }); }).not.toThrow(); @@ -385,7 +385,7 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt64, () => UInt64.MAXINT()); - const y = Provable.witness(UInt64, () => new UInt64(Field(0))); + const y = Provable.witness(UInt64, () => new UInt64(0)); x.div(y); }); }).toThrow(); @@ -396,9 +396,9 @@ describe('int', () => { it('1%1=0', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1))); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); - x.mod(y).assertEquals(new UInt64(Field(0))); + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(1)); + x.mod(y).assertEquals(new UInt64(0)); }); }).not.toThrow(); }); @@ -406,9 +406,9 @@ describe('int', () => { it('500%32=20', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(500))); - const y = Provable.witness(UInt64, () => new UInt64(Field(32))); - x.mod(y).assertEquals(new UInt64(Field(20))); + const x = Provable.witness(UInt64, () => new UInt64(500)); + const y = Provable.witness(UInt64, () => new UInt64(32)); + x.mod(y).assertEquals(new UInt64(20)); }); }).not.toThrow(); }); @@ -417,8 +417,8 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt64, () => UInt64.MAXINT()); - const y = Provable.witness(UInt64, () => new UInt64(Field(7))); - x.mod(y).assertEquals(new UInt64(Field(1))); + const y = Provable.witness(UInt64, () => new UInt64(7)); + x.mod(y).assertEquals(new UInt64(1)); }); }).not.toThrow(); }); @@ -427,8 +427,8 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt64, () => UInt64.MAXINT()); - const y = Provable.witness(UInt64, () => new UInt64(Field(0))); - x.mod(y).assertEquals(new UInt64(Field(1))); + const y = Provable.witness(UInt64, () => new UInt64(0)); + x.mod(y).assertEquals(new UInt64(1)); }); }).toThrow(); }); @@ -438,8 +438,8 @@ describe('int', () => { it('1<2=true', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1))); - const y = Provable.witness(UInt64, () => new UInt64(Field(2))); + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(2)); x.assertLessThan(y); }); }).not.toThrow(); @@ -448,8 +448,8 @@ describe('int', () => { it('1<1=false', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1))); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(1)); x.assertLessThan(y); }); }).toThrow(); @@ -458,8 +458,8 @@ describe('int', () => { it('2<1=false', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(2))); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); + const x = Provable.witness(UInt64, () => new UInt64(2)); + const y = Provable.witness(UInt64, () => new UInt64(1)); x.assertLessThan(y); }); }).toThrow(); @@ -468,10 +468,10 @@ describe('int', () => { it('1000<100000=true', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1000))); + const x = Provable.witness(UInt64, () => new UInt64(1000)); const y = Provable.witness( UInt64, - () => new UInt64(Field(100000)) + () => new UInt64(100000) ); x.assertLessThan(y); }); @@ -483,9 +483,9 @@ describe('int', () => { Provable.runAndCheck(() => { const x = Provable.witness( UInt64, - () => new UInt64(Field(100000)) + () => new UInt64(100000) ); - const y = Provable.witness(UInt64, () => new UInt64(Field(1000))); + const y = Provable.witness(UInt64, () => new UInt64(1000)); x.assertLessThan(y); }); }).toThrow(); @@ -506,8 +506,8 @@ describe('int', () => { it('1<=1=true', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1))); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(1)); x.assertLessThanOrEqual(y); }); }).not.toThrow(); @@ -516,8 +516,8 @@ describe('int', () => { it('2<=1=false', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(2))); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); + const x = Provable.witness(UInt64, () => new UInt64(2)); + const y = Provable.witness(UInt64, () => new UInt64(1)); x.assertLessThanOrEqual(y); }); }).toThrow(); @@ -526,10 +526,10 @@ describe('int', () => { it('1000<=100000=true', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1000))); + const x = Provable.witness(UInt64, () => new UInt64(1000)); const y = Provable.witness( UInt64, - () => new UInt64(Field(100000)) + () => new UInt64(100000) ); x.assertLessThanOrEqual(y); }); @@ -541,9 +541,9 @@ describe('int', () => { Provable.runAndCheck(() => { const x = Provable.witness( UInt64, - () => new UInt64(Field(100000)) + () => new UInt64(100000) ); - const y = Provable.witness(UInt64, () => new UInt64(Field(1000))); + const y = Provable.witness(UInt64, () => new UInt64(1000)); x.assertLessThanOrEqual(y); }); }).toThrow(); @@ -564,8 +564,8 @@ describe('int', () => { it('2>1=true', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(2))); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); + const x = Provable.witness(UInt64, () => new UInt64(2)); + const y = Provable.witness(UInt64, () => new UInt64(1)); x.assertGreaterThan(y); }); }).not.toThrow(); @@ -574,8 +574,8 @@ describe('int', () => { it('1>1=false', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1))); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(1)); x.assertGreaterThan(y); }); }).toThrow(); @@ -584,8 +584,8 @@ describe('int', () => { it('1>2=false', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1))); - const y = Provable.witness(UInt64, () => new UInt64(Field(2))); + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(2)); x.assertGreaterThan(y); }); }).toThrow(); @@ -596,9 +596,9 @@ describe('int', () => { Provable.runAndCheck(() => { const x = Provable.witness( UInt64, - () => new UInt64(Field(100000)) + () => new UInt64(100000) ); - const y = Provable.witness(UInt64, () => new UInt64(Field(1000))); + const y = Provable.witness(UInt64, () => new UInt64(1000)); x.assertGreaterThan(y); }); }).not.toThrow(); @@ -607,10 +607,10 @@ describe('int', () => { it('1000>100000=false', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1000))); + const x = Provable.witness(UInt64, () => new UInt64(1000)); const y = Provable.witness( UInt64, - () => new UInt64(Field(100000)) + () => new UInt64(100000) ); x.assertGreaterThan(y); }); @@ -632,8 +632,8 @@ describe('int', () => { it('1<=1=true', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1))); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(1)); x.assertGreaterThanOrEqual(y); }); }).not.toThrow(); @@ -642,8 +642,8 @@ describe('int', () => { it('1>=2=false', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1))); - const y = Provable.witness(UInt64, () => new UInt64(Field(2))); + const x = Provable.witness(UInt64, () => new UInt64(1)); + const y = Provable.witness(UInt64, () => new UInt64(2)); x.assertGreaterThanOrEqual(y); }); }).toThrow(); @@ -654,9 +654,9 @@ describe('int', () => { Provable.runAndCheck(() => { const x = Provable.witness( UInt64, - () => new UInt64(Field(100000)) + () => new UInt64(100000) ); - const y = Provable.witness(UInt64, () => new UInt64(Field(1000))); + const y = Provable.witness(UInt64, () => new UInt64(1000)); x.assertGreaterThanOrEqual(y); }); }).not.toThrow(); @@ -665,10 +665,10 @@ describe('int', () => { it('1000>=100000=false', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1000))); + const x = Provable.witness(UInt64, () => new UInt64(1000)); const y = Provable.witness( UInt64, - () => new UInt64(Field(100000)) + () => new UInt64(100000) ); x.assertGreaterThanOrEqual(y); }); @@ -692,7 +692,7 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt64, () => UInt64.from(1)); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); + const y = Provable.witness(UInt64, () => new UInt64(1)); x.assertEquals(y); }); }).not.toThrow(); @@ -706,7 +706,7 @@ describe('int', () => { ); const y = Provable.witness( UInt64, - () => new UInt64(Field(String(NUMBERMAX))) + () => new UInt64(String(NUMBERMAX)) ); x.assertEquals(y); }); @@ -718,7 +718,7 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt64, () => UInt64.from('1')); - const y = Provable.witness(UInt64, () => new UInt64(Field(1))); + const y = Provable.witness(UInt64, () => new UInt64(1)); x.assertEquals(y); }); }).not.toThrow(); @@ -732,7 +732,7 @@ describe('int', () => { ); const y = Provable.witness( UInt64, - () => new UInt64(Field(String(NUMBERMAX))) + () => new UInt64(String(NUMBERMAX)) ); x.assertEquals(y); }); @@ -745,19 +745,19 @@ describe('int', () => { describe('Outside of circuit', () => { describe('add', () => { it('1+1=2', () => { - expect(new UInt64(Field(1)).add(1).toString()).toEqual('2'); + expect(new UInt64(1).add(1).toString()).toEqual('2'); }); it('5000+5000=10000', () => { - expect(new UInt64(Field(5000)).add(5000).toString()).toEqual('10000'); + expect(new UInt64(5000).add(5000).toString()).toEqual('10000'); }); it('(MAXINT/2+MAXINT/2) adds to MAXINT', () => { - const value = Field((((1n << 64n) - 2n) / 2n).toString()); + const value = ((1n << 64n) - 2n) / 2n; expect( new UInt64(value) .add(new UInt64(value)) - .add(new UInt64(Field(1))) + .add(new UInt64(1)) .toString() ).toEqual(UInt64.MAXINT().toString()); }); @@ -771,11 +771,11 @@ describe('int', () => { describe('sub', () => { it('1-1=0', () => { - expect(new UInt64(Field(1)).sub(1).toString()).toEqual('0'); + expect(new UInt64(1).sub(1).toString()).toEqual('0'); }); it('10000-5000=5000', () => { - expect(new UInt64(Field(10000)).sub(5000).toString()).toEqual('5000'); + expect(new UInt64(10000).sub(5000).toString()).toEqual('5000'); }); it('should throw on sub if results in negative number', () => { @@ -787,15 +787,15 @@ describe('int', () => { describe('mul', () => { it('1x2=2', () => { - expect(new UInt64(Field(1)).mul(2).toString()).toEqual('2'); + expect(new UInt64(1).mul(2).toString()).toEqual('2'); }); it('1x0=0', () => { - expect(new UInt64(Field(1)).mul(0).toString()).toEqual('0'); + expect(new UInt64(1).mul(0).toString()).toEqual('0'); }); it('1000x1000=1000000', () => { - expect(new UInt64(Field(1000)).mul(1000).toString()).toEqual( + expect(new UInt64(1000).mul(1000).toString()).toEqual( '1000000' ); }); @@ -815,15 +815,15 @@ describe('int', () => { describe('div', () => { it('2/1=2', () => { - expect(new UInt64(Field(2)).div(1).toString()).toEqual('2'); + expect(new UInt64(2).div(1).toString()).toEqual('2'); }); it('0/1=0', () => { - expect(new UInt64(Field(0)).div(1).toString()).toEqual('0'); + expect(new UInt64(0).div(1).toString()).toEqual('0'); }); it('2000/1000=2', () => { - expect(new UInt64(Field(2000)).div(1000).toString()).toEqual('2'); + expect(new UInt64(2000).div(1000).toString()).toEqual('2'); }); it('MAXINT/1=MAXINT', () => { @@ -841,11 +841,11 @@ describe('int', () => { describe('mod', () => { it('1%1=0', () => { - expect(new UInt64(Field(1)).mod(1).toString()).toEqual('0'); + expect(new UInt64(1).mod(1).toString()).toEqual('0'); }); it('500%32=20', () => { - expect(new UInt64(Field(500)).mod(32).toString()).toEqual('20'); + expect(new UInt64(500).mod(32).toString()).toEqual('20'); }); it('MAXINT%7=1', () => { @@ -861,32 +861,32 @@ describe('int', () => { describe('lt', () => { it('1<2=true', () => { - expect(new UInt64(Field(1)).lessThan(new UInt64(Field(2)))).toEqual( + expect(new UInt64(1).lessThan(new UInt64(2))).toEqual( Bool(true) ); }); it('1<1=false', () => { - expect(new UInt64(Field(1)).lessThan(new UInt64(Field(1)))).toEqual( + expect(new UInt64(1).lessThan(new UInt64(1))).toEqual( Bool(false) ); }); it('2<1=false', () => { - expect(new UInt64(Field(2)).lessThan(new UInt64(Field(1)))).toEqual( + expect(new UInt64(2).lessThan(new UInt64(1))).toEqual( Bool(false) ); }); it('1000<100000=true', () => { expect( - new UInt64(Field(1000)).lessThan(new UInt64(Field(100000))) + new UInt64(1000).lessThan(new UInt64(100000)) ).toEqual(Bool(true)); }); it('100000<1000=false', () => { expect( - new UInt64(Field(100000)).lessThan(new UInt64(Field(1000))) + new UInt64(100000).lessThan(new UInt64(1000)) ).toEqual(Bool(false)); }); @@ -900,25 +900,25 @@ describe('int', () => { describe('lte', () => { it('1<=1=true', () => { expect( - new UInt64(Field(1)).lessThanOrEqual(new UInt64(Field(1))) + new UInt64(1).lessThanOrEqual(new UInt64(1)) ).toEqual(Bool(true)); }); it('2<=1=false', () => { expect( - new UInt64(Field(2)).lessThanOrEqual(new UInt64(Field(1))) + new UInt64(2).lessThanOrEqual(new UInt64(1)) ).toEqual(Bool(false)); }); it('1000<=100000=true', () => { expect( - new UInt64(Field(1000)).lessThanOrEqual(new UInt64(Field(100000))) + new UInt64(1000).lessThanOrEqual(new UInt64(100000)) ).toEqual(Bool(true)); }); it('100000<=1000=false', () => { expect( - new UInt64(Field(100000)).lessThanOrEqual(new UInt64(Field(1000))) + new UInt64(100000).lessThanOrEqual(new UInt64(1000)) ).toEqual(Bool(false)); }); @@ -932,28 +932,28 @@ describe('int', () => { describe('assertLessThanOrEqual', () => { it('1<=1=true', () => { expect(() => { - new UInt64(Field(1)).assertLessThanOrEqual(new UInt64(Field(1))); + new UInt64(1).assertLessThanOrEqual(new UInt64(1)); }).not.toThrow(); }); it('2<=1=false', () => { expect(() => { - new UInt64(Field(2)).assertLessThanOrEqual(new UInt64(Field(1))); + new UInt64(2).assertLessThanOrEqual(new UInt64(1)); }).toThrow(); }); it('1000<=100000=true', () => { expect(() => { - new UInt64(Field(1000)).assertLessThanOrEqual( - new UInt64(Field(100000)) + new UInt64(1000).assertLessThanOrEqual( + new UInt64(100000) ); }).not.toThrow(); }); it('100000<=1000=false', () => { expect(() => { - new UInt64(Field(100000)).assertLessThanOrEqual( - new UInt64(Field(1000)) + new UInt64(100000).assertLessThanOrEqual( + new UInt64(1000) ); }).toThrow(); }); @@ -968,31 +968,31 @@ describe('int', () => { describe('greaterThan', () => { it('2>1=true', () => { expect( - new UInt64(Field(2)).greaterThan(new UInt64(Field(1))) + new UInt64(2).greaterThan(new UInt64(1)) ).toEqual(Bool(true)); }); it('1>1=false', () => { expect( - new UInt64(Field(1)).greaterThan(new UInt64(Field(1))) + new UInt64(1).greaterThan(new UInt64(1)) ).toEqual(Bool(false)); }); it('1>2=false', () => { expect( - new UInt64(Field(1)).greaterThan(new UInt64(Field(2))) + new UInt64(1).greaterThan(new UInt64(2)) ).toEqual(Bool(false)); }); it('100000>1000=true', () => { expect( - new UInt64(Field(100000)).greaterThan(new UInt64(Field(1000))) + new UInt64(100000).greaterThan(new UInt64(1000)) ).toEqual(Bool(true)); }); it('1000>100000=false', () => { expect( - new UInt64(Field(1000)).greaterThan(new UInt64(Field(100000))) + new UInt64(1000).greaterThan(new UInt64(100000)) ).toEqual(Bool(false)); }); @@ -1006,34 +1006,34 @@ describe('int', () => { describe('greaterThanOrEqual', () => { it('2>=1=true', () => { expect( - new UInt64(Field(2)).greaterThanOrEqual(new UInt64(Field(1))) + new UInt64(2).greaterThanOrEqual(new UInt64(1)) ).toEqual(Bool(true)); }); it('1>=1=true', () => { expect( - new UInt64(Field(1)).greaterThanOrEqual(new UInt64(Field(1))) + new UInt64(1).greaterThanOrEqual(new UInt64(1)) ).toEqual(Bool(true)); }); it('1>=2=false', () => { expect( - new UInt64(Field(1)).greaterThanOrEqual(new UInt64(Field(2))) + new UInt64(1).greaterThanOrEqual(new UInt64(2)) ).toEqual(Bool(false)); }); it('100000>=1000=true', () => { expect( - new UInt64(Field(100000)).greaterThanOrEqual( - new UInt64(Field(1000)) + new UInt64(100000).greaterThanOrEqual( + new UInt64(1000) ) ).toEqual(Bool(true)); }); it('1000>=100000=false', () => { expect( - new UInt64(Field(1000)).greaterThanOrEqual( - new UInt64(Field(100000)) + new UInt64(1000).greaterThanOrEqual( + new UInt64(100000) ) ).toEqual(Bool(false)); }); @@ -1048,28 +1048,28 @@ describe('int', () => { describe('assertGreaterThan', () => { it('1>1=false', () => { expect(() => { - new UInt64(Field(1)).assertGreaterThan(new UInt64(Field(1))); + new UInt64(1).assertGreaterThan(new UInt64(1)); }).toThrow(); }); it('2>1=true', () => { expect(() => { - new UInt64(Field(2)).assertGreaterThan(new UInt64(Field(1))); + new UInt64(2).assertGreaterThan(new UInt64(1)); }).not.toThrow(); }); it('1000>100000=false', () => { expect(() => { - new UInt64(Field(1000)).assertGreaterThan( - new UInt64(Field(100000)) + new UInt64(1000).assertGreaterThan( + new UInt64(100000) ); }).toThrow(); }); it('100000>1000=true', () => { expect(() => { - new UInt64(Field(100000)).assertGreaterThan( - new UInt64(Field(1000)) + new UInt64(100000).assertGreaterThan( + new UInt64(1000) ); }).not.toThrow(); }); @@ -1084,28 +1084,28 @@ describe('int', () => { describe('assertGreaterThanOrEqual', () => { it('1>=1=true', () => { expect(() => { - new UInt64(Field(1)).assertGreaterThanOrEqual(new UInt64(Field(1))); + new UInt64(1).assertGreaterThanOrEqual(new UInt64(1)); }).not.toThrow(); }); it('2>=1=true', () => { expect(() => { - new UInt64(Field(2)).assertGreaterThanOrEqual(new UInt64(Field(1))); + new UInt64(2).assertGreaterThanOrEqual(new UInt64(1)); }).not.toThrow(); }); it('1000>=100000=false', () => { expect(() => { - new UInt64(Field(1000)).assertGreaterThanOrEqual( - new UInt64(Field(100000)) + new UInt64(1000).assertGreaterThanOrEqual( + new UInt64(100000) ); }).toThrow(); }); it('100000>=1000=true', () => { expect(() => { - new UInt64(Field(100000)).assertGreaterThanOrEqual( - new UInt64(Field(1000)) + new UInt64(100000).assertGreaterThanOrEqual( + new UInt64(1000) ); }).not.toThrow(); }); @@ -1119,12 +1119,12 @@ describe('int', () => { describe('toString()', () => { it('should be the same as Field(0)', async () => { - const uint64 = new UInt64(Field(0)); + const uint64 = new UInt64(0); const field = Field(0); expect(uint64.toString()).toEqual(field.toString()); }); it('should be the same as 2^53-1', async () => { - const uint64 = new UInt64(Field(String(NUMBERMAX))); + const uint64 = new UInt64(String(NUMBERMAX)); const field = Field(String(NUMBERMAX)); expect(uint64.toString()).toEqual(field.toString()); }); @@ -1138,7 +1138,7 @@ describe('int', () => { }); it('should throw checking over MAXINT', () => { - const aboveMax = new UInt64(Field((1n << 64n).toString())); // This number is defined in UInt64.MAXINT() + const aboveMax = new UInt64((1n << 64n).toString()); // This number is defined in UInt64.MAXINT() expect(() => { UInt64.check(aboveMax); }).toThrow(); @@ -1149,7 +1149,7 @@ describe('int', () => { describe('fromNumber()', () => { it('should be the same as Field(1)', () => { const uint = UInt64.from(1); - expect(uint.value).toEqual(new UInt64(Field(1)).value); + expect(uint.value).toEqual(new UInt64(1).value); }); it('should be the same as 2^53-1', () => { @@ -1160,7 +1160,7 @@ describe('int', () => { describe('fromString()', () => { it('should be the same as Field(1)', () => { const uint = UInt64.from('1'); - expect(uint.value).toEqual(new UInt64(Field(1)).value); + expect(uint.value).toEqual(new UInt64(1).value); }); it('should be the same as 2^53-1', () => { @@ -1180,9 +1180,9 @@ describe('int', () => { it('1+1=2', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1))); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); - x.add(y).assertEquals(new UInt32(Field(2))); + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.add(y).assertEquals(new UInt32(2)); }); }).not.toThrow(); }); @@ -1190,15 +1190,15 @@ describe('int', () => { it('5000+5000=10000', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(5000))); - const y = Provable.witness(UInt32, () => new UInt32(Field(5000))); - x.add(y).assertEquals(new UInt32(Field(10000))); + const x = Provable.witness(UInt32, () => new UInt32(5000)); + const y = Provable.witness(UInt32, () => new UInt32(5000)); + x.add(y).assertEquals(new UInt32(10000)); }); }).not.toThrow(); }); it('(MAXINT/2+MAXINT/2) adds to MAXINT', () => { - const n = Field((((1n << 32n) - 2n) / 2n).toString()); + const n = ((1n << 32n) - 2n) / 2n; expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt32, () => new UInt32(n)); @@ -1212,7 +1212,7 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt32, () => UInt32.MAXINT()); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); + const y = Provable.witness(UInt32, () => new UInt32(1)); x.add(y); }); }).toThrow(); @@ -1223,9 +1223,9 @@ describe('int', () => { it('1-1=0', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1))); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); - x.sub(y).assertEquals(new UInt32(Field(0))); + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.sub(y).assertEquals(new UInt32(0)); }); }).not.toThrow(); }); @@ -1235,10 +1235,10 @@ describe('int', () => { Provable.runAndCheck(() => { const x = Provable.witness( UInt32, - () => new UInt32(Field(10000)) + () => new UInt32(10000) ); - const y = Provable.witness(UInt32, () => new UInt32(Field(5000))); - x.sub(y).assertEquals(new UInt32(Field(5000))); + const y = Provable.witness(UInt32, () => new UInt32(5000)); + x.sub(y).assertEquals(new UInt32(5000)); }); }).not.toThrow(); }); @@ -1246,8 +1246,8 @@ describe('int', () => { it('should throw on sub if results in negative number', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(0))); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); + const x = Provable.witness(UInt32, () => new UInt32(0)); + const y = Provable.witness(UInt32, () => new UInt32(1)); x.sub(y); }); }).toThrow(); @@ -1258,9 +1258,9 @@ describe('int', () => { it('1x2=2', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1))); - const y = Provable.witness(UInt32, () => new UInt32(Field(2))); - x.mul(y).assertEquals(new UInt32(Field(2))); + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(2)); + x.mul(y).assertEquals(new UInt32(2)); }); }).not.toThrow(); }); @@ -1268,9 +1268,9 @@ describe('int', () => { it('1x0=0', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1))); - const y = Provable.witness(UInt32, () => new UInt32(Field(0))); - x.mul(y).assertEquals(new UInt32(Field(0))); + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(0)); + x.mul(y).assertEquals(new UInt32(0)); }); }).not.toThrow(); }); @@ -1278,9 +1278,9 @@ describe('int', () => { it('1000x1000=1000000', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1000))); - const y = Provable.witness(UInt32, () => new UInt32(Field(1000))); - x.mul(y).assertEquals(new UInt32(Field(1000000))); + const x = Provable.witness(UInt32, () => new UInt32(1000)); + const y = Provable.witness(UInt32, () => new UInt32(1000)); + x.mul(y).assertEquals(new UInt32(1000000)); }); }).not.toThrow(); }); @@ -1289,7 +1289,7 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt32, () => UInt32.MAXINT()); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); + const y = Provable.witness(UInt32, () => new UInt32(1)); x.mul(y).assertEquals(UInt32.MAXINT()); }); }).not.toThrow(); @@ -1299,7 +1299,7 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt32, () => UInt32.MAXINT()); - const y = Provable.witness(UInt32, () => new UInt32(Field(2))); + const y = Provable.witness(UInt32, () => new UInt32(2)); x.mul(y); }); }).toThrow(); @@ -1310,9 +1310,9 @@ describe('int', () => { it('2/1=2', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(2))); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); - x.div(y).assertEquals(new UInt32(Field(2))); + const x = Provable.witness(UInt32, () => new UInt32(2)); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.div(y).assertEquals(new UInt32(2)); }); }).not.toThrow(); }); @@ -1320,9 +1320,9 @@ describe('int', () => { it('0/1=0', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(0))); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); - x.div(y).assertEquals(new UInt32(Field(0))); + const x = Provable.witness(UInt32, () => new UInt32(0)); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.div(y).assertEquals(new UInt32(0)); }); }).not.toThrow(); }); @@ -1330,9 +1330,9 @@ describe('int', () => { it('2000/1000=2', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(2000))); - const y = Provable.witness(UInt32, () => new UInt32(Field(1000))); - x.div(y).assertEquals(new UInt32(Field(2))); + const x = Provable.witness(UInt32, () => new UInt32(2000)); + const y = Provable.witness(UInt32, () => new UInt32(1000)); + x.div(y).assertEquals(new UInt32(2)); }); }).not.toThrow(); }); @@ -1341,7 +1341,7 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt32, () => UInt32.MAXINT()); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); + const y = Provable.witness(UInt32, () => new UInt32(1)); x.div(y).assertEquals(UInt32.MAXINT()); }); }).not.toThrow(); @@ -1351,7 +1351,7 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt32, () => UInt32.MAXINT()); - const y = Provable.witness(UInt32, () => new UInt32(Field(0))); + const y = Provable.witness(UInt32, () => new UInt32(0)); x.div(y); }); }).toThrow(); @@ -1362,9 +1362,9 @@ describe('int', () => { it('1%1=0', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1))); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); - x.mod(y).assertEquals(new UInt32(Field(0))); + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(1)); + x.mod(y).assertEquals(new UInt32(0)); }); }).not.toThrow(); }); @@ -1372,9 +1372,9 @@ describe('int', () => { it('500%32=20', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(500))); - const y = Provable.witness(UInt32, () => new UInt32(Field(32))); - x.mod(y).assertEquals(new UInt32(Field(20))); + const x = Provable.witness(UInt32, () => new UInt32(500)); + const y = Provable.witness(UInt32, () => new UInt32(32)); + x.mod(y).assertEquals(new UInt32(20)); }); }).not.toThrow(); }); @@ -1383,8 +1383,8 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt32, () => UInt32.MAXINT()); - const y = Provable.witness(UInt32, () => new UInt32(Field(7))); - x.mod(y).assertEquals(new UInt32(Field(3))); + const y = Provable.witness(UInt32, () => new UInt32(7)); + x.mod(y).assertEquals(new UInt32(3)); }); }).not.toThrow(); }); @@ -1393,8 +1393,8 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt32, () => UInt32.MAXINT()); - const y = Provable.witness(UInt32, () => new UInt32(Field(0))); - x.mod(y).assertEquals(new UInt32(Field(1))); + const y = Provable.witness(UInt32, () => new UInt32(0)); + x.mod(y).assertEquals(new UInt32(1)); }); }).toThrow(); }); @@ -1404,8 +1404,8 @@ describe('int', () => { it('1<2=true', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1))); - const y = Provable.witness(UInt32, () => new UInt32(Field(2))); + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(2)); x.assertLessThan(y); }); }).not.toThrow(); @@ -1414,8 +1414,8 @@ describe('int', () => { it('1<1=false', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1))); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(1)); x.assertLessThan(y); }); }).toThrow(); @@ -1424,8 +1424,8 @@ describe('int', () => { it('2<1=false', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(2))); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); + const x = Provable.witness(UInt32, () => new UInt32(2)); + const y = Provable.witness(UInt32, () => new UInt32(1)); x.assertLessThan(y); }); }).toThrow(); @@ -1434,10 +1434,10 @@ describe('int', () => { it('1000<100000=true', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1000))); + const x = Provable.witness(UInt32, () => new UInt32(1000)); const y = Provable.witness( UInt32, - () => new UInt32(Field(100000)) + () => new UInt32(100000) ); x.assertLessThan(y); }); @@ -1449,9 +1449,9 @@ describe('int', () => { Provable.runAndCheck(() => { const x = Provable.witness( UInt32, - () => new UInt32(Field(100000)) + () => new UInt32(100000) ); - const y = Provable.witness(UInt32, () => new UInt32(Field(1000))); + const y = Provable.witness(UInt32, () => new UInt32(1000)); x.assertLessThan(y); }); }).toThrow(); @@ -1472,8 +1472,8 @@ describe('int', () => { it('1<=1=true', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1))); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(1)); x.assertLessThanOrEqual(y); }); }).not.toThrow(); @@ -1482,8 +1482,8 @@ describe('int', () => { it('2<=1=false', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(2))); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); + const x = Provable.witness(UInt32, () => new UInt32(2)); + const y = Provable.witness(UInt32, () => new UInt32(1)); x.assertLessThanOrEqual(y); }); }).toThrow(); @@ -1492,10 +1492,10 @@ describe('int', () => { it('1000<=100000=true', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1000))); + const x = Provable.witness(UInt32, () => new UInt32(1000)); const y = Provable.witness( UInt32, - () => new UInt32(Field(100000)) + () => new UInt32(100000) ); x.assertLessThanOrEqual(y); }); @@ -1507,9 +1507,9 @@ describe('int', () => { Provable.runAndCheck(() => { const x = Provable.witness( UInt32, - () => new UInt32(Field(100000)) + () => new UInt32(100000) ); - const y = Provable.witness(UInt32, () => new UInt32(Field(1000))); + const y = Provable.witness(UInt32, () => new UInt32(1000)); x.assertLessThanOrEqual(y); }); }).toThrow(); @@ -1530,8 +1530,8 @@ describe('int', () => { it('2>1=true', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(2))); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); + const x = Provable.witness(UInt32, () => new UInt32(2)); + const y = Provable.witness(UInt32, () => new UInt32(1)); x.assertGreaterThan(y); }); }).not.toThrow(); @@ -1540,8 +1540,8 @@ describe('int', () => { it('1>1=false', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1))); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(1)); x.assertGreaterThan(y); }); }).toThrow(); @@ -1550,8 +1550,8 @@ describe('int', () => { it('1>2=false', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1))); - const y = Provable.witness(UInt32, () => new UInt32(Field(2))); + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(2)); x.assertGreaterThan(y); }); }).toThrow(); @@ -1562,9 +1562,9 @@ describe('int', () => { Provable.runAndCheck(() => { const x = Provable.witness( UInt32, - () => new UInt32(Field(100000)) + () => new UInt32(100000) ); - const y = Provable.witness(UInt32, () => new UInt32(Field(1000))); + const y = Provable.witness(UInt32, () => new UInt32(1000)); x.assertGreaterThan(y); }); }).not.toThrow(); @@ -1573,10 +1573,10 @@ describe('int', () => { it('1000>100000=false', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1000))); + const x = Provable.witness(UInt32, () => new UInt32(1000)); const y = Provable.witness( UInt32, - () => new UInt32(Field(100000)) + () => new UInt32(100000) ); x.assertGreaterThan(y); }); @@ -1598,8 +1598,8 @@ describe('int', () => { it('1<=1=true', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1))); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(1)); x.assertGreaterThanOrEqual(y); }); }).not.toThrow(); @@ -1608,8 +1608,8 @@ describe('int', () => { it('1>=2=false', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1))); - const y = Provable.witness(UInt32, () => new UInt32(Field(2))); + const x = Provable.witness(UInt32, () => new UInt32(1)); + const y = Provable.witness(UInt32, () => new UInt32(2)); x.assertGreaterThanOrEqual(y); }); }).toThrow(); @@ -1620,9 +1620,9 @@ describe('int', () => { Provable.runAndCheck(() => { const x = Provable.witness( UInt32, - () => new UInt32(Field(100000)) + () => new UInt32(100000) ); - const y = Provable.witness(UInt32, () => new UInt32(Field(1000))); + const y = Provable.witness(UInt32, () => new UInt32(1000)); x.assertGreaterThanOrEqual(y); }); }).not.toThrow(); @@ -1631,10 +1631,10 @@ describe('int', () => { it('1000>=100000=false', () => { expect(() => { Provable.runAndCheck(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1000))); + const x = Provable.witness(UInt32, () => new UInt32(1000)); const y = Provable.witness( UInt32, - () => new UInt32(Field(100000)) + () => new UInt32(100000) ); x.assertGreaterThanOrEqual(y); }); @@ -1658,7 +1658,7 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt32, () => UInt32.from(1)); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); + const y = Provable.witness(UInt32, () => new UInt32(1)); x.assertEquals(y); }); }).not.toThrow(); @@ -1672,7 +1672,7 @@ describe('int', () => { ); const y = Provable.witness( UInt32, - () => new UInt32(Field(String(NUMBERMAX))) + () => new UInt32(String(NUMBERMAX)) ); x.assertEquals(y); }); @@ -1684,7 +1684,7 @@ describe('int', () => { expect(() => { Provable.runAndCheck(() => { const x = Provable.witness(UInt32, () => UInt32.from('1')); - const y = Provable.witness(UInt32, () => new UInt32(Field(1))); + const y = Provable.witness(UInt32, () => new UInt32(1)); x.assertEquals(y); }); }).not.toThrow(); @@ -1698,7 +1698,7 @@ describe('int', () => { ); const y = Provable.witness( UInt32, - () => new UInt32(Field(String(NUMBERMAX))) + () => new UInt32(String(NUMBERMAX)) ); x.assertEquals(y); }); @@ -1711,19 +1711,19 @@ describe('int', () => { describe('Outside of circuit', () => { describe('add', () => { it('1+1=2', () => { - expect(new UInt32(Field(1)).add(1).toString()).toEqual('2'); + expect(new UInt32(1).add(1).toString()).toEqual('2'); }); it('5000+5000=10000', () => { - expect(new UInt32(Field(5000)).add(5000).toString()).toEqual('10000'); + expect(new UInt32(5000).add(5000).toString()).toEqual('10000'); }); it('(MAXINT/2+MAXINT/2) adds to MAXINT', () => { - const value = Field((((1n << 32n) - 2n) / 2n).toString()); + const value = ((1n << 32n) - 2n) / 2n; expect( new UInt32(value) .add(new UInt32(value)) - .add(new UInt32(Field(1))) + .add(new UInt32(1)) .toString() ).toEqual(UInt32.MAXINT().toString()); }); @@ -1737,11 +1737,11 @@ describe('int', () => { describe('sub', () => { it('1-1=0', () => { - expect(new UInt32(Field(1)).sub(1).toString()).toEqual('0'); + expect(new UInt32(1).sub(1).toString()).toEqual('0'); }); it('10000-5000=5000', () => { - expect(new UInt32(Field(10000)).sub(5000).toString()).toEqual('5000'); + expect(new UInt32(10000).sub(5000).toString()).toEqual('5000'); }); it('should throw on sub if results in negative number', () => { @@ -1753,15 +1753,15 @@ describe('int', () => { describe('mul', () => { it('1x2=2', () => { - expect(new UInt32(Field(1)).mul(2).toString()).toEqual('2'); + expect(new UInt32(1).mul(2).toString()).toEqual('2'); }); it('1x0=0', () => { - expect(new UInt32(Field(1)).mul(0).toString()).toEqual('0'); + expect(new UInt32(1).mul(0).toString()).toEqual('0'); }); it('1000x1000=1000000', () => { - expect(new UInt32(Field(1000)).mul(1000).toString()).toEqual( + expect(new UInt32(1000).mul(1000).toString()).toEqual( '1000000' ); }); @@ -1781,15 +1781,15 @@ describe('int', () => { describe('div', () => { it('2/1=2', () => { - expect(new UInt32(Field(2)).div(1).toString()).toEqual('2'); + expect(new UInt32(2).div(1).toString()).toEqual('2'); }); it('0/1=0', () => { - expect(new UInt32(Field(0)).div(1).toString()).toEqual('0'); + expect(new UInt32(0).div(1).toString()).toEqual('0'); }); it('2000/1000=2', () => { - expect(new UInt32(Field(2000)).div(1000).toString()).toEqual('2'); + expect(new UInt32(2000).div(1000).toString()).toEqual('2'); }); it('MAXINT/1=MAXINT', () => { @@ -1807,11 +1807,11 @@ describe('int', () => { describe('mod', () => { it('1%1=0', () => { - expect(new UInt32(Field(1)).mod(1).toString()).toEqual('0'); + expect(new UInt32(1).mod(1).toString()).toEqual('0'); }); it('500%32=20', () => { - expect(new UInt32(Field(500)).mod(32).toString()).toEqual('20'); + expect(new UInt32(500).mod(32).toString()).toEqual('20'); }); it('MAXINT%7=3', () => { @@ -1827,32 +1827,32 @@ describe('int', () => { describe('lessThan', () => { it('1<2=true', () => { - expect(new UInt32(Field(1)).lessThan(new UInt32(Field(2)))).toEqual( + expect(new UInt32(1).lessThan(new UInt32(2))).toEqual( Bool(true) ); }); it('1<1=false', () => { - expect(new UInt32(Field(1)).lessThan(new UInt32(Field(1)))).toEqual( + expect(new UInt32(1).lessThan(new UInt32(1))).toEqual( Bool(false) ); }); it('2<1=false', () => { - expect(new UInt32(Field(2)).lessThan(new UInt32(Field(1)))).toEqual( + expect(new UInt32(2).lessThan(new UInt32(1))).toEqual( Bool(false) ); }); it('1000<100000=true', () => { expect( - new UInt32(Field(1000)).lessThan(new UInt32(Field(100000))) + new UInt32(1000).lessThan(new UInt32(100000)) ).toEqual(Bool(true)); }); it('100000<1000=false', () => { expect( - new UInt32(Field(100000)).lessThan(new UInt32(Field(1000))) + new UInt32(100000).lessThan(new UInt32(1000)) ).toEqual(Bool(false)); }); @@ -1866,25 +1866,25 @@ describe('int', () => { describe('lessThanOrEqual', () => { it('1<=1=true', () => { expect( - new UInt32(Field(1)).lessThanOrEqual(new UInt32(Field(1))) + new UInt32(1).lessThanOrEqual(new UInt32(1)) ).toEqual(Bool(true)); }); it('2<=1=false', () => { expect( - new UInt32(Field(2)).lessThanOrEqual(new UInt32(Field(1))) + new UInt32(2).lessThanOrEqual(new UInt32(1)) ).toEqual(Bool(false)); }); it('1000<=100000=true', () => { expect( - new UInt32(Field(1000)).lessThanOrEqual(new UInt32(Field(100000))) + new UInt32(1000).lessThanOrEqual(new UInt32(100000)) ).toEqual(Bool(true)); }); it('100000<=1000=false', () => { expect( - new UInt32(Field(100000)).lessThanOrEqual(new UInt32(Field(1000))) + new UInt32(100000).lessThanOrEqual(new UInt32(1000)) ).toEqual(Bool(false)); }); @@ -1898,28 +1898,28 @@ describe('int', () => { describe('assertLessThanOrEqual', () => { it('1<=1=true', () => { expect(() => { - new UInt32(Field(1)).assertLessThanOrEqual(new UInt32(Field(1))); + new UInt32(1).assertLessThanOrEqual(new UInt32(1)); }).not.toThrow(); }); it('2<=1=false', () => { expect(() => { - new UInt32(Field(2)).assertLessThanOrEqual(new UInt32(Field(1))); + new UInt32(2).assertLessThanOrEqual(new UInt32(1)); }).toThrow(); }); it('1000<=100000=true', () => { expect(() => { - new UInt32(Field(1000)).assertLessThanOrEqual( - new UInt32(Field(100000)) + new UInt32(1000).assertLessThanOrEqual( + new UInt32(100000) ); }).not.toThrow(); }); it('100000<=1000=false', () => { expect(() => { - new UInt32(Field(100000)).assertLessThanOrEqual( - new UInt32(Field(1000)) + new UInt32(100000).assertLessThanOrEqual( + new UInt32(1000) ); }).toThrow(); }); @@ -1934,31 +1934,31 @@ describe('int', () => { describe('greaterThan', () => { it('2>1=true', () => { expect( - new UInt32(Field(2)).greaterThan(new UInt32(Field(1))) + new UInt32(2).greaterThan(new UInt32(1)) ).toEqual(Bool(true)); }); it('1>1=false', () => { expect( - new UInt32(Field(1)).greaterThan(new UInt32(Field(1))) + new UInt32(1).greaterThan(new UInt32(1)) ).toEqual(Bool(false)); }); it('1>2=false', () => { expect( - new UInt32(Field(1)).greaterThan(new UInt32(Field(2))) + new UInt32(1).greaterThan(new UInt32(2)) ).toEqual(Bool(false)); }); it('100000>1000=true', () => { expect( - new UInt32(Field(100000)).greaterThan(new UInt32(Field(1000))) + new UInt32(100000).greaterThan(new UInt32(1000)) ).toEqual(Bool(true)); }); it('1000>100000=false', () => { expect( - new UInt32(Field(1000)).greaterThan(new UInt32(Field(100000))) + new UInt32(1000).greaterThan(new UInt32(100000)) ).toEqual(Bool(false)); }); @@ -1972,28 +1972,28 @@ describe('int', () => { describe('assertGreaterThan', () => { it('1>1=false', () => { expect(() => { - new UInt32(Field(1)).assertGreaterThan(new UInt32(Field(1))); + new UInt32(1).assertGreaterThan(new UInt32(1)); }).toThrow(); }); it('2>1=true', () => { expect(() => { - new UInt32(Field(2)).assertGreaterThan(new UInt32(Field(1))); + new UInt32(2).assertGreaterThan(new UInt32(1)); }).not.toThrow(); }); it('1000>100000=false', () => { expect(() => { - new UInt32(Field(1000)).assertGreaterThan( - new UInt32(Field(100000)) + new UInt32(1000).assertGreaterThan( + new UInt32(100000) ); }).toThrow(); }); it('100000>1000=true', () => { expect(() => { - new UInt32(Field(100000)).assertGreaterThan( - new UInt32(Field(1000)) + new UInt32(100000).assertGreaterThan( + new UInt32(1000) ); }).not.toThrow(); }); @@ -2008,34 +2008,34 @@ describe('int', () => { describe('greaterThanOrEqual', () => { it('2>=1=true', () => { expect( - new UInt32(Field(2)).greaterThanOrEqual(new UInt32(Field(1))) + new UInt32(2).greaterThanOrEqual(new UInt32(1)) ).toEqual(Bool(true)); }); it('1>=1=true', () => { expect( - new UInt32(Field(1)).greaterThanOrEqual(new UInt32(Field(1))) + new UInt32(1).greaterThanOrEqual(new UInt32(1)) ).toEqual(Bool(true)); }); it('1>=2=false', () => { expect( - new UInt32(Field(1)).greaterThanOrEqual(new UInt32(Field(2))) + new UInt32(1).greaterThanOrEqual(new UInt32(2)) ).toEqual(Bool(false)); }); it('100000>=1000=true', () => { expect( - new UInt32(Field(100000)).greaterThanOrEqual( - new UInt32(Field(1000)) + new UInt32(100000).greaterThanOrEqual( + new UInt32(1000) ) ).toEqual(Bool(true)); }); it('1000>=100000=false', () => { expect( - new UInt32(Field(1000)).greaterThanOrEqual( - new UInt32(Field(100000)) + new UInt32(1000).greaterThanOrEqual( + new UInt32(100000) ) ).toEqual(Bool(false)); }); @@ -2050,28 +2050,28 @@ describe('int', () => { describe('assertGreaterThanOrEqual', () => { it('1>=1=true', () => { expect(() => { - new UInt32(Field(1)).assertGreaterThanOrEqual(new UInt32(Field(1))); + new UInt32(1).assertGreaterThanOrEqual(new UInt32(1)); }).not.toThrow(); }); it('2>=1=true', () => { expect(() => { - new UInt32(Field(2)).assertGreaterThanOrEqual(new UInt32(Field(1))); + new UInt32(2).assertGreaterThanOrEqual(new UInt32(1)); }).not.toThrow(); }); it('1000>=100000=false', () => { expect(() => { - new UInt32(Field(1000)).assertGreaterThanOrEqual( - new UInt32(Field(100000)) + new UInt32(1000).assertGreaterThanOrEqual( + new UInt32(100000) ); }).toThrow(); }); it('100000>=1000=true', () => { expect(() => { - new UInt32(Field(100000)).assertGreaterThanOrEqual( - new UInt32(Field(1000)) + new UInt32(100000).assertGreaterThanOrEqual( + new UInt32(1000) ); }).not.toThrow(); }); @@ -2085,12 +2085,12 @@ describe('int', () => { describe('toString()', () => { it('should be the same as Field(0)', async () => { - const x = new UInt32(Field(0)); + const x = new UInt32(0); const y = Field(0); expect(x.toString()).toEqual(y.toString()); }); it('should be the same as 2^32-1', async () => { - const x = new UInt32(Field(String(NUMBERMAX))); + const x = new UInt32(String(NUMBERMAX)); const y = Field(String(NUMBERMAX)); expect(x.toString()).toEqual(y.toString()); }); @@ -2104,7 +2104,7 @@ describe('int', () => { }); it('should throw checking over MAXINT', () => { - const x = new UInt32(Field((1n << 32n).toString())); // This number is defined in UInt32.MAXINT() + const x = new UInt32((1n << 32n).toString()); // This number is defined in UInt32.MAXINT() expect(() => { UInt32.check(x); }).toThrow(); @@ -2115,7 +2115,7 @@ describe('int', () => { describe('fromNumber()', () => { it('should be the same as Field(1)', () => { const x = UInt32.from(1); - expect(x.value).toEqual(new UInt32(Field(1)).value); + expect(x.value).toEqual(new UInt32(1).value); }); it('should be the same as 2^53-1', () => { @@ -2126,7 +2126,7 @@ describe('int', () => { describe('fromString()', () => { it('should be the same as Field(1)', () => { const x = UInt32.from('1'); - expect(x.value).toEqual(new UInt32(Field(1)).value); + expect(x.value).toEqual(new UInt32(1).value); }); it('should be the same as 2^53-1', () => { From b3ad149a1ab9e4953f49505666696537e3b4bd8a Mon Sep 17 00:00:00 2001 From: julio4 Date: Fri, 16 Feb 2024 18:39:22 +0900 Subject: [PATCH 03/11] Fix: sha256 unsafe Uint --- src/lib/gadgets/sha256.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/lib/gadgets/sha256.ts b/src/lib/gadgets/sha256.ts index b1e764d3f6..a7e201814f 100644 --- a/src/lib/gadgets/sha256.ts +++ b/src/lib/gadgets/sha256.ts @@ -70,7 +70,7 @@ function padding(data: FlexibleBytes): UInt32[][] { // chunk 4 bytes into one UInt32, as expected by SHA256 // bytesToWord expects little endian, so we reverse the bytes chunks.push( - UInt32.from(bytesToWord(paddedMessage.slice(i, i + 4).reverse())) + UInt32.Unsafe.fromField(bytesToWord(paddedMessage.slice(i, i + 4).reverse())) ); } @@ -104,7 +104,7 @@ const SHA256 = { .add(DeltaZero(W[t - 15]).value.add(W[t - 16].value)); // mod 32bit the unreduced field element - W[t] = UInt32.from(divMod32(unreduced, 16).remainder); + W[t] = UInt32.Unsafe.fromField(divMod32(unreduced, 16).remainder); } // initialize working variables @@ -133,11 +133,11 @@ const SHA256 = { h = g; g = f; f = e; - e = UInt32.from(divMod32(d.value.add(unreducedT1), 16).remainder); // mod 32bit the unreduced field element + e = UInt32.Unsafe.fromField(divMod32(d.value.add(unreducedT1), 16).remainder); // mod 32bit the unreduced field element d = c; c = b; b = a; - a = UInt32.from(divMod32(unreducedT2.add(unreducedT1), 16).remainder); // mod 32bit + a = UInt32.Unsafe.fromField(divMod32(unreducedT2.add(unreducedT1), 16).remainder); // mod 32bit } // new intermediate hash value @@ -163,7 +163,7 @@ function Ch(x: UInt32, y: UInt32, z: UInt32) { let xAndY = x.and(y).value; let xNotAndZ = x.not().and(z).value; let ch = xAndY.add(xNotAndZ).seal(); - return UInt32.from(ch); + return UInt32.Unsafe.fromField(ch); } function Maj(x: UInt32, y: UInt32, z: UInt32) { @@ -172,7 +172,7 @@ function Maj(x: UInt32, y: UInt32, z: UInt32) { let sum = x.value.add(y.value).add(z.value).seal(); let xor = x.xor(y).xor(z).value; let maj = sum.sub(xor).div(2).seal(); - return UInt32.from(maj); + return UInt32.Unsafe.fromField(maj); } function SigmaZero(x: UInt32) { @@ -276,5 +276,5 @@ function sigma(u: UInt32, bits: TupleN, firstShifted = false) { // since xor() is implicitly range-checking both of its inputs, this provides the missing // proof that xRotR0, xRotR1, xRotR2 < 2^32, which implies x0 < 2^d0, x1 < 2^d1, x2 < 2^d2 - return UInt32.from(xRotR0).xor(new UInt32(xRotR1)).xor(new UInt32(xRotR2)); + return UInt32.Unsafe.fromField(xRotR0).xor(UInt32.Unsafe.fromField(xRotR1)).xor(UInt32.Unsafe.fromField(xRotR2)); } From cebbe414f16c680b155f4a261ed4c1e122051f2f Mon Sep 17 00:00:00 2001 From: Gregor Mitscha-Baude Date: Wed, 28 Feb 2024 11:02:20 +0100 Subject: [PATCH 04/11] Update src/lib/int.ts --- src/lib/int.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib/int.ts b/src/lib/int.ts index 8bf4373584..6c4b4ea554 100644 --- a/src/lib/int.ts +++ b/src/lib/int.ts @@ -27,8 +27,9 @@ class UInt64 extends CircuitValue { */ constructor(x: UInt64 | UInt32 | FieldVar | number | string | bigint) { if (x instanceof UInt64 || x instanceof UInt32) x = x.value.value; - super({ value: Field(x) }); - UInt64.checkConstant(this.value); + let value = Field(x); + super({ value }); + UInt64.checkConstant(value); } static Unsafe = { From 4ea799d7a48db5afb99b8544bdf60ee8f49d54a1 Mon Sep 17 00:00:00 2001 From: Gregor Mitscha-Baude Date: Wed, 28 Feb 2024 11:14:55 +0100 Subject: [PATCH 05/11] Update src/lib/int.ts --- src/lib/int.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib/int.ts b/src/lib/int.ts index 6c4b4ea554..b6fc2b4709 100644 --- a/src/lib/int.ts +++ b/src/lib/int.ts @@ -573,8 +573,9 @@ class UInt32 extends CircuitValue { */ constructor(x: UInt32 | FieldVar | number | string | bigint) { if (x instanceof UInt32) x = x.value.value; - super({ value: Field(x) }); - UInt32.checkConstant(this.value); + let value = Field(x); + super({ value }); + UInt32.checkConstant(value); } static Unsafe = { From e7b19062bab877dbb64a289189d46e5bc4c457c3 Mon Sep 17 00:00:00 2001 From: Gregor Date: Thu, 7 Mar 2024 11:27:12 +0100 Subject: [PATCH 06/11] fix uint construction and remove some code duplication --- src/lib/int.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/lib/int.ts b/src/lib/int.ts index b6fc2b4709..ea14260e2a 100644 --- a/src/lib/int.ts +++ b/src/lib/int.ts @@ -28,7 +28,8 @@ class UInt64 extends CircuitValue { constructor(x: UInt64 | UInt32 | FieldVar | number | string | bigint) { if (x instanceof UInt64 || x instanceof UInt32) x = x.value.value; let value = Field(x); - super({ value }); + super(value); + // check the range if the argument is a constant UInt64.checkConstant(value); } @@ -128,13 +129,12 @@ class UInt64 extends CircuitValue { return x; } - // this checks the range if the argument is a constant /** * Creates a new {@link UInt64}. */ static from(x: UInt64 | UInt32 | number | string | bigint) { - let _x = (x instanceof UInt64 || x instanceof UInt32) ? x.value : Field(x); - return new this(this.checkConstant(_x).value); + if (x instanceof UInt64) return x; + return new this(x); } /** @@ -574,7 +574,8 @@ class UInt32 extends CircuitValue { constructor(x: UInt32 | FieldVar | number | string | bigint) { if (x instanceof UInt32) x = x.value.value; let value = Field(x); - super({ value }); + super(value); + // check the range if the argument is a constant UInt32.checkConstant(value); } @@ -659,8 +660,8 @@ class UInt32 extends CircuitValue { * Creates a new {@link UInt32}. */ static from(x: UInt32 | number | string | bigint) { - let _x = x instanceof UInt32 ? x.value : Field(x); - return new this(this.checkConstant(_x).value); + if (x instanceof UInt32) return x; + return new this(x); } /** From c697f18017c902053cddd0beee997226e6bc2615 Mon Sep 17 00:00:00 2001 From: Gregor Date: Thu, 7 Mar 2024 11:42:07 +0100 Subject: [PATCH 07/11] fixup unit test --- src/lib/circuit-value.unit-test.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/lib/circuit-value.unit-test.ts b/src/lib/circuit-value.unit-test.ts index 08a2127fb4..13c6af344e 100644 --- a/src/lib/circuit-value.unit-test.ts +++ b/src/lib/circuit-value.unit-test.ts @@ -65,15 +65,16 @@ await Provable.runAndCheck(() => { }); // should fail `check` if `check` of subfields doesn't pass + +// manually construct an invalid uint32 +let noUint32 = new UInt32(1); +noUint32.value = Field(-1); + await expect(() => Provable.runAndCheck(() => { let x = Provable.witness(type, () => ({ ...value, - uint: [ - UInt32.zero, - // invalid Uint32 - new UInt32(-1), - ], + uint: [UInt32.zero, noUint32], })); }) ).rejects.toThrow(`Constraint unsatisfied`); From 99e8cccf70fccd480e82e04567dd73ead60d4394 Mon Sep 17 00:00:00 2001 From: Gregor Date: Thu, 7 Mar 2024 11:58:11 +0100 Subject: [PATCH 08/11] fix clamped uint64 -> uint64 --- src/lib/int.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lib/int.ts b/src/lib/int.ts index ea14260e2a..0a835246a0 100644 --- a/src/lib/int.ts +++ b/src/lib/int.ts @@ -89,11 +89,12 @@ class UInt64 extends CircuitValue { */ toUInt32Clamped() { let max = (1n << 32n) - 1n; - return Provable.if( + let field = Provable.if( this.greaterThan(UInt64.from(max)), - UInt32.from(max), - new UInt32(this.value.value) + Field.from(max), + this.value ); + return UInt32.Unsafe.fromField(field); } static check(x: UInt64) { From 9eb9d7c454bf2de08f031f6736ead1fc5d6fbabc Mon Sep 17 00:00:00 2001 From: Gregor Date: Thu, 7 Mar 2024 12:45:13 +0100 Subject: [PATCH 09/11] fixup int test --- src/lib/int.test.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lib/int.test.ts b/src/lib/int.test.ts index 3298e727ef..fe29d19a6a 100644 --- a/src/lib/int.test.ts +++ b/src/lib/int.test.ts @@ -1081,7 +1081,8 @@ describe('int', () => { }); it('should throw checking over MAXINT', () => { - const aboveMax = new UInt64((1n << 64n).toString()); // This number is defined in UInt64.MAXINT() + const aboveMax = new UInt64(1); + aboveMax.value = Field(1n << 64n); expect(() => { UInt64.check(aboveMax); }).toThrow(); @@ -1990,9 +1991,10 @@ describe('int', () => { }); it('should throw checking over MAXINT', () => { - const x = new UInt32((1n << 32n).toString()); // This number is defined in UInt32.MAXINT() + const aboveMax = new UInt32(1); + aboveMax.value = Field(1n << 32n); expect(() => { - UInt32.check(x); + UInt32.check(aboveMax); }).toThrow(); }); }); From 0fee0fe8f1985e1538c84140748c2ff23b337cb5 Mon Sep 17 00:00:00 2001 From: Gregor Date: Thu, 7 Mar 2024 12:50:17 +0100 Subject: [PATCH 10/11] changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18c72e73ba..1c5309965b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - `Provable.runAndCheckSync()` added and immediately deprecated for a smoother upgrade path for tests - `Reducer.reduce()` requires the maximum number of actions per method as an explicit (optional) argument https://github.com/o1-labs/o1js/pull/1450 - The default value is 1 and should work for most existing contracts +- `new UInt64()` and `UInt64.from()` no longer unsafely accept a field element as input. As a replacement, there is `UInt64.Unsafe.fromField()` + - This prevents you from accidentally creating a `UInt64` without proving that it fits in 64 bits + - Equivalent changes were made to `UInt32` ### Added From 80a5e3e5a8557c324659e2e337b9e071b714c76b Mon Sep 17 00:00:00 2001 From: Gregor Date: Thu, 7 Mar 2024 12:57:01 +0100 Subject: [PATCH 11/11] tweak changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c5309965b..7c95adb53f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - `Provable.runAndCheckSync()` added and immediately deprecated for a smoother upgrade path for tests - `Reducer.reduce()` requires the maximum number of actions per method as an explicit (optional) argument https://github.com/o1-labs/o1js/pull/1450 - The default value is 1 and should work for most existing contracts -- `new UInt64()` and `UInt64.from()` no longer unsafely accept a field element as input. As a replacement, there is `UInt64.Unsafe.fromField()` +- `new UInt64()` and `UInt64.from()` no longer unsafely accept a field element as input. https://github.com/o1-labs/o1js/pull/1438 [@julio4](https://github.com/julio4) + 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`