From 8cf420fd88aebd2c81a4617d9be213585e0f91b4 Mon Sep 17 00:00:00 2001 From: morrigan Date: Mon, 11 Nov 2019 15:39:09 +0100 Subject: [PATCH] Expose noise class --- src/noise.ts | 42 ++++++++++++++++++++++++++++++++++++++++-- src/types/libp2p.ts | 7 +++++-- test/noise.test.ts | 12 ++++++++++++ test/utils.ts | 8 ++++++++ 4 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 test/noise.test.ts diff --git a/src/noise.ts b/src/noise.ts index 24887a3..4e6631b 100644 --- a/src/noise.ts +++ b/src/noise.ts @@ -1,17 +1,55 @@ +import { x25519 } from 'bcrypto'; + import { bytes } from "./types/basic"; import { Connection } from "./types/libp2p"; +import { KeyPair, XXHandshake } from "./xx"; +import { signPayload } from "../test/utils"; +import {Buffer} from "buffer"; export class Noise { - constructor(privateKey: bytes, staticNoiseKey?: bytes, earlyData?: bytes) { + private readonly privateKey: bytes; + private staticKeys?: KeyPair; + private earlyData?: bytes; + constructor(privateKey: bytes, staticNoiseKey?: bytes, earlyData?: bytes) { + this.privateKey = privateKey; + this.earlyData = earlyData; + + if (staticNoiseKey) { + const publicKey = x25519.publicKeyCreate(staticNoiseKey); + this.staticKeys = { + privateKey: staticNoiseKey, + publicKey, + } + } } public tag() { return '/noise'; } - public encrypt(InsecureConnection: Connection, remotePublicKey: bytes) { + public async encrypt(InsecureConnection: Connection, remotePublicKey: bytes) { + const isInitiator = InsecureConnection.stats.direction === "outbound"; + const secretKey = await this.doHandshake(isInitiator, remotePublicKey); } + private async doHandshake(isInitiator: boolean, remotePublicKey: bytes) : Promise { + const xx = new XXHandshake(); + if (!this.staticKeys) { + this.staticKeys = await xx.generateKeypair(); + } + + let signedPayload; + if (this.earlyData) { + const payload = Buffer.concat([this.earlyData, this.staticKeys.publicKey]) + signedPayload = await signPayload(this.privateKey, payload); + } + + const prologue = Buffer.from(this.tag()); + const nsInit = await xx.initSession(isInitiator, prologue, this.staticKeys, remotePublicKey); + // TODO: Send messages, confirm handshake and return shared key + return Buffer.alloc(0); + } + } diff --git a/src/types/libp2p.ts b/src/types/libp2p.ts index 62303fa..135b82a 100644 --- a/src/types/libp2p.ts +++ b/src/types/libp2p.ts @@ -1,15 +1,18 @@ +import { bytes } from "./basic"; + type PeerId = { id: string, privKey: string, pubKey: string, }; -type ConnectionStat = { +type ConnectionStats = { direction: "inbound" | "outbound", + encryption: string, } export interface Connection { localPeer: PeerId, remotePeer: PeerId, - stat: ConnectionStat, + stats: ConnectionStats, } diff --git a/test/noise.test.ts b/test/noise.test.ts new file mode 100644 index 0000000..86efadd --- /dev/null +++ b/test/noise.test.ts @@ -0,0 +1,12 @@ +import { expect } from "chai"; +import { Noise } from "../src"; +import {generateEd25519Keys} from "./utils"; + +describe("Noise", () => { + it("should encrypt", async() => { + const libp2pKeys = await generateEd25519Keys(); + + const noise = new Noise(libp2pKeys._key); + await noise.encrypt(); + }) +}); diff --git a/test/utils.ts b/test/utils.ts index 6792447..7c9b6cb 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -1,5 +1,7 @@ import protobuf from "protobufjs"; import * as crypto from 'libp2p-crypto'; +import { ed25519 } from 'bcrypto'; +import { bytes } from "../src/types/basic"; export async function loadPayloadProto () { const payloadProtoBuf = await protobuf.load("protos/payload.proto"); @@ -9,3 +11,9 @@ export async function loadPayloadProto () { export async function generateEd25519Keys() { return await crypto.keys.generateKeyPair('ed25519'); } + +export async function signPayload(privateKey: bytes, payload: bytes) { + const Ed25519PrivateKey = crypto.keys.supportedKeys.ed25519.Ed25519PrivateKey; + // const ed25519 = Ed25519PrivateKey(privateKey, "need-to-get-public-key"); + // return ed25519.sign(privateKey, payload); +}