@aztec/key-store 0.0.1-commit.e3c1de76 → 0.0.1-commit.e588bc7e5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -30,6 +30,8 @@ export declare class KeyStore {
30
30
  * @returns A Promise that resolves to an array of account addresses.
31
31
  */
32
32
  getAccounts(): Promise<AztecAddress[]>;
33
+ /** Checks whether an account is registered in the key store. */
34
+ hasAccount(account: AztecAddress): Promise<boolean>;
33
35
  /**
34
36
  * Gets the key validation request for a given master public key hash and contract address.
35
37
  * @throws If the account corresponding to the master public key hash does not exist in the key store.
@@ -89,6 +91,13 @@ export declare class KeyStore {
89
91
  * @dev Used when feeding the sk_m to the kernel circuit for keys verification.
90
92
  */
91
93
  getMasterSecretKey(pkM: PublicKey): Promise<GrumpkinScalar>;
94
+ /**
95
+ * Checks whether a given account has a key matching the provided master public key hash.
96
+ * @param account - The account address to check.
97
+ * @param pkMHash - The master public key hash to look for.
98
+ * @returns True if the account has a key with the given hash.
99
+ */
100
+ accountHasKey(account: AztecAddress, pkMHash: Fr): Promise<boolean>;
92
101
  /**
93
102
  * Gets the key prefix and account address for a given value.
94
103
  * @returns A tuple containing the key prefix and account address.
@@ -97,4 +106,4 @@ export declare class KeyStore {
97
106
  */
98
107
  getKeyPrefixAndAccount(value: Bufferable): Promise<[KeyPrefix, AztecAddress]>;
99
108
  }
