Provable
Provable: {
Array: <A>(elementType: A, length: number) => InferredProvable<ToProvable<A>[]>;
asProver: (f: () => void) => void;
assertEqual: <T>(type: FlexibleProvableType<T>, x: T, y: T) => void<T>(x: T, y: T) => void;
assertEqualIf: <A, T>(enabled: Bool, type: A, x: T, y: T) => void;
constraintSystem: (f: () => Promise<void> | () => void) => Promise<ConstraintSystemSummary>;
equal: <T>(type: FlexibleProvableType<T>, x: T, y: T) => Bool;
if: <T>(condition: Bool, type: FlexibleProvableType<T>, x: T, y: T) => T<T>(condition: Bool, x: T, y: T) => T;
inCheckedComputation: () => boolean;
inProver: () => boolean;
log: (...args: any) => void;
switch: <T, A>(mask: Bool[], type: A, values: T[], __namedParameters: {
allowNonExclusive: boolean;
}) => T;
witness: <A, T>(type: A, compute: () => T) => InferProvable<ToProvable<A>>;
witnessAsync: <A, T>(type: A, compute: () => Promise<T>) => Promise<T>;
witnessFields: <N, C>(size: N, compute: C) => TupleN<Field, N>;
runAndCheck: Promise<void>;
runUnchecked: Promise<void>;
toCanonical: T;
toConstant: T;
};
Defined in: lib/provable/provable.ts:46
Type declaration
Array()
Array: <A>(elementType: A, length: number) => InferredProvable<ToProvable<A>[]> = provableArray;
Creates a Provable for a generic array.
Type Parameters
• A extends FlexibleProvableType
<any
>
Parameters
elementType
A
length
number
Returns
InferredProvable
<ToProvable
<A
>[]>
Example
const ProvableArray = Provable.Array(Field, 5);
asProver()
asProver: (f: () => void) => void;
Runs code as a prover.
Parameters
f
() => void
Returns
void
Example
Provable.asProver(() => {
// Your prover code here
});
assertEqual()
assertEqual: <T>(type: FlexibleProvableType<T>, x: T, y: T) => void<T>(x: T, y: T) => void;
Asserts that two values are equal.
Type Parameters
• T
Parameters
type
FlexibleProvableType
<T
>
x
T
y
T
Returns
void
Type Parameters
• T extends ToFieldable
Parameters
x
T
y
T
Returns
void
Example
class MyStruct extends Struct({ a: Field, b: Bool }) {};
const a: MyStruct = { a: Field(0), b: Bool(false) };
const b: MyStruct = { a: Field(1), b: Bool(true) };
Provable.assertEqual(MyStruct, a, b);
assertEqualIf()
assertEqualIf: <A, T>(enabled: Bool, type: A, x: T, y: T) => void;
Asserts that two values are equal, if an enabling condition is true.
If the condition is false, the assertion is skipped.
Type Parameters
• A extends ProvableType
<any
>
• T extends any
= InferProvableType
<A
>
Parameters
enabled
type
A
x
T
y
T
Returns
void
constraintSystem()
constraintSystem: (f: () => Promise<void> | () => void) => Promise<ConstraintSystemSummary>;
Returns information about the constraints created by the callback function.
Parameters
f
() => Promise
<void
> | () => void
Returns
Promise
<ConstraintSystemSummary
>
Example
const result = await Provable.constraintSystem(circuit);
console.log(result);
equal()
equal: <T>(type: FlexibleProvableType<T>, x: T, y: T) => Bool;
Checks if two elements are equal.
Type Parameters
• T
Parameters
type
FlexibleProvableType
<T
>
x
T
y
T
Returns
Example
class MyStruct extends Struct({ a: Field, b: Bool }) {};
const a: MyStruct = { a: Field(0), b: Bool(false) };
const b: MyStruct = { a: Field(1), b: Bool(true) };
const isEqual = Provable.equal(MyStruct, a, b);
if()
if: <T>(condition: Bool, type: FlexibleProvableType<T>, x: T, y: T) => T<T>(condition: Bool, x: T, y: T) => T = if_;
Proof-compatible if-statement. This behaves like a ternary conditional statement in JS.
Warning: Since Provable.if()
is a normal JS function call, both the if and the else branch
are evaluated before calling it. Therefore, you can't use this function
to guard against execution of one of the branches. It only allows you to pick one of two values.
Type Parameters
• T
Parameters
condition
type
FlexibleProvableType
<T
>
x
T
y
T
Returns
T
Type Parameters
• T extends ToFieldable
Parameters
condition
x
T
y
T
Returns
T
Example
const condition = Bool(true);
const result = Provable.if(condition, Field(1), Field(2)); // returns Field(1)
inCheckedComputation()
inCheckedComputation: () => boolean;
Checks if the code is run in checked computation mode.
Returns
boolean
Example
if (Provable.inCheckedComputation()) {
// Checked computation-specific code
}
inProver()
inProver: () => boolean;
Checks if the code is run in prover mode.
Returns
boolean
Example
if (Provable.inProver()) {
// Prover-specific code
}
log()
log: (...args: any) => void;
Interface to log elements within a circuit. Similar to console.log()
.
Parameters
args
...any
Returns
void
Example
const element = Field(42);
Provable.log(element);
switch()
switch: <T, A>(mask: Bool[], type: A, values: T[], __namedParameters: {
allowNonExclusive: boolean;
}) => T = switch_;
Generalization of Provable.if for choosing between more than two different cases.
It takes a "mask", which is an array of Bool
s that contains only one true
element, a type/constructor, and an array of values of that type.
The result is that value which corresponds to the true element of the mask.
Type Parameters
• T
• A extends FlexibleProvableType
<T
>
Parameters
mask
Bool
[]
type
A
values
T
[]
__namedParameters
allowNonExclusive
boolean
= false
Returns
T
Example
let x = Provable.switch([Bool(false), Bool(true)], Field, [Field(1), Field(2)]);
x.assertEquals(2);
witness()
witness: <A, T>(type: A, compute: () => T) => InferProvable<ToProvable<A>>;
Create a new witness. A witness, or variable, is a value that is provided as input
by the prover. This provides a flexible way to introduce values from outside into the circuit.
However, note that nothing about how the value was created is part of the proof - Provable.witness
behaves exactly like user input. So, make sure that after receiving the witness you make any assertions
that you want to associate with it.
The only constraints enforced on the witnessed value come from its type. This means
the witnessed value may be anything which satisfies the constraints defined in Type.check()
.
Note that for composite types like (Structs, the
default Type.check()
method calls check()
on each Struct field.
Warning: Be extremely wary of any custom check()
methods, which may have forgotten
to call check()
on sub-components of the Struct.
Type Parameters
• A extends ProvableType
<any
, any
>
• T extends any
= From
<ToProvable
<A
>>
Parameters
type
A
compute
() => T
Returns
Example
Example for re-implementing Field.inv
with the help of witness
:
let invX = Provable.witness(Field, () => {
// compute the inverse of `x` outside the circuit, however you like!
return Field.inv(x);
}
// prove that `invX` is really the inverse of `x`:
invX.mul(x).assertEquals(1);
Example for decomposing a 64-bit integer into two 32-bit limbs. Provable.witness will prove that the two limbs are actually 32-bits, ensuring the decomposition is unique.
function decompose(value: UInt64) {
// get two arbitrary 32-bit values from the prover
let lowerLimb = Provable.witness(UInt32, () => {
return value.and(new UInt64(0xffffffffn)).toUInt32();
});
let upperLimb = Provable.witness(UInt32, () => {
return value
.and(new UInt64(0xffffffff00000000n))
.div(2 ** 32)
.toUInt32();
});
// prove the 32-bit lower and upper limbs match the 64-bit value
value.assertEquals(
lowerLimb
.toUInt64()
.add(upperLimb.toUInt64().mul(UInt64.from(2n ** 32n)))
);
}
Modified example for decomposing a 64-bit integer into two 32-bit limbs. This time we use a Struct to get both 32-bit values from the prover at once, while still proving each limb is actually 32 bits.
class Decomposition extends Struct({
lower: UInt32,
upper: UInt32,
}) {}
function decompose(value: UInt64) {
// get two arbitrary 32-bit values from the prover
let limbs = Provable.witness(Decomposition, () => {
return new Decomposition({
lower: value.and(new UInt64(0xffffffffn)).toUInt32(),
upper: value
.and(new UInt64(0xffffffff00000000n))
.div(2 ** 32)
.toUInt32(),
});
});
// prove the 32-bit lower and upper limbs match the 64-bit value
value.assertEquals(
limbs.lower
.toUInt64()
.add(limbs.upper.toUInt64().mul(UInt64.from(2n ** 32n)))
);
}
witnessAsync()
witnessAsync: <A, T>(type: A, compute: () => Promise<T>) => Promise<T>;
Create a new witness from an async callback.
See Provable.witness for more information.
Type Parameters
• A extends ProvableType
<any
, any
>
• T extends any
= From
<ToProvable
<A
>>
Parameters
type
A
compute
() => Promise
<T
>
Returns
Promise
<T
>
witnessFields()
witnessFields: <N, C>(size: N, compute: C) => TupleN<Field, N>;
Witness a tuple of field elements. This works just like Provable.witness, but optimized for witnessing plain field elements, which is especially common in low-level provable code.
Type Parameters
• N extends number
• C extends () => TupleN
<bigint
| Field
, N
>
Parameters
size
N
compute
C
Returns
runAndCheck()
Runs provable code quickly, without creating a proof, but still checking whether constraints are satisfied.
Parameters
f
() => Promise
<void
> | () => void
Returns
Promise
<void
>
Example
await Provable.runAndCheck(() => {
// Your code to check here
});
runUnchecked()
Runs provable code quickly, without creating a proof, and not checking whether constraints are satisfied.
Parameters
f
() => Promise
<void
> | () => void
Returns
Promise
<void
>
Example
await Provable.runUnchecked(() => {
// Your code to run here
});
toCanonical()
Return a canonical version of a value, where
canonical is defined by the type
.
Type Parameters
• T
Parameters
type
Provable
<T
, any
>
value
T
Returns
T
toConstant()
Returns a constant version of a provable type.
Type Parameters
• T
Parameters
type
ProvableType
<T
>
value
T
Returns
T