Skip to content

Commit ea0b2c2

Browse files
Merge pull request #1558 from input-output-hk/feat/lw-12104-remove-async-from-crypto-interfaces
2 parents 882dc9d + 91b7fa2 commit ea0b2c2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+291
-230
lines changed

packages/cardano-services/src/StakePool/HttpStakePoolMetadata/HttpStakePoolMetadataService.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,10 @@ export const createHttpStakePoolMetadataService = (
124124
const signature = (await axiosClient.get<Crypto.Ed25519SignatureHex>(metadata.extSigUrl)).data;
125125
const message = HexBlob.fromBytes(Buffer.from(JSON.stringify(extMetadata)));
126126
const publicKey = Crypto.Ed25519PublicKeyHex(metadata.extVkey);
127-
const bip32Ed25519 = new Crypto.SodiumBip32Ed25519();
127+
const bip32Ed25519 = await Crypto.SodiumBip32Ed25519.create();
128128

129129
// Verify the signature
130-
const isSignatureValid = await bip32Ed25519.verify(signature, message, publicKey);
130+
const isSignatureValid = bip32Ed25519.verify(signature, message, publicKey);
131131

132132
// If not valid -> omit extended metadata from response and add specific error
133133
if (!isSignatureValid) {

packages/core/test/Cardano/util/computeImplicitCoin.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,16 @@ describe('Cardano.util.computeImplicitCoin', () => {
77
let dRepPublicKey: Crypto.Ed25519PublicKeyHex;
88
let dRepKeyHash: Crypto.Ed25519KeyHashHex;
99

10+
beforeAll(() => Crypto.ready());
11+
1012
beforeEach(async () => {
1113
rewardAccount = Cardano.RewardAccount('stake_test1uqfu74w3wh4gfzu8m6e7j987h4lq9r3t7ef5gaw497uu85qsqfy27');
1214
stakeCredential = {
1315
hash: Cardano.RewardAccount.toHash(rewardAccount) as unknown as Crypto.Hash28ByteBase16,
1416
type: Cardano.CredentialType.KeyHash
1517
};
1618
dRepPublicKey = Crypto.Ed25519PublicKeyHex('deeb8f82f2af5836ebbc1b450b6dbf0b03c93afe5696f10d49e8a8304ebfac01');
17-
dRepKeyHash = (await Crypto.Ed25519PublicKey.fromHex(dRepPublicKey).hash()).hex();
19+
dRepKeyHash = Crypto.Ed25519PublicKey.fromHex(dRepPublicKey).hash().hex();
1820
});
1921

2022
describe('calculates deposit', () => {

packages/crypto/src/Bip32/Bip32PrivateKey.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ export class Bip32PrivateKey {
7171
* - 32 bytes: Ed25519 curve scalar from which few bits have been tweaked according to ED25519-BIP32
7272
* - 32 bytes: Ed25519 binary blob used as IV for signing
7373
*
74+
* NOTE: You must await `Crypto.ready()` at least once before calling this function.
75+
*
7476
* @param entropy Random stream of bytes generated from a BIP39 seed phrase.
7577
* @param password The second factor authentication password for the mnemonic phrase.
7678
* @returns The secret extended key.
@@ -123,11 +125,12 @@ export class Bip32PrivateKey {
123125
* This is why deriving the private key should not fail while deriving
124126
* the public key may fail (if the derivation index is invalid).
125127
*
128+
* NOTE: You must await `Crypto.ready()` at least once before calling this function.
129+
*
126130
* @param derivationIndices The derivation indices.
127131
* @returns The child BIP-32 key.
128132
*/
129-
async derive(derivationIndices: number[]): Promise<Bip32PrivateKey> {
130-
await sodium.ready;
133+
derive(derivationIndices: number[]): Bip32PrivateKey {
131134
let key = Buffer.from(this.#key);
132135

133136
for (const index of derivationIndices) {
@@ -145,10 +148,11 @@ export class Bip32PrivateKey {
145148
/**
146149
* Computes the BIP-32 public key from this BIP-32 private key.
147150
*
151+
* NOTE: You must await `Crypto.ready()` at least once before calling this function.
152+
*
148153
* @returns the public key.
149154
*/
150-
async toPublic(): Promise<Bip32PublicKey> {
151-
await sodium.ready;
155+
toPublic(): Bip32PublicKey {
152156
const scalar = extendedScalar(this.#key.slice(0, EXTENDED_ED25519_PRIVATE_KEY_LENGTH));
153157
const publicKey = sodium.crypto_scalarmult_ed25519_base_noclamp(scalar);
154158

packages/crypto/src/Bip32/Bip32PublicKey.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,12 @@ export class Bip32PublicKey {
5353
/**
5454
* Given a set of indices, this function computes the corresponding child extended key.
5555
*
56+
* NOTE: You must await `Crypto.ready()` at least once before calling this function.
57+
*
5658
* @param derivationIndices The list of derivation indices.
5759
* @returns The child extended private key.
5860
*/
59-
async derive(derivationIndices: number[]): Promise<Bip32PublicKey> {
60-
await sodium.ready;
61+
derive(derivationIndices: number[]): Bip32PublicKey {
6162
let key = Buffer.from(this.#key);
6263

6364
for (const index of derivationIndices) {
@@ -77,9 +78,8 @@ export class Bip32PublicKey {
7778
return Bip32PublicKeyHex(Buffer.from(this.#key).toString('hex'));
7879
}
7980

80-
/** Gets the blake2 hash of the key. */
81-
async hash(): Promise<Bip32PublicKeyHashHex> {
82-
await sodium.ready;
81+
/** Gets the blake2 hash of the key. NOTE: You must await `Crypto.ready()` at least once before calling this function. */
82+
hash(): Bip32PublicKeyHashHex {
8383
const hash = sodium.crypto_generichash(BIP32_PUBLIC_KEY_HASH_LENGTH, this.#key);
8484
return Bip32PublicKeyHashHex(Buffer.from(hash).toString('hex'));
8585
}

packages/crypto/src/Bip32Ed25519.ts

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,32 +37,32 @@ export interface Bip32Ed25519 {
3737
* @param privateKey The private key to generate the public key from.
3838
* @returns The matching public key.
3939
*/
40-
getPublicKey(privateKey: Ed25519PrivateExtendedKeyHex | Ed25519PrivateNormalKeyHex): Promise<Ed25519PublicKeyHex>;
40+
getPublicKey(privateKey: Ed25519PrivateExtendedKeyHex | Ed25519PrivateNormalKeyHex): Ed25519PublicKeyHex;
4141

4242
/**
4343
* Computes the hash of the given public key.
4444
*
4545
* @param publicKey The public key to compute the hash from.
4646
* @returns The public key hash.
4747
*/
48-
getPubKeyHash(publicKey: Ed25519PublicKeyHex): Promise<Ed25519KeyHashHex>;
48+
getPubKeyHash(publicKey: Ed25519PublicKeyHex): Ed25519KeyHashHex;
4949

5050
/** Gets the Ed25519 raw private key. This key can be used for cryptographically signing messages. */
51-
getRawPrivateKey(bip32PrivateKey: Bip32PrivateKeyHex): Promise<Ed25519PrivateExtendedKeyHex>;
51+
getRawPrivateKey(bip32PrivateKey: Bip32PrivateKeyHex): Ed25519PrivateExtendedKeyHex;
5252

5353
/**
5454
* Gets the Ed25519 raw public key. This key can be used for cryptographically verifying messages
5555
* previously signed with the matching Ed25519 raw private key.
5656
*/
57-
getRawPublicKey(bip32PublicKey: Bip32PublicKeyHex): Promise<Ed25519PublicKeyHex>;
57+
getRawPublicKey(bip32PublicKey: Bip32PublicKeyHex): Ed25519PublicKeyHex;
5858

5959
/**
6060
* The function computes the BIP-32 public key from the provided BIP-32 private key.
6161
*
6262
* @param privateKey The extended private key to generate the public key from.
6363
* @returns The extended public key.
6464
*/
65-
getBip32PublicKey(privateKey: Bip32PrivateKeyHex): Promise<Bip32PublicKeyHex>;
65+
getBip32PublicKey(privateKey: Bip32PrivateKeyHex): Bip32PublicKeyHex;
6666

6767
/**
6868
* Given a parent extended key and a set of indices, this function computes the corresponding child extended key.
@@ -71,7 +71,7 @@ export interface Bip32Ed25519 {
7171
* @param derivationIndices The list of derivation indices.
7272
* @returns The child extended private key.
7373
*/
74-
derivePrivateKey(parentKey: Bip32PrivateKeyHex, derivationIndices: BIP32Path): Promise<Bip32PrivateKeyHex>;
74+
derivePrivateKey(parentKey: Bip32PrivateKeyHex, derivationIndices: BIP32Path): Bip32PrivateKeyHex;
7575

7676
/**
7777
* Given a parent extended key and a set of indices, this function computes the corresponding child extended key.
@@ -80,7 +80,7 @@ export interface Bip32Ed25519 {
8080
* @param derivationIndices The list of derivation indices.
8181
* @returns The child extended public key.
8282
*/
83-
derivePublicKey(parentKey: Bip32PublicKeyHex, derivationIndices: BIP32Path): Promise<Bip32PublicKeyHex>;
83+
derivePublicKey(parentKey: Bip32PublicKeyHex, derivationIndices: BIP32Path): Bip32PublicKeyHex;
8484

8585
/**
8686
* Generates an Ed25519 signature using an extended private key.
@@ -89,10 +89,7 @@ export interface Bip32Ed25519 {
8989
* @param message The message to be signed.
9090
* @returns The Ed25519 digital signature.
9191
*/
92-
sign(
93-
privateKey: Ed25519PrivateExtendedKeyHex | Ed25519PrivateNormalKeyHex,
94-
message: HexBlob
95-
): Promise<Ed25519SignatureHex>;
92+
sign(privateKey: Ed25519PrivateExtendedKeyHex | Ed25519PrivateNormalKeyHex, message: HexBlob): Ed25519SignatureHex;
9693

9794
/**
9895
* Verifies that the passed-in signature was generated with a extended private key that matches
@@ -103,5 +100,5 @@ export interface Bip32Ed25519 {
103100
* @param publicKey The Ed25519 public key that validates the given signature.
104101
* @returns true if the signature is valid; otherwise; false.
105102
*/
106-
verify(signature: Ed25519SignatureHex, message: HexBlob, publicKey: Ed25519PublicKeyHex): Promise<boolean>;
103+
verify(signature: Ed25519SignatureHex, message: HexBlob, publicKey: Ed25519PublicKeyHex): boolean;
107104
}

packages/crypto/src/Ed25519e/Ed25519PrivateKey.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ export class Ed25519PrivateKey {
7878
/**
7979
* Computes the raw public key from this raw private key.
8080
*
81+
* NOTE: You must await `Crypto.ready()` at least once before calling this function.
82+
*
8183
* @returns the public key.
8284
*/
83-
async toPublic(): Promise<Ed25519PublicKey> {
84-
await sodium.ready;
85-
85+
toPublic(): Ed25519PublicKey {
8686
return Ed25519PublicKey.fromBytes(
8787
this.__type === Ed25519PrivateKeyType.Extended
8888
? sodium.crypto_scalarmult_ed25519_base_noclamp(extendedScalar(this.#keyMaterial))
@@ -93,17 +93,18 @@ export class Ed25519PrivateKey {
9393
/**
9494
* Generates an Ed25519 signature.
9595
*
96+
* NOTE: You must await `Crypto.ready()` at least once before calling this function.
97+
*
9698
* @param message The message to be signed.
9799
* @returns The Ed25519 digital signature.
98100
*/
99-
async sign(message: HexBlob): Promise<Ed25519Signature> {
100-
await sodium.ready;
101+
sign(message: HexBlob): Ed25519Signature {
101102
return Ed25519Signature.fromBytes(
102103
this.__type === Ed25519PrivateKeyType.Extended
103104
? signExtendedDetached(this.#keyMaterial, Buffer.from(message, 'hex'))
104105
: sodium.crypto_sign_detached(
105106
Buffer.from(message, 'hex'),
106-
Buffer.concat([this.#keyMaterial, (await this.toPublic()).bytes()])
107+
Buffer.concat([this.#keyMaterial, this.toPublic().bytes()])
107108
)
108109
);
109110
}

packages/crypto/src/Ed25519e/Ed25519PublicKey.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@ export class Ed25519PublicKey {
2626
* Verifies that the passed-in signature was generated with a private key that matches
2727
* the given public key.
2828
*
29+
* NOTE: You must await `Crypto.ready()` at least once before calling this function.
30+
*
2931
* @param signature The signature bytes to be verified.
3032
* @param message The original message the signature was computed from.
3133
* @returns true if the signature is valid; otherwise; false.
3234
*/
33-
async verify(signature: Ed25519Signature, message: HexBlob): Promise<boolean> {
34-
await sodium.ready;
35+
verify(signature: Ed25519Signature, message: HexBlob): boolean {
3536
return sodium.crypto_sign_verify_detached(signature.bytes(), Buffer.from(message, 'hex'), this.#keyMaterial);
3637
}
3738

@@ -58,9 +59,8 @@ export class Ed25519PublicKey {
5859
return Ed25519PublicKey.fromBytes(Buffer.from(keyMaterial, 'hex'));
5960
}
6061

61-
/** Gets the blake2 hash of the key material. */
62-
async hash(): Promise<Ed25519KeyHash> {
63-
await sodium.ready;
62+
/** Gets the blake2 hash of the key material. NOTE: You must await `Crypto.ready()` at least once before calling this function. */
63+
hash(): Ed25519KeyHash {
6464
const hash = sodium.crypto_generichash(ED25519_PUBLIC_KEY_HASH_LENGTH, this.#keyMaterial);
6565
return Ed25519KeyHash.fromBytes(hash);
6666
}

packages/crypto/src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import blake2b from 'blake2b';
2+
import sodium from 'libsodium-wrappers-sumo';
23
export { blake2b };
34

45
export * from './Bip32';
@@ -7,3 +8,6 @@ export * from './Ed25519e';
78
export * from './strategies';
89
export * from './hexTypes';
910
export * from './types';
11+
12+
/** This function must be awaited before calling any other function in this module. It is safe to await this function multiple times. */
13+
export const ready = async (): Promise<void> => await sodium.ready;

packages/crypto/src/strategies/CmlBip32Ed25519.ts

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ export class CmlBip32Ed25519 implements Bip32Ed25519 {
3030
return Bip32PrivateKeyHex(Buffer.from(hexKey).toString('hex'));
3131
}
3232

33-
public getPublicKey(
34-
privateKey: Ed25519PrivateExtendedKeyHex | Ed25519PrivateNormalKeyHex
35-
): Promise<Ed25519PublicKeyHex> {
33+
public getPublicKey(privateKey: Ed25519PrivateExtendedKeyHex | Ed25519PrivateNormalKeyHex): Ed25519PublicKeyHex {
3634
return usingAutoFree((scope) => {
3735
const cmlPrivateKey =
3836
privateKey.length === EXTENDED_KEY_HEX_LENGTH
@@ -41,90 +39,86 @@ export class CmlBip32Ed25519 implements Bip32Ed25519 {
4139

4240
const pubKeyBytes = scope.manage(cmlPrivateKey.to_public()).as_bytes();
4341

44-
return Promise.resolve(Ed25519PublicKeyHex(Buffer.from(pubKeyBytes).toString('hex')));
42+
return Ed25519PublicKeyHex(Buffer.from(pubKeyBytes).toString('hex'));
4543
});
4644
}
4745

48-
public getPubKeyHash(publicKey: Ed25519PublicKeyHex): Promise<Ed25519KeyHashHex> {
46+
public getPubKeyHash(publicKey: Ed25519PublicKeyHex): Ed25519KeyHashHex {
4947
return usingAutoFree((scope) => {
5048
const cmlPubKey = scope.manage(this.#CML.PublicKey.from_bytes(Buffer.from(publicKey, 'hex')));
5149
const keyHash = scope.manage(cmlPubKey.hash()).to_bytes();
5250

53-
return Promise.resolve(Ed25519KeyHashHex(Buffer.from(keyHash).toString('hex')));
51+
return Ed25519KeyHashHex(Buffer.from(keyHash).toString('hex'));
5452
});
5553
}
5654

57-
public getRawPrivateKey(bip32PrivateKey: Bip32PrivateKeyHex): Promise<Ed25519PrivateExtendedKeyHex> {
55+
public getRawPrivateKey(bip32PrivateKey: Bip32PrivateKeyHex): Ed25519PrivateExtendedKeyHex {
5856
return usingAutoFree((scope) => {
5957
const cmlPrivateKey = scope.manage(this.#CML.Bip32PrivateKey.from_bytes(Buffer.from(bip32PrivateKey, 'hex')));
6058
const bytes = scope.manage(cmlPrivateKey.to_raw_key()).as_bytes();
61-
return Promise.resolve(Ed25519PrivateExtendedKeyHex(Buffer.from(bytes).toString('hex')));
59+
return Ed25519PrivateExtendedKeyHex(Buffer.from(bytes).toString('hex'));
6260
});
6361
}
6462

65-
public getRawPublicKey(bip32PublicKey: Bip32PublicKeyHex): Promise<Ed25519PublicKeyHex> {
63+
public getRawPublicKey(bip32PublicKey: Bip32PublicKeyHex): Ed25519PublicKeyHex {
6664
return usingAutoFree((scope) => {
6765
const cmlPublicKey = scope.manage(this.#CML.Bip32PublicKey.from_bytes(Buffer.from(bip32PublicKey, 'hex')));
6866
const bytes = scope.manage(cmlPublicKey.to_raw_key()).as_bytes();
69-
return Promise.resolve(Ed25519PublicKeyHex(Buffer.from(bytes).toString('hex')));
67+
return Ed25519PublicKeyHex(Buffer.from(bytes).toString('hex'));
7068
});
7169
}
7270

73-
public getBip32PublicKey(privateKey: Bip32PrivateKeyHex): Promise<Bip32PublicKeyHex> {
71+
public getBip32PublicKey(privateKey: Bip32PrivateKeyHex): Bip32PublicKeyHex {
7472
return usingAutoFree((scope) => {
7573
const cmlPrivateKey = scope.manage(this.#CML.Bip32PrivateKey.from_bytes(Buffer.from(privateKey, 'hex')));
7674
const pubKeyBytes = scope.manage(cmlPrivateKey.to_public()).as_bytes();
77-
return Promise.resolve(Bip32PublicKeyHex(Buffer.from(pubKeyBytes).toString('hex')));
75+
return Bip32PublicKeyHex(Buffer.from(pubKeyBytes).toString('hex'));
7876
});
7977
}
8078

81-
public derivePrivateKey(parentKey: Bip32PrivateKeyHex, derivationIndices: BIP32Path): Promise<Bip32PrivateKeyHex> {
79+
public derivePrivateKey(parentKey: Bip32PrivateKeyHex, derivationIndices: BIP32Path): Bip32PrivateKeyHex {
8280
return usingAutoFree((scope) => {
8381
let cmlKey = scope.manage(this.#CML.Bip32PrivateKey.from_bytes(Buffer.from(parentKey, 'hex')));
8482

8583
for (const index of derivationIndices) {
8684
cmlKey = scope.manage(cmlKey.derive(index));
8785
}
8886

89-
return Promise.resolve(Bip32PrivateKeyHex(Buffer.from(cmlKey.as_bytes()).toString('hex')));
87+
return Bip32PrivateKeyHex(Buffer.from(cmlKey.as_bytes()).toString('hex'));
9088
});
9189
}
9290

93-
public derivePublicKey(parentKey: Bip32PublicKeyHex, derivationIndices: BIP32Path): Promise<Bip32PublicKeyHex> {
91+
public derivePublicKey(parentKey: Bip32PublicKeyHex, derivationIndices: BIP32Path): Bip32PublicKeyHex {
9492
return usingAutoFree((scope) => {
9593
let cmlKey = scope.manage(this.#CML.Bip32PublicKey.from_bytes(Buffer.from(parentKey, 'hex')));
9694

9795
for (const index of derivationIndices) {
9896
cmlKey = scope.manage(cmlKey.derive(index));
9997
}
10098

101-
return Promise.resolve(Bip32PublicKeyHex(Buffer.from(cmlKey.as_bytes()).toString('hex')));
99+
return Bip32PublicKeyHex(Buffer.from(cmlKey.as_bytes()).toString('hex'));
102100
});
103101
}
104102

105-
public async sign(
103+
public sign(
106104
privateKey: Ed25519PrivateExtendedKeyHex | Ed25519PrivateNormalKeyHex,
107105
message: HexBlob
108-
): Promise<Ed25519SignatureHex> {
106+
): Ed25519SignatureHex {
109107
return usingAutoFree((scope) => {
110108
const cmlPrivateKey =
111109
privateKey.length === EXTENDED_KEY_HEX_LENGTH
112110
? scope.manage(this.#CML.PrivateKey.from_extended_bytes(Buffer.from(privateKey, 'hex')))
113111
: scope.manage(this.#CML.PrivateKey.from_normal_bytes(Buffer.from(privateKey, 'hex')));
114112
const signature = scope.manage(cmlPrivateKey.sign(Buffer.from(message, 'hex'))).to_bytes();
115-
return Promise.resolve(Ed25519SignatureHex(Buffer.from(signature).toString('hex')));
113+
return Ed25519SignatureHex(Buffer.from(signature).toString('hex'));
116114
});
117115
}
118116

119-
public async verify(
120-
signature: Ed25519SignatureHex,
121-
message: HexBlob,
122-
publicKey: Ed25519PublicKeyHex
123-
): Promise<boolean> {
117+
public verify(signature: Ed25519SignatureHex, message: HexBlob, publicKey: Ed25519PublicKeyHex): boolean {
124118
return usingAutoFree((scope) => {
125119
const cmlKey = scope.manage(this.#CML.PublicKey.from_bytes(Buffer.from(publicKey, 'hex')));
126120
const cmlSignature = scope.manage(this.#CML.Ed25519Signature.from_bytes(Buffer.from(signature, 'hex')));
127-
return Promise.resolve(cmlKey.verify(Buffer.from(message, 'hex'), cmlSignature));
121+
return cmlKey.verify(Buffer.from(message, 'hex'), cmlSignature);
128122
});
129123
}
130124
}

0 commit comments

Comments
 (0)