Skip to content

Commit

Permalink
simplify interaction with proof attestation
Browse files Browse the repository at this point in the history
  • Loading branch information
mitschabaude committed Oct 14, 2024
1 parent 9ff5c12 commit a74776a
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 12 deletions.
58 changes: 57 additions & 1 deletion src/program-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import {
VerificationKey,
type ProvablePure,
DynamicProof,
type InferProvable,
FeatureFlags,
Proof,
} from 'o1js';
import type { ExcludeFromRecord } from './types.ts';
import {
Expand Down Expand Up @@ -191,7 +194,7 @@ function AProof<
DataType extends NestedProvablePure,
InputType extends ProvablePureType,
Data extends InferNestedProvable<DataType>,
Input extends InferProvableType<InputType>
Input extends InferProvable<InputType>
>(
Proof: typeof DynamicProof<Input, Data>,
dataType: DataType
Expand Down Expand Up @@ -219,9 +222,62 @@ function AProof<
};
}

async function AProofFromProgram<
DataType extends ProvablePure<any>,
InputType extends ProvablePure<any>,
Data extends InferNestedProvable<DataType>,
Input extends InferProvable<InputType>
>(
{
program,
}: {
program: {
publicInputType: InputType;
publicOutputType: DataType;
analyzeMethods: () => Promise<{
[I in keyof any]: any;
}>;
};
},
// TODO this needs to be exposed on the program!!
maxProofsVerified: 0 | 1 | 2 = 0
) {
const featureFlags = await FeatureFlags.fromZkProgram(program);

class InputProof extends DynamicProof<Input, Data> {
static publicInputType = program.publicInputType;
static publicOutputType = program.publicOutputType;
static maxProofsVerified = maxProofsVerified;
static featureFlags = featureFlags;
}

return Object.assign(
AProof<DataType, InputType, Data, Input>(
InputProof,
program.publicOutputType
),
{
fromProof(proof: Proof<Input, Data>): DynamicProof<Input, Data> {
return InputProof.fromProof(proof as any);
},
dummyProof(
publicInput: Input,
publicOutput: Data
): Promise<DynamicProof<Input, Data>> {
return InputProof.dummy(
publicInput,
publicOutput as any,
maxProofsVerified
);
},
}
);
}

const Attestation = {
none: ANone,
proof: AProof,
proofFromProgram: AProofFromProgram,
signature: ASignature,
};

Expand Down
10 changes: 10 additions & 0 deletions src/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,22 @@ import {
type UserInputs,
} from './program-config.ts';
import { NestedProvable } from './nested.ts';
import { type ProvablePureType } from './o1js-missing.ts';

export { createProgram };

type Program<Data, Inputs extends Record<string, Input>> = {
compile(): Promise<VerificationKey>;

run(input: UserInputs<Inputs>): Promise<Proof<PublicInputs<Inputs>, Data>>;

program: ZkProgram<
{
publicInput: ProvablePureType<PublicInputs<Inputs>>;
publicOutput: ProvablePureType<Data>;
},
any
>;
};

function createProgram<S extends Spec>(
Expand Down Expand Up @@ -60,6 +69,7 @@ function createProgram<S extends Spec>(
let result = await program.run(publicInput, privateInput);
return result as any;
},
program: program as any,
};
}

Expand Down
17 changes: 6 additions & 11 deletions tests/program-with-proof.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, test } from 'node:test';
import assert from 'node:assert';
import { Field, Bytes, DynamicProof, Struct } from 'o1js';
import { Field, Bytes } from 'o1js';
import { createProgram } from '../src/program.ts';
import {
Attestation,
Expand All @@ -18,18 +18,13 @@ const inputProofSpec = Spec({ data: Input.private(InputData) }, ({ data }) => ({
data,
}));
const inputProgram = createProgram(inputProofSpec);

// TODO simplify this
class InputProof extends DynamicProof<{}, { age: Field; name: Bytes }> {
static publicInputType = Struct({});
static publicOutputType = Struct({ age: Field, name: Bytes32 });
static maxProofsVerified: 0 = 0;
}
let inputVk = await inputProgram.compile();

const ProvedData = await Attestation.proofFromProgram(inputProgram);

const spec = Spec(
{
provedData: Attestation.proof(InputProof, InputData),
provedData: ProvedData,
targetAge: Input.public(Field),
targetName: Input.constant(Bytes32, Bytes32.fromString('Alice')),
},
Expand Down Expand Up @@ -95,7 +90,7 @@ async function createProofAttestation(data: {
name: Bytes;
}): Promise<UserInputs<typeof spec.inputs>['provedData']> {
let inputProof = await inputProgram.run({ data });
let proof = InputProof.fromProof(inputProof);
let proof = ProvedData.fromProof(inputProof);
return {
public: inputVk.hash,
private: { vk: inputVk, proof },
Expand All @@ -107,7 +102,7 @@ async function createInvalidProofAttestation(data: {
age: Field;
name: Bytes;
}): Promise<UserInputs<typeof spec.inputs>['provedData']> {
let proof = await InputProof.dummy({}, data, 0);
let proof = await ProvedData.dummyProof({}, data);
return {
public: inputVk.hash,
private: { vk: inputVk, proof },
Expand Down

0 comments on commit a74776a

Please sign in to comment.