Skip to content

Commit 49a0181

Browse files
authored
Merge pull request #2585 from o1-labs/florian/kimchi-proof-rust
Add serde functionality to kimchi proofs and verifier index
2 parents a583a9c + ce1b5f2 commit 49a0181

File tree

8 files changed

+200
-84
lines changed

8 files changed

+200
-84
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ This project adheres to
1818

1919
## [Unreleased](https://github.com/o1-labs/o1js/compare/3453d1e53...HEAD)
2020

21+
### Added
22+
23+
- Add `KimchiProof.toJSON()` and `KimchiProof.fromJSON()`
24+
https://github.com/o1-labs/o1js/pull/2594
25+
- Add `KimchiVerificationKey.toString()` and
26+
`KimchiVerificationKey.fromString()` https://github.com/o1-labs/o1js/pull/2594
27+
2128
### Internal
2229

2330
- Change cache harness to only allow writes when `dump` mode is active.

src/bindings.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ declare namespace Snarky {
7373
type Keypair = unknown;
7474
type VerificationKey = unknown;
7575
type Proof = unknown;
76+
type ProofWithEvals = unknown;
7677
}
7778

7879
/**
@@ -406,6 +407,11 @@ declare const Snarky: {
406407
verificationKey: Snarky.VerificationKey
407408
): boolean;
408409

410+
411+
proofToBackendProofEvals(publicInput: MlArray<FieldConst>, proof: Snarky.Proof): Snarky.ProofWithEvals;
412+
413+
proofFromBackendProofEvals(proof: Snarky.ProofWithEvals): Snarky.Proof;
414+
409415
keypair: {
410416
getVerificationKey(keypair: Snarky.Keypair): Snarky.VerificationKey;
411417
/**

src/bindings/ocaml/lib/snarky_bindings.ml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,12 @@ module Circuit = struct
406406
Backend.Field.Vector.emplace_back public_input_vec x ) ;
407407
Backend.Proof.verify proof vk public_input_vec |> Js.bool
408408

409+
let proof_to_backend_proof_evals xs (t : Backend.Proof.with_public_evals) =
410+
Backend.Proof.to_backend_with_public_evals' [] xs t
411+
412+
let proof_from_backend_proof_evals t =
413+
Backend.Proof.of_backend_with_public_evals t
414+
409415
module Keypair = struct
410416
let get_vk t = Impl.Keypair.vk t
411417

@@ -582,6 +588,11 @@ let snarky =
582588

583589
method verify = Circuit.verify
584590

591+
method proofToBackendProofEvals = Circuit.proof_to_backend_proof_evals
592+
593+
method proofFromBackendProofEvals =
594+
Circuit.proof_from_backend_proof_evals
595+
585596
val keypair =
586597
object%js
587598
method getVerificationKey = Circuit.Keypair.get_vk

src/bindings/ocaml/lib/snarky_bindings.mli

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,10 @@ val snarky :
273273
Kimchi_types.poly_comm )
274274
Kimchi_types.VerifierIndex.verifier_index
275275
-> bool Js.t )
276-
Js.meth >
276+
Js.meth
277+
; proofToBackendProofEvals :
278+
(field array -> Backend.Proof.with_public_evals -> Backend.Proof.Backend.with_public_evals) Js.meth
279+
; proofFromBackendProofEvals : (Backend.Proof.Backend.with_public_evals -> Backend.Proof.with_public_evals) Js.meth >
277280
Js.t
278281
Js.readonly_prop >
279282
Js.t

src/examples/zkfunction/root.ts

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Experimental, Field, Gadgets } from 'o1js';
1+
import { assert, Experimental, Field, Gadgets } from 'o1js';
22
const { ZkFunction } = Experimental;
33

44
/**
@@ -22,15 +22,43 @@ console.time('compile...');
2222
const { verificationKey } = await main.compile();
2323
console.timeEnd('compile...');
2424

25-
console.time('prove...');
2625
const x = Field(8);
2726
const y = Field(2);
27+
28+
console.time('prove...');
2829
const proof = await main.prove(x, y);
2930
console.timeEnd('prove...');
3031

3132
console.time('verify...');
32-
let isValid = await main.verify(proof, verificationKey);
33+
let ok = await main.verify(proof, verificationKey);
3334
console.timeEnd('verify...');
3435

35-
console.log('isValid?', isValid);
36-
if (!isValid) throw Error('verification failed!');
36+
assert(ok, 'proof should verify');
37+
38+
console.log('testing round trips');
39+
40+
ok = await proofRoundTrip(proof).verify(verificationKey);
41+
assert(ok, 'proof should verify');
42+
43+
console.log('verification key round trip...');
44+
45+
ok = await proof.verify(verificationKeyRoundTrip(verificationKey));
46+
47+
assert(ok, 'proof should verify');
48+
49+
function proofRoundTrip(proof: Experimental.KimchiProof): Experimental.KimchiProof {
50+
let json = proof.toJSON();
51+
console.log('proof json:', {
52+
proof: json.proof.slice(0, 10),
53+
publicInputFields: json.publicInputFields,
54+
});
55+
return Experimental.KimchiProof.fromJSON(json);
56+
}
57+
58+
function verificationKeyRoundTrip(
59+
vk: Experimental.KimchiVerificationKey
60+
): Experimental.KimchiVerificationKey {
61+
let json = vk.toString();
62+
console.log('vk string:', json.slice(0, 10));
63+
return Experimental.KimchiVerificationKey.fromString(json);
64+
}

src/index.ts

Lines changed: 70 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,115 @@
11
/**
22
* Include in this file all the exports that should be part of the public API.
33
*/
4-
export { TupleN } from './lib/util/types.js';
5-
export type { ProvablePure } from './lib/provable/types/provable-intf.js';
6-
export { Ledger, initializeBindings } from './bindings.js';
7-
export { Field, Bool, Group, Scalar } from './lib/provable/wrapped.js';
4+
export { initializeBindings, Ledger } from './bindings.js';
5+
export { createForeignCurve, ForeignCurve, toPoint } from './lib/provable/crypto/foreign-curve.js';
6+
export type { FlexiblePoint } from './lib/provable/crypto/foreign-curve.js';
7+
export { createEcdsa, EcdsaSignature } from './lib/provable/crypto/foreign-ecdsa.js';
8+
export { Hash } from './lib/provable/crypto/hash.js';
9+
export { Keccak } from './lib/provable/crypto/keccak.js';
10+
export { Poseidon, ProvableHashable, TokenSymbol } from './lib/provable/crypto/poseidon.js';
811
export {
9-
createForeignField,
10-
ForeignField,
1112
AlmostForeignField,
1213
CanonicalForeignField,
14+
createForeignField,
15+
ForeignField,
1316
} from './lib/provable/foreign-field.js';
14-
export { createForeignCurve, ForeignCurve, toPoint } from './lib/provable/crypto/foreign-curve.js';
15-
export type { FlexiblePoint } from './lib/provable/crypto/foreign-curve.js';
16-
export { createEcdsa, EcdsaSignature } from './lib/provable/crypto/foreign-ecdsa.js';
1717
export { ScalarField } from './lib/provable/scalar-field.js';
18-
export { Poseidon, TokenSymbol, ProvableHashable } from './lib/provable/crypto/poseidon.js';
19-
export { Keccak } from './lib/provable/crypto/keccak.js';
20-
export { Hash } from './lib/provable/crypto/hash.js';
18+
export type { ProvablePure } from './lib/provable/types/provable-intf.js';
19+
export { Bool, Field, Group, Scalar } from './lib/provable/wrapped.js';
20+
export { TupleN } from './lib/util/types.js';
2121

