mirror of https://github.com/waku-org/js-waku.git
Consolidate signature verification logic
This commit is contained in:
parent
2ed3580584
commit
c85c39a427
|
@ -80,3 +80,19 @@ export function compressPublicKey(publicKey: Uint8Array): Uint8Array {
|
||||||
const point = secp.Point.fromHex(publicKey);
|
const point = secp.Point.fromHex(publicKey);
|
||||||
return point.toRawBytes(true);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import * as secp from "@noble/secp256k1";
|
|
||||||
import * as base32 from "hi-base32";
|
import * as base32 from "hi-base32";
|
||||||
import { fromString } from "uint8arrays/from-string";
|
import { fromString } from "uint8arrays/from-string";
|
||||||
|
|
||||||
import { keccak256 } from "../crypto";
|
import { keccak256, verifySignature } from "../crypto";
|
||||||
import { ENR } from "../enr";
|
import { ENR } from "../enr";
|
||||||
import { utf8ToBytes } from "../utils";
|
import { utf8ToBytes } from "../utils";
|
||||||
|
|
||||||
|
@ -47,17 +46,11 @@ export class ENRTree {
|
||||||
64
|
64
|
||||||
);
|
);
|
||||||
|
|
||||||
let isVerified;
|
const isVerified = verifySignature(
|
||||||
try {
|
signatureBuffer,
|
||||||
const _sig = secp.Signature.fromCompact(signatureBuffer.slice(0, 64));
|
|
||||||
isVerified = secp.verify(
|
|
||||||
_sig,
|
|
||||||
keccak256(signedComponentBuffer),
|
keccak256(signedComponentBuffer),
|
||||||
new Uint8Array(decodedPublicKey)
|
new Uint8Array(decodedPublicKey)
|
||||||
);
|
);
|
||||||
} catch {
|
|
||||||
isVerified = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isVerified) throw new Error("Unable to verify ENRTree root signature");
|
if (!isVerified) throw new Error("Unable to verify ENRTree root signature");
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { fromString } from "uint8arrays/from-string";
|
||||||
import { toString } from "uint8arrays/to-string";
|
import { toString } from "uint8arrays/to-string";
|
||||||
import { encode as varintEncode } from "varint";
|
import { encode as varintEncode } from "varint";
|
||||||
|
|
||||||
import { compressPublicKey } from "../crypto";
|
import { compressPublicKey, keccak256, verifySignature } from "../crypto";
|
||||||
import { bytesToHex, bytesToUtf8, hexToBytes, utf8ToBytes } from "../utils";
|
import { bytesToHex, bytesToUtf8, hexToBytes, utf8ToBytes } from "../utils";
|
||||||
|
|
||||||
import { ERR_INVALID_ID, ERR_NO_SIGNATURE, MAX_RECORD_SIZE } from "./constants";
|
import { ERR_INVALID_ID, ERR_NO_SIGNATURE, MAX_RECORD_SIZE } from "./constants";
|
||||||
|
@ -472,7 +472,7 @@ export class ENR extends Map<ENRKey, ENRValue> {
|
||||||
if (!this.publicKey) {
|
if (!this.publicKey) {
|
||||||
throw new Error("Failed to verify ENR: No public key");
|
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<Uint8Array> {
|
async sign(data: Uint8Array, privateKey: Uint8Array): Promise<Uint8Array> {
|
||||||
|
|
|
@ -49,15 +49,6 @@ export class Secp256k1Keypair implements IKeypair {
|
||||||
return true;
|
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 {
|
get privateKey(): Uint8Array {
|
||||||
if (!this._privateKey) {
|
if (!this._privateKey) {
|
||||||
throw new Error();
|
throw new Error();
|
||||||
|
|
|
@ -10,6 +10,5 @@ export interface IKeypair {
|
||||||
publicKey: Uint8Array;
|
publicKey: Uint8Array;
|
||||||
privateKeyVerify(): boolean;
|
privateKeyVerify(): boolean;
|
||||||
publicKeyVerify(): boolean;
|
publicKeyVerify(): boolean;
|
||||||
verify(msg: Uint8Array, sig: Uint8Array): boolean;
|
|
||||||
hasPrivateKey(): boolean;
|
hasPrivateKey(): boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
export function nodeId(pubKey: Uint8Array): NodeId {
|
||||||
const publicKey = secp.Point.fromHex(pubKey);
|
const publicKey = secp.Point.fromHex(pubKey);
|
||||||
const uncompressedPubkey = publicKey.toRawBytes(false);
|
const uncompressedPubkey = publicKey.toRawBytes(false);
|
||||||
|
|
Loading…
Reference in New Issue