diff options
author | Minteck <contact@minteck.org> | 2023-01-10 14:54:04 +0100 |
---|---|---|
committer | Minteck <contact@minteck.org> | 2023-01-10 14:54:04 +0100 |
commit | 99c1d9af689e5325f3cf535c4007b3aeb8325229 (patch) | |
tree | e663b3c2ebdbd67c818ac0c5147f0ce1d2463cda /school/node_modules/node-forge/js/kem.js | |
parent | 9871b03912fc28ad38b4037ebf26a78aa937baba (diff) | |
download | pluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.tar.gz pluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.tar.bz2 pluralconnect-99c1d9af689e5325f3cf535c4007b3aeb8325229.zip |
Update - This is an automated commit
Diffstat (limited to 'school/node_modules/node-forge/js/kem.js')
-rw-r--r-- | school/node_modules/node-forge/js/kem.js | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/school/node_modules/node-forge/js/kem.js b/school/node_modules/node-forge/js/kem.js new file mode 100644 index 0000000..7ac7851 --- /dev/null +++ b/school/node_modules/node-forge/js/kem.js @@ -0,0 +1,221 @@ +/** + * Javascript implementation of RSA-KEM. + * + * @author Lautaro Cozzani Rodriguez + * @author Dave Longley + * + * Copyright (c) 2014 Lautaro Cozzani <lautaro.cozzani@scytl.com> + * Copyright (c) 2014 Digital Bazaar, Inc. + */ +(function() { +/* ########## Begin module implementation ########## */ +function initModule(forge) { + +forge.kem = forge.kem || {}; + +var BigInteger = forge.jsbn.BigInteger; + +/** + * The API for the RSA Key Encapsulation Mechanism (RSA-KEM) from ISO 18033-2. + */ +forge.kem.rsa = {}; + +/** + * Creates an RSA KEM API object for generating a secret asymmetric key. + * + * The symmetric key may be generated via a call to 'encrypt', which will + * produce a ciphertext to be transmitted to the recipient and a key to be + * kept secret. The ciphertext is a parameter to be passed to 'decrypt' which + * will produce the same secret key for the recipient to use to decrypt a + * message that was encrypted with the secret key. + * + * @param kdf the KDF API to use (eg: new forge.kem.kdf1()). + * @param options the options to use. + * [prng] a custom crypto-secure pseudo-random number generator to use, + * that must define "getBytesSync". + */ +forge.kem.rsa.create = function(kdf, options) { + options = options || {}; + var prng = options.prng || forge.random; + + var kem = {}; + + /** + * Generates a secret key and its encapsulation. + * + * @param publicKey the RSA public key to encrypt with. + * @param keyLength the length, in bytes, of the secret key to generate. + * + * @return an object with: + * encapsulation: the ciphertext for generating the secret key, as a + * binary-encoded string of bytes. + * key: the secret key to use for encrypting a message. + */ + kem.encrypt = function(publicKey, keyLength) { + // generate a random r where 1 > r > n + var byteLength = Math.ceil(publicKey.n.bitLength() / 8); + var r; + do { + r = new BigInteger( + forge.util.bytesToHex(prng.getBytesSync(byteLength)), + 16).mod(publicKey.n); + } while(r.equals(BigInteger.ZERO)); + + // prepend r with zeros + r = forge.util.hexToBytes(r.toString(16)); + var zeros = byteLength - r.length; + if(zeros > 0) { + r = forge.util.fillString(String.fromCharCode(0), zeros) + r; + } + + // encrypt the random + var encapsulation = publicKey.encrypt(r, 'NONE'); + + // generate the secret key + var key = kdf.generate(r, keyLength); + + return {encapsulation: encapsulation, key: key}; + }; + + /** + * Decrypts an encapsulated secret key. + * + * @param privateKey the RSA private key to decrypt with. + * @param encapsulation the ciphertext for generating the secret key, as + * a binary-encoded string of bytes. + * @param keyLength the length, in bytes, of the secret key to generate. + * + * @return the secret key as a binary-encoded string of bytes. + */ + kem.decrypt = function(privateKey, encapsulation, keyLength) { + // decrypt the encapsulation and generate the secret key + var r = privateKey.decrypt(encapsulation, 'NONE'); + return kdf.generate(r, keyLength); + }; + + return kem; +}; + +// TODO: add forge.kem.kdf.create('KDF1', {md: ..., ...}) API? + +/** + * Creates a key derivation API object that implements KDF1 per ISO 18033-2. + * + * @param md the hash API to use. + * @param [digestLength] an optional digest length that must be positive and + * less than or equal to md.digestLength. + * + * @return a KDF1 API object. + */ +forge.kem.kdf1 = function(md, digestLength) { + _createKDF(this, md, 0, digestLength || md.digestLength); +}; + +/** + * Creates a key derivation API object that implements KDF2 per ISO 18033-2. + * + * @param md the hash API to use. + * @param [digestLength] an optional digest length that must be positive and + * less than or equal to md.digestLength. + * + * @return a KDF2 API object. + */ +forge.kem.kdf2 = function(md, digestLength) { + _createKDF(this, md, 1, digestLength || md.digestLength); +}; + +/** + * Creates a KDF1 or KDF2 API object. + * + * @param md the hash API to use. + * @param counterStart the starting index for the counter. + * @param digestLength the digest length to use. + * + * @return the KDF API object. + */ +function _createKDF(kdf, md, counterStart, digestLength) { + /** + * Generate a key of the specified length. + * + * @param x the binary-encoded byte string to generate a key from. + * @param length the number of bytes to generate (the size of the key). + * + * @return the key as a binary-encoded string. + */ + kdf.generate = function(x, length) { + var key = new forge.util.ByteBuffer(); + + // run counter from counterStart to ceil(length / Hash.len) + var k = Math.ceil(length / digestLength) + counterStart; + + var c = new forge.util.ByteBuffer(); + for(var i = counterStart; i < k; ++i) { + // I2OSP(i, 4): convert counter to an octet string of 4 octets + c.putInt32(i); + + // digest 'x' and the counter and add the result to the key + md.start(); + md.update(x + c.getBytes()); + var hash = md.digest(); + key.putBytes(hash.getBytes(digestLength)); + } + + // truncate to the correct key length + key.truncate(key.length() - length); + return key.getBytes(); + }; +} + +} // end module implementation + +/* ########## Begin module wrapper ########## */ +var name = 'kem'; +if(typeof define !== 'function') { + // NodeJS -> AMD + if(typeof module === 'object' && module.exports) { + var nodeJS = true; + define = function(ids, factory) { + factory(require, module); + }; + } else { + // <script> + if(typeof forge === 'undefined') { + forge = {}; + } + return initModule(forge); + } +} +// AMD +var deps; +var defineFunc = function(require, module) { + module.exports = function(forge) { + var mods = deps.map(function(dep) { + return require(dep); + }).concat(initModule); + // handle circular dependencies + forge = forge || {}; + forge.defined = forge.defined || {}; + if(forge.defined[name]) { + return forge[name]; + } + forge.defined[name] = true; + for(var i = 0; i < mods.length; ++i) { + mods[i](forge); + } + return forge[name]; + }; +}; +var tmpDefine = define; +define = function(ids, factory) { + deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2); + if(nodeJS) { + delete define; + return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0)); + } + define = tmpDefine; + return define.apply(null, Array.prototype.slice.call(arguments, 0)); +}; +define(['require', 'module', './util','./random','./jsbn'], function() { + defineFunc.apply(null, Array.prototype.slice.call(arguments, 0)); +}); +})(); |