o1js
Version:
TypeScript framework for zk-SNARKs and zkApps
52 lines (43 loc) • 1.75 kB
text/typescript
import { expect } from 'expect';
import {
bytesToBigInt,
bigIntToBytes,
bigintToBytes32,
bytesToBigint32,
parseHexString32,
} from './bigint-helpers.js';
import { Fp } from './finite-field.js';
import { Random, test } from '../../lib/testing/property.js';
function testBigintRoundtrip(x: bigint, size: number) {
let bytes = bigIntToBytes(x, size);
let x1 = bytesToBigInt(bytes);
expect(x1).toEqual(x);
if (size === 32) {
let bytes32 = bigintToBytes32(x, new Uint8Array(32));
let x2 = bytesToBigint32(bytes32);
expect(x2).toEqual(x);
}
}
let fieldSize = Math.ceil(Fp.sizeInBits / 8);
testBigintRoundtrip(0n, 1);
testBigintRoundtrip(0n, fieldSize);
testBigintRoundtrip(56n, 2);
testBigintRoundtrip(40n, fieldSize);
testBigintRoundtrip(1309180n, fieldSize);
testBigintRoundtrip(0x10000000n, 4);
testBigintRoundtrip(0xffffffffn, 4);
testBigintRoundtrip(0x10ff00ffffn, fieldSize);
testBigintRoundtrip(Fp.modulus, fieldSize);
test(Random.field, (x) => testBigintRoundtrip(x, fieldSize));
// failure cases
expect(() => bigIntToBytes(256n, 1)).toThrow(/does not fit in 1 bytes/);
expect(() => bigIntToBytes(100_000n, 2)).toThrow(/does not fit in 2 bytes/);
expect(() => bigIntToBytes(4n * Fp.modulus, 32)).toThrow(/does not fit in 32 bytes/);
// parseHexString32
expect(parseHexString32('01' + '00'.repeat(31))).toEqual(1n);
expect(parseHexString32('ff' + '00'.repeat(31))).toEqual(255n);
expect(parseHexString32('0001' + '00'.repeat(30))).toEqual(16n ** 2n);
expect(parseHexString32('0010' + '00'.repeat(30))).toEqual(16n ** 3n);
expect(parseHexString32('00'.repeat(31) + '80')).toEqual(1n << 255n);
expect(parseHexString32('ff'.repeat(32))).toEqual((1n << 256n) - 1n);
console.log('bigint unit tests are passing! 🎉');