Skip to content

Commit c5a0a6d

Browse files
committed
RuntimeTable: make backwards compatible, deprecating old functions
1 parent 098c478 commit c5a0a6d

File tree

7 files changed

+128
-6
lines changed

7 files changed

+128
-6
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@ This project adheres to
2323
- Updated Rust nightly version from `2024-06-13` to `2024-09-05` to match the
2424
version used in Mina proof-systems repository.
2525

26-
- Updated the runtime table API with less abstract function names.
26+
- Improved the runtime table API with a `RuntimeTable` class with better
27+
readability.
28+
29+
### Deprecated
30+
31+
- Deprecate the `Gates.addRuntimeTableConfig` and `Gadgets.inTable` functions in favor
32+
of the `RuntimeTable` class API.
2733

2834
### Fixed
2935

src/lib/provable/gadgets/gadgets.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import { divMod32, addMod32, divMod64, addMod64 } from './arithmetic.js';
3333
import { SHA2 } from './sha2.js';
3434
import { SHA256 } from './sha256.js';
3535
import { BLAKE2B } from './blake2b.js';
36-
import { rangeCheck3x12 } from './lookup.js';
36+
import { rangeCheck3x12, inTable } from './lookup.js';
3737
import { arrayGet, arrayGetGeneric } from './basic.js';
3838
import { sliceField3 } from './bit-slices.js';
3939

@@ -586,6 +586,31 @@ const Gadgets = {
586586
return rangeCheck3x12(v0, v1, v2);
587587
},
588588

589+
/**
590+
* In-circuit check that up to 3 pairs of index and value are in the runtime
591+
* table given by the identifier. Each given pair is a tuple composed of a
592+
* bigint and a Field.
593+
*
594+
* Internally, it creates a lookup gate for the three pairs. If fewer pairs are
595+
* given, the remaining pairs are duplicates of the first one.
596+
*
597+
* @param id
598+
* @param pair0
599+
* @param pair1
600+
* @param pair2
601+
*
602+
* @deprecated {@link inTable} is deprecated in favor of RuntimeTable class,
603+
* which provides a more ergonomic API.
604+
*/
605+
inTable(
606+
id: number,
607+
pair0: [bigint, Field],
608+
pair1?: [bigint, Field] | undefined,
609+
pair2?: [bigint, Field] | undefined
610+
) {
611+
return inTable(id, pair0, pair1, pair2);
612+
},
613+
589614
/**
590615
* Gadgets for foreign field operations.
591616
*

src/lib/provable/gadgets/lookup.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Field } from '../field.js';
22
import { Gates } from '../gates.js';
33

4-
export { rangeCheck3x12 };
4+
export { rangeCheck3x12, inTable };
55

66
function rangeCheck3x12(v0: Field, v1: Field, v2: Field) {
77
// Checks that all three input values exist in the RANGE_CHECK_TABLE (tableId: 1)
@@ -17,4 +17,34 @@ function rangeCheck3x12(v0: Field, v1: Field, v2: Field) {
1717
v2,
1818
Field.from(0)
1919
);
20-
}
20+
}
21+
22+
/**
23+
* In-circuit check that up to 3 pairs of index and value are in the runtime
24+
* table given by the identifier. Each given pair is a tuple composed of a
25+
* bigint and a Field.
26+
*
27+
* **Note**: The runtime table must be configured before calling this function.
28+
*
29+
* **Note**: Table id 0 and 1 are reserved values, do not use them.
30+
*
31+
* @param id
32+
* @param pair0
33+
* @param pair1
34+
* @param pair2
35+
*
36+
* @deprecated {@link inTable} is deprecated in favor of {@link RuntimeTable} class,
37+
* which provides a more ergonomic API.
38+
*/
39+
function inTable(
40+
id: number,
41+
pair0: [bigint, Field],
42+
pair1?: [bigint, Field] | undefined,
43+
pair2?: [bigint, Field] | undefined
44+
) {
45+
let [idx0, v0] = pair0;
46+
let [idx1, v1] = pair1 === undefined ? pair0 : pair1;
47+
let [idx2, v2] = pair2 === undefined ? pair0 : pair2;
48+
49+
Gates.lookup(Field.from(id), Field.from(idx0), v0, Field.from(idx1), v1, Field.from(idx2), v2);
50+
}

src/lib/provable/gadgets/runtime-table.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,4 @@ class RuntimeTable {
9191
this.pairs = [];
9292
}
9393
}
94-
}
94+
}