2222
export { assert } from './lib/provable/gadgets/common.js';
2323

2424
export * from './lib/provable/crypto/signature.js';
2525
export type {
26-
ProvableExtended,
2726
FlexibleProvable,
2827
FlexibleProvablePure,
2928
InferProvable,
29+
ProvableExtended,
3030
} from './lib/provable/types/struct.js';
3131

3232
export { provableFromClass } from './lib/provable/types/provable-derivers.js';
3333
export type { ProvablePureExtended } from './lib/provable/types/struct.js';
3434

35-
export { From, InferValue, InferJson, IsPure } from './bindings/lib/provable-generic.js';
36-
export { ProvableType } from './lib/provable/types/provable-intf.js';
35+
export { From, InferJson, InferValue, IsPure } from './bindings/lib/provable-generic.js';
36+
export { Types } from './bindings/mina-transaction/v1/types.js';
37+
export { Circuit, circuitMain, Keypair, public_ } from './lib/proof-system/circuit.js';
38+
export { DynamicArray } from './lib/provable/dynamic-array.js';
39+
export { Gadgets } from './lib/provable/gadgets/gadgets.js';
40+
export { RuntimeTable } from './lib/provable/gadgets/runtime-table.js';
41+
export { Int64, Sign, UInt32, UInt64, UInt8 } from './lib/provable/int.js';
42+
export { Hashed, Packed } from './lib/provable/packed.js';
43+
export { Provable } from './lib/provable/provable.js';
3744
export { provable, provablePure } from './lib/provable/types/provable-derivers.js';
45+
export { ProvableType } from './lib/provable/types/provable-intf.js';
3846
export { Struct } from './lib/provable/types/struct.js';
3947
export { Unconstrained } from './lib/provable/types/unconstrained.js';
40-
export { Provable } from './lib/provable/provable.js';
41-
export { Circuit, Keypair, public_, circuitMain } from './lib/proof-system/circuit.js';
42-
export { UInt32, UInt64, Int64, Sign, UInt8 } from './lib/provable/int.js';
4348
export { Bytes, FlexibleBytes } from './lib/provable/wrapped-classes.js';
44-
export { Packed, Hashed } from './lib/provable/packed.js';
45-
export { Gadgets } from './lib/provable/gadgets/gadgets.js';
46-
export { RuntimeTable } from './lib/provable/gadgets/runtime-table.js';
47-
export { Types } from './bindings/mina-transaction/v1/types.js';
48-
export { DynamicArray } from './lib/provable/dynamic-array.js';
4949

