classicfm-discord-bot/node_modules/sodium/lib/box.js
2024-05-09 14:45:10 -04:00

174 lines
5.6 KiB
JavaScript
Executable file

/**
* Created by bmf on 11/2/13.
*
* Documentation of crypto http://nacl.cr.yp.to/box.html
*/
/* jslint node: true */
'use strict';
var binding = require('../build/Release/sodium');
var toBuffer = require('./toBuffer');
var BoxKey = require('./keys/box-key');
var Nonce = require('./nonces/box-nonce');
var assert = require('assert');
/**
* Public-key authenticated encryption: Box
*
* @param {String|Buffer|Array} secretKey sender's private key.
* @param {String|Buffer|Array} publicKey recipient's public key.
* @param {Boolean} easy Use regular or easy mode. Defaults to regular
*
* @see Keys
* @constructor
*/
module.exports = function Box(publicKey, secretKey, easy) {
var self = this;
/** default encoding to use in all string operations */
self.defaultEncoding = undefined;
/** Set of keys used to encrypt and decrypt messages */
self.boxKey = new BoxKey(publicKey, secretKey);
/** Set mode to regular or easy */
self.easy = easy || false;
/**
* Messages passed to low level API should be padded with zeroBytes at the beginning.
* This implementation automatically pads the message, so no need to do it on your own
*/
self.zeroBytes = function() {
return binding.crypto_box_ZEROBYTES;
};
/**
* Encrypted messages are padded with zeroBoxSize bytes of zeros. If the padding is not
* there the message will not decrypt successfully.
*/
self.boxZeroBytes = function() {
return binding.crypto_box_BOXZEROBYTES;
};
/**
* Padding used in beforenm method. Like zeroBytes this implementation automatically
* pads the message.
*
* @see Const.Box.zeroBytes
*/
self.beforenmBytes = function() {
return binding.crypto_box_BEFORENMBYTES;
};
/** String name of the default crypto primitive used in box operations */
self.primitive = function() {
return binding.crypto_box_PRIMITIVE;
};
/**
* Get the box-key secret keypair object
* @returns {BoxKey|*}
*/
self.key = function() {
return self.boxKey;
};
/**
* Set the default encoding to use in all string conversions
* @param {String} encoding encoding to use
*/
self.setEncoding = function(encoding) {
assert(!!encoding.match(/^(?:utf8|ascii|binary|hex|utf16le|ucs2|base64)$/), 'Encoding ' + encoding + ' is currently unsupported.');
self.defaultEncoding = encoding;
};
/**
* Get the current default encoding
* @returns {undefined|String}
*/
self.getEncoding = function() {
return self.defaultEncoding;
};
/**
* Encrypt a message
* The encrypt function encrypts and authenticates a message using the
* sender's secret key, the receiver's public key, and a nonce n.
*
* If no options are given a new random nonce will be generated automatically
* and both planText and cipherText must be buffers
*
* options.encoding is optional and specifies the encoding of the plainText
* nonce, and cipherText if they are passed as strings. If plainText and
* nonce are buffers, options.encoding will only affect the resulting
* cipherText.
* The basic API leaves it up to the
* caller to generate a unique nonce for every message, in the high level
* API a random nonce is generated automatically and you do no need to
* worry about it.
*
* @param {Buffer|String|Array} plainText message to encrypt
* @param {String} [encoding] encoding of message string
*
* @returns {Object} cipher box
*/
self.encrypt = function (plainText, encoding) {
encoding = encoding || self.defaultEncoding;
// generate a new random nonce
var nonce = new Nonce();
var buf = toBuffer(plainText, encoding);
var cipherText = (self.easy ? binding.crypto_box_easy : binding.crypto_box)(
buf,
nonce.get(),
self.boxKey.getPublicKey().get(),
self.boxKey.getSecretKey().get());
if( !cipherText ) {
return undefined;
}
return {
cipherText: cipherText,
nonce : nonce.get()
};
};
/**
* The decrypt function verifies and decrypts a cipherText using the
* receiver's secret key, the sender's public key, and a nonce.
* The function returns the resulting plaintext m.
*
* @param {Buffer|String|Array} cipherText the encrypted message
* @param {Buffer|String|Array} nonce the nonce used to encrypt
* @param {String} [encoding] the encoding to used in cipherText, nonce, plainText
*/
self.decrypt = function (cipherBox, encoding) {
encoding = String(encoding || self.defaultEncoding);
assert(typeof cipherBox == 'object' && cipherBox.hasOwnProperty('cipherText') && cipherBox.hasOwnProperty('nonce'), 'cipherBox is an object with properties `cipherText` and `nonce`.');
assert(cipherBox.cipherText instanceof Buffer, 'cipherBox should have a cipherText property that is a buffer') ;
var nonce = new Nonce(cipherBox.nonce);
var plainText = (self.easy ? binding.crypto_box_open_easy : binding.crypto_box_open)(
cipherBox.cipherText,
nonce.get(),
self.boxKey.getPublicKey().get(),
self.boxKey.getSecretKey().get()
);
if( encoding ) {
return plainText.toString(encoding);
}
return plainText;
};
// Aliases
self.close = self.encrypt;
self.open = self.decrypt;
};