Change generating keys

This commit is contained in:
morrigan 2019-11-06 15:16:13 +01:00
parent fe706fbd71
commit 1666769690
2 changed files with 41 additions and 17 deletions

View File

@ -1,6 +1,5 @@
import {bytes32, bytes16, uint32, uint64, bytes} from './types/basic'
import { Buffer } from 'buffer';
import * as crypto from 'libp2p-crypto';
import { AEAD, x25519, HKDF, SHA256 } from 'bcrypto';
import { BN } from 'bn.js';
@ -75,7 +74,10 @@ export class XXHandshake {
}
private dh(privateKey: bytes32, publicKey: bytes32) : bytes32 {
return x25519.derive(privateKey, publicKey);
const derived = x25519.derive(privateKey, publicKey);
const result = Buffer.alloc(32);
derived.copy(result);
return result;
}
private convertNonce(n: uint32) : bytes {
@ -146,14 +148,14 @@ export class XXHandshake {
const ck = h;
const key = this.createEmptyKey();
const cs = this.initializeKey(key);
const cs:CipherState = this.initializeKey(key);
return { cs, ck, h };
}
private mixKey(ss: SymmetricState, ikm: bytes32) {
const [ ck, tempK ] = this.getHkdf(ss.ck, ikm);
ss.cs = this.initializeKey(tempK);
ss.cs = this.initializeKey(tempK) as CipherState;
ss.ck = ck;
}
@ -234,9 +236,11 @@ export class XXHandshake {
hs.e = await this.generateKeypair();
const ne = hs.e.publicKey;
this.mixHash(hs.ss, ne);
await this.mixKey(hs.ss, this.dh(hs.e.privateKey, hs.re));
this.mixKey(hs.ss, this.dh(hs.e.privateKey, hs.re));
const spk = Buffer.from(hs.s.publicKey);
const ns = await this.encryptAndHash(hs.ss, spk);
this.mixKey(hs.ss, this.dh(hs.s.privateKey, hs.re));
const ciphertext = await this.encryptAndHash(hs.ss, payload);
@ -304,11 +308,12 @@ export class XXHandshake {
}
public async generateKeypair() : Promise<KeyPair> {
const Ed25519PrivateKey = await crypto.keys.generateKeyPair('ed25519');
const privateKey = x25519.privateKeyGenerate();
const publicKey = x25519.publicKeyCreate(privateKey);
return {
publicKey: Ed25519PrivateKey.public.bytes,
privateKey: Ed25519PrivateKey.bytes,
publicKey,
privateKey,
}
}
@ -359,7 +364,7 @@ export class XXHandshake {
throw new Error("Session invalid.")
}
session.mc++;
session.mc = session.mc.add(new BN(1));
return messageBuffer;
}
@ -391,7 +396,7 @@ export class XXHandshake {
throw new Error("Session invalid.");
}
session.mc++;
session.mc = session.mc.add(new BN(1));
return plaintext;
}
}

View File

@ -2,6 +2,7 @@ import { expect, assert } from "chai";
import { Buffer } from 'buffer';
import * as crypto from 'libp2p-crypto';
import protobuf from 'protobufjs';
import { ed25519 } from 'bcrypto';
import { XXHandshake, KeyPair } from "../src/xx";
@ -31,8 +32,8 @@ describe("Index", () => {
expect(k3.toString('hex')).to.equal('ff67bf9727e31b06efc203907e6786667d2c7a74ac412b4d31a80ba3fd766f68');
})
async function generateKeypair() {
return await crypto.keys.generateKeyPair('ed25519');;
async function generateEd25519Keys() {
return await crypto.keys.generateKeyPair('ed25519');
}
async function doHandshake() {
@ -42,11 +43,11 @@ describe("Index", () => {
const payloadString = Buffer.from("noise-libp2p-static-key:");
// initiator setup
const libp2pInitKeys = await generateKeypair();
const libp2pInitKeys = await generateEd25519Keys();
const initSignedPayload = await libp2pInitKeys.sign(Buffer.concat([payloadString, kpInit.publicKey]));
// responder setup
const libp2pRespKeys = await generateKeypair();
const libp2pRespKeys = await generateEd25519Keys();
const respSignedPayload = await libp2pRespKeys.sign(Buffer.concat([payloadString, kpResp.publicKey]));
// initiator: new XX noise session
@ -54,16 +55,15 @@ describe("Index", () => {
// responder: new XX noise session
const nsResp = await xx.initSession(false, prologue, kpResp, kpInit.publicKey);
/* stage 0: initiator */
/* STAGE 0 */
// initiator creates payload
const payloadProtoBuf = await protobuf.load("payload.proto");
const NoiseHandshakePayload = payloadProtoBuf.lookupType("pb.NoiseHandshakePayload");
const payloadInit = NoiseHandshakePayload.create({
libp2pKey: libp2pInitKeys.bytes.toString('hex'),
libp2pKey: libp2pInitKeys.bytes,
noiseStaticKeySignature: initSignedPayload,
});
const payloadInitEnc = NoiseHandshakePayload.encode(payloadInit).finish();
// initiator sends message
@ -71,6 +71,25 @@ describe("Index", () => {
const messageBuffer = await xx.sendMessage(nsInit, message);
expect(messageBuffer.ne.length).not.equal(0);
// responder receives message
const plaintext = await xx.RecvMessage(nsResp, messageBuffer);
/* STAGE 1 */
// responder creates payload
const payloadResp = NoiseHandshakePayload.create({
libp2pKey: libp2pRespKeys.bytes,
noiseStaticKeySignature: respSignedPayload,
});
const payloadRespEnc = NoiseHandshakePayload.encode(payloadResp).finish();
const message1 = Buffer.concat([message, payloadRespEnc]);
console.log("nsResp: ", nsResp)
const messageBuffer2 = await xx.sendMessage(nsResp, message1);
expect(messageBuffer2.ne.length).not.equal(0);
expect(messageBuffer2.ns.length).not.equal(0);
}
it("Test handshake", async () => {