Add Secp256k1.uncompressPubkey

This commit is contained in:
Simon Warta 2022-02-17 18:33:23 +01:00
parent 034f205d45
commit 065e714cf8
3 changed files with 41 additions and 0 deletions

View File

@ -9,6 +9,7 @@ and this project adheres to
### Changed
- all: The TypeScript compilation target is now ES2018.
- @cosmjs/crypto: Add `Secp256k1.uncompressPubkey`.
- @cosmjs/faucet: Set default value of `FAUCET_GAS_LIMIT` to 100_000 to better
support Cosmos SDK 0.45 chains.
- @cosmjs/stargate: The `AminoTypes` now always requires an argument of type

View File

@ -570,6 +570,30 @@ describe("Secp256k1", () => {
});
});
describe("uncompressPubkey", () => {
it("throws for a pubkey with invalid length", () => {
const pubkey = fromHex("aa".repeat(32));
expect(() => Secp256k1.uncompressPubkey(pubkey)).toThrowError(/invalid pubkey length/i);
});
it("returns an uncompressPubkey pubkey unchanged", () => {
// Test data generated at https://iancoleman.io/bitcoin-key-compression/
const pubkey = fromHex(
"044f04181eeba35391b858633a765c4a0c189697b40d216354d50890d350c7029013b587a681e836cc187a8164b98a5848a2b89b3173315fdd0740d5032e259cd5",
);
expect(Secp256k1.uncompressPubkey(pubkey)).toEqual(pubkey);
});
it("uncompresses a compressed pubkey", () => {
// Test data generated at https://iancoleman.io/bitcoin-key-compression/
const uncompressed = fromHex(
"044f04181eeba35391b858633a765c4a0c189697b40d216354d50890d350c7029013b587a681e836cc187a8164b98a5848a2b89b3173315fdd0740d5032e259cd5",
);
const compressed = fromHex("034f04181eeba35391b858633a765c4a0c189697b40d216354d50890d350c70290");
expect(Secp256k1.uncompressPubkey(compressed)).toEqual(uncompressed);
});
});
describe("trimRecoveryByte", () => {
it("throws for a signature with invalid length", () => {
const signature = fromHex("aa".repeat(66));

View File

@ -121,6 +121,22 @@ export class Secp256k1 {
}
}
/**
* Takes a compressed or uncompressed pubkey and returns an uncompressed one.
*
* This function is idempotent.
*/
public static uncompressPubkey(pubkey: Uint8Array): Uint8Array {
switch (pubkey.length) {
case 33:
return Uint8Array.from(secp256k1.keyFromPublic(pubkey).getPublic(false, "array"));
case 65:
return pubkey;
default:
throw new Error("Invalid pubkey length");
}
}
public static trimRecoveryByte(signature: Uint8Array): Uint8Array {
switch (signature.length) {
case 64: