Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: app siloing in new key store #5721

Merged
merged 5 commits into from
Apr 15, 2024
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
27 changes: 27 additions & 0 deletions yarn-project/circuit-types/src/keys/new_key_store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,31 @@ export interface NewKeyStore {
* @returns A Promise that resolves to the master tagging key.
*/
getMasterTaggingPublicKey(account: AztecAddress): Promise<PublicKey>;

/**
* Retrieves application nullifier secret key.
* @throws If the account does not exist in the key store.
* @param account - The account to retrieve the application nullifier secret key for.
* @param app - The application address to retrieve the nullifier secret key for.
* @returns A Promise that resolves to the application nullifier secret key.
*/
getAppNullifierSecretKey(account: AztecAddress, app: AztecAddress): Promise<Fr>;

/**
* Retrieves application incoming viewing secret key.
* @throws If the account does not exist in the key store.
* @param account - The account to retrieve the application incoming viewing secret key for.
* @param app - The application address to retrieve the incoming viewing secret key for.
* @returns A Promise that resolves to the application incoming viewing secret key.
*/
getAppIncomingViewingSecretKey(account: AztecAddress, app: AztecAddress): Promise<Fr>;

/**
* Retrieves application outgoing viewing secret key.
* @throws If the account does not exist in the key store.
* @param account - The account to retrieve the application outgoing viewing secret key for.
* @param app - The application address to retrieve the outgoing viewing secret key for.
* @returns A Promise that resolves to the application outgoing viewing secret key.
*/
getAppOutgoingViewingSecretKey(account: AztecAddress, app: AztecAddress): Promise<Fr>;
}
20 changes: 19 additions & 1 deletion yarn-project/key-store/src/new_test_key_store.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Fr } from '@aztec/circuits.js';
import { AztecAddress, Fr } from '@aztec/circuits.js';
import { Grumpkin } from '@aztec/circuits.js/barretenberg';
import { openTmpStore } from '@aztec/kv-store/utils';

Expand Down Expand Up @@ -37,5 +37,23 @@ describe('NewTestKeyStore', () => {
expect(masterTaggingPublicKey.toString()).toMatchInlineSnapshot(
`"0x076429010fdebfa522b053267f654a4c5daf18589915d96f7e5001d63ea2033f27f915f254560c84450aa38e93c3162be52492d05b316e75f542e3b302117360"`,
);

// Arbitrary app contract address
const appAddress = AztecAddress.fromBigInt(624n);

const appNullifierSecretKey = await keyStore.getAppNullifierSecretKey(accountAddress, appAddress);
expect(appNullifierSecretKey.toString()).toMatchInlineSnapshot(
`"0x230a44dfe7cfec7a735c89f7289c5cb5d2c3dc0bf5d3505917fd2476f67873a8"`,
);

const appIncomingViewingSecretKey = await keyStore.getAppIncomingViewingSecretKey(accountAddress, appAddress);
expect(appIncomingViewingSecretKey.toString()).toMatchInlineSnapshot(
`"0x0084c92262407236c992dcea10cf3406a642074cad6c6034d2990ffb073207a7"`,
);

const appOutgoingViewingSecretKey = await keyStore.getAppOutgoingViewingSecretKey(accountAddress, appAddress);
expect(appOutgoingViewingSecretKey.toString()).toMatchInlineSnapshot(
`"0x2639b26510f9d30b7e173d301b263b246b7a576186be1f44cd7c86bc06773f8a"`,
);
});
});
76 changes: 74 additions & 2 deletions yarn-project/key-store/src/new_test_key_store.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type NewKeyStore, type PublicKey } from '@aztec/circuit-types';
import { AztecAddress, Fr, GeneratorIndex, type PartialAddress, Point } from '@aztec/circuits.js';
import { AztecAddress, Fr, GeneratorIndex, GrumpkinScalar, type PartialAddress, Point } from '@aztec/circuits.js';
import { type Grumpkin } from '@aztec/circuits.js/barretenberg';
import { poseidon2Hash, sha512ToGrumpkinScalar } from '@aztec/foundation/crypto';
import { type AztecKVStore, type AztecMap } from '@aztec/kv-store';
Expand Down Expand Up @@ -60,7 +60,12 @@ export class NewTestKeyStore implements NewKeyStore {
const accountAddressFr = poseidon2Hash([partialAddress, publicKeysHash, GeneratorIndex.CONTRACT_ADDRESS_V1]);
const accountAddress = AztecAddress.fromField(accountAddressFr);

// We store the keys in the database
// We store all the public and secret keys in the database
await this.#keys.set(`${accountAddress.toString()}-nsk_m`, masterNullifierSecretKey.toBuffer());
await this.#keys.set(`${accountAddress.toString()}-ivsk_m`, masterIncomingViewingSecretKey.toBuffer());
await this.#keys.set(`${accountAddress.toString()}-ovsk_m`, masterOutgoingViewingSecretKey.toBuffer());
await this.#keys.set(`${accountAddress.toString()}-tsk_m`, masterTaggingSecretKey.toBuffer());

await this.#keys.set(`${accountAddress.toString()}-npk_m`, masterNullifierPublicKey.toBuffer());
await this.#keys.set(`${accountAddress.toString()}-ivpk_m`, masterIncomingViewingPublicKey.toBuffer());
await this.#keys.set(`${accountAddress.toString()}-ovpk_m`, masterOutgoingViewingPublicKey.toBuffer());
Expand Down Expand Up @@ -125,4 +130,71 @@ export class NewTestKeyStore implements NewKeyStore {
}
return Promise.resolve(Point.fromBuffer(masterTaggingPublicKeyBuffer));
}

