121 lines
2.4 KiB
JavaScript
121 lines
2.4 KiB
JavaScript
'use strict';
|
|
|
|
var utils = exports;
|
|
var BN = require('bn.js');
|
|
var minAssert = require('minimalistic-assert');
|
|
var minUtils = require('minimalistic-crypto-utils');
|
|
|
|
utils.assert = minAssert;
|
|
utils.toArray = minUtils.toArray;
|
|
utils.zero2 = minUtils.zero2;
|
|
utils.toHex = minUtils.toHex;
|
|
utils.encode = minUtils.encode;
|
|
|
|
// Represent num in a w-NAF form
|
|
function getNAF(num, w) {
|
|
var naf = [];
|
|
var ws = 1 << (w + 1);
|
|
var k = num.clone();
|
|
while (k.cmpn(1) >= 0) {
|
|
var z;
|
|
if (k.isOdd()) {
|
|
var mod = k.andln(ws - 1);
|
|
if (mod > (ws >> 1) - 1)
|
|
z = (ws >> 1) - mod;
|
|
else
|
|
z = mod;
|
|
k.isubn(z);
|
|
} else {
|
|
z = 0;
|
|
}
|
|
naf.push(z);
|
|
|
|
// Optimization, shift by word if possible
|
|
var shift = (k.cmpn(0) !== 0 && k.andln(ws - 1) === 0) ? (w + 1) : 1;
|
|
for (var i = 1; i < shift; i++)
|
|
naf.push(0);
|
|
k.iushrn(shift);
|
|
}
|
|
|
|
return naf;
|
|
}
|
|
utils.getNAF = getNAF;
|
|
|
|
// Represent k1, k2 in a Joint Sparse Form
|
|
function getJSF(k1, k2) {
|
|
var jsf = [
|
|
[],
|
|
[]
|
|
];
|
|
|
|
k1 = k1.clone();
|
|
k2 = k2.clone();
|
|
var d1 = 0;
|
|
var d2 = 0;
|
|
while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) {
|
|
|
|
// First phase
|
|
var m14 = (k1.andln(3) + d1) & 3;
|
|
var m24 = (k2.andln(3) + d2) & 3;
|
|
if (m14 === 3)
|
|
m14 = -1;
|
|
if (m24 === 3)
|
|
m24 = -1;
|
|
var u1;
|
|
if ((m14 & 1) === 0) {
|
|
u1 = 0;
|
|
} else {
|
|
var m8 = (k1.andln(7) + d1) & 7;
|
|
if ((m8 === 3 || m8 === 5) && m24 === 2)
|
|
u1 = -m14;
|
|
else
|
|
u1 = m14;
|
|
}
|
|
jsf[0].push(u1);
|
|
|
|
var u2;
|
|
if ((m24 & 1) === 0) {
|
|
u2 = 0;
|
|
} else {
|
|
var m8 = (k2.andln(7) + d2) & 7;
|
|
if ((m8 === 3 || m8 === 5) && m14 === 2)
|
|
u2 = -m24;
|
|
else
|
|
u2 = m24;
|
|
}
|
|
jsf[1].push(u2);
|
|
|
|
// Second phase
|
|
if (2 * d1 === u1 + 1)
|
|
d1 = 1 - d1;
|
|
if (2 * d2 === u2 + 1)
|
|
d2 = 1 - d2;
|
|
k1.iushrn(1);
|
|
k2.iushrn(1);
|
|
}
|
|
|
|
return jsf;
|
|
}
|
|
utils.getJSF = getJSF;
|
|
|
|
function cachedProperty(obj, name, computer) {
|
|
var key = '_' + name;
|
|
obj.prototype[name] = function cachedProperty() {
|
|
return this[key] !== undefined ? this[key] :
|
|
this[key] = computer.call(this);
|
|
};
|
|
}
|
|
utils.cachedProperty = cachedProperty;
|
|
|
|
function parseBytes(bytes) {
|
|
return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') :
|
|
bytes;
|
|
}
|
|
utils.parseBytes = parseBytes;
|
|
|
|
function intFromLE(bytes) {
|
|
return new BN(bytes, 'hex', 'le');
|
|
}
|
|
utils.intFromLE = intFromLE;
|
|
|