100
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5X3N0b3JlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMva2V5X3N0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEVBQUUsY0FBYyxFQUFTLE1BQU0sbUNBQW1DLENBQUM7QUFFMUUsT0FBTyxFQUFFLEtBQUssVUFBVSxFQUFxQixNQUFNLDZCQUE2QixDQUFDO0FBQ2pGLE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFpQixNQUFNLGlCQUFpQixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsZUFBZSxFQUFFLEtBQUssY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDOUUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDNUQsT0FBTyxFQUVMLEtBQUssU0FBUyxFQUNkLEtBQUssU0FBUyxFQUlmLE1BQU0sb0JBQW9CLENBQUM7QUFFNUI7O0dBRUc7QUFDSCxxQkFBYSxRQUFROztJQUNuQixnQkFBdUIsY0FBYyxLQUFLO0lBSTFDLFlBQVksUUFBUSxFQUFFLGlCQUFpQixFQUd0QztJQUVEOzs7T0FHRztJQUNJLGFBQWEsSUFBSSxPQUFPLENBQUMsZUFBZSxDQUFDLENBSS9DO0lBRUQ7Ozs7O09BS0c7SUFDVSxVQUFVLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxjQUFjLEVBQUUsY0FBYyxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0F3Q3hGO0lBRUQ7OztPQUdHO0lBQ1UsV0FBVyxJQUFJLE9BQU8sQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUtsRDtJQUVEOzs7Ozs7T0FNRztJQUNVLHVCQUF1QixDQUFDLE9BQU8sRUFBRSxFQUFFLEVBQUUsZUFBZSxFQUFFLFlBQVksR0FBRyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FxQzlHO0lBRUQ7Ozs7O09BS0c7SUFDVSwyQkFBMkIsQ0FBQyxPQUFPLEVBQUUsWUFBWSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FRbEY7SUFFRDs7Ozs7T0FLRztJQUNVLGlDQUFpQyxDQUFDLE9BQU8sRUFBRSxZQUFZLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQVF4RjtJQUVEOzs7OztPQUtHO0lBQ1UsaUNBQWlDLENBQUMsT0FBTyxFQUFFLFlBQVksR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBUXhGO0lBRUQ7Ozs7O09BS0c7SUFDVSx5QkFBeUIsQ0FBQyxPQUFPLEVBQUUsWUFBWSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FRaEY7SUFFRDs7Ozs7T0FLRztJQUNVLGlDQUFpQyxDQUFDLE9BQU8sRUFBRSxZQUFZLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQVE3RjtJQUVEOzs7Ozs7T0FNRztJQUNVLDhCQUE4QixDQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsR0FBRyxFQUFFLFlBQVksR0FBRyxPQUFPLENBQUMsRUFBRSxDQUFDLENBYWpHO0lBRUQ7Ozs7OztPQU1HO0lBQ1Usa0JBQWtCLENBQUMsR0FBRyxFQUFFLFNBQVMsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDLENBaUJ2RTtJQUVEOzs7OztPQUtHO0lBQ1Usc0JBQXNCLENBQUMsS0FBSyxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FjekY7Q0FDRiJ9
109
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5X3N0b3JlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMva2V5X3N0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEVBQUUsY0FBYyxFQUFTLE1BQU0sbUNBQW1DLENBQUM7QUFFMUUsT0FBTyxFQUFFLEtBQUssVUFBVSxFQUFxQixNQUFNLDZCQUE2QixDQUFDO0FBQ2pGLE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFpQixNQUFNLGlCQUFpQixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsZUFBZSxFQUFFLEtBQUssY0FBYyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDOUUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDNUQsT0FBTyxFQUVMLEtBQUssU0FBUyxFQUNkLEtBQUssU0FBUyxFQUlmLE1BQU0sb0JBQW9CLENBQUM7QUFPNUI7O0dBRUc7QUFDSCxxQkFBYSxRQUFROztJQUNuQixnQkFBdUIsY0FBYyxLQUFLO0lBSTFDLFlBQVksUUFBUSxFQUFFLGlCQUFpQixFQUd0QztJQUVEOzs7T0FHRztJQUNJLGFBQWEsSUFBSSxPQUFPLENBQUMsZUFBZSxDQUFDLENBSS9DO0lBRUQ7Ozs7O09BS0c7SUFDVSxVQUFVLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxjQUFjLEVBQUUsY0FBYyxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0F3Q3hGO0lBRUQ7OztPQUdHO0lBQ1UsV0FBVyxJQUFJLE9BQU8sQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUtsRDtJQUVELGdFQUFnRTtJQUNuRCxVQUFVLENBQUMsT0FBTyxFQUFFLFlBQVksR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLENBRS9EO0lBRUQ7Ozs7OztPQU1HO0lBQ1UsdUJBQXVCLENBQUMsT0FBTyxFQUFFLEVBQUUsRUFBRSxlQUFlLEVBQUUsWUFBWSxHQUFHLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQXNDOUc7SUFFRDs7Ozs7T0FLRztJQUNVLDJCQUEyQixDQUFDLE9BQU8sRUFBRSxZQUFZLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQVFsRjtJQUVEOzs7OztPQUtHO0lBQ1UsaUNBQWlDLENBQUMsT0FBTyxFQUFFLFlBQVksR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBUXhGO0lBRUQ7Ozs7O09BS0c7SUFDVSxpQ0FBaUMsQ0FBQyxPQUFPLEVBQUUsWUFBWSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FReEY7SUFFRDs7Ozs7T0FLRztJQUNVLHlCQUF5QixDQUFDLE9BQU8sRUFBRSxZQUFZLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQVFoRjtJQUVEOzs7OztPQUtHO0lBQ1UsaUNBQWlDLENBQUMsT0FBTyxFQUFFLFlBQVksR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDLENBUTdGO0lBRUQ7Ozs7OztPQU1HO0lBQ1UsOEJBQThCLENBQUMsT0FBTyxFQUFFLFlBQVksRUFBRSxHQUFHLEVBQUUsWUFBWSxHQUFHLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0Fhakc7SUFFRDs7Ozs7O09BTUc7SUFDVSxrQkFBa0IsQ0FBQyxHQUFHLEVBQUUsU0FBUyxHQUFHLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FrQnZFO0lBRUQ7Ozs7O09BS0c7SUFDVSxhQUFhLENBQUMsT0FBTyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FTL0U7SUFFRDs7Ozs7T0FLRztJQUNVLHNCQUFzQixDQUFDLEtBQUssRUFBRSxVQUFVLEdBQUcsT0FBTyxDQUFDLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBY3pGO0NBQ0YifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"key_store.d.ts","sourceRoot":"","sources":["../src/key_store.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,EAAE,cAAc,EAAS,MAAM,mCAAmC,CAAC;AAE1E,OAAO,EAAE,KAAK,UAAU,EAAqB,MAAM,6BAA6B,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,SAAS,EAIf,MAAM,oBAAoB,CAAC;AAE5B;;GAEG;AACH,qBAAa,QAAQ;;IACnB,gBAAuB,cAAc,KAAK;IAI1C,YAAY,QAAQ,EAAE,iBAAiB,EAGtC;IAED;;;OAGG;IACI,aAAa,IAAI,OAAO,CAAC,eAAe,CAAC,CAI/C;IAED;;;;;OAKG;IACU,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAwCxF;IAED;;;OAGG;IACU,WAAW,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAKlD;IAED;;;;;;OAMG;IACU,uBAAuB,CAAC,OAAO,EAAE,EAAE,EAAE,eAAe,EAAE,YAAY,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAqC9G;IAED;;;;;OAKG;IACU,2BAA2B,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAQlF;IAED;;;;;OAKG;IACU,iCAAiC,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAQxF;IAED;;;;;OAKG;IACU,iCAAiC,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAQxF;IAED;;;;;OAKG;IACU,yBAAyB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAQhF;IAED;;;;;OAKG;IACU,iCAAiC,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CAQ7F;IAED;;;;;;OAMG;IACU,8BAA8B,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,EAAE,CAAC,CAajG;IAED;;;;;;OAMG;IACU,kBAAkB,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,CAiBvE;IAED;;;;;OAKG;IACU,sBAAsB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAczF;CACF"}
1
+ {"version":3,"file":"key_store.d.ts","sourceRoot":"","sources":["../src/key_store.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,EAAE,cAAc,EAAS,MAAM,mCAAmC,CAAC;AAE1E,OAAO,EAAE,KAAK,UAAU,EAAqB,MAAM,6BAA6B,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,SAAS,EAIf,MAAM,oBAAoB,CAAC;AAO5B;;GAEG;AACH,qBAAa,QAAQ;;IACnB,gBAAuB,cAAc,KAAK;IAI1C,YAAY,QAAQ,EAAE,iBAAiB,EAGtC;IAED;;;OAGG;IACI,aAAa,IAAI,OAAO,CAAC,eAAe,CAAC,CAI/C;IAED;;;;;OAKG;IACU,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAwCxF;IAED;;;OAGG;IACU,WAAW,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAKlD;IAED,gEAAgE;IACnD,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAE/D;IAED;;;;;;OAMG;IACU,uBAAuB,CAAC,OAAO,EAAE,EAAE,EAAE,eAAe,EAAE,YAAY,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAsC9G;IAED;;;;;OAKG;IACU,2BAA2B,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAQlF;IAED;;;;;OAKG;IACU,iCAAiC,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAQxF;IAED;;;;;OAKG;IACU,iCAAiC,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAQxF;IAED;;;;;OAKG;IACU,yBAAyB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAQhF;IAED;;;;;OAKG;IACU,iCAAiC,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CAQ7F;IAED;;;;;;OAMG;IACU,8BAA8B,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,EAAE,CAAC,CAajG;IAED;;;;;;OAMG;IACU,kBAAkB,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,CAkBvE;IAED;;;;;OAKG;IACU,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAS/E;IAED;;;;;OAKG;IACU,sBAAsB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAczF;CACF"}
package/dest/key_store.js CHANGED
@@ -1,4 +1,4 @@
1
- import { GeneratorIndex } from '@aztec/constants';
1
+ import { DomainSeparator } from '@aztec/constants';
2
2
  import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto/poseidon';
3
3
  import { Fr } from '@aztec/foundation/curves/bn254';
4
4
  import { GrumpkinScalar, Point } from '@aztec/foundation/curves/grumpkin';
@@ -8,6 +8,9 @@ import { AztecAddress } from '@aztec/stdlib/aztec-address';
8
8
  import { CompleteAddress } from '@aztec/stdlib/contract';
9
9
  import { KeyValidationRequest } from '@aztec/stdlib/kernel';
10
10
  import { KEY_PREFIXES, computeAppSecretKey, deriveKeys, derivePublicKeyFromSecretKey } from '@aztec/stdlib/keys';
11
+ /** Maps a key prefix to the storage suffix for the corresponding master secret key. */ function secretKeyStorageSuffix(prefix) {
12
+ return prefix === 'n' ? 'nhk_m' : `${prefix}sk_m`;
13
+ }
11
14
  /**
12
15
  * Used for managing keys. Can hold keys of multiple accounts.
13
16
  */ export class KeyStore {
@@ -32,7 +35,7 @@ import { KEY_PREFIXES, computeAppSecretKey, deriveKeys, derivePublicKeyFromSecre
32
35
  * @param partialAddress - The partial address of the account.
33
36
  * @returns The account's complete address.
34
37
  */ async addAccount(sk, partialAddress) {
35
- const { masterNullifierSecretKey, masterIncomingViewingSecretKey, masterOutgoingViewingSecretKey, masterTaggingSecretKey, publicKeys } = await deriveKeys(sk);
38
+ const { masterNullifierHidingKey, masterIncomingViewingSecretKey, masterOutgoingViewingSecretKey, masterTaggingSecretKey, publicKeys } = await deriveKeys(sk);
36
39
  const completeAddress = await CompleteAddress.fromSecretKeyAndPartialAddress(sk, partialAddress);
37
40
  const { address: account } = completeAddress;
38
41
  // Compute hashes before transaction
@@ -45,7 +48,7 @@ import { KEY_PREFIXES, computeAppSecretKey, deriveKeys, derivePublicKeyFromSecre
45
48
  await this.#keys.set(`${account.toString()}-ivsk_m`, masterIncomingViewingSecretKey.toBuffer());
46
49
  await this.#keys.set(`${account.toString()}-ovsk_m`, masterOutgoingViewingSecretKey.toBuffer());
47
50
  await this.#keys.set(`${account.toString()}-tsk_m`, masterTaggingSecretKey.toBuffer());
48
- await this.#keys.set(`${account.toString()}-nsk_m`, masterNullifierSecretKey.toBuffer());
51
+ await this.#keys.set(`${account.toString()}-nhk_m`, masterNullifierHidingKey.toBuffer());
49
52
  await this.#keys.set(`${account.toString()}-npk_m`, publicKeys.masterNullifierPublicKey.toBuffer());
50
53
  await this.#keys.set(`${account.toString()}-ivpk_m`, publicKeys.masterIncomingViewingPublicKey.toBuffer());
51
54
  await this.#keys.set(`${account.toString()}-ovpk_m`, publicKeys.masterOutgoingViewingPublicKey.toBuffer());
@@ -69,6 +72,9 @@ import { KEY_PREFIXES, computeAppSecretKey, deriveKeys, derivePublicKeyFromSecre
69
72
  const accounts = allMapKeys.filter((key)=>key.endsWith('-ivsk_m')).map((key)=>key.split('-')[0]);
70
73
  return accounts.map((account)=>AztecAddress.fromString(account));
71
74
  }
75
+ /** Checks whether an account is registered in the key store. */ async hasAccount(account) {
76
+ return !!await this.#keys.getAsync(`${account.toString()}-ivsk_m`);
77
+ }
72
78
  /**
73
79
  * Gets the key validation request for a given master public key hash and contract address.
74
80
  * @throws If the account corresponding to the master public key hash does not exist in the key store.
@@ -88,9 +94,10 @@ import { KEY_PREFIXES, computeAppSecretKey, deriveKeys, derivePublicKeyFromSecre
88
94
  throw new Error(`Could not find ${keyPrefix}pkM for ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`);
89
95
  }
90
96
  // Now we find the secret key for the public key
91
- const skMBuffer = await this.#keys.getAsync(`${account.toString()}-${keyPrefix}sk_m`);
97
+ const skStorageSuffix = secretKeyStorageSuffix(keyPrefix);
98
+ const skMBuffer = await this.#keys.getAsync(`${account.toString()}-${skStorageSuffix}`);
92
99
  if (!skMBuffer) {
93
- throw new Error(`Could not find ${keyPrefix}sk_m for account ${account.toString()} whose address was successfully obtained with ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`);
100
+ throw new Error(`Could not find ${skStorageSuffix} for account ${account.toString()} whose address was successfully obtained with ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`);
94
101
  }
95
102
  const skM = GrumpkinScalar.fromBuffer(skMBuffer);
96
103
  // We sanity check that it's possible to derive the public key from the secret key
@@ -178,7 +185,7 @@ import { KEY_PREFIXES, computeAppSecretKey, deriveKeys, derivePublicKeyFromSecre
178
185
  masterOutgoingViewingSecretKey.hi,
179
186
  masterOutgoingViewingSecretKey.lo,
180
187
  app
181
- ], GeneratorIndex.OVSK_M);
188
+ ], DomainSeparator.OVSK_M);
182
189
  }
183
190
  /**
184
191
  * Retrieves the sk_m corresponding to the pk_m.
@@ -188,18 +195,34 @@ import { KEY_PREFIXES, computeAppSecretKey, deriveKeys, derivePublicKeyFromSecre
188
195
  * @dev Used when feeding the sk_m to the kernel circuit for keys verification.
189
196
  */ async getMasterSecretKey(pkM) {
190
197
  const [keyPrefix, account] = await this.getKeyPrefixAndAccount(pkM);
191
- const secretKeyBuffer = await this.#keys.getAsync(`${account.toString()}-${keyPrefix}sk_m`);
198
+ const skStorageSuffix = secretKeyStorageSuffix(keyPrefix);
199
+ const secretKeyBuffer = await this.#keys.getAsync(`${account.toString()}-${skStorageSuffix}`);
192
200
  if (!secretKeyBuffer) {
193
- throw new Error(`Could not find ${keyPrefix}sk_m for ${keyPrefix}pk_m ${pkM.toString()}. This should not happen.`);
201
+ throw new Error(`Could not find ${skStorageSuffix} for ${keyPrefix}pk_m ${pkM.toString()}. This should not happen.`);
194
202
  }
195
203
  const skM = GrumpkinScalar.fromBuffer(secretKeyBuffer);
196
204
  const derivedpkM = await derivePublicKeyFromSecretKey(skM);
197
205
  if (!derivedpkM.equals(pkM)) {
198
- throw new Error(`Could not find ${keyPrefix}skM for ${keyPrefix}pkM ${pkM.toString()} in secret keys buffer.`);
206
+ throw new Error(`Could not find ${skStorageSuffix} for ${keyPrefix}pkM ${pkM.toString()} in secret keys buffer.`);
199
207
  }
200
208
  return Promise.resolve(skM);
201
209
  }
202
210
  /**
211
+ * Checks whether a given account has a key matching the provided master public key hash.
212
+ * @param account - The account address to check.
213
+ * @param pkMHash - The master public key hash to look for.
214
+ * @returns True if the account has a key with the given hash.
215
+ */ async accountHasKey(account, pkMHash) {
216
+ const pkMHashBuffer = serializeToBuffer(pkMHash);
217
+ for (const prefix of KEY_PREFIXES){
218
+ const stored = await this.#keys.getAsync(`${account.toString()}-${prefix}pk_m_hash`);
219
+ if (stored && Buffer.from(stored).equals(pkMHashBuffer)) {
220
+ return true;
221
+ }
222
+ }
223
+ return false;
224
+ }
225
+ /**
203
226
  * Gets the key prefix and account address for a given value.
204
227
  * @returns A tuple containing the key prefix and account address.
205
228
  * @dev Note that this is quite inefficient but it should not matter because there should never be too many keys
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/key-store",
3
- "version": "0.0.1-commit.e3c1de76",
3
+ "version": "0.0.1-commit.e588bc7e5",
4
4
  "type": "module",
5
5
  "exports": "./dest/index.js",
6
6
  "typedocOptions": {
@@ -57,10 +57,10 @@
57
57
  ]
58
58
  },
59
59
  "dependencies": {
60
- "@aztec/constants": "0.0.1-commit.e3c1de76",
61
- "@aztec/foundation": "0.0.1-commit.e3c1de76",
62
- "@aztec/kv-store": "0.0.1-commit.e3c1de76",
63
- "@aztec/stdlib": "0.0.1-commit.e3c1de76",
60
+ "@aztec/constants": "0.0.1-commit.e588bc7e5",
61
+ "@aztec/foundation": "0.0.1-commit.e588bc7e5",
62
+ "@aztec/kv-store": "0.0.1-commit.e588bc7e5",
63
+ "@aztec/stdlib": "0.0.1-commit.e588bc7e5",
64
64
  "tslib": "^2.4.0"
65
65
  },
66
66
  "devDependencies": {
package/src/key_store.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { GeneratorIndex } from '@aztec/constants';
1
+ import { DomainSeparator } from '@aztec/constants';
2
2
  import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto/poseidon';
3
3
  import { Fr } from '@aztec/foundation/curves/bn254';
4
4
  import { GrumpkinScalar, Point } from '@aztec/foundation/curves/grumpkin';
@@ -17,6 +17,11 @@ import {
17
17
  derivePublicKeyFromSecretKey,
18
18
  } from '@aztec/stdlib/keys';
19
19
 
20
+ /** Maps a key prefix to the storage suffix for the corresponding master secret key. */
21
+ function secretKeyStorageSuffix(prefix: KeyPrefix): string {
22
+ return prefix === 'n' ? 'nhk_m' : `${prefix}sk_m`;
23
+ }
24
+
20
25
  /**
21
26
  * Used for managing keys. Can hold keys of multiple accounts.
22
27
  */
@@ -48,7 +53,7 @@ export class KeyStore {
48
53
  */
49
54
  public async addAccount(sk: Fr, partialAddress: PartialAddress): Promise<CompleteAddress> {
50
55
  const {
51
- masterNullifierSecretKey,
56
+ masterNullifierHidingKey,
52
57
  masterIncomingViewingSecretKey,
53
58
  masterOutgoingViewingSecretKey,
54
59
  masterTaggingSecretKey,
@@ -69,7 +74,7 @@ export class KeyStore {
69
74
  await this.#keys.set(`${account.toString()}-ivsk_m`, masterIncomingViewingSecretKey.toBuffer());
70
75
  await this.#keys.set(`${account.toString()}-ovsk_m`, masterOutgoingViewingSecretKey.toBuffer());
71
76
  await this.#keys.set(`${account.toString()}-tsk_m`, masterTaggingSecretKey.toBuffer());
72
- await this.#keys.set(`${account.toString()}-nsk_m`, masterNullifierSecretKey.toBuffer());
77
+ await this.#keys.set(`${account.toString()}-nhk_m`, masterNullifierHidingKey.toBuffer());
73
78
 
74
79
  await this.#keys.set(`${account.toString()}-npk_m`, publicKeys.masterNullifierPublicKey.toBuffer());
75
80
  await this.#keys.set(`${account.toString()}-ivpk_m`, publicKeys.masterIncomingViewingPublicKey.toBuffer());
@@ -99,6 +104,11 @@ export class KeyStore {
99
104
  return accounts.map(account => AztecAddress.fromString(account));
100
105
  }
101
106
 
107
+ /** Checks whether an account is registered in the key store. */
108
+ public async hasAccount(account: AztecAddress): Promise<boolean> {
109
+ return !!(await this.#keys.getAsync(`${account.toString()}-ivsk_m`));
110
+ }
111
+
102
112
  /**
103
113
  * Gets the key validation request for a given master public key hash and contract address.
104
114
  * @throws If the account corresponding to the master public key hash does not exist in the key store.
@@ -124,10 +134,11 @@ export class KeyStore {
124
134
  }
125
135
 
126
136
  // Now we find the secret key for the public key
127
- const skMBuffer = await this.#keys.getAsync(`${account.toString()}-${keyPrefix}sk_m`);
137
+ const skStorageSuffix = secretKeyStorageSuffix(keyPrefix);
138
+ const skMBuffer = await this.#keys.getAsync(`${account.toString()}-${skStorageSuffix}`);
128
139
  if (!skMBuffer) {
129
140
  throw new Error(
130
- `Could not find ${keyPrefix}sk_m for account ${account.toString()} whose address was successfully obtained with ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`,
141
+ `Could not find ${skStorageSuffix} for account ${account.toString()} whose address was successfully obtained with ${keyPrefix}pk_m_hash ${pkMHash.toString()}.`,
131
142
  );
132
143
  }
133
144
 
@@ -243,7 +254,7 @@ export class KeyStore {
243
254
 
244
255
  return poseidon2HashWithSeparator(
245
256
  [masterOutgoingViewingSecretKey.hi, masterOutgoingViewingSecretKey.lo, app],
246
- GeneratorIndex.OVSK_M,
257
+ DomainSeparator.OVSK_M,
247
258
  );
248
259
  }
249
260
 
@@ -257,22 +268,40 @@ export class KeyStore {
257
268
  public async getMasterSecretKey(pkM: PublicKey): Promise<GrumpkinScalar> {
258
269
  const [keyPrefix, account] = await this.getKeyPrefixAndAccount(pkM);
259
270
 
260
- const secretKeyBuffer = await this.#keys.getAsync(`${account.toString()}-${keyPrefix}sk_m`);
271
+ const skStorageSuffix = secretKeyStorageSuffix(keyPrefix);
272
+ const secretKeyBuffer = await this.#keys.getAsync(`${account.toString()}-${skStorageSuffix}`);
261
273
  if (!secretKeyBuffer) {
262
274
  throw new Error(
263
- `Could not find ${keyPrefix}sk_m for ${keyPrefix}pk_m ${pkM.toString()}. This should not happen.`,
275
+ `Could not find ${skStorageSuffix} for ${keyPrefix}pk_m ${pkM.toString()}. This should not happen.`,
264
276
  );
265
277
  }
266
278
 
267
279
  const skM = GrumpkinScalar.fromBuffer(secretKeyBuffer);
268
280
  const derivedpkM = await derivePublicKeyFromSecretKey(skM);
269
281
  if (!derivedpkM.equals(pkM)) {
270
- throw new Error(`Could not find ${keyPrefix}skM for ${keyPrefix}pkM ${pkM.toString()} in secret keys buffer.`);
282
+ throw new Error(`Could not find ${skStorageSuffix} for ${keyPrefix}pkM ${pkM.toString()} in secret keys buffer.`);
271
283
  }
272
284
 
273
285
  return Promise.resolve(skM);
274
286
  }
275
287
 
288
+ /**
289
+ * Checks whether a given account has a key matching the provided master public key hash.
290
+ * @param account - The account address to check.
291
+ * @param pkMHash - The master public key hash to look for.
292
+ * @returns True if the account has a key with the given hash.
293
+ */
294
+ public async accountHasKey(account: AztecAddress, pkMHash: Fr): Promise<boolean> {
295
+ const pkMHashBuffer = serializeToBuffer(pkMHash);
296
+ for (const prefix of KEY_PREFIXES) {
297
+ const stored = await this.#keys.getAsync(`${account.toString()}-${prefix}pk_m_hash`);
298
+ if (stored && Buffer.from(stored).equals(pkMHashBuffer)) {
299
+ return true;
300
+ }
301
+ }
302
+ return false;
303
+ }
304
+
276
305
  /**
277
306
  * Gets the key prefix and account address for a given value.
278
307
  * @returns A tuple containing the key prefix and account address.