From c85c39a427924cfc510e0aa81ea34555351303b3 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Fri, 20 May 2022 12:06:14 +1000 Subject: [PATCH] Consolidate signature verification logic --- src/lib/crypto.ts | 16 ++++++++++++++++ src/lib/discovery/enrtree.ts | 19 ++++++------------- src/lib/enr/enr.ts | 4 ++-- src/lib/enr/keypair/secp256k1.ts | 9 --------- src/lib/enr/keypair/types.ts | 1 - src/lib/enr/v4.ts | 13 ------------- 6 files changed, 24 insertions(+), 38 deletions(-) diff --git a/src/lib/crypto.ts b/src/lib/crypto.ts index 32a330e278..0eedbbe6e2 100644 --- a/src/lib/crypto.ts +++ b/src/lib/crypto.ts @@ -80,3 +80,19 @@ export function compressPublicKey(publicKey: Uint8Array): Uint8Array { const point = secp.Point.fromHex(publicKey); return point.toRawBytes(true); } + +/** + * Verify an ECDSA signature. + */ +export function verifySignature( + signature: Uint8Array, + message: Uint8Array | string, + publicKey: Uint8Array +): boolean { + try { + const _signature = secp.Signature.fromCompact(signature.slice(0, 64)); + return secp.verify(_signature, message, publicKey); + } catch { + return false; + } +} diff --git a/src/lib/discovery/enrtree.ts b/src/lib/discovery/enrtree.ts index e87b87946d..ca18a8dc33 100644 --- a/src/lib/discovery/enrtree.ts +++ b/src/lib/discovery/enrtree.ts @@ -1,8 +1,7 @@ -import * as secp from "@noble/secp256k1"; import * as base32 from "hi-base32"; import { fromString } from "uint8arrays/from-string"; -import { keccak256 } from "../crypto"; +import { keccak256, verifySignature } from "../crypto"; import { ENR } from "../enr"; import { utf8ToBytes } from "../utils"; @@ -47,17 +46,11 @@ export class ENRTree { 64 ); - let isVerified; - try { - const _sig = secp.Signature.fromCompact(signatureBuffer.slice(0, 64)); - isVerified = secp.verify( - _sig, - keccak256(signedComponentBuffer), - new Uint8Array(decodedPublicKey) - ); - } catch { - isVerified = false; - } + const isVerified = verifySignature( + signatureBuffer, + keccak256(signedComponentBuffer), + new Uint8Array(decodedPublicKey) + ); if (!isVerified) throw new Error("Unable to verify ENRTree root signature"); diff --git a/src/lib/enr/enr.ts b/src/lib/enr/enr.ts index e0632b83b8..519c4dbcd3 100644 --- a/src/lib/enr/enr.ts +++ b/src/lib/enr/enr.ts @@ -9,7 +9,7 @@ import { fromString } from "uint8arrays/from-string"; import { toString } from "uint8arrays/to-string"; import { encode as varintEncode } from "varint"; -import { compressPublicKey } from "../crypto"; +import { compressPublicKey, keccak256, verifySignature } from "../crypto"; import { bytesToHex, bytesToUtf8, hexToBytes, utf8ToBytes } from "../utils"; import { ERR_INVALID_ID, ERR_NO_SIGNATURE, MAX_RECORD_SIZE } from "./constants"; @@ -472,7 +472,7 @@ export class ENR extends Map { if (!this.publicKey) { throw new Error("Failed to verify ENR: No public key"); } - return v4.verify(this.publicKey, data, signature); + return verifySignature(signature, keccak256(data), this.publicKey); } async sign(data: Uint8Array, privateKey: Uint8Array): Promise { diff --git a/src/lib/enr/keypair/secp256k1.ts b/src/lib/enr/keypair/secp256k1.ts index 0a960fbc35..bac7be7967 100644 --- a/src/lib/enr/keypair/secp256k1.ts +++ b/src/lib/enr/keypair/secp256k1.ts @@ -49,15 +49,6 @@ export class Secp256k1Keypair implements IKeypair { return true; } - verify(msg: Uint8Array, sig: Uint8Array): boolean { - try { - const _sig = secp.Signature.fromCompact(sig.slice(0, 64)); - return secp.verify(_sig, msg, this.publicKey); - } catch { - return false; - } - } - get privateKey(): Uint8Array { if (!this._privateKey) { throw new Error(); diff --git a/src/lib/enr/keypair/types.ts b/src/lib/enr/keypair/types.ts index 4d84d030c1..a24618dadf 100644 --- a/src/lib/enr/keypair/types.ts +++ b/src/lib/enr/keypair/types.ts @@ -10,6 +10,5 @@ export interface IKeypair { publicKey: Uint8Array; privateKeyVerify(): boolean; publicKeyVerify(): boolean; - verify(msg: Uint8Array, sig: Uint8Array): boolean; hasPrivateKey(): boolean; } diff --git a/src/lib/enr/v4.ts b/src/lib/enr/v4.ts index 6555de58ba..296347a849 100644 --- a/src/lib/enr/v4.ts +++ b/src/lib/enr/v4.ts @@ -14,19 +14,6 @@ export async function sign( }); } -export function verify( - pubKey: Uint8Array, - msg: Uint8Array, - sig: Uint8Array -): boolean { - try { - const _sig = secp.Signature.fromCompact(sig.slice(0, 64)); - return secp.verify(_sig, keccak256(msg), pubKey); - } catch { - return false; - } -} - export function nodeId(pubKey: Uint8Array): NodeId { const publicKey = secp.Point.fromHex(pubKey); const uncompressedPubkey = publicKey.toRawBytes(false);