Skip to content

Commit

Permalink
Remove secp256k12 usage from enr.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
D4nte committed Mar 7, 2022
1 parent 8b2b412 commit bcc0b64
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 18 deletions.
4 changes: 2 additions & 2 deletions src/lib/enr/enr.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ describe("ENR", function () {
);
});

it("should encode/decode to RLP encoding", () => {
const decoded = ENR.decode(record.encode(privateKey));
it("should encode/decode to RLP encoding", async () => {
const decoded = ENR.decode(await record.encode(privateKey));
expect(decoded).to.deep.equal(record);
});

Expand Down
22 changes: 15 additions & 7 deletions src/lib/enr/enr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,18 +427,20 @@ export class ENR extends Map<ENRKey, ENRValue> {
return v4.verify(this.publicKey, data, signature);
}

sign(data: Uint8Array, privateKey: Uint8Array): Uint8Array {
async sign(data: Uint8Array, privateKey: Uint8Array): Promise<Uint8Array> {
switch (this.id) {
case "v4":
this.signature = v4.sign(privateKey, data);
this.signature = await v4.sign(privateKey, data);
break;
default:
throw new Error(ERR_INVALID_ID);
}
return this.signature;
}

encodeToValues(privateKey?: Uint8Array): (ENRKey | ENRValue | number[])[] {
async encodeToValues(
privateKey?: Uint8Array
): Promise<(ENRKey | ENRValue | number[])[]> {
// sort keys and flatten into [k, v, k, v, ...]
const content: Array<ENRKey | ENRValue | number[]> = Array.from(this.keys())
.sort((a, b) => a.localeCompare(b))
Expand All @@ -447,7 +449,9 @@ export class ENR extends Map<ENRKey, ENRValue> {
.flat();
content.unshift(new Uint8Array([Number(this.seq)]));
if (privateKey) {
content.unshift(this.sign(hexToBytes(RLP.encode(content)), privateKey));
content.unshift(
await this.sign(hexToBytes(RLP.encode(content)), privateKey)
);
} else {
if (!this.signature) {
throw new Error(ERR_NO_SIGNATURE);
Expand All @@ -457,15 +461,19 @@ export class ENR extends Map<ENRKey, ENRValue> {
return content;
}

encode(privateKey?: Uint8Array): Uint8Array {
const encoded = hexToBytes(RLP.encode(this.encodeToValues(privateKey)));
async encode(privateKey?: Uint8Array): Promise<Uint8Array> {
const encoded = hexToBytes(
RLP.encode(await this.encodeToValues(privateKey))
);
if (encoded.length >= MAX_RECORD_SIZE) {
throw new Error("ENR must be less than 300 bytes");
}
return encoded;
}

async encodeTxt(privateKey?: Uint8Array): Promise<string> {
return ENR.RECORD_PREFIX + (await bytesToBase64(this.encode(privateKey)));
return (
ENR.RECORD_PREFIX + (await bytesToBase64(await this.encode(privateKey)))
);
}
}
29 changes: 20 additions & 9 deletions src/lib/enr/v4.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as secp from "@noble/secp256k1";
import { keccak256 } from "js-sha3";
import * as secp256k1 from "secp256k1";

import { randomBytes } from "../crypto";

Expand All @@ -15,11 +15,17 @@ export function createPrivateKey(): Uint8Array {
}

export function publicKey(privKey: Uint8Array): Uint8Array {
return secp256k1.publicKeyCreate(privKey);
return secp.getPublicKey(privKey, false);
}

export function sign(privKey: Uint8Array, msg: Uint8Array): Uint8Array {
const { signature } = secp256k1.ecdsaSign(hash(msg), privKey);
export async function sign(
privKey: Uint8Array,
msg: Uint8Array
): Promise<Uint8Array> {
const [signature] = await secp.sign(hash(msg), privKey, {
recovered: true,
der: false,
});
return signature;
}

Expand All @@ -28,12 +34,17 @@ export function verify(
msg: Uint8Array,
sig: Uint8Array
): boolean {
// Remove the recovery id if present (byte #65)
return secp256k1.ecdsaVerify(sig.slice(0, 64), hash(msg), pubKey);
try {
const _sig = secp.Signature.fromCompact(sig.slice(0, 64));
return secp.verify(_sig, hash(msg), pubKey);
} catch {
return false;
}
}

export function nodeId(pubKey: Uint8Array): NodeId {
const uncompressedPubkey = secp256k1.publicKeyConvert(pubKey, false);
const publicKey = secp.Point.fromHex(pubKey);
const uncompressedPubkey = publicKey.toRawBytes(false);

return createNodeId(hash(uncompressedPubkey.slice(1)));
}
Expand All @@ -47,7 +58,7 @@ export class ENRKeyPair {

public static create(privateKey?: Uint8Array): ENRKeyPair {
if (privateKey) {
if (!secp256k1.privateKeyVerify(privateKey)) {
if (!secp.utils.isValidPrivateKey(privateKey)) {
throw new Error("Invalid private key");
}
}
Expand All @@ -58,7 +69,7 @@ export class ENRKeyPair {
return new ENRKeyPair(_nodeId, _privateKey, _publicKey);
}

public sign(msg: Uint8Array): Uint8Array {
public async sign(msg: Uint8Array): Promise<Uint8Array> {
return sign(this.privateKey, msg);
}

Expand Down

0 comments on commit bcc0b64

Please sign in to comment.