Skip to content

Remove unnecessary async #1635

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion packages/amino/src/secp256k1hdwallet.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ describe("Secp256k1HdWallet", () => {
};
const { signed, signature } = await wallet.signAmino(defaultAddress, signDoc);
expect(signed).toEqual(signDoc);
const valid = await Secp256k1.verifySignature(
const valid = Secp256k1.verifySignature(
Secp256k1Signature.fromFixedLength(fromBase64(signature.signature)),
sha256(serializeSignDoc(signed)),
defaultPubkey,
Expand Down
24 changes: 11 additions & 13 deletions packages/amino/src/secp256k1hdwallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ export class Secp256k1HdWallet implements OfflineAminoSigner {
}
const { privkey, pubkey } = account;
const message = sha256(serializeSignDoc(signDoc));
const signature = await Secp256k1.createSignature(message, privkey);
const signature = Secp256k1.createSignature(message, privkey);
const signatureBytes = new Uint8Array([...signature.r(32), ...signature.s(32)]);
return {
signed: signDoc,
Expand Down Expand Up @@ -333,27 +333,25 @@ export class Secp256k1HdWallet implements OfflineAminoSigner {
return JSON.stringify(out);
}

private async getKeyPair(hdPath: HdPath): Promise<Secp256k1Keypair> {
private getKeyPair(hdPath: HdPath): Secp256k1Keypair {
const { privkey } = Slip10.derivePath(Slip10Curve.Secp256k1, this.seed, hdPath);
const { pubkey } = await Secp256k1.makeKeypair(privkey);
const { pubkey } = Secp256k1.makeKeypair(privkey);
return {
privkey: privkey,
pubkey: Secp256k1.compressPubkey(pubkey),
};
}

private async getAccountsWithPrivkeys(): Promise<readonly AccountDataWithPrivkey[]> {
return Promise.all(
this.accounts.map(async ({ hdPath, prefix }) => {
const { privkey, pubkey } = await this.getKeyPair(hdPath);
const address = toBech32(prefix, rawSecp256k1PubkeyToRawAddress(pubkey));
return {
private getAccountsWithPrivkeys(): readonly AccountDataWithPrivkey[] {
return this.accounts.map(({ hdPath, prefix }) => {
const { privkey, pubkey } = this.getKeyPair(hdPath);
const address = toBech32(prefix, rawSecp256k1PubkeyToRawAddress(pubkey));
return {
algo: "secp256k1" as const,
privkey: privkey,
pubkey: pubkey,
address: address,
};
}),
);
address: address,
};
});
}
}
2 changes: 1 addition & 1 deletion packages/amino/src/secp256k1wallet.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ describe("Secp256k1Wallet", () => {
};
const { signed, signature } = await signer.signAmino(defaultAddress, signDoc);
expect(signed).toEqual(signDoc);
const valid = await Secp256k1.verifySignature(
const valid = Secp256k1.verifySignature(
Secp256k1Signature.fromFixedLength(fromBase64(signature.signature)),
new Sha256(serializeSignDoc(signed)).digest(),
defaultPubkey,
Expand Down
8 changes: 4 additions & 4 deletions packages/amino/src/secp256k1wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ export class Secp256k1Wallet implements OfflineAminoSigner {
* @param privkey The private key.
* @param prefix The bech32 address prefix (human readable part). Defaults to "cosmos".
*/
public static async fromKey(privkey: Uint8Array, prefix = "cosmos"): Promise<Secp256k1Wallet> {
const uncompressed = (await Secp256k1.makeKeypair(privkey)).pubkey;
return new Secp256k1Wallet(privkey, Secp256k1.compressPubkey(uncompressed), prefix);
public static fromKey(privkey: Uint8Array, prefix = "cosmos"): Secp256k1Wallet {
const { pubkey } = Secp256k1.makeKeypair(privkey);
return new Secp256k1Wallet(privkey, Secp256k1.compressPubkey(pubkey), prefix);
}

private readonly pubkey: Uint8Array;
Expand Down Expand Up @@ -52,7 +52,7 @@ export class Secp256k1Wallet implements OfflineAminoSigner {
throw new Error(`Address ${signerAddress} not found in wallet`);
}
const message = new Sha256(serializeSignDoc(signDoc)).digest();
const signature = await Secp256k1.createSignature(message, this.privkey);
const signature = Secp256k1.createSignature(message, this.privkey);
const signatureBytes = new Uint8Array([...signature.r(32), ...signature.s(32)]);
return {
signed: signDoc,
Expand Down
78 changes: 39 additions & 39 deletions packages/crypto/src/secp256k1.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe("Secp256k1", () => {
// example data generated by OpenSSL (caution: LibreSSL 2.2.7 sometimes adds a leading 00 for the privkey):
// openssl ecparam -name secp256k1 -genkey | openssl ec -text -noout -conv_form uncompressed
const privkey = fromHex("5b1d5975dfdfb0027802265241d891e4af744cd39e78595658afaa7ac801d1d3");
const keypair = await Secp256k1.makeKeypair(privkey);
const keypair = Secp256k1.makeKeypair(privkey);
expect(keypair.pubkey).toEqual(
fromHex(
"043e1113575cf01f9281381f626deccf76cdc85a320052297f7cae3548ea024d0b9fbec8a56d345a2984050be859c96471ef6aa4669ff31a659ce1d32db372f9b9",
Expand All @@ -32,115 +32,115 @@ describe("Secp256k1", () => {

it("preserves private key when making a keypair", async () => {
const privkey = fromHex("8c8bc2bc7954db5ef751e3e84b4e99bbe387a90d8019d8066c0e1e8bf33e713f");
const keypair = await Secp256k1.makeKeypair(privkey);
const keypair = Secp256k1.makeKeypair(privkey);
expect(keypair.privkey).toEqual(
fromHex("8c8bc2bc7954db5ef751e3e84b4e99bbe387a90d8019d8066c0e1e8bf33e713f"),
);
});

it("can load private keys", async () => {
expect(
await Secp256k1.makeKeypair(
Secp256k1.makeKeypair(
fromHex("5eaf4344dab73d0caee1fd03607bb969074fb217f076896c2125f8607feab7b1"),
),
).toBeTruthy();
expect(
await Secp256k1.makeKeypair(
Secp256k1.makeKeypair(
fromHex("f7ac570ea2844e29e7f3b3c6a724ee1f47d3de8c2175a69abae94ae871573d0e"),
),
).toBeTruthy();
expect(
await Secp256k1.makeKeypair(
Secp256k1.makeKeypair(
fromHex("e4ade2a5232a7c6f37e7b854a774e25e6047ee7c6d63e8304ae04fa190bc1732"),
),
).toBeTruthy();

// smallest and largest allowed values: 1 and N-1 (from https://crypto.stackexchange.com/a/30273)
expect(
await Secp256k1.makeKeypair(
Secp256k1.makeKeypair(
fromHex("0000000000000000000000000000000000000000000000000000000000000001"),
),
).toBeTruthy();
expect(
await Secp256k1.makeKeypair(
Secp256k1.makeKeypair(
fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140"),
),
).toBeTruthy();

// too short and too long
await Secp256k1.makeKeypair(fromHex("e4ade2a5232a7c6f37e7b854a774e25e6047ee7c6d63e8304ae04fa190bc17"))
Secp256k1.makeKeypair(fromHex("e4ade2a5232a7c6f37e7b854a774e25e6047ee7c6d63e8304ae04fa190bc17"))
.then(() => fail("promise must be rejected"))
.catch((error) => expect(error.message).toContain("not a valid secp256k1 private key"));
await Secp256k1.makeKeypair(fromHex("e4ade2a5232a7c6f37e7b854a774e25e6047ee7c6d63e8304ae04fa190bc1732aa"))
Secp256k1.makeKeypair(fromHex("e4ade2a5232a7c6f37e7b854a774e25e6047ee7c6d63e8304ae04fa190bc1732aa"))
.then(() => fail("promise must be rejected"))
.catch((error) => expect(error.message).toContain("not a valid secp256k1 private key"));
// value out of range (too small)
await Secp256k1.makeKeypair(fromHex("0000000000000000000000000000000000000000000000000000000000000000"))
Secp256k1.makeKeypair(fromHex("0000000000000000000000000000000000000000000000000000000000000000"))
.then(() => fail("promise must be rejected"))
.catch((error) => expect(error.message).toContain("not a valid secp256k1 private key"));
// value out of range (>= n)
await Secp256k1.makeKeypair(fromHex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"))
Secp256k1.makeKeypair(fromHex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"))
.then(() => fail("promise must be rejected"))
.catch((error) => expect(error.message).toContain("not a valid secp256k1 private key"));
await Secp256k1.makeKeypair(fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"))
Secp256k1.makeKeypair(fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"))
.then(() => fail("promise must be rejected"))
.catch((error) => expect(error.message).toContain("not a valid secp256k1 private key"));
});

it("creates signatures", async () => {
const privkey = fromHex("43a9c17ccbb0e767ea29ce1f10813afde5f1e0a7a504e89b4d2cc2b952b8e0b9");
const keypair = await Secp256k1.makeKeypair(privkey);
const keypair = Secp256k1.makeKeypair(privkey);
const messageHash = new Uint8Array([0x11, 0x22]);
const signature = (await Secp256k1.createSignature(messageHash, keypair.privkey)).toDer();
const signature = Secp256k1.createSignature(messageHash, keypair.privkey).toDer();
expect(signature).toBeTruthy();
expect(signature.byteLength).toBeGreaterThanOrEqual(70);
expect(signature.byteLength).toBeLessThanOrEqual(72);
});

it("creates signatures deterministically", async () => {
const privkey = fromHex("43a9c17ccbb0e767ea29ce1f10813afde5f1e0a7a504e89b4d2cc2b952b8e0b9");
const keypair = await Secp256k1.makeKeypair(privkey);
const keypair = Secp256k1.makeKeypair(privkey);
const messageHash = new Uint8Array([0x11, 0x22]);

const signature1 = await Secp256k1.createSignature(messageHash, keypair.privkey);
const signature2 = await Secp256k1.createSignature(messageHash, keypair.privkey);
const signature1 = Secp256k1.createSignature(messageHash, keypair.privkey);
const signature2 = Secp256k1.createSignature(messageHash, keypair.privkey);
expect(signature1).toEqual(signature2);
});

it("throws for empty message hash in signing", async () => {
const privkey = fromHex("43a9c17ccbb0e767ea29ce1f10813afde5f1e0a7a504e89b4d2cc2b952b8e0b9");
const keypair = await Secp256k1.makeKeypair(privkey);
const keypair = Secp256k1.makeKeypair(privkey);
const messageHash = new Uint8Array([]);
await Secp256k1.createSignature(messageHash, keypair.privkey)
Secp256k1.createSignature(messageHash, keypair.privkey)
.then(() => fail("must not resolve"))
.catch((error) => expect(error).toMatch(/message hash must not be empty/i));
});

it("throws for message hash longer than 32 bytes in signing", async () => {
const privkey = fromHex("43a9c17ccbb0e767ea29ce1f10813afde5f1e0a7a504e89b4d2cc2b952b8e0b9");
const keypair = await Secp256k1.makeKeypair(privkey);
const keypair = Secp256k1.makeKeypair(privkey);
const messageHash = fromHex("11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff11");
await Secp256k1.createSignature(messageHash, keypair.privkey)
Secp256k1.createSignature(messageHash, keypair.privkey)
.then(() => fail("must not resolve"))
.catch((error) => expect(error).toMatch(/message hash length must not exceed 32 bytes/i));
});

it("verifies signatures", async () => {
const privkey = fromHex("43a9c17ccbb0e767ea29ce1f10813afde5f1e0a7a504e89b4d2cc2b952b8e0b9");
const keypair = await Secp256k1.makeKeypair(privkey);
const keypair = Secp256k1.makeKeypair(privkey);
const messageHash = new Uint8Array([0x11, 0x22]);
const signature = await Secp256k1.createSignature(messageHash, keypair.privkey);
const signature = Secp256k1.createSignature(messageHash, keypair.privkey);

{
// valid
const ok = await Secp256k1.verifySignature(signature, messageHash, keypair.pubkey);
const ok = Secp256k1.verifySignature(signature, messageHash, keypair.pubkey);
expect(ok).toEqual(true);
}

{
// messageHash corrupted
const corruptedMessageHash = messageHash.map((x, i) => (i === 0 ? x ^ 0x01 : x));
const ok = await Secp256k1.verifySignature(signature, corruptedMessageHash, keypair.pubkey);
const ok = Secp256k1.verifySignature(signature, corruptedMessageHash, keypair.pubkey);
expect(ok).toEqual(false);
}

Expand All @@ -149,15 +149,15 @@ describe("Secp256k1", () => {
const corruptedSignature = Secp256k1Signature.fromDer(
signature.toDer().map((x, i) => (i === 5 ? x ^ 0x01 : x)),
);
const ok = await Secp256k1.verifySignature(corruptedSignature, messageHash, keypair.pubkey);
const ok = Secp256k1.verifySignature(corruptedSignature, messageHash, keypair.pubkey);
expect(ok).toEqual(false);
}

{
// wrong pubkey
const otherPrivkey = fromHex("91099374790843e29552c3cfa5e9286d6c77e00a2c109aaf3d0a307081314a09");
const wrongPubkey = (await Secp256k1.makeKeypair(otherPrivkey)).pubkey;
const ok = await Secp256k1.verifySignature(signature, messageHash, wrongPubkey);
const wrongPubkey = Secp256k1.makeKeypair(otherPrivkey).pubkey;
const ok = Secp256k1.verifySignature(signature, messageHash, wrongPubkey);
expect(ok).toEqual(false);
}
});
Expand All @@ -168,11 +168,11 @@ describe("Secp256k1", () => {
"304602210083de9be443bcf480892b8c8ca1d5ee65c79a315642c3f7b5305aff3065fda2780221009747932122b93cec42cad8ee4630a8f6cbe127578b8c495b4ab927275f657658",
),
);
const keypair = await Secp256k1.makeKeypair(
const keypair = Secp256k1.makeKeypair(
fromHex("43a9c17ccbb0e767ea29ce1f10813afde5f1e0a7a504e89b4d2cc2b952b8e0b9"),
);
const messageHash = new Uint8Array([]);
await Secp256k1.verifySignature(dummySignature, messageHash, keypair.pubkey)
Secp256k1.verifySignature(dummySignature, messageHash, keypair.pubkey)
.then(() => fail("must not resolve"))
.catch((error) => expect(error).toMatch(/message hash must not be empty/i));
});
Expand All @@ -183,11 +183,11 @@ describe("Secp256k1", () => {
"304602210083de9be443bcf480892b8c8ca1d5ee65c79a315642c3f7b5305aff3065fda2780221009747932122b93cec42cad8ee4630a8f6cbe127578b8c495b4ab927275f657658",
),
);
const keypair = await Secp256k1.makeKeypair(
const keypair = Secp256k1.makeKeypair(
fromHex("43a9c17ccbb0e767ea29ce1f10813afde5f1e0a7a504e89b4d2cc2b952b8e0b9"),
);
const messageHash = fromHex("11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff11");
await Secp256k1.verifySignature(dummySignature, messageHash, keypair.privkey)
Secp256k1.verifySignature(dummySignature, messageHash, keypair.privkey)
.then(() => fail("must not resolve"))
.catch((error) => expect(error).toMatch(/message hash length must not exceed 32 bytes/i));
});
Expand Down Expand Up @@ -382,9 +382,9 @@ describe("Secp256k1", () => {
];

for (const [index, row] of data.entries()) {
const pubkey = (await Secp256k1.makeKeypair(row.privkey)).pubkey;
const pubkey = Secp256k1.makeKeypair(row.privkey).pubkey;
const messageHash = sha256(row.message);
const isValid = await Secp256k1.verifySignature(
const isValid = Secp256k1.verifySignature(
Secp256k1Signature.fromDer(row.signature),
messageHash,
pubkey,
Expand Down Expand Up @@ -493,18 +493,18 @@ describe("Secp256k1", () => {
];

for (const [index, row] of data.entries()) {
const keypair = await Secp256k1.makeKeypair(row.privkey);
const keypair = Secp256k1.makeKeypair(row.privkey);
const messageHash = sha256(row.message);

// create signature
const calculatedSignature = await Secp256k1.createSignature(messageHash, row.privkey);
const calculatedSignature = Secp256k1.createSignature(messageHash, row.privkey);

// verify calculated signature
const ok1 = await Secp256k1.verifySignature(calculatedSignature, messageHash, keypair.pubkey);
const ok1 = Secp256k1.verifySignature(calculatedSignature, messageHash, keypair.pubkey);
expect(ok1).withContext(`(index ${index})`).toEqual(true);

// verify original signature
const ok2 = await Secp256k1.verifySignature(
const ok2 = Secp256k1.verifySignature(
Secp256k1Signature.fromDer(row.signature),
messageHash,
keypair.pubkey,
Expand All @@ -521,7 +521,7 @@ describe("Secp256k1", () => {
{
// Test data from https://github.com/ethereumjs/ethereumjs-util/blob/v6.1.0/test/index.js#L496
const expectedPubkey = (
await Secp256k1.makeKeypair(
Secp256k1.makeKeypair(
fromHex("3c9229289a6125f7fdf1885a77bb12c37a8d3b4962d936f7e3084dece32a3ca1"),
)
).pubkey;
Expand Down
10 changes: 5 additions & 5 deletions packages/crypto/src/secp256k1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class Secp256k1 {
* The resulting pubkey is uncompressed. For the use in Cosmos it should
* be compressed first using `Secp256k1.compressPubkey`.
*/
public static async makeKeypair(privkey: Uint8Array): Promise<Secp256k1Keypair> {
public static makeKeypair(privkey: Uint8Array): Secp256k1Keypair {
if (privkey.length !== 32) {
// is this check missing in secp256k1.validatePrivateKey?
// https://github.com/bitjson/bitcoin-ts/issues/4
Expand Down Expand Up @@ -64,10 +64,10 @@ export class Secp256k1 {
* - lowS signature
* - DER encoded
*/
public static async createSignature(
public static createSignature(
messageHash: Uint8Array,
privkey: Uint8Array,
): Promise<ExtendedSecp256k1Signature> {
): ExtendedSecp256k1Signature {
if (messageHash.length === 0) {
throw new Error("Message hash must not be empty");
}
Expand All @@ -86,11 +86,11 @@ export class Secp256k1 {
);
}

public static async verifySignature(
public static verifySignature(
signature: Secp256k1Signature,
messageHash: Uint8Array,
pubkey: Uint8Array,
): Promise<boolean> {
): boolean {
if (messageHash.length === 0) {
throw new Error("Message hash must not be empty");
}
Expand Down
2 changes: 1 addition & 1 deletion packages/ledger-amino/src/ledgersigner.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ describe("LedgerSigner", () => {
);
const { signed, signature } = await signer.signAmino(firstAccount.address, signDoc);
expect(signed).toEqual(signDoc);
const valid = await Secp256k1.verifySignature(
const valid = Secp256k1.verifySignature(
Secp256k1Signature.fromFixedLength(fromBase64(signature.signature)),
sha256(serializeSignDoc(signed)),
firstAccount.pubkey,
Expand Down
2 changes: 1 addition & 1 deletion packages/proto-signing/src/directsecp256k1hdwallet.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ describe("DirectSecp256k1HdWallet", () => {
);
const signDocBytes = makeSignBytes(signDoc);
const { signature } = await wallet.signDirect(faucet.address, signDoc);
const valid = await Secp256k1.verifySignature(
const valid = Secp256k1.verifySignature(
Secp256k1Signature.fromFixedLength(fromBase64(signature.signature)),
sha256(signDocBytes),
pubkey.value,
Expand Down
Loading