5050
export { MerkleList, MerkleListIterator } from './lib/provable/merkle-list.js';
51+
export { Option } from './lib/provable/option.js';
5152
import {
5253
IndexedMerkleMap as IndexedMerkleMap_,
5354
IndexedMerkleMapBase,
5455
} from './lib/provable/merkle-tree-indexed.js';
5556
export let IndexedMerkleMap = IndexedMerkleMap_;
5657
export type IndexedMerkleMap = IndexedMerkleMapBase;
57-
export { Option } from './lib/provable/option.js';
5858

59+
export { Reducer } from './lib/mina/v1/actions/reducer.js';
5960
export * as Mina from './lib/mina/v1/mina.js';
61+
export { declareState, state, State } from './lib/mina/v1/state.js';
6062
export {
6163
Transaction,
62-
type TransactionPromise,
63-
type PendingTransaction,
6464
type IncludedTransaction,
65-
type RejectedTransaction,
65+
type PendingTransaction,
6666
type PendingTransactionPromise,
67+
type RejectedTransaction,
68+
type TransactionPromise,
6769
} from './lib/mina/v1/transaction.js';
70+
export { declareMethods, method, SmartContract } from './lib/mina/v1/zkapp.js';
6871
export type { DeployArgs } from './lib/mina/v1/zkapp.js';
69-
export { SmartContract, method, declareMethods } from './lib/mina/v1/zkapp.js';
70-
export { Reducer } from './lib/mina/v1/actions/reducer.js';
71-
export { state, State, declareState } from './lib/mina/v1/state.js';
7272

73-
export type { JsonProof } from './lib/proof-system/zkprogram.js';
74-
export { SelfProof, verify, Empty, Undefined, Void } from './lib/proof-system/zkprogram.js';
75-
export { VerificationKey } from './lib/proof-system/verification-key.js';
76-
export { type ProofBase, Proof, DynamicProof } from './lib/proof-system/proof.js';
77-
export { FeatureFlags } from './lib/proof-system/feature-flags.js';
7873
export { Cache, CacheHeader } from './lib/proof-system/cache.js';
74+
export { FeatureFlags } from './lib/proof-system/feature-flags.js';
75+
export { DynamicProof, Proof, type ProofBase } from './lib/proof-system/proof.js';
76+
export { VerificationKey } from './lib/proof-system/verification-key.js';
77+
export { Empty, SelfProof, Undefined, verify, Void } from './lib/proof-system/zkprogram.js';
78+
export type { JsonProof } from './lib/proof-system/zkprogram.js';
7979

80-
export { Account } from './lib/mina/v1/account.js';
8180
export {
82-
TokenId,
8381
AccountUpdate,
84-
Permissions,
85-
ZkappPublicInput,
86-
TransactionVersion,
8782
AccountUpdateForest,
8883
AccountUpdateTree,
84+
Permissions,
85+
TokenId,
86+
TransactionVersion,
87+
ZkappPublicInput,
8988
} from './lib/mina/v1/account-update.js';
89+
export { Account } from './lib/mina/v1/account.js';
9090

9191
export { TokenAccountUpdateIterator } from './lib/mina/v1/token/forest-iterator.js';
9292
export { TokenContract } from './lib/mina/v1/token/token-contract.js';
9393

