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

View File

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