/**
* Retrieves application nullifier secret key.
* @throws If the account does not exist in the key store.
* @param account - The account to retrieve the application nullifier secret key for.
* @param app - The application address to retrieve the nullifier secret key for.
* @returns A Promise that resolves to the application nullifier secret key.
*/
public getAppNullifierSecretKey(account: AztecAddress, app: AztecAddress): Promise<Fr> {
const masterNullifierSecretKeyBuffer = this.#keys.get(`${account.toString()}-nsk_m`);
if (!masterNullifierSecretKeyBuffer) {
throw new Error(`Account ${account.toString()} does not exist.`);
}
const masterNullifierSecretKey = GrumpkinScalar.fromBuffer(masterNullifierSecretKeyBuffer);

return Promise.resolve(
poseidon2Hash([masterNullifierSecretKey.high, masterNullifierSecretKey.low, app, GeneratorIndex.NSK_M]),
);
}

/**
* Retrieves application incoming viewing secret key.
* @throws If the account does not exist in the key store.
* @param account - The account to retrieve the application incoming viewing secret key for.
* @param app - The application address to retrieve the incoming viewing secret key for.
* @returns A Promise that resolves to the application incoming viewing secret key.
*/
public getAppIncomingViewingSecretKey(account: AztecAddress, app: AztecAddress): Promise<Fr> {
const masterIncomingViewingSecretKeyBuffer = this.#keys.get(`${account.toString()}-ivsk_m`);
if (!masterIncomingViewingSecretKeyBuffer) {
throw new Error(`Account ${account.toString()} does not exist.`);
}
const masterIncomingViewingSecretKey = GrumpkinScalar.fromBuffer(masterIncomingViewingSecretKeyBuffer);

return Promise.resolve(
poseidon2Hash([
masterIncomingViewingSecretKey.high,
masterIncomingViewingSecretKey.low,
app,
GeneratorIndex.IVSK_M,
]),
);
}

/**
* Retrieves application outgoing viewing secret key.
* @throws If the account does not exist in the key store.
* @param account - The account to retrieve the application outgoing viewing secret key for.
* @param app - The application address to retrieve the outgoing viewing secret key for.
* @returns A Promise that resolves to the application outgoing viewing secret key.
*/
public getAppOutgoingViewingSecretKey(account: AztecAddress, app: AztecAddress): Promise<Fr> {
const masterOutgoingViewingSecretKeyBuffer = this.#keys.get(`${account.toString()}-ovsk_m`);
if (!masterOutgoingViewingSecretKeyBuffer) {
throw new Error(`Account ${account.toString()} does not exist.`);
}
const masterOutgoingViewingSecretKey = GrumpkinScalar.fromBuffer(masterOutgoingViewingSecretKeyBuffer);

return Promise.resolve(
poseidon2Hash([
masterOutgoingViewingSecretKey.high,
masterOutgoingViewingSecretKey.low,
app,
GeneratorIndex.OVSK_M,
]),
);
}
}
Loading