Skip to content

Commit 3f27a08

Browse files
feat!: add hashAsync and derivePublicKeyAsync variants to Blake2b and Bip32Ed25519
1 parent aaca2b8 commit 3f27a08

File tree

5 files changed

+56
-5
lines changed

5 files changed

+56
-5
lines changed

packages/crypto/src/Bip32Ed25519.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ export interface Bip32Ed25519 {
8282
*/
8383
derivePublicKey(parentKey: Bip32PublicKeyHex, derivationIndices: BIP32Path): Bip32PublicKeyHex;
8484

85+
/**
86+
* Given a parent extended key and a set of indices, this function computes the corresponding child extended key.
87+
*
88+
* @param parentKey The parent extended key.
89+
* @param derivationIndices The list of derivation indices.
90+
* @returns A promise returning the child extended public key.
91+
*/
92+
derivePublicKeyAsync(parentKey: Bip32PublicKeyHex, derivationIndices: BIP32Path): Promise<Bip32PublicKeyHex>;
93+
8594
/**
8695
* Generates an Ed25519 signature using an extended private key.
8796
*

packages/crypto/src/blake2b-hash.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,23 @@ export interface Blake2b {
2222
* @param outputLengthBytes digest size, e.g. 28 for blake2b-224 or 32 for blake2b-256
2323
*/
2424
hash<T extends HexBlob>(message: HexBlob, outputLengthBytes: number): T;
25+
26+
/**
27+
* @param message payload to hash
28+
* @param outputLengthBytes digest size, e.g. 28 for blake2b-224 or 32 for blake2b-256
29+
*/
30+
hashAsync<T extends HexBlob>(message: HexBlob, outputLengthBytes: number): Promise<T>;
2531
}
2632

2733
export const blake2b: Blake2b = {
2834
hash<T extends HexBlob>(message: HexBlob, outputLengthBytes: number) {
2935
return hash(outputLengthBytes).update(hexStringToBuffer(message)).digest('hex') as T;
36+
},
37+
async hashAsync<T extends HexBlob>(message: HexBlob, outputLengthBytes: number): Promise<T> {
38+
return new Promise((resolve) => {
39+
setImmediate(() => {
40+
resolve(blake2b.hash<T>(message, outputLengthBytes));
41+
});
42+
});
3043
}
3144
};

packages/crypto/src/strategies/CmlBip32Ed25519.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,17 @@ export class CmlBip32Ed25519 implements Bip32Ed25519 {
100100
});
101101
}
102102

103+
public async derivePublicKeyAsync(
104+
parentKey: Bip32PublicKeyHex,
105+
derivationIndices: BIP32Path
106+
): Promise<Bip32PublicKeyHex> {
107+
return new Promise((resolve) => {
108+
setImmediate(() => {
109+
resolve(this.derivePublicKey(parentKey, derivationIndices));
110+
});
111+
});
112+
}
113+
103114
public sign(
104115
privateKey: Ed25519PrivateExtendedKeyHex | Ed25519PrivateNormalKeyHex,
105116
message: HexBlob

packages/crypto/src/strategies/SodiumBip32Ed25519.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,17 @@ export class SodiumBip32Ed25519 implements Bip32Ed25519 {
7070
return pubKey.derive(derivationIndices).hex();
7171
}
7272

73+
public async derivePublicKeyAsync(
74+
parentKey: Bip32PublicKeyHex,
75+
derivationIndices: BIP32Path
76+
): Promise<Bip32PublicKeyHex> {
77+
return new Promise((resolve) => {
78+
setImmediate(() => {
79+
resolve(this.derivePublicKey(parentKey, derivationIndices));
80+
});
81+
});
82+
}
83+
7384
public sign(
7485
privateKey: Ed25519PrivateExtendedKeyHex | Ed25519PrivateNormalKeyHex,
7586
message: HexBlob

packages/key-management/src/Bip32Account.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ type Bip32AccountProps = {
2323
};
2424

2525
export type Bip32AccountDependencies = {
26-
bip32Ed25519: Pick<Bip32Ed25519, 'derivePublicKey'>;
26+
bip32Ed25519: Pick<Bip32Ed25519, 'derivePublicKeyAsync'>;
2727
blake2b: Blake2b;
2828
};
2929

@@ -47,8 +47,8 @@ export class Bip32Account {
4747
this.accountIndex = accountIndex;
4848
}
4949

50-
async derivePublicKey(derivationPath: AccountKeyDerivationPath) {
51-
const extendedKey = this.#bip32Ed25519.derivePublicKey(this.extendedAccountPublicKeyHex, [
50+
async derivePublicKey(derivationPath: AccountKeyDerivationPath): Promise<Crypto.Ed25519PublicKeyHex> {
51+
const extendedKey = await this.#bip32Ed25519.derivePublicKeyAsync(this.extendedAccountPublicKeyHex, [
5252
derivationPath.role,
5353
derivationPath.index
5454
]);
@@ -69,10 +69,16 @@ export class Bip32Account {
6969
role: Number(paymentKeyDerivationPath.type)
7070
});
7171

72-
const derivedPublicPaymentKeyHash = this.#blake2b.hash(derivedPublicPaymentKey, BIP32_PUBLIC_KEY_HASH_LENGTH);
72+
const derivedPublicPaymentKeyHash = (await this.#blake2b.hashAsync(
73+
derivedPublicPaymentKey,
74+
BIP32_PUBLIC_KEY_HASH_LENGTH
75+
)) as Crypto.Hash28ByteBase16;
7376

7477
const publicStakeKey = await this.derivePublicKey(stakeKeyDerivationPath);
75-
const publicStakeKeyHash = this.#blake2b.hash(publicStakeKey, BIP32_PUBLIC_KEY_HASH_LENGTH);
78+
const publicStakeKeyHash = (await this.#blake2b.hashAsync(
79+
publicStakeKey,
80+
BIP32_PUBLIC_KEY_HASH_LENGTH
81+
)) as Crypto.Hash28ByteBase16;
7682

7783
const stakeCredential = { hash: publicStakeKeyHash, type: Cardano.CredentialType.KeyHash };
7884

@@ -105,6 +111,7 @@ export class Bip32Account {
105111
* Creates a new instance of the Bip32Ed25519AddressManager class.
106112
*
107113
* @param keyAgent The key agent that will be used to derive addresses.
114+
* @param dependencies Optional dependencies for the Bip32Account. If not provided, default dependencies will be created.
108115
*/
109116
static async fromAsyncKeyAgent(
110117
keyAgent: AsyncKeyAgent,

0 commit comments

Comments
 (0)