o1js
Version:
TypeScript framework for zk-SNARKs and zkApps
1,207 lines (1,050 loc) • 104 kB
text/typescript
import { Experimental, Field } from 'o1js';
const { createProvableBigInt } = Experimental;
// p = 17
// p = PALLAS_PRIME
// p = BLS_PRIME
// p = brainpoolP512r1_PRIME
describe('BigInt17', () => {
const modulus = 17n;
const BigInt17 = createProvableBigInt(modulus);
describe('Creation and Conversion', () => {
it('should correctly create a BigInt17 instance from a bigint and convert back to bigint', () => {
const value = 12n;
const bigInt = BigInt17.fromBigInt(value);
expect(bigInt.toBigInt()).toStrictEqual(value);
});
it('should correctly create a BigInt17 instance from a negative bigint', () => {
const value = -12n;
const bigInt = BigInt17.fromBigInt(value);
expect(bigInt.toBigInt()).toStrictEqual(5n);
});
it('should correctly reduce a number bigger than modulus', () => {
const value = 19n;
const bigInt = BigInt17.fromBigInt(value);
expect(bigInt.toBigInt()).toStrictEqual(2n);
});
it('should correctly create a BigInt17 instance from a maximum bigint', () => {
const value = 16n;
const bigInt = BigInt17.fromBigInt(value);
expect(bigInt.toBigInt()).toStrictEqual(value);
});
it('should correctly convert a BigInt17 instance to bits and convert back to BigInt17', () => {
const value = 11n;
const bigInt = BigInt17.fromBigInt(value);
const bits = bigInt.toBits();
const newBigInt = BigInt17.Unsafe.fromBits(bits);
expect(bigInt.toBigInt()).toStrictEqual(newBigInt.toBigInt());
});
it('should correctly convert a BigInt17 instance to fields and convert back to BigInt17', () => {
const value = 11n;
const bigInt = BigInt17.fromBigInt(value);
const fields = bigInt.toFields();
const newBigInt = BigInt17.Unsafe.fromFields(fields);
expect(bigInt.toBigInt()).toStrictEqual(newBigInt.toBigInt());
});
});
describe('Addition', () => {
it('should correctly add two BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(9n);
const b = BigInt17.fromBigInt(13n);
const result = a.add(b);
expect(result.toBigInt()).toStrictEqual((a.toBigInt() + b.toBigInt()) % modulus);
});
it('should correctly add two zero BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(0n);
const b = BigInt17.fromBigInt(0n);
const result = a.add(b);
expect(result.toBigInt()).toStrictEqual(a.toBigInt() + b.toBigInt());
});
it('should correctly add two maximum BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(modulus - 1n);
const b = BigInt17.fromBigInt(modulus - 1n);
const result = a.add(b);
expect(result.toBigInt()).toStrictEqual((modulus - 1n + (modulus - 1n)) % modulus);
});
it('should satisfy commutativity of addition for BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(13n);
const b = BigInt17.fromBigInt(9n);
expect(a.add(b).equals(b.add(a)).toBoolean()).toStrictEqual(true);
});
it('should satisfy addition with identity element for BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(7n);
const b = BigInt17.fromBigInt(0n);
expect(a.add(b).toBigInt()).toStrictEqual(a.toBigInt());
});
it('should satisfy associativity of addition for BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(3n);
const b = BigInt17.fromBigInt(15n);
const c = BigInt17.fromBigInt(9n);
expect(
a
.add(b)
.add(c)
.equals(a.add(b.add(c)))
.toBoolean()
).toStrictEqual(true);
});
});
describe('Subtraction', () => {
it('should correctly subtract two BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(13n);
const b = BigInt17.fromBigInt(9n);
const result = a.sub(b);
expect(result.toBigInt()).toStrictEqual(a.toBigInt() - (b.toBigInt() % modulus));
});
it('should satisfy subtraction with identity element for BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(9n);
const b = BigInt17.fromBigInt(0n);
expect(a.sub(b).toBigInt()).toStrictEqual(a.toBigInt());
});
it('should correctly subtract two BigInt17 numbers resulting in zero', () => {
const a = BigInt17.fromBigInt(9n);
const b = BigInt17.fromBigInt(9n);
const result = a.sub(b);
expect(result.toBigInt()).toStrictEqual(0n);
});
it('should correctly subtract two max BigInt17 numbers resulting in zero', () => {
const a = BigInt17.fromBigInt(modulus - 1n);
const b = BigInt17.fromBigInt(modulus - 1n);
const result = a.sub(b);
expect(result.toBigInt()).toStrictEqual(0n);
});
it('should correctly subtract two BigInt17 numbers with reduced results', () => {
const a = BigInt17.fromBigInt(3n);
const b = BigInt17.fromBigInt(9n);
const result = a.sub(b);
expect(result.toBigInt()).toStrictEqual(11n);
});
it('should correctly subtract max BigInt17 from zero BigInt17', () => {
const a = BigInt17.zero();
const b = BigInt17.fromBigInt(modulus - 1n);
const result = a.sub(b);
expect(result.toBigInt()).toStrictEqual(1n);
});
it('should correctly subtract max BigInt17 from one BigInt17', () => {
const a = BigInt17.one();
const b = BigInt17.fromBigInt(modulus - 1n);
const result = a.sub(b);
expect(result.toBigInt()).toStrictEqual(2n);
});
});
describe('Multiplication', () => {
it('should correctly multiply two BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(9n);
const b = BigInt17.fromBigInt(7n);
const result = a.mul(b);
expect(result.toBigInt()).toStrictEqual(BigInt(a.toBigInt() * b.toBigInt()) % modulus);
});
it('should correctly multiply two BigInt17 numbers with small values', () => {
const a = BigInt17.fromBigInt(2n);
const b = BigInt17.fromBigInt(3n);
const result = a.mul(b);
expect(result.toBigInt()).toStrictEqual(BigInt(a.toBigInt() * b.toBigInt()) % modulus);
});
it('should correctly multiply two max BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(modulus - 1n);
const b = BigInt17.fromBigInt(modulus - 1n);
const result = a.mul(b);
expect(result.toBigInt()).toStrictEqual(BigInt(a.toBigInt() * b.toBigInt()) % modulus);
});
it('should satisfy multiplication with identity element for BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(12n);
const b = BigInt17.fromBigInt(1n);
expect(a.mul(b).toBigInt()).toStrictEqual(a.toBigInt());
});
it('should satisfy multiplication with zero for BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(12n);
const b = BigInt17.fromBigInt(0n);
expect(a.mul(b).toBigInt()).toStrictEqual(b.toBigInt()); // not equal when not using toBigints
});
it('should satisfy multiplication with zero commuted for BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(7n);
const b = BigInt17.fromBigInt(0n);
expect(a.mul(b).toBigInt()).toStrictEqual(b.toBigInt());
});
it('should satisfy commutativity of multiplication for BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(3n);
const b = BigInt17.fromBigInt(4n);
expect(a.mul(b).equals(b.mul(a)).toBoolean()).toStrictEqual(true);
});
it('should satisfy associativity of multiplication for BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(3n);
const b = BigInt17.fromBigInt(5n);
const c = BigInt17.fromBigInt(11n);
expect(a.mul(b.mul(c)).equals(a.mul(b).mul(c)).toBoolean()).toStrictEqual(true);
});
it('should satisfy distributivity of multiplication over addition for BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(4n);
const b = BigInt17.fromBigInt(7n);
const c = BigInt17.fromBigInt(13n);
expect(
a
.mul(b.add(c))
.equals(a.mul(b).add(a.mul(c)))
.toBoolean()
).toStrictEqual(true);
});
});
//! We should test (a * y^-1) % p
// The inverse logic is included in the witness and can't be used here
// as a utility for testing
describe('Division', () => {
it('should correctly divide two BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(10n);
const b = BigInt17.fromBigInt(3n);
const result = a.div(b);
expect(result.mul(b).toBigInt()).toStrictEqual(a.toBigInt());
});
it('should satisfy division with identity element for BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(13n);
const b = BigInt17.fromBigInt(1n);
const result = a.div(b);
expect(result.toBigInt()).toStrictEqual(a.toBigInt());
});
it('should throw a division by zero error ', () => {
const a = BigInt17.fromBigInt(13n);
const b = BigInt17.fromBigInt(0n);
expect(() => a.div(b)).toThrowError();
});
it('should correctly divide two BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(3n);
const b = BigInt17.fromBigInt(10n);
const result = a.div(b);
expect(result.toBigInt()).toStrictEqual(2n);
});
});
describe('Square root', () => {
it('should correctly take square root of a ProvableBigInt', () => {
const a = BigInt17.fromBigInt(4n);
const result = a.sqrt();
expect(result.toBigInt()).toStrictEqual(2n);
});
it('should correctly take square root of a ProvableBigInt', () => {
const a = BigInt17.fromBigInt(9n);
const result = a.sqrt();
expect(result.toBigInt()).toStrictEqual(14n); // 14² ≡ 9 (mod 17)
});
it('should correctly take square root of a ProvableBigInt', () => {
const a = BigInt17.fromBigInt(16n);
const result = a.sqrt();
expect(result.toBigInt()).toStrictEqual(4n);
});
it('should correctly take square root of 1', () => {
const a = BigInt17.fromBigInt(1n);
const result = a.sqrt();
expect(result.toBigInt()).toStrictEqual(1n);
});
it('should correctly take square root of 0', () => {
const a = BigInt17.fromBigInt(0n);
const result = a.sqrt();
expect(result.toBigInt()).toStrictEqual(0n);
});
it('should throw when square root does not exist', () => {
const a = BigInt17.fromBigInt(5n);
expect(() => a.sqrt()).toThrowError();
});
});
describe('Negate', () => {
it('should correctly compute the additive inverse of a ProvableBigInt', () => {
const a = BigInt17.fromBigInt(9n);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual(modulus - a.toBigInt());
});
it('should correctly compute the additive inverse of 0', () => {
const a = BigInt17.fromBigInt(0n);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual(0n);
});
it('should correctly compute the additive inverse of a large number', () => {
const a = BigInt17.fromBigInt(modulus - 1n);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual(1n);
});
it('should correctly compute the additive inverse of 1', () => {
const a = BigInt17.fromBigInt(1n);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual(modulus - 1n);
});
it('should correctly compute the additive inverse of a random number', () => {
const a = BigInt17.fromBigInt(1234567890123456789012345678901234567890n % modulus);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual((modulus - a.toBigInt()) % modulus);
});
it('should correctly compute the additive inverse of a negative number', () => {
const a = BigInt17.fromBigInt(-5n);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual((modulus - a.toBigInt()) % modulus);
});
it('should correctly compute the additive inverse of the modulus itself', () => {
const a = BigInt17.fromBigInt(modulus);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual(0n);
});
it('should correctly compute the additive inverse of a number greater than the modulus', () => {
const a = BigInt17.fromBigInt(modulus + 5n);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual((modulus - (a.toBigInt() % modulus)) % modulus);
});
it('should correctly compute the additive inverse of a number much larger than the modulus', () => {
const a = BigInt17.fromBigInt(987654321098765432109876543210987654321n);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual((modulus - (a.toBigInt() % modulus)) % modulus);
});
});
describe('Inverse', () => {
it('should correctly compute the modular inverse of a ProvableBigInt', () => {
const a = BigInt17.fromBigInt(2n);
const result = a.inverse();
expect(result.toBigInt()).toStrictEqual(9n);
});
it('should correctly compute the modular inverse of 1', () => {
const a = BigInt17.fromBigInt(1n);
const result = a.inverse();
expect(result.toBigInt()).toStrictEqual(1n);
});
it('should correctly compute the modular inverse of a large number', () => {
const a = BigInt17.fromBigInt(modulus - 1n);
const result = a.inverse();
expect(result.toBigInt()).toStrictEqual(modulus - 1n); // 16 * 16 ≡ 1 (mod 17)
});
it('should correctly compute the modular inverse of a random number', () => {
const a = BigInt17.fromBigInt(1234567890123456789012345678901234567890n % modulus);
const result = a.inverse();
const expected =
(BigInt(1234567890123456789012345678901234567890n) % modulus) ** (modulus - 2n) % modulus;
expect(result.toBigInt()).toStrictEqual(expected);
});
it('should correctly compute the modular inverse of a negative number', () => {
const a = BigInt17.fromBigInt(-5n);
const result = a.inverse();
const expected = (modulus - (BigInt(5n) % modulus)) ** (modulus - 2n) % modulus;
expect(result.toBigInt()).toStrictEqual(expected);
});
it('should correctly compute the modular inverse of the modulus itself', () => {
const a = BigInt17.fromBigInt(modulus);
expect(() => a.inverse()).toThrowError('a is not invertible');
});
it('should correctly compute the modular inverse of a number greater than the modulus', () => {
const a = BigInt17.fromBigInt(modulus + 5n);
const result = a.inverse();
const expected = BigInt(5n) ** (modulus - 2n) % modulus;
expect(result.toBigInt()).toStrictEqual(expected);
});
it('should correctly compute the modular inverse of a number much larger than the modulus', () => {
const a = BigInt17.fromBigInt(987654321098765432109876543210987654320n);
const result = a.inverse();
const expected =
(BigInt(987654321098765432109876543210987654320n) % modulus) ** (modulus - 2n) % modulus;
expect(result.toBigInt()).toStrictEqual(expected);
});
it('should correctly compute the modular inverse of 0', () => {
const a = BigInt17.fromBigInt(0n);
expect(() => a.inverse()).toThrowError('a is not invertible');
});
});
describe('Power', () => {
it('should correctly compute the power of a ProvableBigInt with exponent 0', () => {
const base = BigInt17.fromBigInt(5n);
const exponent = BigInt17.fromBigInt(0n);
const result = base.pow(exponent);
expect(result.toBigInt()).toStrictEqual(
BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus))
); // 5^0 ≡ 1 (mod 17)
});
it('should correctly compute the power of a ProvableBigInt with exponent 1', () => {
const base = BigInt17.fromBigInt(5n);
const exponent = BigInt17.fromBigInt(1n);
const result = base.pow(exponent);
expect(result.toBigInt()).toStrictEqual(
BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus))
); // 5^1 ≡ 5 (mod 17)
});
it('should correctly compute the power of a ProvableBigInt with a small exponent', () => {
const base = BigInt17.fromBigInt(12n);
const exponent = BigInt17.fromBigInt(2n);
const result = base.pow(exponent);
expect(result.toBigInt()).toStrictEqual(
BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus))
); // 12^2 ≡ 144 ≡ 8 (mod 17)
});
it('should correctly compute the power of a ProvableBigInt with a large exponent', () => {
const base = BigInt17.fromBigInt(3n);
const exponent = BigInt17.fromBigInt(16n);
const result = base.pow(exponent);
expect(result.toBigInt()).toStrictEqual(
BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus))
); // 3^16 % 17
});
it('should correctly compute the power of a ProvableBigInt with a large base and exponent', () => {
const base = BigInt17.fromBigInt(16n);
const exponent = BigInt17.fromBigInt(16n);
const result = base.pow(exponent);
expect(result.toBigInt()).toStrictEqual(
BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus))
); // 16^16 % 17
});
it('should correctly compute the power of a ProvableBigInt with a negative exponent', () => {
const base = BigInt17.fromBigInt(3n);
const exponent = BigInt17.fromBigInt(-1n);
const result = base.pow(exponent);
const expected = BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus));
expect(result.toBigInt()).toStrictEqual(expected);
});
it('should correctly compute the power of a ProvableBigInt with a random base and exponent', () => {
const base = BigInt17.fromBigInt(7n);
const exponent = BigInt17.fromBigInt(5n);
const result = base.pow(exponent);
const expected = BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus));
expect(result.toBigInt()).toStrictEqual(expected);
});
it('should correctly compute the power of a ProvableBigInt with a very large base and small exponent', () => {
const base = BigInt17.fromBigInt(987654321098765432109876543210987654321n);
const exponent = BigInt17.fromBigInt(2n);
const result = base.pow(exponent);
const expected = BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus));
expect(result.toBigInt()).toStrictEqual(expected);
});
it('should correctly compute the power of a ProvableBigInt with a small base and very large exponent', () => {
const base = BigInt17.fromBigInt(2n);
const exponent = BigInt17.fromBigInt(987654321098765432109876543210987654321n);
const result = base.pow(exponent);
const expected = BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus));
expect(result.toBigInt()).toStrictEqual(expected);
});
it('should correctly compute the power of a ProvableBigInt with both base and exponent being very large', () => {
const base = BigInt17.fromBigInt(987654321098765432109876543210987654321n);
const exponent = BigInt17.fromBigInt(987654321098765432109876543210987654321n);
const result = base.pow(exponent);
const expected = BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus));
expect(result.toBigInt()).toStrictEqual(expected);
});
});
describe('Comparison', () => {
it('should correctly compare two BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(13n);
const b = BigInt17.fromBigInt(12n);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(true);
expect(a.lessThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(false);
expect(a.equals(b).toBoolean()).toStrictEqual(false);
});
it('should correctly check equality of two BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(11n);
const b = BigInt17.fromBigInt(11n);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(false);
expect(a.lessThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.equals(b).toBoolean()).toStrictEqual(true);
});
it('should correctly compare BigInt17 numbers with zero', () => {
const a = BigInt17.fromBigInt(0n);
const b = BigInt17.fromBigInt(16n);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(false);
expect(a.lessThan(b).toBoolean()).toStrictEqual(true);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(false);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.equals(b).toBoolean()).toStrictEqual(false);
});
it('should correctly compare BigInt17 numbers with modulus', () => {
const a = BigInt17.fromBigInt(17n);
const b = BigInt17.fromBigInt(1n);
expect(a.lessThan(b).toBoolean()).toStrictEqual(true);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(false);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.equals(b).toBoolean()).toStrictEqual(false);
});
it('should correctly compare negative BigInt17 numbers', () => {
const a = BigInt17.fromBigInt(-1n); // -1 mod 17 = 16
const b = BigInt17.fromBigInt(16n);
expect(a.lessThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.equals(b).toBoolean()).toStrictEqual(true);
});
it('should correctly compare BigInt17 numbers with random values', () => {
const a = BigInt17.fromBigInt(7n);
const b = BigInt17.fromBigInt(5n);
expect(a.lessThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(true);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(false);
expect(a.equals(b).toBoolean()).toStrictEqual(false);
});
it('should correctly compare BigInt17 numbers with equal values', () => {
const a = BigInt17.fromBigInt(8n);
const b = BigInt17.fromBigInt(8n);
expect(a.lessThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.equals(b).toBoolean()).toStrictEqual(true);
});
it('should correctly compare BigInt17 numbers with one being zero', () => {
const a = BigInt17.fromBigInt(0n);
const b = BigInt17.fromBigInt(0n);
expect(a.lessThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.equals(b).toBoolean()).toStrictEqual(true);
});
it('should correctly compare BigInt17 numbers with one being the modulus', () => {
const a = BigInt17.fromBigInt(17n);
const b = BigInt17.fromBigInt(0n);
expect(a.lessThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.equals(b).toBoolean()).toStrictEqual(true);
});
});
});
describe('BigInt255', () => {
const modulus = Field.ORDER;
const BigInt255 = createProvableBigInt(modulus);
describe('Creation and Conversion', () => {
it('should correctly create a BigInt255 instance from a bigint and convert back to bigint', () => {
const value = 12n;
const bigInt = BigInt255.fromBigInt(value);
expect(bigInt.toBigInt()).toStrictEqual(value);
});
it('should correctly create a BigInt255 instance from a negative bigint', () => {
const value = -12n;
const bigInt = BigInt255.fromBigInt(value);
expect(bigInt.toBigInt()).toStrictEqual(value + modulus);
});
it('should correctly reduce a number bigger than modulus', () => {
const value = modulus + 79n;
const bigInt = BigInt255.fromBigInt(value);
expect(bigInt.toBigInt()).toStrictEqual(value % modulus);
});
it('should correctly create a BigInt255 instance from a maximum bigint', () => {
const value = modulus - 1n;
const bigInt = BigInt255.fromBigInt(value);
expect(bigInt.toBigInt()).toStrictEqual(value);
});
it('should correctly convert a BigInt255 instance to bits and convert back to BigInt255', () => {
const value = Field.random().toBigInt();
const bigInt = BigInt255.fromBigInt(value);
const bits = bigInt.toBits();
const newBigInt = BigInt255.Unsafe.fromBits(bits);
expect(bigInt.toBigInt()).toStrictEqual(newBigInt.toBigInt());
});
it('should correctly convert a BigInt255 instance to fields and convert back to BigInt255', () => {
const value = Field.random().toBigInt();
const bigInt = BigInt255.fromBigInt(value);
const fields = bigInt.toFields();
const newBigInt = BigInt255.Unsafe.fromFields(fields);
expect(bigInt.toBigInt()).toStrictEqual(newBigInt.toBigInt());
});
});
describe('Addition', () => {
it('should correctly add two BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(9n);
const b = BigInt255.fromBigInt(13n);
const result = a.add(b);
expect(result.toBigInt()).toStrictEqual((a.toBigInt() + b.toBigInt()) % modulus);
});
it('should correctly add two zero BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(0n);
const b = BigInt255.fromBigInt(0n);
const result = a.add(b);
expect(result.toBigInt()).toStrictEqual(a.toBigInt() + b.toBigInt());
});
it('should correctly add two maximum BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(modulus - 1n);
const b = BigInt255.fromBigInt(modulus - 1n);
const result = a.add(b);
expect(result.toBigInt()).toStrictEqual((modulus - 1n + (modulus - 1n)) % modulus);
});
it('should satisfy commutativity of addition for BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(13n);
const b = BigInt255.fromBigInt(9n);
expect(a.add(b).equals(b.add(a)).toBoolean()).toStrictEqual(true);
});
it('should satisfy addition with identity element for BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(7n);
const b = BigInt255.fromBigInt(0n);
expect(a.add(b).toBigInt()).toStrictEqual(a.toBigInt());
});
it('should satisfy associativity of addition for BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(3n);
const b = BigInt255.fromBigInt(15n);
const c = BigInt255.fromBigInt(9n);
expect(
a
.add(b)
.add(c)
.equals(a.add(b.add(c)))
.toBoolean()
).toStrictEqual(true);
});
});
describe('Subtraction', () => {
it('should correctly subtract two BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(13n);
const b = BigInt255.fromBigInt(9n);
const result = a.sub(b);
expect(result.toBigInt()).toStrictEqual(a.toBigInt() - (b.toBigInt() % modulus));
});
it('should satisfy subtraction with identity element for BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(9n);
const b = BigInt255.fromBigInt(0n);
expect(a.sub(b).toBigInt()).toStrictEqual(a.toBigInt());
});
it('should correctly subtract two BigInt255 numbers resulting in zero', () => {
const a = BigInt255.fromBigInt(9n);
const b = BigInt255.fromBigInt(9n);
const result = a.sub(b);
expect(result.toBigInt()).toStrictEqual(0n);
});
it('should correctly subtract two max BigInt255 numbers resulting in zero', () => {
const a = BigInt255.fromBigInt(modulus - 1n);
const b = BigInt255.fromBigInt(modulus - 1n);
const result = a.sub(b);
expect(result.toBigInt()).toStrictEqual(0n);
});
it('should correctly subtract two BigInt255 numbers with reduced results', () => {
const a = BigInt255.fromBigInt(3n);
const b = BigInt255.fromBigInt(9n);
const result = a.sub(b);
expect(result.toBigInt()).toStrictEqual(a.toBigInt() - b.toBigInt() + modulus);
});
it('should correctly subtract max BigInt255 from zero BigInt255', () => {
const a = BigInt255.zero();
const b = BigInt255.fromBigInt(modulus - 1n);
const result = a.sub(b);
expect(result.toBigInt()).toStrictEqual(a.toBigInt() - b.toBigInt() + modulus);
});
it('should correctly subtract max BigInt255 from one BigInt255', () => {
const a = BigInt255.one();
const b = BigInt255.fromBigInt(modulus - 1n);
const result = a.sub(b);
expect(result.toBigInt()).toStrictEqual(a.toBigInt() - b.toBigInt() + modulus);
});
});
describe('Multiplication', () => {
it('should correctly multiply two BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(9n);
const b = BigInt255.fromBigInt(7n);
const result = a.mul(b);
expect(result.toBigInt()).toStrictEqual(BigInt(a.toBigInt() * b.toBigInt()) % modulus);
});
it('should correctly multiply two BigInt255 numbers with small values', () => {
const a = BigInt255.fromBigInt(2n);
const b = BigInt255.fromBigInt(3n);
const result = a.mul(b);
expect(result.toBigInt()).toStrictEqual(BigInt(a.toBigInt() * b.toBigInt()) % modulus);
});
it('should correctly multiply two max BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(modulus - 1n);
const b = BigInt255.fromBigInt(modulus - 1n);
const result = a.mul(b);
expect(result.toBigInt()).toStrictEqual(BigInt(a.toBigInt() * b.toBigInt()) % modulus);
});
it('should satisfy multiplication with identity element for BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(12n);
const b = BigInt255.fromBigInt(1n);
expect(a.mul(b).toBigInt()).toStrictEqual(a.toBigInt());
});
it('should satisfy multiplication with zero for BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(12n);
const b = BigInt255.fromBigInt(0n);
expect(a.mul(b).toBigInt()).toStrictEqual(b.toBigInt()); // not equal when not using toBigints
});
it('should satisfy multiplication with zero commuted for BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(7n);
const b = BigInt255.fromBigInt(0n);
expect(a.mul(b).toBigInt()).toStrictEqual(b.toBigInt());
});
it('should satisfy commutativity of multiplication for BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(3n);
const b = BigInt255.fromBigInt(4n);
expect(a.mul(b).equals(b.mul(a)).toBoolean()).toStrictEqual(true);
});
it('should satisfy associativity of multiplication for BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(3n);
const b = BigInt255.fromBigInt(5n);
const c = BigInt255.fromBigInt(11n);
expect(a.mul(b.mul(c)).equals(a.mul(b).mul(c)).toBoolean()).toStrictEqual(true);
});
it('should satisfy distributivity of multiplication over addition for BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(4n);
const b = BigInt255.fromBigInt(7n);
const c = BigInt255.fromBigInt(13n);
expect(
a
.mul(b.add(c))
.equals(a.mul(b).add(a.mul(c)))
.toBoolean()
).toStrictEqual(true);
});
});
//! We should test (a * y^-1) % p
// The inverse logic is included in the witness and can't be used here
// as a utility for testing
describe('Division', () => {
it('should correctly divide two BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(10n);
const b = BigInt255.fromBigInt(3n);
const result = a.div(b);
expect(result.mul(b).toBigInt()).toStrictEqual(a.toBigInt());
});
it('should satisfy division with identity element for BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(13n);
const b = BigInt255.fromBigInt(1n);
const result = a.div(b);
expect(result.toBigInt()).toStrictEqual(a.toBigInt());
});
it('should throw a division by zero error ', () => {
const a = BigInt255.fromBigInt(13n);
const b = BigInt255.fromBigInt(0n);
expect(() => a.div(b)).toThrowError();
});
it('should correctly divide two BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(3n);
const b = BigInt255.fromBigInt(10n);
const result = a.div(b);
expect(result.toBigInt()).toStrictEqual((3n * modularInverse(10n, modulus)) % modulus);
});
});
describe('Square root', () => {
it('should correctly take square root of a ProvableBigInt', () => {
const a = BigInt255.fromBigInt(4n);
const result = a.sqrt();
expect(modularExponentiation(result.toBigInt(), 2n, modulus)).toStrictEqual(a.toBigInt());
});
it('should correctly take square root of a ProvableBigInt', () => {
const a = BigInt255.fromBigInt(9n);
const result = a.sqrt();
expect(modularExponentiation(result.toBigInt(), 2n, modulus)).toStrictEqual(a.toBigInt());
});
it('should correctly take square root of a ProvableBigInt', () => {
const a = BigInt255.fromBigInt(16n);
const result = a.sqrt();
expect(modularExponentiation(result.toBigInt(), 2n, modulus)).toStrictEqual(a.toBigInt());
});
it('should correctly take square root of 1', () => {
const a = BigInt255.fromBigInt(1n);
const result = a.sqrt();
expect(result.toBigInt()).toStrictEqual(1n);
});
it('should correctly take square root of 0', () => {
const a = BigInt255.fromBigInt(0n);
const result = a.sqrt();
expect(result.toBigInt()).toStrictEqual(0n);
});
it('should throw when square root does not exist', () => {
const a = BigInt255.fromBigInt(5n);
expect(() => a.sqrt()).toThrowError();
});
});
describe('Negate', () => {
it('should correctly compute the additive inverse of a ProvableBigInt', () => {
const a = BigInt255.fromBigInt(9n);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual(modulus - a.toBigInt());
});
it('should correctly compute the additive inverse of 0', () => {
const a = BigInt255.fromBigInt(0n);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual(0n);
});
it('should correctly compute the additive inverse of a large number', () => {
const a = BigInt255.fromBigInt(modulus - 1n);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual(1n);
});
it('should correctly compute the additive inverse of 1', () => {
const a = BigInt255.fromBigInt(1n);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual(modulus - 1n);
});
it('should correctly compute the additive inverse of a random number', () => {
const a = BigInt255.fromBigInt(1234567890123456789012345678901234567890n % modulus);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual((modulus - a.toBigInt()) % modulus);
});
it('should correctly compute the additive inverse of a negative number', () => {
const a = BigInt255.fromBigInt(-5n);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual((modulus - a.toBigInt()) % modulus);
});
it('should correctly compute the additive inverse of the modulus itself', () => {
const a = BigInt255.fromBigInt(modulus);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual(0n);
});
it('should correctly compute the additive inverse of a number greater than the modulus', () => {
const a = BigInt255.fromBigInt(modulus + 5n);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual((modulus - (a.toBigInt() % modulus)) % modulus);
});
it('should correctly compute the additive inverse of a number much larger than the modulus', () => {
const a = BigInt255.fromBigInt(987654321098765432109876543210987654321n);
const result = a.negate();
expect(result.toBigInt()).toStrictEqual((modulus - (a.toBigInt() % modulus)) % modulus);
});
});
describe('Inverse', () => {
it('should correctly compute the modular inverse of a ProvableBigInt', () => {
const a = BigInt255.fromBigInt(2n);
const result = a.inverse();
expect(result.toBigInt()).toStrictEqual(modularInverse(2n, modulus));
});
it('should correctly compute the modular inverse of 1', () => {
const a = BigInt255.fromBigInt(1n);
const result = a.inverse();
expect(result.toBigInt()).toStrictEqual(1n);
});
it('should correctly compute the modular inverse of a large number', () => {
const a = BigInt255.fromBigInt(modulus - 1n);
const result = a.inverse();
expect(result.toBigInt()).toStrictEqual(modulus - 1n); // 16 * 16 ≡ 1 (mod 17)
});
it('should correctly compute the modular inverse of a random number', () => {
const a = BigInt255.fromBigInt(1234567890123456789012345678901234567890n % modulus);
const result = a.inverse();
const expected = modularInverse(a.toBigInt(), modulus);
expect(result.toBigInt()).toStrictEqual(expected);
});
it('should correctly compute the modular inverse of a negative number', () => {
const a = BigInt255.fromBigInt(-5n);
const result = a.inverse();
const expected = modularInverse(a.toBigInt(), modulus);
expect(result.toBigInt()).toStrictEqual(expected);
});
it('should correctly compute the modular inverse of the modulus itself', () => {
const a = BigInt255.fromBigInt(modulus);
expect(() => a.inverse()).toThrowError('a is not invertible');
});
it('should correctly compute the modular inverse of a number greater than the modulus', () => {
const a = BigInt255.fromBigInt(modulus + 5n);
const result = a.inverse();
const expected = modularInverse(a.toBigInt(), modulus);
expect(result.toBigInt()).toStrictEqual(expected);
});
it('should correctly compute the modular inverse of a number much larger than the modulus', () => {
const a = BigInt255.fromBigInt(987654321098765432109876543210987654320n);
const result = a.inverse();
const expected = modularInverse(a.toBigInt(), modulus);
expect(result.toBigInt()).toStrictEqual(expected);
});
it('should correctly compute the modular inverse of 0', () => {
const a = BigInt255.fromBigInt(0n);
expect(() => a.inverse()).toThrowError('a is not invertible');
});
});
describe('Power', () => {
it('should correctly compute the power of a ProvableBigInt with exponent 0', () => {
const base = BigInt255.fromBigInt(5n);
const exponent = BigInt255.fromBigInt(0n);
const result = base.pow(exponent);
expect(result.toBigInt()).toStrictEqual(
BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus))
); // 5^0 ≡ 1 (mod 17)
});
it('should correctly compute the power of a ProvableBigInt with exponent 1', () => {
const base = BigInt255.fromBigInt(5n);
const exponent = BigInt255.fromBigInt(1n);
const result = base.pow(exponent);
expect(result.toBigInt()).toStrictEqual(
BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus))
); // 5^1 ≡ 5 (mod 17)
});
it('should correctly compute the power of a ProvableBigInt with a small exponent', () => {
const base = BigInt255.fromBigInt(12n);
const exponent = BigInt255.fromBigInt(2n);
const result = base.pow(exponent);
expect(result.toBigInt()).toStrictEqual(
BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus))
); // 12^2 ≡ 144 ≡ 8 (mod 17)
});
it('should correctly compute the power of a ProvableBigInt with a large exponent', () => {
const base = BigInt255.fromBigInt(3n);
const exponent = BigInt255.fromBigInt(16n);
const result = base.pow(exponent);
expect(result.toBigInt()).toStrictEqual(
BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus))
); // 3^16 % 17
});
it('should correctly compute the power of a ProvableBigInt with a large base and exponent', () => {
const base = BigInt255.fromBigInt(16n);
const exponent = BigInt255.fromBigInt(16n);
const result = base.pow(exponent);
expect(result.toBigInt()).toStrictEqual(
BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus))
); // 16^16 % 17
});
it('should correctly compute the power of a ProvableBigInt with a negative exponent', () => {
const base = BigInt255.fromBigInt(3n);
const exponent = BigInt255.fromBigInt(-1n);
const result = base.pow(exponent);
const expected = BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus));
expect(result.toBigInt()).toStrictEqual(expected);
});
it('should correctly compute the power of a ProvableBigInt with a random base and exponent', () => {
const base = BigInt255.fromBigInt(7n);
const exponent = BigInt255.fromBigInt(5n);
const result = base.pow(exponent);
const expected = BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus));
expect(result.toBigInt()).toStrictEqual(expected);
});
it('should correctly compute the power of a ProvableBigInt with a very large base and small exponent', () => {
const base = BigInt255.fromBigInt(987654321098765432109876543210987654321n);
const exponent = BigInt255.fromBigInt(2n);
const result = base.pow(exponent);
const expected = BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus));
expect(result.toBigInt()).toStrictEqual(expected);
});
it('should correctly compute the power of a ProvableBigInt with a small base and very large exponent', () => {
const base = BigInt255.fromBigInt(2n);
const exponent = BigInt255.fromBigInt(987654321098765432109876543210987654321n);
const result = base.pow(exponent);
const expected = BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus));
expect(result.toBigInt()).toStrictEqual(expected);
});
it('should correctly compute the power of a ProvableBigInt with both base and exponent being very large', () => {
const base = BigInt255.fromBigInt(987654321098765432109876543210987654321n);
const exponent = BigInt255.fromBigInt(987654321098765432109876543210987654321n);
const result = base.pow(exponent);
const expected = BigInt(modularExponentiation(base.toBigInt(), exponent.toBigInt(), modulus));
expect(result.toBigInt()).toStrictEqual(expected);
});
});
describe('Comparison', () => {
it('should correctly compare two BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(13n);
const b = BigInt255.fromBigInt(12n);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(true);
expect(a.lessThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(false);
expect(a.equals(b).toBoolean()).toStrictEqual(false);
});
it('should correctly check equality of two BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(11n);
const b = BigInt255.fromBigInt(11n);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(false);
expect(a.lessThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.equals(b).toBoolean()).toStrictEqual(true);
});
it('should correctly compare BigInt255 numbers with zero', () => {
const a = BigInt255.fromBigInt(0n);
const b = BigInt255.fromBigInt(16n);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(false);
expect(a.lessThan(b).toBoolean()).toStrictEqual(true);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(false);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.equals(b).toBoolean()).toStrictEqual(false);
});
it('should correctly compare BigInt255 numbers with modulus', () => {
const a = BigInt255.fromBigInt(modulus);
const b = BigInt255.fromBigInt(1n);
expect(a.lessThan(b).toBoolean()).toStrictEqual(true);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(false);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.equals(b).toBoolean()).toStrictEqual(false);
});
it('should correctly compare negative BigInt255 numbers', () => {
const a = BigInt255.fromBigInt(-1n); // -1 mod 17 = 16
const b = BigInt255.fromBigInt(modulus - 1n);
expect(a.lessThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.equals(b).toBoolean()).toStrictEqual(true);
});
it('should correctly compare BigInt255 numbers with random values', () => {
const a = BigInt255.fromBigInt(7n);
const b = BigInt255.fromBigInt(5n);
expect(a.lessThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(true);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(false);
expect(a.equals(b).toBoolean()).toStrictEqual(false);
});
it('should correctly compare BigInt255 numbers with equal values', () => {
const a = BigInt255.fromBigInt(8n);
const b = BigInt255.fromBigInt(8n);
expect(a.lessThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.equals(b).toBoolean()).toStrictEqual(true);
});
it('should correctly compare BigInt255 numbers with one being zero', () => {
const a = BigInt255.fromBigInt(0n);
const b = BigInt255.fromBigInt(0n);
expect(a.lessThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.equals(b).toBoolean()).toStrictEqual(true);
});
it('should correctly compare BigInt255 numbers with one being the modulus', () => {
const a = BigInt255.fromBigInt(modulus);
const b = BigInt255.fromBigInt(0n);
expect(a.lessThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.equals(b).toBoolean()).toStrictEqual(true);
});
it('should correctly compare BigInt255 numbers properly', () => {
const a = BigInt255.Unsafe.fromFields([
new Field(1),
new Field(3),
new Field(3),
new Field(0),
]);
const b = BigInt255.Unsafe.fromFields([
new Field(1),
new Field(2),
new Field(4),
new Field(0),
]);
expect(a.equals(b).toBoolean()).toStrictEqual(false);
expect(a.lessThan(b).toBoolean()).toStrictEqual(true);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(false);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(false);
});
it('should correctly compare BigInt255 numbers properly', () => {
const a = BigInt255.Unsafe.fromFields([
new Field(1),
new Field(0),
new Field(4),
new Field(0),
]);
const b = BigInt255.Unsafe.fromFields([
new Field(1),
new Field(18446744073709551615n),
new Field(1),
new Field(0),
]);
expect(a.equals(b).toBoolean()).toStrictEqual(false);
expect(a.lessThan(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThanOrEqual(b).toBoolean()).toStrictEqual(true);
expect(a.lessThanOrEqual(b).toBoolean()).toStrictEqual(false);
expect(a.greaterThan(b).toBoolean()).toStrictEqual(true);
});
it('should correctly compare BigInt255 numbers properly', () => {
const a = BigInt255.Unsafe.fromFields([
new Field(18446744073709551615n),
new Field(1),
new Field(1),
new Field(0),
]);
const b = BigInt255.Unsafe.fromFields([
new Field(1),
new Field(1),
new Field(2),
new Fiel