222 lines
6.1 KiB
JavaScript
222 lines
6.1 KiB
JavaScript
"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;
|