Skip to content

Commit

Permalink
fix: Take a deep copy of circuit inputs for proving
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilWindle committed Apr 16, 2024
1 parent 8f6fc0f commit 114eec6
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { makePublicCallData } from '../../tests/factories.js';
import { PublicCallData } from './public_call_data.js';

describe('PublicCallData', () => {
it('PublicCallData after serialization and deserialization is equal to the original', () => {
const original = makePublicCallData(123, true);
const serialized = PublicCallData.fromBuffer(original.toBuffer());
expect(original).toEqual(serialized);
});
});
26 changes: 20 additions & 6 deletions yarn-project/circuits.js/src/structs/kernel/public_call_data.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { type Fr } from '@aztec/foundation/fields';
import { type Tuple, serializeToBuffer } from '@aztec/foundation/serialize';
import { Fr } from '@aztec/foundation/fields';
import { BufferReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize';

import { type MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL } from '../../constants.gen.js';
import { type CallRequest } from '../call_request.js';
import { type Proof } from '../proof.js';
import { type PublicCallStackItem } from '../public_call_stack_item.js';
import { MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL } from '../../constants.gen.js';
import { CallRequest } from '../call_request.js';
import { Proof } from '../proof.js';
import { PublicCallStackItem } from '../public_call_stack_item.js';

/**
* Public calldata assembled from the kernel execution result and proof.
Expand Down Expand Up @@ -42,4 +42,18 @@ export class PublicCallData {
this.bytecodeHash,
);
}

static fromBuffer(buffer: BufferReader | Buffer) {
const reader = BufferReader.asReader(buffer);
return new PublicCallData(
reader.readObject(PublicCallStackItem),
reader.readArray<CallRequest, typeof MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL>(
MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,
CallRequest,
),
reader.readObject(Proof),
reader.readObject(Fr),
reader.readObject(Fr),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { makePublicKernelCircuitPrivateInputs } from '../../tests/factories.js';
import { PublicKernelCircuitPrivateInputs } from './public_kernel_circuit_private_inputs.js';

describe('PublicKernelCircuitPrivateInputs', () => {
it('PublicKernelCircuitPrivateInputs after serialization and deserialization is equal to the original', () => {
const original = makePublicKernelCircuitPrivateInputs(123);
const serialized = PublicKernelCircuitPrivateInputs.fromBuffer(original.toBuffer());
expect(original).toEqual(serialized);
});

it('PublicKernelCircuitPrivateInputs after clone is equal to the original', () => {
const original = makePublicKernelCircuitPrivateInputs(123);
const serialized = original.clone();
expect(original).toEqual(serialized);
expect(original).not.toBe(serialized);
});
});
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { serializeToBuffer } from '@aztec/foundation/serialize';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';

import { type PublicCallData } from './public_call_data.js';
import { type PublicKernelData } from './public_kernel_data.js';
import { PublicCallData } from './public_call_data.js';
import { PublicKernelData } from './public_kernel_data.js';

/**
* Inputs to the public kernel circuit.
Expand All @@ -21,4 +21,15 @@ export class PublicKernelCircuitPrivateInputs {
toBuffer() {
return serializeToBuffer(this.previousKernel, this.publicCall);
}

static fromBuffer(buffer: BufferReader | Buffer) {
const reader = BufferReader.asReader(buffer);
const previousKernel = reader.readObject(PublicKernelData);
const publicCall = reader.readObject(PublicCallData);
return new PublicKernelCircuitPrivateInputs(previousKernel, publicCall);
}

clone() {
return PublicKernelCircuitPrivateInputs.fromBuffer(this.toBuffer());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { makePublicKernelTailCircuitPrivateInputs } from '../../tests/factories.js';
import { PublicKernelTailCircuitPrivateInputs } from './public_kernel_tail_circuit_private_inputs.js';

describe('PublicKernelTailCircuitPrivateInputs', () => {
it('PublicKernelTailCircuitPrivateInputs after serialization and deserialization is equal to the original', () => {
const original = makePublicKernelTailCircuitPrivateInputs(123);
const serialized = PublicKernelTailCircuitPrivateInputs.fromBuffer(original.toBuffer());
expect(original).toEqual(serialized);
});

it('PublicKernelTailCircuitPrivateInputs after clone is equal to the original', () => {
const original = makePublicKernelTailCircuitPrivateInputs(123);
const serialized = original.clone();
expect(original).toEqual(serialized);
expect(original).not.toBe(serialized);
});
});
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { serializeToBuffer } from '@aztec/foundation/serialize';
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';

import { type NullifierNonExistentReadRequestHints } from '../non_existent_read_request_hints.js';
import { type NullifierReadRequestHints } from '../read_request_hints.js';
import { type PublicKernelData } from './public_kernel_data.js';
import {
type NullifierNonExistentReadRequestHints,
nullifierNonExistentReadRequestHintsFromBuffer,
} from '../non_existent_read_request_hints.js';
import { type NullifierReadRequestHints, nullifierReadRequestHintsFromBuffer } from '../read_request_hints.js';
import { PublicKernelData } from './public_kernel_data.js';

/**
* Inputs to the public kernel circuit.
Expand Down Expand Up @@ -30,4 +33,17 @@ export class PublicKernelTailCircuitPrivateInputs {
this.nullifierNonExistentReadRequestHints,
);
}

static fromBuffer(buffer: Buffer | BufferReader) {
const reader = BufferReader.asReader(buffer);
return new PublicKernelTailCircuitPrivateInputs(
reader.readObject(PublicKernelData),
nullifierReadRequestHintsFromBuffer(reader),
nullifierNonExistentReadRequestHintsFromBuffer(reader),
);
}

clone() {
return PublicKernelTailCircuitPrivateInputs.fromBuffer(this.toBuffer());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,12 @@ export class NonExistentReadRequestHints<
}

toBuffer() {
return serializeToBuffer(this.nonMembershipHints, this.nextPendingValueIndices);
return serializeToBuffer(
this.nonMembershipHints,
this.nextPendingValueIndices,
this.sortedPendingValues,
this.sortedPendingValueHints,
);
}
}

Expand Down
7 changes: 4 additions & 3 deletions yarn-project/simulator/src/public/abstract_phase_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,14 +338,15 @@ export abstract class AbstractPhaseManager {
): Promise<[PublicKernelCircuitPrivateInputs, PublicKernelCircuitPublicInputs]> {
const previousKernel = this.getPreviousKernelData(previousOutput, previousProof);

// We take a deep copy (clone) of these inputs to be passed to the prover
const inputs = new PublicKernelCircuitPrivateInputs(previousKernel, callData);
switch (this.phase) {
case PublicKernelPhase.SETUP:
return [inputs, await this.publicKernel.publicKernelCircuitSetup(inputs)];
return [inputs.clone(), await this.publicKernel.publicKernelCircuitSetup(inputs)];
case PublicKernelPhase.APP_LOGIC:
return [inputs, await this.publicKernel.publicKernelCircuitAppLogic(inputs)];
return [inputs.clone(), await this.publicKernel.publicKernelCircuitAppLogic(inputs)];
case PublicKernelPhase.TEARDOWN:
return [inputs, await this.publicKernel.publicKernelCircuitTeardown(inputs)];
return [inputs.clone(), await this.publicKernel.publicKernelCircuitTeardown(inputs)];
default:
throw new Error(`No public kernel circuit for inputs`);
}
Expand Down
4 changes: 3 additions & 1 deletion yarn-project/simulator/src/public/tail_phase_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,14 @@ export class TailPhaseManager extends AbstractPhaseManager {
endNonRevertibleData.newNullifiers,
end.newNullifiers,
);

// We take a deep copy (clone) of these to pass to the prover
const inputs = new PublicKernelTailCircuitPrivateInputs(
previousKernel,
nullifierReadRequestHints,
nullifierNonExistentReadRequestHints,
);
return [inputs, await this.publicKernel.publicKernelCircuitTail(inputs)];
return [inputs.clone(), await this.publicKernel.publicKernelCircuitTail(inputs)];
}

private sortNoteHashes<N extends number>(noteHashes: Tuple<SideEffect, N>): Tuple<Fr, N> {
Expand Down

0 comments on commit 114eec6

Please sign in to comment.