Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions yarn-project/foundation/src/crypto/poseidon/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Barretenberg } from '@aztec/bb.js';
import { BarretenbergSync } from '@aztec/bb.js';

import { Fr } from '../../curves/bn254/field.js';
import { poseidon2Permutation } from './index.js';

describe('poseidon2Permutation', () => {
beforeAll(async () => {
await Barretenberg.initSingleton({ threads: 1 });
await BarretenbergSync.initSingleton();
});

it('test vectors from cpp should match', async () => {
Expand Down
76 changes: 42 additions & 34 deletions yarn-project/foundation/src/crypto/poseidon/index.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
import { Barretenberg } from '@aztec/bb.js';
import { Barretenberg, BarretenbergSync } from '@aztec/bb.js';

import { Fr } from '../../curves/bn254/field.js';
import { type Fieldable, serializeToFields } from '../../serialize/serialize.js';

const IS_BROWSER = typeof window !== 'undefined';

async function poseidon2HashFields(inputFields: Fr[]): Promise<Fr> {
if (IS_BROWSER) {
await BarretenbergSync.initSingleton();
const api = BarretenbergSync.getSingleton();
const response = api.poseidon2Hash({
inputs: inputFields.map(i => i.toBuffer()),
});
return Fr.fromBuffer(Buffer.from(response.hash));
} else {
await Barretenberg.initSingleton();
const api = Barretenberg.getSingleton();
const response = await api.poseidon2Hash({
inputs: inputFields.map(i => i.toBuffer()),
});
return Fr.fromBuffer(Buffer.from(response.hash));
}
}

/**
* Create a poseidon hash (field) from an array of input fields.
* @param input - The input fields to hash.
* @returns The poseidon hash.
*/
export async function poseidon2Hash(input: Fieldable[]): Promise<Fr> {
const inputFields = serializeToFields(input);
await Barretenberg.initSingleton();
const api = Barretenberg.getSingleton();
const response = await api.poseidon2Hash({
inputs: inputFields.map(i => i.toBuffer()),
});
return Fr.fromBuffer(Buffer.from(response.hash));
export function poseidon2Hash(input: Fieldable[]): Promise<Fr> {
return poseidon2HashFields(serializeToFields(input));
}

/**
Expand All @@ -24,15 +38,10 @@ export async function poseidon2Hash(input: Fieldable[]): Promise<Fr> {
* @param separator - The domain separator.
* @returns The poseidon hash.
*/
export async function poseidon2HashWithSeparator(input: Fieldable[], separator: number): Promise<Fr> {
export function poseidon2HashWithSeparator(input: Fieldable[], separator: number): Promise<Fr> {
const inputFields = serializeToFields(input);
inputFields.unshift(new Fr(separator));
await Barretenberg.initSingleton();
const api = Barretenberg.getSingleton();
const response = await api.poseidon2Hash({
inputs: inputFields.map(i => i.toBuffer()),
});
return Fr.fromBuffer(Buffer.from(response.hash));
return poseidon2HashFields(inputFields);
}

/**
Expand All @@ -42,19 +51,24 @@ export async function poseidon2HashWithSeparator(input: Fieldable[], separator:
*/
export async function poseidon2Permutation(input: Fieldable[]): Promise<Fr[]> {
const inputFields = serializeToFields(input);
// We'd like this assertion but it's not possible to use it in the browser.
// assert(input.length === 4, 'Input state must be of size 4');
await Barretenberg.initSingleton();
const api = Barretenberg.getSingleton();
const response = await api.poseidon2Permutation({
inputs: inputFields.map(i => i.toBuffer()),
});
// We'd like this assertion but it's not possible to use it in the browser.
// assert(response.outputs.length === 4, 'Output state must be of size 4');
return response.outputs.map(o => Fr.fromBuffer(Buffer.from(o)));
if (IS_BROWSER) {
await BarretenbergSync.initSingleton();
const api = BarretenbergSync.getSingleton();
const response = api.poseidon2Permutation({
inputs: inputFields.map(i => i.toBuffer()),
});
return response.outputs.map(o => Fr.fromBuffer(Buffer.from(o)));
} else {
await Barretenberg.initSingleton();
const api = Barretenberg.getSingleton();
const response = await api.poseidon2Permutation({
inputs: inputFields.map(i => i.toBuffer()),
});
return response.outputs.map(o => Fr.fromBuffer(Buffer.from(o)));
}
}

export async function poseidon2HashBytes(input: Buffer): Promise<Fr> {
export function poseidon2HashBytes(input: Buffer): Promise<Fr> {
const inputFields = [];
for (let i = 0; i < input.length; i += 31) {
const fieldBytes = Buffer.alloc(32, 0);
Expand All @@ -65,11 +79,5 @@ export async function poseidon2HashBytes(input: Buffer): Promise<Fr> {
inputFields.push(Fr.fromBuffer(fieldBytes));
}

await Barretenberg.initSingleton();
const api = Barretenberg.getSingleton();
const response = await api.poseidon2Hash({
inputs: inputFields.map(i => i.toBuffer()),
});

return Fr.fromBuffer(Buffer.from(response.hash));
return poseidon2HashFields(inputFields);
}
Loading