-
Notifications
You must be signed in to change notification settings - Fork 271
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
022a899
commit 5e2b5f4
Showing
9 changed files
with
207 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import { pedersenCommit } from '@aztec/foundation/crypto'; | ||
|
||
import { type AvmContext } from '../avm_context.js'; | ||
import { Field, Uint32 } from '../avm_memory_types.js'; | ||
import { initContext, randomMemoryFields } from '../fixtures/index.js'; | ||
import { Addressing, AddressingMode } from './addressing_mode.js'; | ||
import { PedersenCommitment } from './commitment.js'; | ||
|
||
describe('Commitment Opcode', () => { | ||
let context: AvmContext; | ||
|
||
beforeEach(async () => { | ||
context = initContext(); | ||
}); | ||
|
||
describe('Pedersen Commitment', () => { | ||
it('Should (de)serialize correctly', () => { | ||
const buf = Buffer.from([ | ||
PedersenCommitment.opcode, // opcode | ||
1, // indirect | ||
...Buffer.from('23456789', 'hex'), // inputOffset | ||
...Buffer.from('3456789a', 'hex'), // inputSizeOffset | ||
...Buffer.from('12345678', 'hex'), // outputOffset | ||
...Buffer.from('00000000', 'hex'), // genIndexOffset | ||
]); | ||
const inst = new PedersenCommitment( | ||
/*indirect=*/ 1, | ||
/*inputOffset=*/ 0x23456789, | ||
/*inputSizeOffset=*/ 0x3456789a, | ||
/*outputOffset=*/ 0x12345678, | ||
/*genIndexOffset=*/ 0, | ||
); | ||
|
||
expect(PedersenCommitment.deserialize(buf)).toEqual(inst); | ||
expect(inst.serialize()).toEqual(buf); | ||
}); | ||
|
||
it('Should commit correctly - direct', async () => { | ||
const args = randomMemoryFields(10); | ||
const inputOffset = 0; | ||
const inputSizeOffset = 20; | ||
const outputOffset = 50; | ||
const indirect = 0; | ||
const generatorIndexOffset = 10; | ||
|
||
context.machineState.memory.setSlice(inputOffset, args); | ||
context.machineState.memory.set(inputSizeOffset, new Uint32(args.length)); | ||
context.machineState.memory.set(generatorIndexOffset, new Uint32(0)); | ||
|
||
const expectedCommitment = pedersenCommit(args.map(f => f.toBuffer())).map(f => new Field(f)); | ||
await new PedersenCommitment(indirect, inputOffset, outputOffset, inputSizeOffset, generatorIndexOffset).execute( | ||
context, | ||
); | ||
|
||
const result = context.machineState.memory.getSlice(outputOffset, 2); | ||
expect(result).toEqual(expectedCommitment); | ||
// Check Inf | ||
expect(0).toEqual(context.machineState.memory.get(outputOffset + 2).toNumber()); | ||
}); | ||
|
||
it('Should commit correctly - indirect', async () => { | ||
const args = randomMemoryFields(10); | ||
const indirect = new Addressing([ | ||
/*inputOffset=*/ AddressingMode.INDIRECT, | ||
/*outputOffset*/ AddressingMode.INDIRECT, | ||
/*inputSizeOffset=*/ AddressingMode.DIRECT, | ||
/*generatorIndexOffset=*/ AddressingMode.DIRECT, | ||
]).toWire(); | ||
const inputOffset = 0; | ||
const inputSizeOffset = 20; | ||
const outputOffset = 50; | ||
const realOutputOffset = 100; | ||
const realInputOffset = 200; | ||
const generatorIndexOffset = 51; | ||
|
||
context.machineState.memory.set(outputOffset, new Uint32(realOutputOffset)); | ||
context.machineState.memory.set(inputOffset, new Uint32(realInputOffset)); | ||
context.machineState.memory.setSlice(realInputOffset, args); | ||
context.machineState.memory.set(inputSizeOffset, new Uint32(args.length)); | ||
context.machineState.memory.set(generatorIndexOffset, new Uint32(0)); | ||
|
||
const expectedCommitment = pedersenCommit(args.map(f => f.toBuffer())).map(f => new Field(f)); | ||
await new PedersenCommitment(indirect, inputOffset, outputOffset, inputSizeOffset, generatorIndexOffset).execute( | ||
context, | ||
); | ||
|
||
const result = context.machineState.memory.getSlice(realOutputOffset, 2); | ||
expect(result).toEqual(expectedCommitment); | ||
// Check Inf | ||
expect(0).toEqual(context.machineState.memory.get(realOutputOffset + 2).toNumber()); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { pedersenCommit } from '@aztec/foundation/crypto'; | ||
|
||
import { type AvmContext } from '../avm_context.js'; | ||
import { Field, TypeTag, Uint8 } from '../avm_memory_types.js'; | ||
import { Opcode, OperandType } from '../serialization/instruction_serialization.js'; | ||
import { Addressing } from './addressing_mode.js'; | ||
import { Instruction } from './instruction.js'; | ||
|
||
export class PedersenCommitment extends Instruction { | ||
static type: string = 'PEDERSENCOMMITMENT'; | ||
static readonly opcode: Opcode = Opcode.PEDERSENCOMMITMENT; | ||
|
||
// Informs (de)serialization. See Instruction.deserialize. | ||
static readonly wireFormat: OperandType[] = [ | ||
OperandType.UINT8 /* Opcode */, | ||
OperandType.UINT8 /* Indirect */, | ||
OperandType.UINT32 /* Input Offset*/, | ||
OperandType.UINT32 /* Dst Offset */, | ||
OperandType.UINT32 /* Input Size Offset */, | ||
OperandType.UINT32 /* Generator Index Offset */, | ||
]; | ||
|
||
constructor( | ||
private indirect: number, | ||
private inputOffset: number, | ||
private outputOffset: number, | ||
private inputSizeOffset: number, | ||
private genIndexOffset: number, | ||
) { | ||
super(); | ||
} | ||
|
||
public async execute(context: AvmContext): Promise<void> { | ||
const memory = context.machineState.memory.track(this.type); | ||
const [inputOffset, outputOffset, inputSizeOffset, genIndexOffset] = Addressing.fromWire(this.indirect).resolve( | ||
[this.inputOffset, this.outputOffset, this.inputSizeOffset, this.genIndexOffset], | ||
memory, | ||
); | ||
|
||
const inputSize = Number(memory.get(inputSizeOffset).toBigInt()); | ||
memory.checkTag(TypeTag.UINT32, inputSizeOffset); | ||
|
||
const inputs = memory.getSlice(inputOffset, inputSize); | ||
memory.checkTagsRange(TypeTag.FIELD, inputOffset, inputSize); | ||
|
||
// Generator index not used for now since we dont utilise it in the pedersenCommit function | ||
memory.checkTag(TypeTag.UINT32, genIndexOffset); | ||
|
||
const memoryOperations = { reads: inputSize + 1, writes: 3, indirect: this.indirect }; | ||
context.machineState.consumeGas(this.gasCost(memoryOperations)); | ||
|
||
const inputBuffer: Buffer[] = inputs.map(input => input.toBuffer()); | ||
// TODO: Add the generate index to the pedersenCommit function | ||
const commitment = pedersenCommit(inputBuffer).map(f => new Field(f)); | ||
// The function doesnt include a flag if the output point is infinity, come back to this | ||
// for now we just check if theyre zero - until we know how bb encodes them | ||
const isInfinity = commitment[0].equals(new Field(0)) && commitment[1].equals(new Field(0)); | ||
|
||
memory.set(outputOffset, commitment[0]); // Field typed | ||
memory.set(outputOffset + 1, commitment[1]); // Field typed | ||
memory.set(outputOffset + 2, new Uint8(Number(isInfinity))); // U8 typed | ||
|
||
memory.assert(memoryOperations); | ||
context.machineState.incrementPc(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters