Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions packages/discv5/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,14 @@
"devDependencies": {},
"dependencies": {
"@chainsafe/enr": "^4.0.1",
"@ethereumjs/rlp": "^5.0.2",
"@libp2p/crypto": "^5.0.1",
"@libp2p/interface": "^2.0.1",
"@multiformats/multiaddr": "^12.1.10",
"@noble/hashes": "^1.7.0",
"@noble/secp256k1": "^2.2.2",
"bigint-buffer": "^1.1.5",
"debug": "^4.3.1",
"lru-cache": "^10.1.0",
"rlp": "^2.2.6",
"strict-event-emitter-types": "^2.0.0"
}
}
7 changes: 3 additions & 4 deletions packages/discv5/src/kademlia/util.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { toBigIntBE } from "bigint-buffer";
import { NodeId } from "@chainsafe/enr";
import { bytesToBigint, NodeId } from "@chainsafe/enr";

import { fromHex } from "../util/index.js";
import { NUM_BUCKETS } from "./constants.js";
import { hexToBytes } from "ethereum-cryptography/utils.js";

/**
* Computes the xor distance between two NodeIds
*/
export function distance(a: NodeId, b: NodeId): bigint {
return toBigIntBE(fromHex(a)) ^ toBigIntBE(fromHex(b));
return bytesToBigint(hexToBytes(a)) ^ bytesToBigint(hexToBytes(b));
}

export function log2Distance(a: NodeId, b: NodeId): number {
Expand Down
5 changes: 2 additions & 3 deletions packages/discv5/src/keypair/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { KeyType } from "@libp2p/interface";
import { IKeypair } from "./types.js";
import { ERR_TYPE_NOT_IMPLEMENTED } from "./constants.js";
import { Secp256k1Keypair } from "./secp256k1.js";
import { toBuffer } from "../util/index.js";

export * from "./types.js";
export * from "./secp256k1.js";
Expand Down Expand Up @@ -33,8 +32,8 @@ export function createKeypair(init: KeypairInit): IKeypair {
switch (init.type) {
case "secp256k1":
return new Secp256k1Keypair(
init.privateKey ? toBuffer(init.privateKey) : undefined,
init.publicKey ? toBuffer(init.publicKey) : undefined
init.privateKey ? init.privateKey : undefined,
init.publicKey ? init.publicKey : undefined
);
default:
throw new Error(ERR_TYPE_NOT_IMPLEMENTED);
Expand Down
31 changes: 15 additions & 16 deletions packages/discv5/src/keypair/secp256k1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,23 @@ import { KeyType } from "@libp2p/interface";
import { AbstractKeypair, IKeypair, IKeypairClass } from "./types.js";
import { ERR_INVALID_KEYPAIR_TYPE } from "./constants.js";
import { getDiscv5Crypto } from "../util/crypto.js";
import { toBuffer } from "../util/index.js";

export function secp256k1PublicKeyToCompressed(publicKey: Buffer): Buffer {
import { concatBytes } from "@noble/hashes/utils";
export function secp256k1PublicKeyToCompressed(publicKey: Uint8Array): Uint8Array {
if (publicKey.length === 64) {
publicKey = Buffer.concat([Buffer.from([4]), publicKey]);
publicKey = concatBytes(Uint8Array.from([4]), publicKey);
}
return toBuffer(getDiscv5Crypto().secp256k1.publicKeyConvert(publicKey, true));
return getDiscv5Crypto().secp256k1.publicKeyConvert(publicKey, true);
}

export function secp256k1PublicKeyToRaw(publicKey: Buffer): Buffer {
return toBuffer(getDiscv5Crypto().secp256k1.publicKeyConvert(publicKey, false));
export function secp256k1PublicKeyToRaw(publicKey: Uint8Array): Uint8Array {
return getDiscv5Crypto().secp256k1.publicKeyConvert(publicKey, false);
}

export const Secp256k1Keypair: IKeypairClass = class Secp256k1Keypair extends AbstractKeypair implements IKeypair {
readonly type: KeyType;

constructor(privateKey?: Buffer, publicKey?: Buffer) {
let pub = publicKey ?? toBuffer(getDiscv5Crypto().secp256k1.publicKeyCreate(privateKey!));
constructor(privateKey?: Uint8Array, publicKey?: Uint8Array) {
let pub = publicKey ?? getDiscv5Crypto().secp256k1.publicKeyCreate(privateKey!);
if (pub) {
pub = secp256k1PublicKeyToCompressed(pub);
}
Expand All @@ -28,8 +27,8 @@ export const Secp256k1Keypair: IKeypairClass = class Secp256k1Keypair extends Ab
}

static generate(): Secp256k1Keypair {
const privateKey = toBuffer(getDiscv5Crypto().secp256k1.generatePrivateKey());
const publicKey = toBuffer(getDiscv5Crypto().secp256k1.publicKeyCreate(privateKey));
const privateKey = getDiscv5Crypto().secp256k1.generatePrivateKey();
const publicKey = getDiscv5Crypto().secp256k1.publicKeyCreate(privateKey);
return new Secp256k1Keypair(privateKey, publicKey);
}

Expand All @@ -45,16 +44,16 @@ export const Secp256k1Keypair: IKeypairClass = class Secp256k1Keypair extends Ab
}
return true;
}
sign(msg: Buffer): Buffer {
return toBuffer(getDiscv5Crypto().secp256k1.sign(msg, this.privateKey));
sign(msg: Uint8Array): Uint8Array {
return getDiscv5Crypto().secp256k1.sign(msg, this.privateKey);
}
verify(msg: Buffer, sig: Buffer): boolean {
verify(msg: Uint8Array, sig: Uint8Array): boolean {
return getDiscv5Crypto().secp256k1.verify(this.publicKey, msg, sig);
}
deriveSecret(keypair: IKeypair): Buffer {
deriveSecret(keypair: IKeypair): Uint8Array {
if (keypair.type !== this.type) {
throw new Error(ERR_INVALID_KEYPAIR_TYPE);
}
return toBuffer(getDiscv5Crypto().secp256k1.deriveSecret(this.privateKey, keypair.publicKey));
return getDiscv5Crypto().secp256k1.deriveSecret(this.privateKey, keypair.publicKey);
}
};
22 changes: 11 additions & 11 deletions packages/discv5/src/keypair/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,39 @@ import { KeyType } from "@libp2p/interface";

export interface IKeypair {
type: KeyType;
privateKey: Buffer;
publicKey: Buffer;
privateKey: Uint8Array;
publicKey: Uint8Array;
privateKeyVerify(): boolean;
publicKeyVerify(): boolean;
sign(msg: Buffer): Buffer;
verify(msg: Buffer, sig: Buffer): boolean;
deriveSecret(keypair: IKeypair): Buffer;
sign(msg: Uint8Array): Uint8Array;
verify(msg: Uint8Array, sig: Uint8Array): boolean;
deriveSecret(keypair: IKeypair): Uint8Array;
hasPrivateKey(): boolean;
}

export interface IKeypairClass {
new (privateKey?: Buffer, publicKey?: Buffer): IKeypair;
new (privateKey?: Uint8Array, publicKey?: Uint8Array): IKeypair;
generate(): IKeypair;
}

export abstract class AbstractKeypair {
readonly _privateKey?: Buffer;
readonly _publicKey?: Buffer;
constructor(privateKey?: Buffer, publicKey?: Buffer) {
readonly _privateKey?: Uint8Array;
readonly _publicKey?: Uint8Array;
constructor(privateKey?: Uint8Array, publicKey?: Uint8Array) {
if ((this._privateKey = privateKey) && !this.privateKeyVerify()) {
throw new Error("Invalid private key");
}
if ((this._publicKey = publicKey) && !this.publicKeyVerify()) {
throw new Error("Invalid private key");
}
}
get privateKey(): Buffer {
get privateKey(): Uint8Array {
if (!this._privateKey) {
throw new Error();
}
return this._privateKey;
}
get publicKey(): Buffer {
get publicKey(): Uint8Array {
if (!this._publicKey) {
throw new Error();
}
Expand Down
14 changes: 6 additions & 8 deletions packages/discv5/src/message/create.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { randomBytes } from "@noble/hashes/utils";
import { toBigIntBE } from "bigint-buffer";
import { SequenceNumber, ENR } from "@chainsafe/enr";
import { randomBytes, toBytes } from "@noble/hashes/utils";
import { bytesToBigint, SequenceNumber, ENR } from "@chainsafe/enr";

import {
RequestId,
Expand All @@ -11,10 +10,9 @@ import {
ITalkReqMessage,
ITalkRespMessage,
} from "./types.js";
import { toBuffer } from "../index.js";

export function createRequestId(): RequestId {
return toBigIntBE(toBuffer(randomBytes(8)));
return bytesToBigint(randomBytes(8));
}

export function createPingMessage(enrSeq: SequenceNumber): IPingMessage {
Expand Down Expand Up @@ -46,14 +44,14 @@ export function createTalkRequestMessage(request: string | Uint8Array, protocol:
return {
type: MessageType.TALKREQ,
id: createRequestId(),
protocol: Buffer.from(protocol),
request: Buffer.from(request),
protocol: toBytes(protocol),
request: toBytes(request),
};
}
export function createTalkResponseMessage(requestId: RequestId, payload: Uint8Array): ITalkRespMessage {
return {
type: MessageType.TALKRESP,
id: requestId,
response: toBuffer(payload),
response: payload,
};
}
Loading