diff --git a/CHANGELOG.md b/CHANGELOG.md index 18c72e73ba..7c95adb53f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,10 @@ 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. 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` ### Added diff --git a/src/lib/circuit-value.unit-test.ts b/src/lib/circuit-value.unit-test.ts index 206762fd91..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(Field(-1)), - ], + uint: [UInt32.zero, noUint32], })); }) ).rejects.toThrow(`Constraint unsatisfied`); 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)); } diff --git a/src/lib/int.test.ts b/src/lib/int.test.ts index 22e9131f95..fe29d19a6a 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.runAndCheckSync(() => { - 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.runAndCheckSync(() => { - 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.runAndCheckSync(() => { const x = Provable.witness(UInt64, () => new UInt64(n)); @@ -246,7 +246,7 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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.runAndCheckSync(() => { - 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(); }); @@ -267,12 +267,9 @@ describe('int', () => { it('10000-5000=5000', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness( - UInt64, - () => new UInt64(Field(10000)) - ); - const y = Provable.witness(UInt64, () => new UInt64(Field(5000))); - x.sub(y).assertEquals(new UInt64(Field(5000))); + const x = Provable.witness(UInt64, () => new UInt64(10000)); + const y = Provable.witness(UInt64, () => new UInt64(5000)); + x.sub(y).assertEquals(new UInt64(5000)); }); }).not.toThrow(); }); @@ -280,8 +277,8 @@ describe('int', () => { it('should throw on sub if results in negative number', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +289,9 @@ describe('int', () => { it('1x2=2', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +299,9 @@ describe('int', () => { it('1x0=0', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +309,9 @@ describe('int', () => { it('1000x1000=1000000', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +320,7 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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 +330,7 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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 +341,9 @@ describe('int', () => { it('2/1=2', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +351,9 @@ describe('int', () => { it('0/1=0', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +361,9 @@ describe('int', () => { it('2000/1000=2', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +372,7 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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 +382,7 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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 +393,9 @@ describe('int', () => { it('1%1=0', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +403,9 @@ describe('int', () => { it('500%32=20', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +414,8 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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 +424,8 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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 +435,8 @@ describe('int', () => { it('1<2=true', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +445,8 @@ describe('int', () => { it('1<1=false', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +455,8 @@ describe('int', () => { it('2<1=false', () => { expect(() => { Provable.runAndCheckSync(() => { - 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,11 +465,8 @@ describe('int', () => { it('1000<100000=true', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1000))); - const y = Provable.witness( - UInt64, - () => new UInt64(Field(100000)) - ); + const x = Provable.witness(UInt64, () => new UInt64(1000)); + const y = Provable.witness(UInt64, () => new UInt64(100000)); x.assertLessThan(y); }); }).not.toThrow(); @@ -481,11 +475,8 @@ describe('int', () => { it('100000<1000=false', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness( - UInt64, - () => new UInt64(Field(100000)) - ); - const y = Provable.witness(UInt64, () => new UInt64(Field(1000))); + const x = Provable.witness(UInt64, () => new UInt64(100000)); + const y = Provable.witness(UInt64, () => new UInt64(1000)); x.assertLessThan(y); }); }).toThrow(); @@ -506,8 +497,8 @@ describe('int', () => { it('1<=1=true', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +507,8 @@ describe('int', () => { it('2<=1=false', () => { expect(() => { Provable.runAndCheckSync(() => { - 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,11 +517,8 @@ describe('int', () => { it('1000<=100000=true', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1000))); - const y = Provable.witness( - UInt64, - () => new UInt64(Field(100000)) - ); + const x = Provable.witness(UInt64, () => new UInt64(1000)); + const y = Provable.witness(UInt64, () => new UInt64(100000)); x.assertLessThanOrEqual(y); }); }).not.toThrow(); @@ -539,11 +527,8 @@ describe('int', () => { it('100000<=1000=false', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness( - UInt64, - () => new UInt64(Field(100000)) - ); - const y = Provable.witness(UInt64, () => new UInt64(Field(1000))); + const x = Provable.witness(UInt64, () => new UInt64(100000)); + const y = Provable.witness(UInt64, () => new UInt64(1000)); x.assertLessThanOrEqual(y); }); }).toThrow(); @@ -564,8 +549,8 @@ describe('int', () => { it('2>1=true', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +559,8 @@ describe('int', () => { it('1>1=false', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +569,8 @@ describe('int', () => { it('1>2=false', () => { expect(() => { Provable.runAndCheckSync(() => { - 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(); @@ -594,11 +579,8 @@ describe('int', () => { it('100000>1000=true', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness( - UInt64, - () => new UInt64(Field(100000)) - ); - const y = Provable.witness(UInt64, () => new UInt64(Field(1000))); + const x = Provable.witness(UInt64, () => new UInt64(100000)); + const y = Provable.witness(UInt64, () => new UInt64(1000)); x.assertGreaterThan(y); }); }).not.toThrow(); @@ -607,11 +589,8 @@ describe('int', () => { it('1000>100000=false', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1000))); - const y = Provable.witness( - UInt64, - () => new UInt64(Field(100000)) - ); + const x = Provable.witness(UInt64, () => new UInt64(1000)); + const y = Provable.witness(UInt64, () => new UInt64(100000)); x.assertGreaterThan(y); }); }).toThrow(); @@ -632,8 +611,8 @@ describe('int', () => { it('1<=1=true', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +621,8 @@ describe('int', () => { it('1>=2=false', () => { expect(() => { Provable.runAndCheckSync(() => { - 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(); @@ -652,11 +631,8 @@ describe('int', () => { it('100000>=1000=true', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness( - UInt64, - () => new UInt64(Field(100000)) - ); - const y = Provable.witness(UInt64, () => new UInt64(Field(1000))); + const x = Provable.witness(UInt64, () => new UInt64(100000)); + const y = Provable.witness(UInt64, () => new UInt64(1000)); x.assertGreaterThanOrEqual(y); }); }).not.toThrow(); @@ -665,11 +641,8 @@ describe('int', () => { it('1000>=100000=false', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt64, () => new UInt64(Field(1000))); - const y = Provable.witness( - UInt64, - () => new UInt64(Field(100000)) - ); + const x = Provable.witness(UInt64, () => new UInt64(1000)); + const y = Provable.witness(UInt64, () => new UInt64(100000)); x.assertGreaterThanOrEqual(y); }); }).toThrow(); @@ -692,7 +665,7 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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 +679,7 @@ describe('int', () => { ); const y = Provable.witness( UInt64, - () => new UInt64(Field(String(NUMBERMAX))) + () => new UInt64(String(NUMBERMAX)) ); x.assertEquals(y); }); @@ -718,7 +691,7 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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 +705,7 @@ describe('int', () => { ); const y = Provable.witness( UInt64, - () => new UInt64(Field(String(NUMBERMAX))) + () => new UInt64(String(NUMBERMAX)) ); x.assertEquals(y); }); @@ -745,19 +718,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 +744,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,17 +760,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( - '1000000' - ); + expect(new UInt64(1000).mul(1000).toString()).toEqual('1000000'); }); it('MAXINTx1=MAXINT', () => { @@ -815,15 +786,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 +812,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,33 +832,27 @@ describe('int', () => { describe('lt', () => { it('1<2=true', () => { - expect(new UInt64(Field(1)).lessThan(new UInt64(Field(2)))).toEqual( - Bool(true) - ); + 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( - Bool(false) - ); + 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( - Bool(false) - ); + 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))) - ).toEqual(Bool(true)); + expect(new UInt64(1000).lessThan(new UInt64(100000))).toEqual( + Bool(true) + ); }); it('100000<1000=false', () => { - expect( - new UInt64(Field(100000)).lessThan(new UInt64(Field(1000))) - ).toEqual(Bool(false)); + expect(new UInt64(100000).lessThan(new UInt64(1000))).toEqual( + Bool(false) + ); }); it('MAXINT { @@ -899,27 +864,27 @@ describe('int', () => { describe('lte', () => { it('1<=1=true', () => { - expect( - new UInt64(Field(1)).lessThanOrEqual(new UInt64(Field(1))) - ).toEqual(Bool(true)); + expect(new UInt64(1).lessThanOrEqual(new UInt64(1))).toEqual( + Bool(true) + ); }); it('2<=1=false', () => { - expect( - new UInt64(Field(2)).lessThanOrEqual(new UInt64(Field(1))) - ).toEqual(Bool(false)); + expect(new UInt64(2).lessThanOrEqual(new UInt64(1))).toEqual( + Bool(false) + ); }); it('1000<=100000=true', () => { - expect( - new UInt64(Field(1000)).lessThanOrEqual(new UInt64(Field(100000))) - ).toEqual(Bool(true)); + expect(new UInt64(1000).lessThanOrEqual(new UInt64(100000))).toEqual( + Bool(true) + ); }); it('100000<=1000=false', () => { - expect( - new UInt64(Field(100000)).lessThanOrEqual(new UInt64(Field(1000))) - ).toEqual(Bool(false)); + expect(new UInt64(100000).lessThanOrEqual(new UInt64(1000))).toEqual( + Bool(false) + ); }); it('MAXINT<=MAXINT=true', () => { @@ -932,29 +897,25 @@ 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(); }); @@ -967,33 +928,27 @@ describe('int', () => { describe('greaterThan', () => { it('2>1=true', () => { - expect( - new UInt64(Field(2)).greaterThan(new UInt64(Field(1))) - ).toEqual(Bool(true)); + expect(new UInt64(2).greaterThan(new UInt64(1))).toEqual(Bool(true)); }); it('1>1=false', () => { - expect( - new UInt64(Field(1)).greaterThan(new UInt64(Field(1))) - ).toEqual(Bool(false)); + expect(new UInt64(1).greaterThan(new UInt64(1))).toEqual(Bool(false)); }); it('1>2=false', () => { - expect( - new UInt64(Field(1)).greaterThan(new UInt64(Field(2))) - ).toEqual(Bool(false)); + expect(new UInt64(1).greaterThan(new UInt64(2))).toEqual(Bool(false)); }); it('100000>1000=true', () => { - expect( - new UInt64(Field(100000)).greaterThan(new UInt64(Field(1000))) - ).toEqual(Bool(true)); + expect(new UInt64(100000).greaterThan(new UInt64(1000))).toEqual( + Bool(true) + ); }); it('1000>100000=false', () => { - expect( - new UInt64(Field(1000)).greaterThan(new UInt64(Field(100000))) - ).toEqual(Bool(false)); + expect(new UInt64(1000).greaterThan(new UInt64(100000))).toEqual( + Bool(false) + ); }); it('MAXINT>MAXINT=false', () => { @@ -1005,36 +960,32 @@ describe('int', () => { describe('greaterThanOrEqual', () => { it('2>=1=true', () => { - expect( - new UInt64(Field(2)).greaterThanOrEqual(new UInt64(Field(1))) - ).toEqual(Bool(true)); + expect(new UInt64(2).greaterThanOrEqual(new UInt64(1))).toEqual( + Bool(true) + ); }); it('1>=1=true', () => { - expect( - new UInt64(Field(1)).greaterThanOrEqual(new UInt64(Field(1))) - ).toEqual(Bool(true)); + expect(new UInt64(1).greaterThanOrEqual(new UInt64(1))).toEqual( + Bool(true) + ); }); it('1>=2=false', () => { - expect( - new UInt64(Field(1)).greaterThanOrEqual(new UInt64(Field(2))) - ).toEqual(Bool(false)); + expect(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,29 +999,25 @@ 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,29 +1031,25 @@ 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 +1062,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 +1081,8 @@ 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(1); + aboveMax.value = Field(1n << 64n); expect(() => { UInt64.check(aboveMax); }).toThrow(); @@ -1149,7 +1093,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 +1104,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 +1124,9 @@ describe('int', () => { it('1+1=2', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +1134,15 @@ describe('int', () => { it('5000+5000=10000', () => { expect(() => { Provable.runAndCheckSync(() => { - 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.runAndCheckSync(() => { const x = Provable.witness(UInt32, () => new UInt32(n)); @@ -1212,7 +1156,7 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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 +1167,9 @@ describe('int', () => { it('1-1=0', () => { expect(() => { Provable.runAndCheckSync(() => { - 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(); }); @@ -1233,12 +1177,9 @@ describe('int', () => { it('10000-5000=5000', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness( - UInt32, - () => new UInt32(Field(10000)) - ); - const y = Provable.witness(UInt32, () => new UInt32(Field(5000))); - x.sub(y).assertEquals(new UInt32(Field(5000))); + const x = Provable.witness(UInt32, () => new UInt32(10000)); + const y = Provable.witness(UInt32, () => new UInt32(5000)); + x.sub(y).assertEquals(new UInt32(5000)); }); }).not.toThrow(); }); @@ -1246,8 +1187,8 @@ describe('int', () => { it('should throw on sub if results in negative number', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +1199,9 @@ describe('int', () => { it('1x2=2', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +1209,9 @@ describe('int', () => { it('1x0=0', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +1219,9 @@ describe('int', () => { it('1000x1000=1000000', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +1230,7 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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 +1240,7 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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 +1251,9 @@ describe('int', () => { it('2/1=2', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +1261,9 @@ describe('int', () => { it('0/1=0', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +1271,9 @@ describe('int', () => { it('2000/1000=2', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +1282,7 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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 +1292,7 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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 +1303,9 @@ describe('int', () => { it('1%1=0', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +1313,9 @@ describe('int', () => { it('500%32=20', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +1324,8 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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 +1334,8 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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 +1345,8 @@ describe('int', () => { it('1<2=true', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +1355,8 @@ describe('int', () => { it('1<1=false', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +1365,8 @@ describe('int', () => { it('2<1=false', () => { expect(() => { Provable.runAndCheckSync(() => { - 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,11 +1375,8 @@ describe('int', () => { it('1000<100000=true', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1000))); - const y = Provable.witness( - UInt32, - () => new UInt32(Field(100000)) - ); + const x = Provable.witness(UInt32, () => new UInt32(1000)); + const y = Provable.witness(UInt32, () => new UInt32(100000)); x.assertLessThan(y); }); }).not.toThrow(); @@ -1447,11 +1385,8 @@ describe('int', () => { it('100000<1000=false', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness( - UInt32, - () => new UInt32(Field(100000)) - ); - const y = Provable.witness(UInt32, () => new UInt32(Field(1000))); + const x = Provable.witness(UInt32, () => new UInt32(100000)); + const y = Provable.witness(UInt32, () => new UInt32(1000)); x.assertLessThan(y); }); }).toThrow(); @@ -1472,8 +1407,8 @@ describe('int', () => { it('1<=1=true', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +1417,8 @@ describe('int', () => { it('2<=1=false', () => { expect(() => { Provable.runAndCheckSync(() => { - 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,11 +1427,8 @@ describe('int', () => { it('1000<=100000=true', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1000))); - const y = Provable.witness( - UInt32, - () => new UInt32(Field(100000)) - ); + const x = Provable.witness(UInt32, () => new UInt32(1000)); + const y = Provable.witness(UInt32, () => new UInt32(100000)); x.assertLessThanOrEqual(y); }); }).not.toThrow(); @@ -1505,11 +1437,8 @@ describe('int', () => { it('100000<=1000=false', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness( - UInt32, - () => new UInt32(Field(100000)) - ); - const y = Provable.witness(UInt32, () => new UInt32(Field(1000))); + const x = Provable.witness(UInt32, () => new UInt32(100000)); + const y = Provable.witness(UInt32, () => new UInt32(1000)); x.assertLessThanOrEqual(y); }); }).toThrow(); @@ -1530,8 +1459,8 @@ describe('int', () => { it('2>1=true', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +1469,8 @@ describe('int', () => { it('1>1=false', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +1479,8 @@ describe('int', () => { it('1>2=false', () => { expect(() => { Provable.runAndCheckSync(() => { - 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(); @@ -1560,11 +1489,8 @@ describe('int', () => { it('100000>1000=true', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness( - UInt32, - () => new UInt32(Field(100000)) - ); - const y = Provable.witness(UInt32, () => new UInt32(Field(1000))); + const x = Provable.witness(UInt32, () => new UInt32(100000)); + const y = Provable.witness(UInt32, () => new UInt32(1000)); x.assertGreaterThan(y); }); }).not.toThrow(); @@ -1573,11 +1499,8 @@ describe('int', () => { it('1000>100000=false', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1000))); - const y = Provable.witness( - UInt32, - () => new UInt32(Field(100000)) - ); + const x = Provable.witness(UInt32, () => new UInt32(1000)); + const y = Provable.witness(UInt32, () => new UInt32(100000)); x.assertGreaterThan(y); }); }).toThrow(); @@ -1598,8 +1521,8 @@ describe('int', () => { it('1<=1=true', () => { expect(() => { Provable.runAndCheckSync(() => { - 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 +1531,8 @@ describe('int', () => { it('1>=2=false', () => { expect(() => { Provable.runAndCheckSync(() => { - 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(); @@ -1618,11 +1541,8 @@ describe('int', () => { it('100000>=1000=true', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness( - UInt32, - () => new UInt32(Field(100000)) - ); - const y = Provable.witness(UInt32, () => new UInt32(Field(1000))); + const x = Provable.witness(UInt32, () => new UInt32(100000)); + const y = Provable.witness(UInt32, () => new UInt32(1000)); x.assertGreaterThanOrEqual(y); }); }).not.toThrow(); @@ -1631,11 +1551,8 @@ describe('int', () => { it('1000>=100000=false', () => { expect(() => { Provable.runAndCheckSync(() => { - const x = Provable.witness(UInt32, () => new UInt32(Field(1000))); - const y = Provable.witness( - UInt32, - () => new UInt32(Field(100000)) - ); + const x = Provable.witness(UInt32, () => new UInt32(1000)); + const y = Provable.witness(UInt32, () => new UInt32(100000)); x.assertGreaterThanOrEqual(y); }); }).toThrow(); @@ -1658,7 +1575,7 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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 +1589,7 @@ describe('int', () => { ); const y = Provable.witness( UInt32, - () => new UInt32(Field(String(NUMBERMAX))) + () => new UInt32(String(NUMBERMAX)) ); x.assertEquals(y); }); @@ -1684,7 +1601,7 @@ describe('int', () => { expect(() => { Provable.runAndCheckSync(() => { 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 +1615,7 @@ describe('int', () => { ); const y = Provable.witness( UInt32, - () => new UInt32(Field(String(NUMBERMAX))) + () => new UInt32(String(NUMBERMAX)) ); x.assertEquals(y); }); @@ -1711,19 +1628,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 +1654,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,17 +1670,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( - '1000000' - ); + expect(new UInt32(1000).mul(1000).toString()).toEqual('1000000'); }); it('MAXINTx1=MAXINT', () => { @@ -1781,15 +1696,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 +1722,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,33 +1742,27 @@ describe('int', () => { describe('lessThan', () => { it('1<2=true', () => { - expect(new UInt32(Field(1)).lessThan(new UInt32(Field(2)))).toEqual( - Bool(true) - ); + 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( - Bool(false) - ); + 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( - Bool(false) - ); + 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))) - ).toEqual(Bool(true)); + expect(new UInt32(1000).lessThan(new UInt32(100000))).toEqual( + Bool(true) + ); }); it('100000<1000=false', () => { - expect( - new UInt32(Field(100000)).lessThan(new UInt32(Field(1000))) - ).toEqual(Bool(false)); + expect(new UInt32(100000).lessThan(new UInt32(1000))).toEqual( + Bool(false) + ); }); it('MAXINT { @@ -1865,27 +1774,27 @@ describe('int', () => { describe('lessThanOrEqual', () => { it('1<=1=true', () => { - expect( - new UInt32(Field(1)).lessThanOrEqual(new UInt32(Field(1))) - ).toEqual(Bool(true)); + expect(new UInt32(1).lessThanOrEqual(new UInt32(1))).toEqual( + Bool(true) + ); }); it('2<=1=false', () => { - expect( - new UInt32(Field(2)).lessThanOrEqual(new UInt32(Field(1))) - ).toEqual(Bool(false)); + expect(new UInt32(2).lessThanOrEqual(new UInt32(1))).toEqual( + Bool(false) + ); }); it('1000<=100000=true', () => { - expect( - new UInt32(Field(1000)).lessThanOrEqual(new UInt32(Field(100000))) - ).toEqual(Bool(true)); + expect(new UInt32(1000).lessThanOrEqual(new UInt32(100000))).toEqual( + Bool(true) + ); }); it('100000<=1000=false', () => { - expect( - new UInt32(Field(100000)).lessThanOrEqual(new UInt32(Field(1000))) - ).toEqual(Bool(false)); + expect(new UInt32(100000).lessThanOrEqual(new UInt32(1000))).toEqual( + Bool(false) + ); }); it('MAXINT<=MAXINT=true', () => { @@ -1898,29 +1807,25 @@ 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(); }); @@ -1933,33 +1838,27 @@ describe('int', () => { describe('greaterThan', () => { it('2>1=true', () => { - expect( - new UInt32(Field(2)).greaterThan(new UInt32(Field(1))) - ).toEqual(Bool(true)); + expect(new UInt32(2).greaterThan(new UInt32(1))).toEqual(Bool(true)); }); it('1>1=false', () => { - expect( - new UInt32(Field(1)).greaterThan(new UInt32(Field(1))) - ).toEqual(Bool(false)); + expect(new UInt32(1).greaterThan(new UInt32(1))).toEqual(Bool(false)); }); it('1>2=false', () => { - expect( - new UInt32(Field(1)).greaterThan(new UInt32(Field(2))) - ).toEqual(Bool(false)); + expect(new UInt32(1).greaterThan(new UInt32(2))).toEqual(Bool(false)); }); it('100000>1000=true', () => { - expect( - new UInt32(Field(100000)).greaterThan(new UInt32(Field(1000))) - ).toEqual(Bool(true)); + expect(new UInt32(100000).greaterThan(new UInt32(1000))).toEqual( + Bool(true) + ); }); it('1000>100000=false', () => { - expect( - new UInt32(Field(1000)).greaterThan(new UInt32(Field(100000))) - ).toEqual(Bool(false)); + expect(new UInt32(1000).greaterThan(new UInt32(100000))).toEqual( + Bool(false) + ); }); it('MAXINT>MAXINT=false', () => { @@ -1972,29 +1871,25 @@ 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(); }); @@ -2007,36 +1902,32 @@ describe('int', () => { describe('greaterThanOrEqual', () => { it('2>=1=true', () => { - expect( - new UInt32(Field(2)).greaterThanOrEqual(new UInt32(Field(1))) - ).toEqual(Bool(true)); + expect(new UInt32(2).greaterThanOrEqual(new UInt32(1))).toEqual( + Bool(true) + ); }); it('1>=1=true', () => { - expect( - new UInt32(Field(1)).greaterThanOrEqual(new UInt32(Field(1))) - ).toEqual(Bool(true)); + expect(new UInt32(1).greaterThanOrEqual(new UInt32(1))).toEqual( + Bool(true) + ); }); it('1>=2=false', () => { - expect( - new UInt32(Field(1)).greaterThanOrEqual(new UInt32(Field(2))) - ).toEqual(Bool(false)); + expect(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,29 +1941,25 @@ 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 +1972,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,9 +1991,10 @@ describe('int', () => { }); it('should throw checking over MAXINT', () => { - const x = new UInt32(Field((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(); }); }); @@ -2115,7 +2003,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 +2014,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', () => { diff --git a/src/lib/int.ts b/src/lib/int.ts index 99c0d04e29..0a835246a0 100644 --- a/src/lib/int.ts +++ b/src/lib/int.ts @@ -19,23 +19,43 @@ 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; + let value = Field(x); + super(value); + // check the range if the argument is a constant + UInt64.checkConstant(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 +76,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; } @@ -69,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) + Field.from(max), + this.value ); + return UInt32.Unsafe.fromField(field); } static check(x: UInt64) { @@ -109,20 +130,19 @@ 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 | 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) { + if (x instanceof UInt64) return x; + return new this(x); } /** * 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 +160,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 +178,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 +213,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 +222,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 +231,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 +254,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 +287,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 +319,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 +340,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 +361,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 +390,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 +566,44 @@ 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; + let value = Field(x); + super(value); + // check the range if the argument is a constant + UInt32.checkConstant(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 +622,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 +660,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) { + if (x instanceof UInt32) return x; + return new this(x); } /** * 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 +694,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 +712,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 +744,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 +752,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 +760,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 +783,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 +814,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 +846,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 +869,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 +892,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 +921,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 +1177,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 +1309,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 +1684,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); } /**