src/lib/provable/gates.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export {
1717
foreignFieldAdd,
1818
foreignFieldMul,
1919
KimchiGateType,
20+
addRuntimeTableConfig,
2021
};
2122

2223
export { fieldVar };
@@ -292,6 +293,9 @@ function raw(kind: KimchiGateType, values: Field[], coefficients: bigint[]) {
292293
*
293294
* @param id
294295
* @param firstColumn
296+
*
297+
* @deprecated {@link addRuntimeTableConfig} is deprecated in favor of RuntimeTable
298+
* class, which provides a more ergonomic API.
295299
*/
296300
function addRuntimeTableConfig(id: number, firstColumn: bigint[]) {
297301
Snarky.gates.addRuntimeTableConfig(

src/lib/provable/test/lookup.unit-test.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import { Spec, boolean, equivalentAsync, fieldWithRng } from '../../testing/equi
44
import { Random } from '../../testing/property.js';
55
import { assert } from '../gadgets/common.js';
66
import { Gadgets } from '../gadgets/gadgets.js';
7+
import { Gates } from '../gates.js';
78
import { constraintSystem, contains } from '../../testing/constraint-system.js';
9+
import { FeatureFlags } from '../../proof-system/feature-flags.js';
10+
import { Cache } from '../../proof-system/cache.js';
811

912
let uint = (n: number | bigint): Spec<bigint, Field> => {
1013
return fieldWithRng(Random.bignat((1n << BigInt(n)) - 1n));
@@ -45,3 +48,56 @@ let uint = (n: number | bigint): Spec<bigint, Field> => {
4548
}
4649
);
4750
}
51+
52+
// Runtime table tests
53+
{
54+
let RuntimeTable = ZkProgram({
55+
name: 'runtime-table',
56+
methods: {
57+
runtimeTable: {
58+
privateInputs: [Field, Field, Field],
59+
async method(v0: Field, v1: Field, v2: Field) {
60+
let tableId = 2;
61+
let indices = [0n, 1n, 2n, 3n, 4n, 5n, 6n, 7n, 8n, 9n];
62+
Gates.addRuntimeTableConfig(tableId, indices);
63+
// values are inserted into the table in the given positions
64+
Gadgets.inTable(tableId, [5n, v0], [6n, v1], [7n, v2]);
65+
// a second time can be used to check more values in more positions
66+
Gadgets.inTable(tableId, [2n, v0]);
67+
// can ask for the same index asked previously
68+
Gadgets.inTable(tableId, [6n, v1]);
69+
// even multiple times in the same call
70+
Gadgets.inTable(tableId, [6n, v1], [6n, v1]);
71+
},
72+
},
73+
},
74+
});
75+
76+
// constraint system sanity check
77+
78+
constraintSystem.fromZkProgram(RuntimeTable, 'runtimeTable', contains(['Lookup']));
79+
80+
// check feature flags are set up correctly
81+
const featureFlags = await FeatureFlags.fromZkProgram(RuntimeTable, true);
82+
assert(featureFlags.lookup === true);
83+
assert(featureFlags.runtimeTables === true);
84+
85+
await RuntimeTable.compile({
86+
cache: Cache.None,
87+
forceRecompile: true,
88+
withRuntimeTables: true,
89+
});
90+
91+
await equivalentAsync({ from: [uint(12), uint(12), uint(12)], to: boolean }, { runs: 1 })(
92+
(x, y, z) => {
93+
assert(x < 1n << 12n);
94+
assert(y < 1n << 12n);
95+
assert(z < 1n << 12n);
96+
return true;
97+
},
98+
async (x, y, z) => {
99+
let { proof } = await RuntimeTable.runtimeTable(x, y, z);
100+
return await RuntimeTable.verify(proof);
101+
}
102+
);
103+
}

src/lib/provable/test/runtime-table.unit-test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import { Random } from '../../testing/property.js';
55
import { assert } from '../gadgets/common.js';
66
import { RuntimeTable } from '../gadgets/runtime-table.js';
77
import { constraintSystem, contains } from '../../testing/constraint-system.js';
8-
import { FeatureFlags, Cache } from 'o1js';
8+
import { FeatureFlags } from '../../proof-system/feature-flags.js';
9+
import { Cache } from '../../proof-system/cache.js';
910

1011
let uint = (n: number | bigint): Spec<bigint, Field> => {
1112
return fieldWithRng(Random.bignat((1n << BigInt(n)) - 1n));

0 commit comments

Comments
 (0)