UNPKG

o1js

Version:

TypeScript framework for zk-SNARKs and zkApps

194 lines (161 loc) 5.31 kB
import { Bool, Provable, Int64, Struct, Field, PrivateKey, PublicKey, } from 'o1js'; describe('Provable', () => { it('Provable.if out of snark', () => { let x = Provable.if(Bool(false), Int64, Int64.from(-1), Int64.from(-2)); expect(x.toString()).toBe('-2'); }); it('Provable.if in snark', async () => { await Provable.runAndCheck(() => { let x = Provable.witness(Int64, () => Int64.from(-1)); let y = Provable.witness(Int64, () => Int64.from(-2)); let b = Provable.witness(Bool, () => Bool(true)); let z = Provable.if(b, Int64, x, y); Provable.assertEqual(z, Int64.from(-1)); Provable.asProver(() => { expect(z.toString()).toBe('-1'); }); z = Provable.if(b, Int64, Int64.from(99), y); Provable.assertEqual(z, Int64.from(99)); Provable.asProver(() => { expect(z.toString()).toBe('99'); }); z = Provable.if(b.not(), Int64, Int64.from(99), y); Provable.assertEqual(z, Int64.from(-2)); Provable.asProver(() => { expect(z.toString()).toBe('-2'); }); z = Provable.if(Bool(false), Int64, x, y); Provable.assertEqual(z, Int64.from(-2)); Provable.asProver(() => { expect(z.toString()).toBe('-2'); }); }); }); it('Provable.switch picks the right value', () => { const x = Provable.switch([Bool(false), Bool(true), Bool(false)], Int64, [ Int64.from(-1), Int64.from(-2), Int64.from(-3), ]); expect(x.toString()).toBe('-2'); }); it('Provable.switch returns 0 if the mask has only false elements', () => { const x = Provable.switch([Bool(false), Bool(false), Bool(false)], Int64, [ Int64.from(-1), Int64.from(-2), Int64.from(-3), ]); expect(x.toString()).toBe('0'); }); it('Provable.switch throws when mask has >1 true elements', () => { expect(() => Provable.switch([Bool(true), Bool(true), Bool(false)], Int64, [ Int64.from(-1), Int64.from(-2), Int64.from(-3), ]) ).toThrow(/`mask` must have 0 or 1 true element, found 2/); }); it('Provable.assertEqual', async () => { const FieldAndBool = Struct({ x: Field, b: Bool }); await Provable.runAndCheck(() => { let x = Provable.witness(Field, () => Field(1)); let b = Provable.witness(Bool, () => Bool(true)); // positive Provable.assertEqual(b, Bool(true)); Provable.assertEqual( FieldAndBool, { x, b }, { x: Field(1), b: Bool(true) } ); //negative expect(() => Provable.assertEqual(b, Bool(false))).toThrow(); expect(() => Provable.assertEqual( FieldAndBool, { x, b }, { x: Field(5), b: Bool(true) } ) ).toThrow(); expect(() => Provable.assertEqual(b, PrivateKey.random() as any)).toThrow( 'must contain the same number of field elements' ); }); }); it('Provable.equal', async () => { const FieldAndBool = Struct({ x: Field, b: Bool }); let pk1 = PublicKey.fromBase58( 'B62qoCHJ1dcGjKhdMTMuAytzRkLxRFUgq6YC5XSgmmxAt8r7FVi1DhT' ); let pk2 = PublicKey.fromBase58( 'B62qnDjh7J27q6CoG6hkQzP6J6t1USA6bCoKsBFhxNughNHQgVwEtT9' ); function expectBoolean(b: Bool, expected: boolean) { Provable.asProver(() => { expect(b.toBoolean()).toEqual(expected); }); } await Provable.runAndCheck(() => { let x = Provable.witness(Field, () => Field(1)); let b = Provable.witness(Bool, () => Bool(true)); let pk = Provable.witness(PublicKey, () => pk1); expectBoolean(Provable.equal(pk, pk1), true); expectBoolean( Provable.equal(FieldAndBool, { x, b }, { x: Field(1), b: Bool(true) }), true ); expectBoolean(Provable.equal(pk, pk2), false); expectBoolean( Provable.equal(FieldAndBool, { x, b }, { x: Field(1), b: Bool(false) }), false ); expect(() => Provable.equal(b, pk2 as any)).toThrow( 'must contain the same number of field elements' ); }); }); it('can serialize Struct with array', async () => { class MyStruct extends Struct({ values: Provable.Array(Field, 2), }) {} const original = new MyStruct({ values: [Field(0), Field(1)] }); const serialized = MyStruct.toJSON(original); const reconstructed = MyStruct.fromJSON(serialized); Provable.assertEqual<MyStruct>(MyStruct, original, reconstructed); }); it('can serialize nested Struct', async () => { class OtherStruct extends Struct({ x: Field, }) { toString() { return `other-struct:${this.x}`; } } class MyStruct extends Struct({ a: Field, b: PrivateKey, y: OtherStruct, }) { toString() { return `my-struct:${this.a};${this.b.toBase58()};${this.y}`; } } const original = new MyStruct({ a: Field(42), b: PrivateKey.random(), y: new OtherStruct({ x: Field(99) }), }); const serialized = MyStruct.toJSON(original); const reconstructed = MyStruct.fromJSON(serialized); Provable.assertEqual(MyStruct, original, reconstructed); expect(reconstructed.toString()).toEqual(original.toString()); }); });