Fix lint errors in sjcl-ecdsa-recoverablepublickey.js

This commit is contained in:
Chris Clark
2015-05-26 14:14:26 -07:00
parent 50cda426eb
commit e68096bd27

View File

@@ -2,7 +2,7 @@
/* eslint new-cap: [2, {newIsCapExceptions: [
"bn", "invalid", "point", "corrupt", "bug", "publicKey"]}] */
'use strict';
var sjcl = require('sjcl');
const sjcl = require('sjcl');
/**
* This module uses the public key recovery method
@@ -16,7 +16,7 @@ var sjcl = require('sjcl');
*/
// Defined here so that this value only needs to be calculated once
var FIELD_MODULUS_PLUS_ONE_DIVIDED_BY_FOUR;
let FIELD_MODULUS_PLUS_ONE_DIVIDED_BY_FOUR;
/**
* Retrieve the r and s components of a signature
@@ -27,7 +27,7 @@ var FIELD_MODULUS_PLUS_ONE_DIVIDED_BY_FOUR;
*/
function getRandSFromSignature(curve, signature) {
var r_length = curve.r.bitLength();
const r_length = curve.r.bitLength();
return {
r: sjcl.bn.fromBits(sjcl.bitArray.bitSlice(signature, 0, r_length)),
@@ -50,7 +50,7 @@ function getRandSFromSignature(curve, signature) {
*/
function verify_raw(curve, e, r, s, public_key_point) {
var field_order = curve.r;
const field_order = curve.r;
// Return false if r is out of bounds
if ((new sjcl.bn(1)).greaterEquals(r)
@@ -67,11 +67,11 @@ function verify_raw(curve, e, r, s, public_key_point) {
// Check that r = (u1 + u2)G
// u1 = e x s^-1 (mod field_order)
// u2 = r x s^-1 (mod field_order)
var s_mod_inverse_field_order = s.inverseMod(field_order);
var u1 = e.mul(s_mod_inverse_field_order).mod(field_order);
var u2 = r.mul(s_mod_inverse_field_order).mod(field_order);
const s_mod_inverse_field_order = s.inverseMod(field_order);
const u1 = e.mul(s_mod_inverse_field_order).mod(field_order);
const u2 = r.mul(s_mod_inverse_field_order).mod(field_order);
var point_computed = curve.G.mult2(u1, u2, public_key_point);
const point_computed = curve.G.mult2(u1, u2, public_key_point);
return r.equals(point_computed.x.mod(field_order));
@@ -90,19 +90,16 @@ function verify_raw(curve, e, r, s, public_key_point) {
function recoverPublicKeyPointFromSignature(curve, signature_r, signature_s,
hash_bits, recovery_factor) {
var field_order = curve.r;
var field_modulus = curve.field.modulus;
// Reduce the recovery_factor to the two bits used
recovery_factor = recovery_factor & 3;
const field_order = curve.r;
const field_modulus = curve.field.modulus;
// The less significant bit specifies whether the y coordinate
// of the compressed point is even or not.
var compressed_point_y_coord_is_even = recovery_factor & 1;
const compressed_point_y_coord_is_even = recovery_factor & 1;
// The more significant bit specifies whether we should use the
// first or second candidate key.
var use_second_candidate_key = recovery_factor >> 1;
const use_second_candidate_key = (recovery_factor & 2) >> 1;
// Calculate (field_order + 1) / 4
if (!FIELD_MODULUS_PLUS_ONE_DIVIDED_BY_FOUR) {
@@ -113,7 +110,7 @@ function recoverPublicKeyPointFromSignature(curve, signature_r, signature_s,
// That is not necessary here because we are given the recovery_factor
// step 1.1 Let x = r + jn
// Here "j" is either 0 or 1
var x;
let x;
if (use_second_candidate_key) {
x = signature_r.add(field_order);
} else {
@@ -123,16 +120,16 @@ function recoverPublicKeyPointFromSignature(curve, signature_r, signature_s,
// step 1.2 and 1.3 convert x to an elliptic curve point
// Following formula in section 2.3.4 Octet-String-to-Elliptic-Curve-Point
// Conversion
var alpha = x.mul(x).mul(x).add(curve.a.mul(x)).add(curve.b).mod(
const alpha = x.mul(x).mul(x).add(curve.a.mul(x)).add(curve.b).mod(
field_modulus);
var beta = alpha.powermod(FIELD_MODULUS_PLUS_ONE_DIVIDED_BY_FOUR,
const beta = alpha.powermod(FIELD_MODULUS_PLUS_ONE_DIVIDED_BY_FOUR,
field_modulus);
// If beta is even but y isn't or
// if beta is odd and y is even
// then subtract beta from the field_modulus
var y;
var beta_is_even = beta.mod(2).equals(0);
let y;
const beta_is_even = beta.mod(2).equals(0);
if (beta_is_even && !compressed_point_y_coord_is_even ||
!beta_is_even && compressed_point_y_coord_is_even) {
y = beta;
@@ -141,7 +138,7 @@ function recoverPublicKeyPointFromSignature(curve, signature_r, signature_s,
}
// generated_point_R is the point generated from x and y
var generated_point_R = new sjcl.ecc.point(curve, x, y);
const generated_point_R = new sjcl.ecc.point(curve, x, y);
// step 1.4 check that R is valid and R x field_order !== infinity
// TODO: add check for R x field_order === infinity
@@ -151,13 +148,13 @@ function recoverPublicKeyPointFromSignature(curve, signature_r, signature_s,
}
// step 1.5 Compute e from M
var message_e = sjcl.bn.fromBits(hash_bits);
var message_e_neg = new sjcl.bn(0).sub(message_e).mod(field_order);
const message_e = sjcl.bn.fromBits(hash_bits);
const message_e_neg = new sjcl.bn(0).sub(message_e).mod(field_order);
// step 1.6 Compute Q = r^-1 (sR - eG)
// console.log('r: ', signature_r);
var signature_r_inv = signature_r.inverseMod(field_order);
var public_key_point = generated_point_R.mult2(signature_s, message_e_neg,
const signature_r_inv = signature_r.inverseMod(field_order);
const public_key_point = generated_point_R.mult2(signature_s, message_e_neg,
curve.G).mult(signature_r_inv);
// Validate public key point
@@ -190,14 +187,14 @@ function recoverPublicKeyPointFromSignature(curve, signature_r, signature_s,
function calculateRecoveryFactor(curve, r, s, hash_bits,
original_public_key_point) {
var original_public_key_point_bits = original_public_key_point.toBits();
const original_public_key_point_bits = original_public_key_point.toBits();
// TODO: verify that it is possible for the recovery_factor to be 2 or 3,
// we may only need 1 bit because the canonical signature might remove the
// possibility of us needing to "use the second candidate key"
for (var possible_factor = 0; possible_factor < 4; possible_factor++) {
for (let possible_factor = 0; possible_factor < 4; possible_factor++) {
var resulting_public_key_point;
let resulting_public_key_point;
try {
resulting_public_key_point = recoverPublicKeyPointFromSignature(
curve, r, s, hash_bits, possible_factor);
@@ -229,10 +226,10 @@ function calculateRecoveryFactor(curve, r, s, hash_bits,
sjcl.ecc.ecdsa.secretKey.prototype.signWithRecoverablePublicKey = function(
hash, paranoia, k_for_testing) {
var self = this;
const self = this;
// Convert hash to bits and determine encoding for output
var hash_bits;
let hash_bits;
if (typeof hash === 'object' && hash.length > 0
&& typeof hash[0] === 'number') {
hash_bits = hash;
@@ -241,25 +238,25 @@ sjcl.ecc.ecdsa.secretKey.prototype.signWithRecoverablePublicKey = function(
}
// Sign hash with standard, canonicalized method
var standard_signature = self.sign(hash_bits, paranoia, k_for_testing);
var canonical_signature = self.canonicalizeSignature(standard_signature);
const standard_signature = self.sign(hash_bits, paranoia, k_for_testing);
const canonical_signature = self.canonicalizeSignature(standard_signature);
// Extract r and s signature components from canonical signature
var r_and_s = getRandSFromSignature(self._curve, canonical_signature);
const r_and_s = getRandSFromSignature(self._curve, canonical_signature);
// Rederive public key
var public_key = self._curve.G.mult(sjcl.bn.fromBits(self.get()));
const public_key = self._curve.G.mult(sjcl.bn.fromBits(self.get()));
// Determine recovery factor based on which possible value
// returns the correct public key
var recovery_factor = calculateRecoveryFactor(self._curve, r_and_s.r,
const recovery_factor = calculateRecoveryFactor(self._curve, r_and_s.r,
r_and_s.s, hash_bits, public_key);
// Prepend recovery_factor to signature and encode in DER
// The value_to_prepend should be 4 bytes total
var value_to_prepend = recovery_factor + 27;
const value_to_prepend = recovery_factor + 27;
var final_signature_bits = sjcl.bitArray.concat([value_to_prepend],
const final_signature_bits = sjcl.bitArray.concat([value_to_prepend],
canonical_signature);
// Return value in bits
@@ -280,19 +277,15 @@ sjcl.ecc.ecdsa.secretKey.prototype.signWithRecoverablePublicKey = function(
* @returns {sjcl.ecc.ecdsa.publicKey} Public key
*/
sjcl.ecc.ecdsa.publicKey.recoverFromSignature = function(
hash, signature, curve) {
hash, signature, curve=sjcl.ecc.curves.k256) {
if (!signature || signature instanceof sjcl.ecc.curve) {
throw new sjcl.exception.invalid(
'must supply hash and signature to recover public key');
}
if (!curve) {
curve = sjcl.ecc.curves.k256;
}
// Convert hash to bits and determine encoding for output
var hash_bits;
let hash_bits;
if (typeof hash === 'object' && hash.length > 0
&& typeof hash[0] === 'number') {
hash_bits = hash;
@@ -300,7 +293,7 @@ sjcl.ecc.ecdsa.publicKey.recoverFromSignature = function(
throw new sjcl.exception.invalid('hash. Must be a bitArray');
}
var signature_bits;
let signature_bits;
if (typeof signature === 'object' && signature.length > 0
&& typeof signature[0] === 'number') {
signature_bits = signature;
@@ -309,7 +302,7 @@ sjcl.ecc.ecdsa.publicKey.recoverFromSignature = function(
}
// Extract recovery_factor from first 4 bytes
var recovery_factor = signature_bits[0] - 27;
const recovery_factor = signature_bits[0] - 27;
if (recovery_factor < 0 || recovery_factor > 3) {
throw new sjcl.exception.invalid(
@@ -318,14 +311,14 @@ sjcl.ecc.ecdsa.publicKey.recoverFromSignature = function(
}
// Separate r and s values
var r_and_s = getRandSFromSignature(curve, signature_bits.slice(1));
var signature_r = r_and_s.r;
var signature_s = r_and_s.s;
const r_and_s = getRandSFromSignature(curve, signature_bits.slice(1));
const signature_r = r_and_s.r;
const signature_s = r_and_s.s;
// Recover public key using recovery_factor
var recovered_public_key_point = recoverPublicKeyPointFromSignature(
const recovered_public_key_point = recoverPublicKeyPointFromSignature(
curve, signature_r, signature_s, hash_bits, recovery_factor);
var recovered_public_key = new sjcl.ecc.ecdsa.publicKey(
const recovered_public_key = new sjcl.ecc.ecdsa.publicKey(
curve, recovered_public_key_point);
return recovered_public_key;