From 37b79ccde1241d36662e0aff9c249bf55c8226cb Mon Sep 17 00:00:00 2001 From: Lee Miller Date: Sun, 25 Dec 2022 00:20:37 +0200 Subject: [PATCH] Add additional functions: encodePublic(publicKey), decodePublic(publicKey) used in encrypt() and decrypt() respectively - to comply with the network. Minor formatting change. --- index.js | 66 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/index.js b/index.js index a63218b..6095df4 100644 --- a/index.js +++ b/index.js @@ -5,12 +5,15 @@ "use strict"; -const EC_GROUP_ORDER = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 'hex'); +const EC_GROUP_ORDER = Buffer.from( + 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 'hex'); const ZERO32 = Buffer.alloc(32, 0); +const curve_secp256k1 = 714, + key_length = 32; + var promise = typeof Promise === "undefined" ? - require("es6-promise").Promise : - Promise; + require("es6-promise").Promise : Promise; var crypto = require("crypto"); // try to use secp256k1, fallback to browser implementation try { @@ -25,7 +28,7 @@ try { } } -function isScalar (x) { +function isScalar(x) { return Buffer.isBuffer(x) && x.length === 32; } @@ -117,6 +120,29 @@ var getPublic = exports.getPublic = function(privateKey) { return secp256k1.publicKeyConvert(compressed, false); }; +// to comply with the bitmessage network +function encodePublic(publicKey) { + assert(publicKey.length === 65, "Bad public key"); + var buf = Buffer.alloc(70); + buf.writeUInt16BE(curve_secp256k1, 0, true); + buf.writeUInt16BE(key_length, 2, true); + publicKey.copy(buf, 4, 1, 33); + buf.writeUInt16BE(key_length, 36, true); + publicKey.copy(buf, 38, 33, 65); + return buf; +} + +function decodePublic(publicKey) { + assert(publicKey.readUInt16BE(0, true) === curve_secp256k1, "Wrong curve!"); + assert(publicKey.readUInt16BE(2, true) === key_length, "Bad key length!"); + assert(publicKey.readUInt16BE(36, true) === key_length, "Bad key length!"); + var buf = Buffer.alloc(65); + buf[0] = 0x04; + publicKey.copy(buf, 1, 4, 36); + publicKey.copy(buf, 33, 38, 70); + return buf; +} + /** * Get compressed version of public key. */ @@ -213,7 +239,7 @@ exports.encrypt = function(publicKeyTo, msg, opts) { { ephemPrivateKey = opts.ephemPrivateKey || crypto.randomBytes(32); } - ephemPublicKey = getPublic(ephemPrivateKey); + ephemPublicKey = encodePublic(getPublic(ephemPrivateKey)); resolve(derive(ephemPrivateKey, publicKeyTo)); }).then(function(Px) { var hash = sha512(Px); @@ -241,18 +267,20 @@ exports.encrypt = function(publicKeyTo, msg, opts) { * plaintext on successful decryption and rejects on failure. */ exports.decrypt = function(privateKey, opts) { - return derive(privateKey, opts.ephemPublicKey).then(function(Px) { - assert(privateKey.length === 32, "Bad private key"); - assert(isValidPrivateKey(privateKey), "Bad private key"); - var hash = sha512(Px); - var encryptionKey = hash.slice(0, 32); - var macKey = hash.slice(32); - var dataToMac = Buffer.concat([ - opts.iv, - opts.ephemPublicKey, - opts.ciphertext - ]); - var realMac = hmacSha256(macKey, dataToMac); - assert(equalConstTime(opts.mac, realMac), "Bad MAC"); return aes256CbcDecrypt(opts.iv, encryptionKey, opts.ciphertext); - }); + return derive( + privateKey, decodePublic(opts.ephemPublicKey)).then(function(Px) { + assert(privateKey.length === 32, "Bad private key"); + assert(isValidPrivateKey(privateKey), "Bad private key"); + var hash = sha512(Px); + var encryptionKey = hash.slice(0, 32); + var macKey = hash.slice(32); + var dataToMac = Buffer.concat([ + opts.iv, + opts.ephemPublicKey, + opts.ciphertext + ]); + var realMac = hmacSha256(macKey, dataToMac); + assert(equalConstTime(opts.mac, realMac), "Bad MAC"); + return aes256CbcDecrypt(opts.iv, encryptionKey, opts.ciphertext); + }); };