| "use strict"; |
| /** |
| * @fileOverview |
| * Core operations on curve 25519 required for the higher level modules. |
| */ |
| |
| /* |
| * Copyright (c) 2007, 2013, 2014 Michele Bini |
| * Copyright (c) 2014 Mega Limited |
| * under the MIT License. |
| * |
| * Authors: Guy K. Kloss, Michele Bini |
| * |
| * You should have received a copy of the license along with this program. |
| */ |
| |
| var core = require('./core'); |
| var utils = require('./utils'); |
| |
| /** |
| * @exports jodid25519/curve255 |
| * Legacy compatibility module for Michele Bini's previous curve255.js. |
| * |
| * @description |
| * Legacy compatibility module for Michele Bini's previous curve255.js. |
| * |
| * <p> |
| * This code presents an API with all key formats as previously available |
| * from Michele Bini's curve255.js implementation. |
| * </p> |
| */ |
| var ns = {}; |
| |
| function curve25519_raw(f, c) { |
| var a, x_1, q; |
| |
| x_1 = c; |
| a = core.dbl(x_1, core.ONE()); |
| q = [x_1, core.ONE()]; |
| |
| var n = 255; |
| |
| while (core.getbit(f, n) == 0) { |
| n--; |
| // For correct constant-time operation, bit 255 should always be |
| // set to 1 so the following 'while' loop is never entered. |
| if (n < 0) { |
| return core.ZERO(); |
| } |
| } |
| n--; |
| |
| var aq = [a, q]; |
| |
| while (n >= 0) { |
| var r, s; |
| var b = core.getbit(f, n); |
| r = core.sum(aq[0][0], aq[0][1], aq[1][0], aq[1][1], x_1); |
| s = core.dbl(aq[1 - b][0], aq[1 - b][1]); |
| aq[1 - b] = s; |
| aq[b] = r; |
| n--; |
| } |
| q = aq[1]; |
| |
| q[1] = core.invmodp(q[1]); |
| q[0] = core.mulmodp(q[0], q[1]); |
| core.reduce(q[0]); |
| return q[0]; |
| } |
| |
| function curve25519b32(a, b) { |
| return _base32encode(curve25519(_base32decode(a), |
| _base32decode(b))); |
| } |
| |
| function curve25519(f, c) { |
| if (!c) { |
| c = core.BASE(); |
| } |
| f[0] &= 0xFFF8; |
| f[15] = (f[15] & 0x7FFF) | 0x4000; |
| return curve25519_raw(f, c); |
| } |
| |
| function _hexEncodeVector(k) { |
| var hexKey = utils.hexEncode(k); |
| // Pad with '0' at the front. |
| hexKey = new Array(64 + 1 - hexKey.length).join('0') + hexKey; |
| // Invert bytes. |
| return hexKey.split(/(..)/).reverse().join(''); |
| } |
| |
| function _hexDecodeVector(v) { |
| // assert(length(x) == 64); |
| // Invert bytes. |
| var hexKey = v.split(/(..)/).reverse().join(''); |
| return utils.hexDecode(hexKey); |
| } |
| |
| |
| // Expose some functions to the outside through this name space. |
| |
| /** |
| * Computes the scalar product of a point on the curve 25519. |
| * |
| * This function is used for the DH key-exchange protocol. |
| * |
| * Before multiplication, some bit operations are applied to the |
| * private key to ensure it is a valid Curve25519 secret key. |
| * It is the user's responsibility to make sure that the private |
| * key is a uniformly random, secret value. |
| * |
| * @function |
| * @param f {array} |
| * Private key. |
| * @param c {array} |
| * Public point on the curve. If not given, the curve's base point is used. |
| * @returns {array} |
| * Key point resulting from scalar product. |
| */ |
| ns.curve25519 = curve25519; |
| |
| /** |
| * Computes the scalar product of a point on the curve 25519. |
| * |
| * This variant does not make sure that the private key is valid. |
| * The user has the responsibility to ensure the private key is |
| * valid or that this results in a safe protocol. Unless you know |
| * exactly what you are doing, you should not use this variant, |
| * please use 'curve25519' instead. |
| * |
| * @function |
| * @param f {array} |
| * Private key. |
| * @param c {array} |
| * Public point on the curve. If not given, the curve's base point is used. |
| * @returns {array} |
| * Key point resulting from scalar product. |
| */ |
| ns.curve25519_raw = curve25519_raw; |
| |
| /** |
| * Encodes the internal representation of a key to a canonical hex |
| * representation. |
| * |
| * This is the format commonly used in other libraries and for |
| * test vectors, and is equivalent to the hex dump of the key in |
| * little-endian binary format. |
| * |
| * @function |
| * @param n {array} |
| * Array representation of key. |
| * @returns {string} |
| * Hexadecimal string representation of key. |
| */ |
| ns.hexEncodeVector = _hexEncodeVector; |
| |
| /** |
| * Decodes a canonical hex representation of a key |
| * to an internally compatible array representation. |
| * |
| * @function |
| * @param n {string} |
| * Hexadecimal string representation of key. |
| * @returns {array} |
| * Array representation of key. |
| */ |
| ns.hexDecodeVector = _hexDecodeVector; |
| |
| /** |
| * Encodes the internal representation of a key into a |
| * hexadecimal representation. |
| * |
| * This is a strict positional notation, most significant digit first. |
| * |
| * @function |
| * @param n {array} |
| * Array representation of key. |
| * @returns {string} |
| * Hexadecimal string representation of key. |
| */ |
| ns.hexencode = utils.hexEncode; |
| |
| /** |
| * Decodes a hex representation of a key to an internally |
| * compatible array representation. |
| * |
| * @function |
| * @param n {string} |
| * Hexadecimal string representation of key. |
| * @returns {array} |
| * Array representation of key. |
| */ |
| ns.hexdecode = utils.hexDecode; |
| |
| /** |
| * Encodes the internal representation of a key to a base32 |
| * representation. |
| * |
| * @function |
| * @param n {array} |
| * Array representation of key. |
| * @returns {string} |
| * Base32 string representation of key. |
| */ |
| ns.base32encode = utils.base32encode; |
| |
| /** |
| * Decodes a base32 representation of a key to an internally |
| * compatible array representation. |
| * |
| * @function |
| * @param n {string} |
| * Base32 string representation of key. |
| * @returns {array} |
| * Array representation of key. |
| */ |
| ns.base32decode = utils.base32decode; |
| |
| module.exports = ns; |