diff --git a/src/lib/crypto.ts b/src/lib/crypto.ts index ffd98757a0..d37a8ab7ae 100644 --- a/src/lib/crypto.ts +++ b/src/lib/crypto.ts @@ -2,6 +2,7 @@ import nodeCrypto from "crypto"; import * as secp from "@noble/secp256k1"; import * as sha3 from "js-sha3"; +import { concat } from "uint8arrays/concat"; import * as symmetric from "./waku_message/symmetric"; import { PrivateKeySize } from "./waku_message/version_1"; @@ -49,6 +50,25 @@ export function generateSymmetricKey(): Uint8Array { */ export const getPublicKey = secp.getPublicKey; +/** + * ECDSA Sign a message with the given private key. + * + * @param message The message to sign, usually a hash. + * @param privateKey The ECDSA private key to use to sign the message. + * + * @returns The signature and the recovery id concatenated. + */ +export async function sign( + message: Uint8Array, + privateKey: Uint8Array +): Promise { + const [signature, recoveryId] = await secp.sign(message, privateKey, { + recovered: true, + der: false, + }); + return concat([signature, [recoveryId]], signature.length + 1); +} + export function keccak256(input: Uint8Array): Uint8Array { return new Uint8Array(sha3.keccak256.arrayBuffer(input)); } diff --git a/src/lib/enr/keypair/secp256k1.ts b/src/lib/enr/keypair/secp256k1.ts index 1b2cdded6a..781af5db69 100644 --- a/src/lib/enr/keypair/secp256k1.ts +++ b/src/lib/enr/keypair/secp256k1.ts @@ -69,14 +69,6 @@ export const Secp256k1Keypair: IKeypairClass = class Secp256k1Keypair return true; } - async sign(msg: Uint8Array): Promise { - const [signature, recid] = await secp.sign(msg, this.privateKey, { - recovered: true, - der: false, - }); - return concat([signature, [recid]], signature.length + 1); - } - verify(msg: Uint8Array, sig: Uint8Array): boolean { try { const _sig = secp.Signature.fromCompact(sig.slice(0, 64)); diff --git a/src/lib/enr/keypair/types.ts b/src/lib/enr/keypair/types.ts index 1673d13bf4..f6f13b3656 100644 --- a/src/lib/enr/keypair/types.ts +++ b/src/lib/enr/keypair/types.ts @@ -10,7 +10,6 @@ export interface IKeypair { publicKey: Uint8Array; privateKeyVerify(): boolean; publicKeyVerify(): boolean; - sign(msg: Uint8Array): Promise; verify(msg: Uint8Array, sig: Uint8Array): boolean; hasPrivateKey(): boolean; } diff --git a/src/lib/waku_message/version_1.ts b/src/lib/waku_message/version_1.ts index 6903e2b935..89e2c7e1c2 100644 --- a/src/lib/waku_message/version_1.ts +++ b/src/lib/waku_message/version_1.ts @@ -1,7 +1,7 @@ import * as secp from "@noble/secp256k1"; import { concat } from "uint8arrays/concat"; -import { keccak256, randomBytes } from "../crypto"; +import { keccak256, randomBytes, sign } from "../crypto"; import { hexToBytes } from "../utils"; import * as ecies from "./ecies"; @@ -61,12 +61,8 @@ export async function clearEncode( if (sigPrivKey) { envelope[0] |= IsSignedMask; const hash = keccak256(envelope); - const [hexSignature, recid] = await secp.sign(hash, sigPrivKey, { - recovered: true, - der: false, - }); - const bytesSignature = hexToBytes(hexSignature); - envelope = concat([envelope, bytesSignature, [recid]]); + const bytesSignature = await sign(hash, sigPrivKey); + envelope = concat([envelope, bytesSignature]); sig = { signature: bytesSignature, publicKey: secp.getPublicKey(sigPrivKey, false),