From a11b756ea63ac464db4a0c0d0e858fdc2d27e586 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 11 Feb 2020 23:50:13 +0100 Subject: [PATCH] Let encodeSecp256k1Signature expect compressed pubkeys --- packages/bcp/src/encode.ts | 3 ++- packages/sdk/src/pubkey.spec.ts | 7 ++----- packages/sdk/src/pubkey.ts | 6 ++++-- packages/sdk/src/signature.spec.ts | 13 ++++--------- packages/sdk/src/signature.ts | 2 +- packages/sdk/types/signature.d.ts | 2 +- 6 files changed, 14 insertions(+), 19 deletions(-) diff --git a/packages/bcp/src/encode.ts b/packages/bcp/src/encode.ts index 23f7385d..64f18cdb 100644 --- a/packages/bcp/src/encode.ts +++ b/packages/bcp/src/encode.ts @@ -72,8 +72,9 @@ export function encodeFee(fee: Fee, tokens: BankTokens): types.StdFee { export function encodeFullSignature(fullSignature: FullSignature): types.StdSignature { switch (fullSignature.pubkey.algo) { case Algorithm.Secp256k1: { + const compressedPubkey = Secp256k1.compressPubkey(fullSignature.pubkey.data); const normalizedSignature = Secp256k1.trimRecoveryByte(fullSignature.signature); - return encodeSecp256k1Signature(fullSignature.pubkey.data, normalizedSignature); + return encodeSecp256k1Signature(compressedPubkey, normalizedSignature); } default: throw new Error("Unsupported signing algorithm"); diff --git a/packages/sdk/src/pubkey.spec.ts b/packages/sdk/src/pubkey.spec.ts index 0224764a..51427488 100644 --- a/packages/sdk/src/pubkey.spec.ts +++ b/packages/sdk/src/pubkey.spec.ts @@ -15,14 +15,11 @@ describe("pubkey", () => { }); }); - it("compresses uncompressed public keys", () => { + it("throws for uncompressed public keys", () => { const pubkey = fromBase64( "BE8EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQE7WHpoHoNswYeoFkuYpYSKK4mzFzMV/dB0DVAy4lnNU=", ); - expect(encodeSecp256k1Pubkey(pubkey)).toEqual({ - type: "tendermint/PubKeySecp256k1", - value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ", - }); + expect(() => encodeSecp256k1Pubkey(pubkey)).toThrowError(/public key must be compressed secp256k1/i); }); }); diff --git a/packages/sdk/src/pubkey.ts b/packages/sdk/src/pubkey.ts index 49a3cfd2..5da2e0a5 100644 --- a/packages/sdk/src/pubkey.ts +++ b/packages/sdk/src/pubkey.ts @@ -1,13 +1,15 @@ -import { Secp256k1 } from "@iov/crypto"; import { Bech32, Encoding } from "@iov/encoding"; import equal from "fast-deep-equal"; import { Bech32PubKey, PubKey, pubkeyType } from "./types"; export function encodeSecp256k1Pubkey(pubkey: Uint8Array): PubKey { + if (pubkey.length !== 33 || (pubkey[0] !== 0x02 && pubkey[0] !== 0x03)) { + throw new Error("Public key must be compressed secp256k1, i.e. 33 bytes starting with 0x02 or 0x03"); + } return { type: pubkeyType.secp256k1, - value: Encoding.toBase64(Secp256k1.compressPubkey(pubkey)), + value: Encoding.toBase64(pubkey), }; } diff --git a/packages/sdk/src/signature.spec.ts b/packages/sdk/src/signature.spec.ts index b95612d1..b0e782c1 100644 --- a/packages/sdk/src/signature.spec.ts +++ b/packages/sdk/src/signature.spec.ts @@ -22,21 +22,16 @@ describe("signature", () => { }); }); - it("compresses uncompressed public keys", () => { + it("throws when getting uncompressed public keys", () => { const pubkey = fromBase64( "BE8EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQE7WHpoHoNswYeoFkuYpYSKK4mzFzMV/dB0DVAy4lnNU=", ); const signature = fromBase64( "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", ); - expect(encodeSecp256k1Signature(pubkey, signature)).toEqual({ - // eslint-disable-next-line @typescript-eslint/camelcase - pub_key: { - type: "tendermint/PubKeySecp256k1", - value: "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ", - }, - signature: "1nUcIH0CLT0/nQ0mBTDrT6kMG20NY/PsH7P2gc4bpYNGLEYjBmdWevXUJouSE/9A/60QG9cYeqyTe5kFDeIPxQ==", - }); + expect(() => encodeSecp256k1Signature(pubkey, signature)).toThrowError( + /public key must be compressed secp256k1/i, + ); }); it("throws if signature contains recovery byte", () => { diff --git a/packages/sdk/src/signature.ts b/packages/sdk/src/signature.ts index a71f03eb..d31eb119 100644 --- a/packages/sdk/src/signature.ts +++ b/packages/sdk/src/signature.ts @@ -6,7 +6,7 @@ import { pubkeyType, StdSignature } from "./types"; /** * Takes a binary pubkey and signature to create a signature object * - * @param pubkey a secp256k1 public key + * @param pubkey a compressed secp256k1 public key * @param signature a 64 byte fixed length representation of secp256k1 signature components r and s */ export function encodeSecp256k1Signature(pubkey: Uint8Array, signature: Uint8Array): StdSignature { diff --git a/packages/sdk/types/signature.d.ts b/packages/sdk/types/signature.d.ts index a2c9586c..c23e7167 100644 --- a/packages/sdk/types/signature.d.ts +++ b/packages/sdk/types/signature.d.ts @@ -2,7 +2,7 @@ import { StdSignature } from "./types"; /** * Takes a binary pubkey and signature to create a signature object * - * @param pubkey a secp256k1 public key + * @param pubkey a compressed secp256k1 public key * @param signature a 64 byte fixed length representation of secp256k1 signature components r and s */ export declare function encodeSecp256k1Signature(pubkey: Uint8Array, signature: Uint8Array): StdSignature;