node-noise
Version:
145 lines • 5.54 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbstractHandshake = void 0;
var equals_1 = require("../uint8arrays/equals");
var concat_1 = require("../uint8arrays/concat");
var uint8arrays_1 = require("../uint8arrays");
var logger_1 = require("../logger");
var nonce_1 = require("../nonce");
var AbstractHandshake = /** @class */ (function () {
function AbstractHandshake(crypto) {
this.crypto = crypto;
}
AbstractHandshake.prototype.encryptWithAd = function (cs, ad, plaintext) {
var e = this.encrypt(cs.k, cs.n, ad, plaintext);
cs.n.increment();
return e;
};
AbstractHandshake.prototype.decryptWithAd = function (cs, ad, ciphertext, dst) {
var _a = this.decrypt(cs.k, cs.n, ad, ciphertext, dst), plaintext = _a.plaintext, valid = _a.valid;
if (valid)
cs.n.increment();
return { plaintext: plaintext, valid: valid };
};
// Cipher state related
AbstractHandshake.prototype.hasKey = function (cs) {
return !this.isEmptyKey(cs.k);
};
AbstractHandshake.prototype.createEmptyKey = function () {
return new Uint8Array(32);
};
AbstractHandshake.prototype.isEmptyKey = function (k) {
var emptyKey = this.createEmptyKey();
return (0, equals_1.equals)(emptyKey, k);
};
AbstractHandshake.prototype.encrypt = function (k, n, ad, plaintext) {
n.assertValue();
return this.crypto.chaCha20Poly1305Encrypt(plaintext, n.getBytes(), ad, k);
};
AbstractHandshake.prototype.encryptAndHash = function (ss, plaintext) {
var ciphertext;
if (this.hasKey(ss.cs)) {
ciphertext = this.encryptWithAd(ss.cs, ss.h, plaintext);
}
else {
ciphertext = plaintext;
}
this.mixHash(ss, ciphertext);
return ciphertext;
};
AbstractHandshake.prototype.decrypt = function (k, n, ad, ciphertext, dst) {
n.assertValue();
var encryptedMessage = this.crypto.chaCha20Poly1305Decrypt(ciphertext, n.getBytes(), ad, k, dst);
if (encryptedMessage) {
return {
plaintext: encryptedMessage,
valid: true
};
}
else {
return {
plaintext: new Uint8Array(0),
valid: false
};
}
};
AbstractHandshake.prototype.decryptAndHash = function (ss, ciphertext) {
var _a;
var plaintext;
var valid = true;
if (this.hasKey(ss.cs)) {
(_a = this.decryptWithAd(ss.cs, ss.h, ciphertext), plaintext = _a.plaintext, valid = _a.valid);
}
else {
plaintext = ciphertext;
}
this.mixHash(ss, ciphertext);
return { plaintext: plaintext, valid: valid };
};
AbstractHandshake.prototype.dh = function (privateKey, publicKey) {
try {
var derivedU8 = this.crypto.generateX25519SharedKey(privateKey, publicKey);
if (derivedU8.length === 32) {
return derivedU8;
}
return derivedU8.subarray(0, 32);
}
catch (e) {
var err = e;
(0, logger_1.logger)(err.message);
return new Uint8Array(32);
}
};
AbstractHandshake.prototype.mixHash = function (ss, data) {
ss.h = this.getHash(ss.h, data);
};
AbstractHandshake.prototype.getHash = function (a, b) {
var u = this.crypto.hashSHA256((0, concat_1.concat)([a, b], a.length + b.length));
return u;
};
AbstractHandshake.prototype.mixKey = function (ss, ikm) {
var _a = this.crypto.getHKDF(ss.ck, ikm), ck = _a[0], tempK = _a[1];
ss.cs = this.initializeKey(tempK);
ss.ck = ck;
};
AbstractHandshake.prototype.initializeKey = function (k) {
return { k: k, n: new nonce_1.Nonce() };
};
// Symmetric state related
AbstractHandshake.prototype.initializeSymmetric = function (protocolName) {
var protocolNameBytes = (0, uint8arrays_1.fromString)(protocolName, 'utf-8');
var h = this.hashProtocolName(protocolNameBytes);
var ck = h;
var key = this.createEmptyKey();
var cs = this.initializeKey(key);
return { cs: cs, ck: ck, h: h };
};
AbstractHandshake.prototype.hashProtocolName = function (protocolName) {
if (protocolName.length <= 32) {
var h = new Uint8Array(32);
h.set(protocolName);
return h;
}
else {
return this.getHash(protocolName, new Uint8Array(0));
}
};
AbstractHandshake.prototype.split = function (ss) {
var _a = this.crypto.getHKDF(ss.ck, new Uint8Array(0)), tempk1 = _a[0], tempk2 = _a[1];
var cs1 = this.initializeKey(tempk1);
var cs2 = this.initializeKey(tempk2);
return { cs1: cs1, cs2: cs2 };
};
AbstractHandshake.prototype.writeMessageRegular = function (cs, payload) {
var ciphertext = this.encryptWithAd(cs, new Uint8Array(0), payload);
var ne = this.createEmptyKey();
var ns = new Uint8Array(0);
return { ne: ne, ns: ns, ciphertext: ciphertext };
};
AbstractHandshake.prototype.readMessageRegular = function (cs, message) {
return this.decryptWithAd(cs, new Uint8Array(0), message.ciphertext);
};
return AbstractHandshake;
}());
exports.AbstractHandshake = AbstractHandshake;
//# sourceMappingURL=abstract-handshake.js.map