Skip to content

Commit 1a903d0

Browse files
committed
add back recursive conditional provers
1 parent dd56e0c commit 1a903d0

File tree

1 file changed

+82
-20
lines changed

1 file changed

+82
-20
lines changed

src/lib/proof-system/recursive.ts

Lines changed: 82 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Tuple } from '../util/types.js';
55
import { Proof } from './proof.js';
66
import { mapObject, mapToObject, zip } from '../util/arrays.js';
77
import { Undefined, Void } from './zkprogram.js';
8+
import { Bool } from '../provable/bool.js';
89

910
export { Recursive };
1011

@@ -38,7 +39,13 @@ function Recursive<
3839
InferProvable<PublicInputType>,
3940
InferProvable<PublicOutputType>,
4041
PrivateInputs[Key]
41-
>;
42+
> & {
43+
if: ConditionalRecursiveProver<
44+
InferProvable<PublicInputType>,
45+
InferProvable<PublicOutputType>,
46+
PrivateInputs[Key]
47+
>;
48+
};
4249
} {
4350
type PublicInput = InferProvable<PublicInputType>;
4451
type PublicOutput = InferProvable<PublicOutputType>;
@@ -62,11 +69,17 @@ function Recursive<
6269

6370
let methodKeys: MethodKey[] = Object.keys(methods);
6471

65-
let regularRecursiveProvers = mapObject(zkprogram, (prover, key) => {
72+
let regularRecursiveProvers = mapToObject(methodKeys, (key) => {
6673
return async function proveRecursively_(
74+
conditionAndConfig: Bool | { condition: Bool; domainLog2?: number },
6775
publicInput: PublicInput,
6876
...args: TupleToInstances<PrivateInputs[MethodKey]>
69-
) {
77+
): Promise<PublicOutput> {
78+
let condition =
79+
conditionAndConfig instanceof Bool
80+
? conditionAndConfig
81+
: conditionAndConfig.condition;
82+
7083
// create the base proof in a witness block
7184
let proof = await Provable.witnessAsync(SelfProof, async () => {
7285
// move method args to constants
@@ -77,6 +90,24 @@ function Recursive<
7790
let constArgs = zip(args, privateInputs[key]).map(([arg, type]) =>
7891
Provable.toConstant(type, arg)
7992
);
93+
94+
if (!condition.toBoolean()) {
95+
let publicOutput: PublicOutput =
96+
ProvableType.synthesize(publicOutputType);
97+
let maxProofsVerified: 0 | 1 | 2 =
98+
(await zkprogram.maxProofsVerified()) as any; // TODO
99+
return SelfProof.dummy(
100+
publicInput,
101+
publicOutput,
102+
maxProofsVerified,
103+
conditionAndConfig instanceof Bool
104+
? undefined
105+
: conditionAndConfig.domainLog2
106+
);
107+
}
108+
109+
let prover = zkprogram[key];
110+
80111
if (hasPublicInput) {
81112
let { proof } = await prover(constInput, ...constArgs);
82113
return proof;
@@ -93,32 +124,48 @@ function Recursive<
93124

94125
// declare and verify the proof, and return its public output
95126
proof.declare();
96-
proof.verify();
127+
proof.verifyIf(condition);
97128
return proof.publicOutput;
98129
};
99130
});
100131

101-
type RecursiveProver_<K extends MethodKey> = RecursiveProver<
102-
PublicInput,
103-
PublicOutput,
104-
PrivateInputs[K]
105-
>;
106-
type RecursiveProvers = {
107-
[K in MethodKey]: RecursiveProver_<K>;
108-
};
109-
let proveRecursively: RecursiveProvers = mapToObject(
110-
methodKeys,
111-
(key: MethodKey) => {
132+
return mapObject(
133+
regularRecursiveProvers,
134+
(
135+
prover
136+
): RecursiveProver<PublicInput, PublicOutput, PrivateInputs[MethodKey]> & {
137+
if: ConditionalRecursiveProver<
138+
PublicInput,
139+
PublicOutput,
140+
PrivateInputs[MethodKey]
141+
>;
142+
} => {
112143
if (!hasPublicInput) {
113-
return ((...args: any) =>
114-
regularRecursiveProvers[key](undefined as any, ...args)) as any;
144+
return Object.assign(
145+
((...args: any) =>
146+
prover(new Bool(true), undefined as any, ...args)) as any,
147+
{
148+
if: (
149+
condition: Bool | { condition: Bool; domainLog2?: number },
150+
...args: any
151+
) => prover(condition, undefined as any, ...args),
152+
}
153+
);
115154
} else {
116-
return regularRecursiveProvers[key] as any;
155+
return Object.assign(
156+
((pi: PublicInput, ...args: any) =>
157+
prover(new Bool(true), pi, ...args)) as any,
158+
{
159+
if: (
160+
condition: Bool | { condition: Bool; domainLog2?: number },
161+
pi: PublicInput,
162+
...args: any
163+
) => prover(condition, pi, ...args),
164+
}
165+
);
117166
}
118167
}
119168
);
120-
121-
return proveRecursively;
122169
}
123170

124171
type RecursiveProver<
@@ -132,6 +179,21 @@ type RecursiveProver<
132179
...args: TupleToInstances<Args>
133180
) => Promise<PublicOutput>;
134181

182+
type ConditionalRecursiveProver<
183+
PublicInput,
184+
PublicOutput,
185+
Args extends Tuple<ProvableType>
186+
> = PublicInput extends undefined
187+
? (
188+
condition: Bool | { condition: Bool; domainLog2?: number },
189+
...args: TupleToInstances<Args>
190+
) => Promise<PublicOutput>
191+
: (
192+
condition: Bool | { condition: Bool; domainLog2?: number },
193+
publicInput: PublicInput,
194+
...args: TupleToInstances<Args>
195+
) => Promise<PublicOutput>;
196+
135197
type TupleToInstances<T> = {
136198
[I in keyof T]: InferProvable<T[I]>;
137199
};

0 commit comments

Comments
 (0)