94-
export type { TransactionStatus } from './lib/mina/v1/graphql.js';
94+
export * as Encoding from './bindings/lib/encoding.js';
9595
export {
96+
addCachedAccount,
97+
checkZkappTransaction,
9698
fetchAccount,
99+
fetchEvents,
97100
fetchLastBlock,
98101
fetchTransactionStatus,
99-
checkZkappTransaction,
100-
fetchEvents,
101-
addCachedAccount,
102+
Lightnet,
103+
sendZkapp,
104+
setArchiveGraphqlEndpoint,
102105
setGraphqlEndpoint,
103106
setGraphqlEndpoints,
104-
setArchiveGraphqlEndpoint,
105-
sendZkapp,
106-
Lightnet,
107107
} from './lib/mina/v1/fetch.js';
108+
export type { TransactionStatus } from './lib/mina/v1/graphql.js';
108109
export * as Encryption from './lib/provable/crypto/encryption.js';
109-
export * as Encoding from './bindings/lib/encoding.js';
110-
export { Character, CircuitString } from './lib/provable/string.js';
111-
export { MerkleTree, MerkleWitness } from './lib/provable/merkle-tree.js';
112110
export { MerkleMap, MerkleMapWitness } from './lib/provable/merkle-map.js';
111+
export { MerkleTree, MerkleWitness } from './lib/provable/merkle-tree.js';
112+
export { Character, CircuitString } from './lib/provable/string.js';
113113

114114
export { Nullifier } from './lib/provable/crypto/nullifier.js';
115115

@@ -120,20 +120,25 @@ export { Crypto } from './lib/provable/crypto/crypto.js';
120120
export type { NetworkId } from './mina-signer/mina-signer.js';
121121

122122
export { setNumberOfWorkers } from './lib/proof-system/workers.js';
123+
export { Experimental };
123124

124125
// experimental APIs
125-
import { memoizeWitness } from './lib/provable/provable.js';
126-
import * as OffchainState_ from './lib/mina/v1/actions/offchain-state.js';
127126
import * as BatchReducer_ from './lib/mina/v1/actions/batch-reducer.js';
128127
import { Actionable } from './lib/mina/v1/actions/offchain-state-serialization.js';
129-
import { InferProvable } from './lib/provable/types/struct.js';
128+
import * as OffchainState_ from './lib/mina/v1/actions/offchain-state.js';
130129
import { Recursive as Recursive_ } from './lib/proof-system/recursive.js';
131130
import {
132-
ProvableBigInt as ProvableBigInt_,
131+
KimchiJsonProof as KimchiJsonProof_,
132+
KimchiProof as KimchiProof_,
133+
KimchiVerificationKey as KimchiVerificationKey_,
134+
ZkFunction as ZkFunction_,
135+
} from './lib/proof-system/zkfunction.js';
136+
import {
133137
createProvableBigInt as createProvableBigInt_,
138+
ProvableBigInt as ProvableBigInt_,
134139
} from './lib/provable/bigint.js';
135-
import { ZkFunction as ZkFunction_ } from './lib/proof-system/zkfunction.js';
136-
export { Experimental };
140+
import { memoizeWitness } from './lib/provable/provable.js';
141+
import { InferProvable } from './lib/provable/types/struct.js';
137142

138143
import * as V2_ from './lib/mina/v2/index.js';
139144
import { Field } from './lib/provable/wrapped.js';
@@ -156,15 +161,15 @@ namespace Experimental {
156161
export type MinaProgramMethodReturn<
157162
State extends V2_.StateLayout = 'GenericState',
158163
Event = Field[],
159-
Action = Field[]
164+
Action = Field[],
160165
> = V2_.MinaProgramMethodReturn<State, Event, Action>;
161166
export type StateDefinition<State extends V2_.StateLayout> = V2_.StateDefinition<State>;
162167
export type ZkappCommandAuthorizationEnvironment = V2_.ZkappCommandAuthorizationEnvironment;
163168
export type MinaProgram<
164169
State extends StateLayout,
165170
Event,
166171
Action,
167-
MethodPrivateInputs extends { [key: string]: V2_.ProvableTuple }
172+
MethodPrivateInputs extends { [key: string]: V2_.ProvableTuple },
168173
> = V2_.MinaProgram<State, Event, Action, MethodPrivateInputs>;
169174
export type DynamicProvable<P> = V2_.DynamicProvable<P>;
170175
}
@@ -177,6 +182,12 @@ namespace Experimental {
177182
export let createProvableBigInt = createProvableBigInt_;
178183

179184
export let ZkFunction = ZkFunction_;
185+
export type KimchiProof = KimchiProof_;
186+
export type KimchiVerificationKey = KimchiVerificationKey_;
187+
export let KimchiProof = KimchiProof_;
188+
export let KimchiVerificationKey = KimchiVerificationKey_;
189+
190+
export type KimchiJsonProof = KimchiJsonProof_;
180191

181192
// offchain state
182193
export let OffchainState = OffchainState_.OffchainState;
@@ -216,7 +227,7 @@ namespace Experimental {
216227
export class BatchReducer<
217228
ActionType extends Actionable<any>,
218229
BatchSize extends number = number,
219-
Action = InferProvable<ActionType>
230+
Action = InferProvable<ActionType>,
220231
> extends BatchReducer_.BatchReducer<ActionType, BatchSize, Action> {}
221232

222233
/**

0 commit comments

Comments
 (0)