2019-11-20 21:38:14 +01:00
|
|
|
import { x25519, ed25519 } from 'bcrypto';
|
|
|
|
import protobuf from "protobufjs";
|
2019-11-11 21:58:04 +01:00
|
|
|
|
2019-11-20 13:23:36 +01:00
|
|
|
import { KeyPair } from "./@types/libp2p";
|
|
|
|
import { bytes } from "./@types/basic";
|
2019-11-20 21:38:14 +01:00
|
|
|
import {Buffer} from "buffer";
|
|
|
|
|
|
|
|
export async function loadPayloadProto () {
|
|
|
|
const payloadProtoBuf = await protobuf.load("protos/payload.proto");
|
|
|
|
return payloadProtoBuf.lookupType("pb.NoiseHandshakePayload");
|
|
|
|
}
|
2019-11-11 21:58:04 +01:00
|
|
|
|
|
|
|
export async function generateKeypair() : Promise<KeyPair> {
|
|
|
|
const privateKey = x25519.privateKeyGenerate();
|
|
|
|
const publicKey = x25519.publicKeyCreate(privateKey);
|
|
|
|
|
|
|
|
return {
|
|
|
|
publicKey,
|
|
|
|
privateKey,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-20 21:38:14 +01:00
|
|
|
export async function createHandshakePayload(
|
|
|
|
libp2pKeys: KeyPair,
|
|
|
|
signedPayload: bytes,
|
|
|
|
earlyData?: bytes,
|
|
|
|
) : Promise<bytes> {
|
|
|
|
const NoiseHandshakePayload = await loadPayloadProto();
|
|
|
|
const payloadInit = NoiseHandshakePayload.create({
|
|
|
|
libp2pKey: libp2pKeys.publicKey,
|
|
|
|
noiseStaticKeySignature: signedPayload,
|
|
|
|
...resolveEarlyDataPayload(libp2pKeys.privateKey, earlyData),
|
|
|
|
});
|
|
|
|
|
|
|
|
return Buffer.from(NoiseHandshakePayload.encode(payloadInit).finish());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function signPayload(privateKey: bytes, payload: bytes) {
|
|
|
|
return ed25519.sign(payload, privateKey);
|
2019-11-11 21:58:04 +01:00
|
|
|
}
|
2019-11-20 21:38:14 +01:00
|
|
|
|
|
|
|
export const getHandshakePayload = (publicKey: bytes ) => Buffer.concat([Buffer.from("noise-libp2p-static-key:"), publicKey]);
|
|
|
|
|
|
|
|
export const getEarlyDataPayload = (earlyData: bytes) => Buffer.concat([Buffer.from("noise-libp2p-early-data:"), earlyData]);
|
|
|
|
|
|
|
|
function resolveEarlyDataPayload(privateKey: bytes, earlyData?: bytes) : Object {
|
|
|
|
if (!earlyData) {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
const payload = getEarlyDataPayload(earlyData);
|
|
|
|
const signedPayload = signPayload(privateKey, payload);
|
|
|
|
return {
|
|
|
|
libp2pData: payload,
|
|
|
|
libp2pDataSignature: signedPayload,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|