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

260 lines
7.2 KiB
JavaScript
Executable file

/**
* Created by bmf on 11/2/13.
*/
/* jslint node: true */
'use strict';
var assert = require('assert');
var CryptoBaseBuffer = require('../crypto-base-buffer');
module.exports = function KeyPair() {
var self = this;
/** secret key */
self.secretKey = new CryptoBaseBuffer();
self.secretKeySize = 0;
/** public key */
self.publicKey = new CryptoBaseBuffer();
self.publicKeySize = 0;
self.type = undefined;
/** default encoding to use in all string operations */
self.defaultEncoding = undefined;
self.init = function(options) {
options = options || {};
if( !options.type ) {
throw new Error('[KeyPair] type not given in init');
}
self.type = options.type;
if( !options.publicKeySize ) {
throw new Error('[KeyPair] public key size not given');
}
self.publicKeySize = options.publicKeySize;
if( !options.secretKeySize ) {
throw new Error('[KeyPair] secret key size not given');
}
self.secretKeySize = options.secretKeySize;
// init both buffers
self.publicKey.init({
expectedSize: options.publicKeySize,
type: self.type + 'PublicKey'
});
self.secretKey.init({
expectedSize: options.secretKeySize,
type: self.type + 'SecretKey'
});
// We will only accept hex string representations of keys
self.publicKey.setValidEncodings(['hex', 'base64']);
self.secretKey.setValidEncodings(['hex', 'base64']);
// the default encoding to us in all string set/toString methods is Hex
self.publicKey.setEncoding('base64');
self.secretKey.setEncoding('base64');
// Public Key
self.setPublicKey(options.publicKey, options.encoding);
// Secret Key
self.setSecretKey(options.secretKey, options.encoding);
};
/** Box Public Key buffer size in bytes */
self.publicKeyBytes = function() {
return self.publicKeySize;
};
/** Box Public Key buffer size in bytes */
self.secretKeyBytes = function() {
return self.secretKeySize;
};
/* Aliases */
self.pkBytes = self.publicKeyBytes;
self.skBytes = self.secretKeyBytes;
/**
* 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;
self.publicKey.setEncoding(encoding);
self.secretKey.setEncoding(encoding);
};
/**
* Get the current default encoding
* @returns {undefined|String}
*/
self.getEncoding = function() {
return self.defaultEncoding;
};
/**
* Check if key pair is valid
* @param keys {Object} an object with secrteKey, and publicKey members
* @returns {boolean} true is both public and secret keys are valid
*/
self.isValid = function(keys, encoding) {
assert.equal(typeof keys, 'object');
assert.ok(keys.publicKey);
assert.ok(keys.secretKey);
encoding = encoding || self.defaultEncoding;
return self.publicKey.isValid(keys.publicKey, encoding) &&
self.secretKey.isValid(keys.secretKey, encoding);
};
/**
* Wipe keys securely
*/
self.wipe = function() {
self.publicKey.wipe();
self.secretKey.wipe();
};
/**
* Generate a random key pair
*/
self.generate = function() {
throw new Error('KeyPair: this method should be implemented in each sub class');
};
/**
* Getter for the public key
* @returns {undefined| Buffer} public key
*/
self.getPublicKey = function() {
return self.publicKey;
};
/**
* Getter for the secretKey
* @returns {undefined| Buffer} secret key
*/
self.getSecretKey = function() {
return self.secretKey;
};
self.pk = self.getPublicKey;
self.sk = self.getSecretKey;
/**
* Getter for the key pair
* @returns {Object} with both public and private keys
*/
self.get = function() {
return {
'publicKey' : self.publicKey.get(),
'secretKey' : self.secretKey.get()
};
};
/**
* Set the secret key to a known value
* @param v {String|Buffer|Array} the secret key
* @param encoding {String} optional. If v is a string you can specify the encoding
*/
self.set = function(keys, encoding) {
assert.equal(typeof keys, 'object');
if( keys instanceof KeyPair ) {
self.secretKey.set(keys.sk(), encoding);
self.publicKey.set(keys.pk(), encoding);
}
else {
encoding = encoding || self.defaultEncoding;
if( typeof keys === 'object' ) {
if( keys.secretKey ) {
self.secretKey.set(keys.secretKey, encoding);
}
if( keys.publicKey ) {
self.publicKey.set(keys.publicKey, encoding);
}
}
}
};
self.setPublicKey = function(key, encoding) {
if( key instanceof KeyPair ) {
self.publicKey = key.pk();
}
else if( key instanceof CryptoBaseBuffer ) {
if( key.size() == self.publicKeySize ) {
self.publicKey = key;
}
}
else {
self.publicKey.init({
expectedSize: self.publicKeySize,
buffer: key,
encoding: encoding,
type: self.type + 'PublicKey'
});
}
};
self.setSecretKey = function(key, encoding) {
if( key instanceof KeyPair ) {
self.secretKey = key.sk();
}
else if( key instanceof CryptoBaseBuffer ) {
if( key.size() == self.secretKeySize ) {
self.secretKey = key;
}
}
else {
self.secretKey.init({
expectedSize: self.secretKeySize,
buffer: key,
encoding: encoding,
type: self.type + 'SecretKey'
});
}
};
/**
* Convert the secret key to a string object
* @param encoding {String} optional sting encoding. defaults to 'hex'
*/
self.toString = function(encoding) {
encoding = encoding || self.defaultEncoding;
return self.secretKey.toString(encoding) + "," +
self.publicKey.toString(encoding);
};
/**
* Convert the secret key to a JSON object
* @param encoding {String} optional sting encoding. defaults to 'hex'
*/
self.toJson = function(encoding) {
encoding = encoding || self.defaultEncoding;
var out = '{';
if( self.secretKey ) {
out += '"secretKey" :"' + self.secretKey.toString(encoding) + '"';
}
if( self.secretKey && self.publicKey ) {
out += ', ';
}
if( self.publicKey ) {
out += '"publicKey" :"' + self.publicKey.toString(encoding) + '"';
}
out += '}';
return out;
};
};