Deduplicate pubkey type strings

This commit is contained in:
Simon Warta 2020-02-05 12:34:34 +01:00
parent 0b3b1559f7
commit 651ba497d9
7 changed files with 44 additions and 35 deletions

View File

@ -1,4 +1,4 @@
import { CosmosBech32Prefix, decodeBech32Pubkey, encodeAddress, isValidAddress } from "@cosmwasm/sdk";
import { CosmosBech32Prefix, decodeBech32Pubkey, encodeAddress, isValidAddress, types } from "@cosmwasm/sdk";
import { Address, Algorithm, PubkeyBundle, PubkeyBytes } from "@iov/bcp";
import { Secp256k1 } from "@iov/crypto";
import { Encoding } from "@iov/encoding";
@ -12,9 +12,9 @@ export function decodeCosmosPubkey(
): { readonly algo: Algorithm; readonly data: PubkeyBytes } {
const sdkPubKey = decodeBech32Pubkey(encodedPubkey);
switch (sdkPubKey.type) {
case "tendermint/PubKeySecp256k1":
case types.pubkeyType.secp256k1:
return { algo: Algorithm.Secp256k1, data: fromBase64(sdkPubKey.value) as PubkeyBytes };
case "tendermint/PubKeyEd25519":
case types.pubkeyType.ed25519:
return { algo: Algorithm.Ed25519, data: fromBase64(sdkPubKey.value) as PubkeyBytes };
default:
throw new Error("Unsupported Pubkey type: " + sdkPubKey.type);
@ -23,22 +23,20 @@ export function decodeCosmosPubkey(
// See https://github.com/tendermint/tendermint/blob/f2ada0a604b4c0763bda2f64fac53d506d3beca7/docs/spec/blockchain/encoding.md#public-key-cryptography
export function pubkeyToAddress(pubkey: PubkeyBundle, prefix: CosmosBech32Prefix): Address {
let pubkeyType: "tendermint/PubKeySecp256k1" | "tendermint/PubKeyEd25519";
let pubkeyData: Uint8Array = pubkey.data;
let sdkKey: types.PubKey;
if (pubkey.algo === Algorithm.Secp256k1) {
pubkeyType = "tendermint/PubKeySecp256k1";
if (pubkeyData.length > 33) {
pubkeyData = Secp256k1.compressPubkey(pubkey.data);
}
sdkKey = {
type: types.pubkeyType.secp256k1,
value: toBase64(pubkey.data.length > 33 ? Secp256k1.compressPubkey(pubkey.data) : pubkey.data),
};
} else if (pubkey.algo === Algorithm.Ed25519) {
pubkeyType = "tendermint/PubKeyEd25519";
sdkKey = {
type: types.pubkeyType.ed25519,
value: toBase64(pubkey.data),
};
} else {
throw new Error(`Unsupported algorithm: ${pubkey.algo}`);
}
const sdkKey = {
type: pubkeyType,
value: toBase64(pubkeyData),
};
return encodeAddress(sdkKey, prefix) as Address;
}

View File

@ -25,14 +25,12 @@ const { fromBase64 } = Encoding;
export function decodePubkey(pubkey: types.PubKey): PubkeyBundle {
switch (pubkey.type) {
// https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/secp256k1/secp256k1.go#L23
case "tendermint/PubKeySecp256k1":
case types.pubkeyType.secp256k1:
return {
algo: Algorithm.Secp256k1,
data: fromBase64(pubkey.value) as PubkeyBytes,
};
// https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/ed25519/ed25519.go#L22
case "tendermint/PubKeyEd25519":
case types.pubkeyType.ed25519:
return {
algo: Algorithm.Ed25519,
data: fromBase64(pubkey.value) as PubkeyBytes,

View File

@ -20,12 +20,12 @@ export function encodePubkey(pubkey: PubkeyBundle): types.PubKey {
switch (pubkey.algo) {
case Algorithm.Secp256k1:
return {
type: "tendermint/PubKeySecp256k1",
type: types.pubkeyType.secp256k1,
value: toBase64(pubkey.data),
};
case Algorithm.Ed25519:
return {
type: "tendermint/PubKeyEd25519",
type: types.pubkeyType.ed25519,
value: toBase64(pubkey.data),
};
default:

View File

@ -2,7 +2,7 @@ import { Ripemd160, Sha256 } from "@iov/crypto";
import { Bech32, Encoding } from "@iov/encoding";
import equal from "fast-deep-equal";
import { Bech32PubKey, PubKey } from "./types";
import { Bech32PubKey, PubKey, pubkeyType } from "./types";
const { fromBase64, toBase64 } = Encoding;
@ -40,7 +40,7 @@ export function decodeBech32Pubkey(bech: Bech32PubKey): PubKey {
throw new Error("Invalid rest data length. Expected 33 bytes (compressed secp256k1 pubkey).");
}
return {
type: "tendermint/PubKeySecp256k1",
type: pubkeyType.secp256k1,
value: toBase64(rest),
};
} else if (equal(aminoPrefix, pubkeyAminoPrefixEd25519)) {
@ -48,7 +48,7 @@ export function decodeBech32Pubkey(bech: Bech32PubKey): PubKey {
throw new Error("Invalid rest data length. Expected 32 bytes (Ed25519 pubkey).");
}
return {
type: "tendermint/PubKeyEd25519",
type: pubkeyType.ed25519,
value: toBase64(rest),
};
} else if (equal(aminoPrefix, pubkeyAminoPrefixSr25519)) {
@ -56,7 +56,7 @@ export function decodeBech32Pubkey(bech: Bech32PubKey): PubKey {
throw new Error("Invalid rest data length. Expected 32 bytes (Sr25519 pubkey).");
}
return {
type: "tendermint/PubKeySr25519",
type: pubkeyType.sr25519,
value: toBase64(rest),
};
} else {
@ -81,7 +81,7 @@ export function isValidAddress(address: string): boolean {
export function encodeAddress(pubkey: PubKey, prefix: string): string {
const pubkeyBytes = fromBase64(pubkey.value);
switch (pubkey.type) {
case "tendermint/PubKeySecp256k1": {
case pubkeyType.secp256k1: {
if (pubkeyBytes.length !== 33) {
throw new Error(`Invalid Secp256k1 pubkey length (compressed): ${pubkeyBytes.length}`);
}
@ -89,14 +89,14 @@ export function encodeAddress(pubkey: PubKey, prefix: string): string {
const hash2 = new Ripemd160(hash1).digest();
return Bech32.encode(prefix, hash2);
}
case "tendermint/PubKeyEd25519": {
case pubkeyType.ed25519: {
if (pubkeyBytes.length !== 32) {
throw new Error(`Invalid Ed25519 pubkey length: ${pubkeyBytes.length}`);
}
const hash = new Sha256(pubkeyBytes).digest();
return Bech32.encode(prefix, hash.slice(0, 20));
}
case "tendermint/PubKeySr25519": {
case pubkeyType.sr25519: {
if (pubkeyBytes.length !== 32) {
throw new Error(`Invalid Sr25519 pubkey length: ${pubkeyBytes.length}`);
}

View File

@ -1,7 +1,7 @@
import { Secp256k1 } from "@iov/crypto";
import { Encoding } from "@iov/encoding";
import { Msg, NonceInfo, StdFee, StdSignature, StdTx } from "./types";
import { Msg, NonceInfo, pubkeyType, StdFee, StdSignature, StdTx } from "./types";
const { toBase64, toUtf8 } = Encoding;
@ -62,7 +62,7 @@ export function encodeSecp256k1Signature(pubkey: Uint8Array, signature: Uint8Arr
return {
// eslint-disable-next-line @typescript-eslint/camelcase
pub_key: {
type: "tendermint/PubKeySecp256k1",
type: pubkeyType.secp256k1,
value: toBase64(Secp256k1.compressPubkey(pubkey)),
},
// Recovery seems to be unused

View File

@ -110,11 +110,16 @@ export interface PubKey {
readonly value: string;
}
export const pubkeyTypes: readonly string[] = [
"tendermint/PubKeySecp256k1",
"tendermint/PubKeyEd25519",
"tendermint/PubKeySr25519",
];
export const pubkeyType = {
/** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/ed25519/ed25519.go#L22 */
secp256k1: "tendermint/PubKeySecp256k1" as const,
/** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/secp256k1/secp256k1.go#L23 */
ed25519: "tendermint/PubKeyEd25519" as const,
/** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/sr25519/codec.go#L12 */
sr25519: "tendermint/PubKeySr25519" as const,
};
export const pubkeyTypes: readonly string[] = [pubkeyType.secp256k1, pubkeyType.ed25519, pubkeyType.sr25519];
// bech32-encoded amino-binary encoded PubKey interface. oof.
export type Bech32PubKey = string;

View File

@ -74,6 +74,14 @@ export interface PubKey {
readonly type: string;
readonly value: string;
}
export declare const pubkeyType: {
/** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/ed25519/ed25519.go#L22 */
secp256k1: "tendermint/PubKeySecp256k1";
/** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/secp256k1/secp256k1.go#L23 */
ed25519: "tendermint/PubKeyEd25519";
/** @see https://github.com/tendermint/tendermint/blob/v0.33.0/crypto/sr25519/codec.go#L12 */
sr25519: "tendermint/PubKeySr25519";
};
export declare const pubkeyTypes: readonly string[];
export declare type Bech32PubKey = string;
export interface BaseAccount {