From daad843c1ec0eda80731de0e427d10e798ab1d15 Mon Sep 17 00:00:00 2001 From: benesjan Date: Thu, 11 Apr 2024 14:57:54 +0000 Subject: [PATCH] WIP --- .../crates/types/src/constants.nr | 2 + .../circuit-types/src/keys/new_key_store.ts | 32 ++--- yarn-project/circuits.js/src/constants.gen.ts | 2 + .../key-store/src/new_test_key_store.ts | 127 +++++++++++++++--- 4 files changed, 128 insertions(+), 35 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 95dc8666cf2f..ed5364b86de6 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -237,3 +237,5 @@ global GENERATOR_INDEX__NSK_M = 47; global GENERATOR_INDEX__IVSK_M = 48; global GENERATOR_INDEX__OVSK_M = 49; global GENERATOR_INDEX__TSK_M = 50; +global GENERATOR_INDEX__PUBLIC_KEYS_HASH = 51; +global GENERATOR_INDEX__CONTRACT_ADDRESS_V1 = 52; diff --git a/yarn-project/circuit-types/src/keys/new_key_store.ts b/yarn-project/circuit-types/src/keys/new_key_store.ts index 861072b81477..faaf018b833a 100644 --- a/yarn-project/circuit-types/src/keys/new_key_store.ts +++ b/yarn-project/circuit-types/src/keys/new_key_store.ts @@ -1,36 +1,38 @@ -import { AztecAddress, Fr, PartialAddress, type PublicKey } from '@aztec/circuits.js'; +import { type AztecAddress, Fr, PartialAddress, type PublicKey } from '@aztec/circuits.js'; /** * Represents a secure storage for managing keys. */ export interface NewKeyStore { /** - * Retrieves the master nullifier public key. - * @returns A Promise that resolves to the master nullifier public key. + * Gets the master nullifier public key for a given account. + * @throws If the account does not exist in the key store. + * @param account - The account address for which to retrieve the master nullifier public key. + * @returns The master nullifier public key for the account. */ - getMasterNullifierPublicKey(): Promise; + getMasterNullifierPublicKey(account: AztecAddress): Promise; /** - * Retrieves the master incoming viewing key. - * @returns A Promise that resolves to the master incoming viewing key. + * Gets the master incoming viewing public key for a given account. + * @throws If the account does not exist in the key store. + * @param account - The account address for which to retrieve the master incoming viewing public key. + * @returns The master incoming viewing public key for the account. */ - getMasterIncomingViewingPublicKey(): Promise; + getMasterIncomingViewingPublicKey(account: AztecAddress): Promise; /** * Retrieves the master outgoing viewing key. + * @throws If the account does not exist in the key store. + * @param account - The account to retrieve the master outgoing viewing key for. * @returns A Promise that resolves to the master outgoing viewing key. */ - getMasterOutgoingViewingPublicKey(): Promise; + getMasterOutgoingViewingPublicKey(account: AztecAddress): Promise; /** * Retrieves the master tagging key. + * @throws If the account does not exist in the key store. + * @param account - The account to retrieve the master tagging key for. * @returns A Promise that resolves to the master tagging key. */ - getMasterTaggingPublicKey(): Promise; - - /** - * Retrieves the hash of the public keys. - * @returns A Promise that resolves to the hash of the public keys. - */ - getPublicKeysHash(): Promise; + getMasterTaggingPublicKey(account: AztecAddress): Promise; } diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 2c0c60814562..a945377f061b 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -152,4 +152,6 @@ export enum GeneratorIndex { IVSK_M = 48, OVSK_M = 49, TSK_M = 50, + PUBLIC_KEYS_HASH = 51, + CONTRACT_ADDRESS_V1 = 52, } diff --git a/yarn-project/key-store/src/new_test_key_store.ts b/yarn-project/key-store/src/new_test_key_store.ts index 14476d6084ba..784410316f98 100644 --- a/yarn-project/key-store/src/new_test_key_store.ts +++ b/yarn-project/key-store/src/new_test_key_store.ts @@ -1,21 +1,9 @@ -import { type NewKeyStore, type KeyPair, type KeyStore, type PublicKey } from '@aztec/circuit-types'; -import { - type AztecAddress, - type GrumpkinPrivateKey, - GrumpkinScalar, - Point, - computeNullifierSecretKey, - computeSiloedNullifierSecretKey, - derivePublicKey, - type Fr, - GeneratorIndex, - Fq, -} from '@aztec/circuits.js'; +import { type NewKeyStore, type PublicKey } from '@aztec/circuit-types'; +import { AztecAddress, Fq, type Fr, GeneratorIndex, type PartialAddress, Point } from '@aztec/circuits.js'; import { type Grumpkin } from '@aztec/circuits.js/barretenberg'; +import { poseidonHash } from '@aztec/foundation/crypto'; import { type AztecKVStore, type AztecMap } from '@aztec/kv-store'; -import { ConstantKeyPair } from './key_pair.js'; -import { poseidonHash } from '@aztec/foundation/crypto'; /** * TestKeyStore is an implementation of the KeyStore interface, used for managing key pairs in a testing environment. * It should be utilized in testing scenarios where secure key management is not required, and ease-of-use is prioritized. @@ -28,13 +16,112 @@ export class NewTestKeyStore implements NewKeyStore { this.#keys = database.openMap('key_store'); } - public async addAccount(sk: Fr): Promise { + public async addAccount(sk: Fr, partialAddress: PartialAddress): Promise { + // First we derive the master secret keys const masterNullifierSecretKey = poseidonHash([sk], GeneratorIndex.NSK_M); - // TODO: Is converting from Fr to Fq an issue? Fr.MODULUS is < Fq.MODULUS so it wont' throw but should we refactor this? - const masterNullifierPublicKey = this.curve.mul(this.curve.generator(), Fq.fromBuffer(masterNullifierSecretKey.toBuffer())) + const masterIncomingViewingSecretKey = poseidonHash([sk], GeneratorIndex.IVSK_M); + const masterOutgoingViewingSecretKey = poseidonHash([sk], GeneratorIndex.OVSK_M); + const masterTaggingSecretKey = poseidonHash([sk], GeneratorIndex.TSK_M); + + // Then we derive the master public keys + // TODO: Is converting from Fr to Fq bellow an issue? Fr.MODULUS is < Fq.MODULUS so it shouldn't but should we refactor this anyway? + const masterNullifierPublicKey = this.curve.mul( + this.curve.generator(), + Fq.fromBuffer(masterNullifierSecretKey.toBuffer()), + ); + const masterIncomingViewingPublicKey = this.curve.mul( + this.curve.generator(), + Fq.fromBuffer(masterIncomingViewingSecretKey.toBuffer()), + ); + const masterOutgoingViewingPublicKey = this.curve.mul( + this.curve.generator(), + Fq.fromBuffer(masterOutgoingViewingSecretKey.toBuffer()), + ); + const masterTaggingPublicKey = this.curve.mul( + this.curve.generator(), + Fq.fromBuffer(masterTaggingSecretKey.toBuffer()), + ); + + // We hash the public keys to get the public keys hash + const publicKeysHash = poseidonHash( + [ + masterNullifierPublicKey, + masterIncomingViewingPublicKey, + masterOutgoingViewingPublicKey, + masterTaggingPublicKey, + ], + GeneratorIndex.PUBLIC_KEYS_HASH, + ); + + // We hash the partial address and the public keys hash to get the account address + // TODO: Should GeneratorIndex.CONTRACT_ADDRESS be removed given that we introduced CONTRACT_ADDRESS_V1? + // TODO: Move the following line to AztecAddress class? + const accountAddressFr = poseidonHash([partialAddress, publicKeysHash], GeneratorIndex.CONTRACT_ADDRESS_V1); + const accountAddress = AztecAddress.fromField(accountAddressFr); + + // We store the keys in the database + 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()); + await this.#keys.set(`${accountAddress.toString()}-tpk_m`, masterTaggingPublicKey.toBuffer()); + + // At last, we return the newly derived account address + return Promise.resolve(accountAddress); + } + + /** + * Gets the master nullifier public key for a given account. + * @throws If the account does not exist in the key store. + * @param account - The account address for which to retrieve the master nullifier public key. + * @returns The master nullifier public key for the account. + */ + public getMasterNullifierPublicKey(account: AztecAddress): Promise { + const masterNullifierPublicKeyBuffer = this.#keys.get(`${account.toString()}-npk_m`); + if (!masterNullifierPublicKeyBuffer) { + throw new Error(`Account ${account.toString()} does not exist.`); + } + return Promise.resolve(Point.fromBuffer(masterNullifierPublicKeyBuffer)); + } + + /** + * Gets the master incoming viewing public key for a given account. + * @throws If the account does not exist in the key store. + * @param account - The account address for which to retrieve the master incoming viewing public key. + * @returns The master incoming viewing public key for the account. + */ + public getMasterIncomingViewingPublicKey(account: AztecAddress): Promise { + const masterIncomingViewingPublicKeyBuffer = this.#keys.get(`${account.toString()}-ivpk_m`); + if (!masterIncomingViewingPublicKeyBuffer) { + throw new Error(`Account ${account.toString()} does not exist.`); + } + return Promise.resolve(Point.fromBuffer(masterIncomingViewingPublicKeyBuffer)); + } + + /** + * Retrieves the master outgoing viewing public key. + * @throws If the account does not exist in the key store. + * @param account - The account to retrieve the master outgoing viewing key for. + * @returns A Promise that resolves to the master outgoing viewing key. + */ + public getMasterOutgoingViewingPublicKey(account: AztecAddress): Promise { + const masterOutgoingViewingPublicKeyBuffer = this.#keys.get(`${account.toString()}-ovpk_m`); + if (!masterOutgoingViewingPublicKeyBuffer) { + throw new Error(`Account ${account.toString()} does not exist.`); + } + return Promise.resolve(Point.fromBuffer(masterOutgoingViewingPublicKeyBuffer)); } - public async getMasterNullifierPublicKey(): Promise { - return poseidonHash() + /** + * Retrieves the master tagging public key. + * @throws If the account does not exist in the key store. + * @param account - The account to retrieve the master tagging key for. + * @returns A Promise that resolves to the master tagging key. + */ + public getMasterTaggingPublicKey(account: AztecAddress): Promise { + const masterTaggingPublicKeyBuffer = this.#keys.get(`${account.toString()}-tpk_m`); + if (!masterTaggingPublicKeyBuffer) { + throw new Error(`Account ${account.toString()} does not exist.`); + } + return Promise.resolve(Point.fromBuffer(masterTaggingPublicKeyBuffer)); } }