cleanup elliptic usage for new version (hybrid keys).

This commit is contained in:
Christopher Jeffrey 2016-07-15 15:17:55 -07:00
parent b780425b50
commit d4356e6255
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -17,7 +17,8 @@ if (!utils.isBrowser)
crypto = require('cry' + 'pto'); crypto = require('cry' + 'pto');
try { try {
secp256k1 = require('secp' + '256k1'); if (+process.env.BCOIN_USE_ELLIPTIC !== 1)
secp256k1 = require('secp' + '256k1');
} catch (e) { } catch (e) {
; ;
} }
@ -95,28 +96,6 @@ ec.publicKeyCreate = function publicKeyCreate(priv, compressed) {
return new Buffer(priv); return new Buffer(priv);
}; };
/**
* Decode a point.
* @param {Buffer} key
* @returns {elliptic.Point}
*/
ec.decodePoint = function decodePoint(key) {
var hybrid, point;
if (key[0] === 0x06 || key[0] === 0x07) {
hybrid = key[0];
key[0] = 0x04;
}
point = ec.elliptic.curve.decodePoint(key);
if (hybrid != null)
key[0] = hybrid;
return point;
};
/** /**
* Compress or decompress public key. * Compress or decompress public key.
* @param {Buffer} pub * @param {Buffer} pub
@ -129,7 +108,7 @@ ec.publicKeyConvert = function publicKeyConvert(key, compressed) {
if (secp256k1) if (secp256k1)
return secp256k1.publicKeyConvert(key, compressed); return secp256k1.publicKeyConvert(key, compressed);
point = ec.decodePoint(key); point = ec.elliptic.curve.decodePoint(key);
return new Buffer(point.encode('array', compressed)); return new Buffer(point.encode('array', compressed));
}; };
@ -142,19 +121,21 @@ ec.publicKeyConvert = function publicKeyConvert(key, compressed) {
*/ */
ec.privateKeyTweakAdd = function privateKeyTweakAdd(privateKey, tweak) { ec.privateKeyTweakAdd = function privateKeyTweakAdd(privateKey, tweak) {
var key;
if (secp256k1) if (secp256k1)
return secp256k1.privateKeyTweakAdd(privateKey, tweak); return secp256k1.privateKeyTweakAdd(privateKey, tweak);
privateKey = new bn(tweak) key = new bn(tweak)
.add(new bn(privateKey)) .add(new bn(privateKey))
.mod(ec.curve.n) .mod(ec.curve.n)
.toArrayLike(Buffer, 'be', 32); .toArrayLike(Buffer, 'be', 32);
// Only a 1 in 2^127 chance of happening. // Only a 1 in 2^127 chance of happening.
if (!ec.privateKeyVerify(privateKey)) if (!ec.privateKeyVerify(key))
throw new Error('Private key is invalid.'); throw new Error('Private key is invalid.');
return privateKey; return key;
}; };
/** /**
@ -165,19 +146,19 @@ ec.privateKeyTweakAdd = function privateKeyTweakAdd(privateKey, tweak) {
*/ */
ec.publicKeyTweakAdd = function publicKeyTweakAdd(publicKey, tweak, compressed) { ec.publicKeyTweakAdd = function publicKeyTweakAdd(publicKey, tweak, compressed) {
var point; var point, key;
if (secp256k1) if (secp256k1)
return secp256k1.publicKeyTweakAdd(publicKey, tweak, compressed); return secp256k1.publicKeyTweakAdd(publicKey, tweak, compressed);
point = ec.decodePoint(publicKey); point = ec.curve.decodePoint(publicKey);
point = ec.curve.g.mul(new bn(tweak)).add(point); point = ec.curve.g.mul(new bn(tweak)).add(point);
publicKey = new Buffer(point.encode('array', compressed)); key = new Buffer(point.encode('array', compressed));
if (!ec.publicKeyVerify(publicKey)) if (!ec.publicKeyVerify(key))
throw new Error('Public key is invalid.'); throw new Error('Public key is invalid.');
return publicKey; return key;
}; };
/** /**
@ -236,7 +217,7 @@ ec.rand = function rand(min, max) {
*/ */
ec.verify = function verify(msg, sig, key, historical, high) { ec.verify = function verify(msg, sig, key, historical, high) {
var hybrid, result; var result;
if (key.getPublicKey) if (key.getPublicKey)
key = key.getPublicKey(); key = key.getPublicKey();
@ -280,23 +261,12 @@ ec.verify = function verify(msg, sig, key, historical, high) {
if (!high && !ec.isLowS(sig)) if (!high && !ec.isLowS(sig))
return false; return false;
// Elliptic does not support
// openssl's "hybrid" keys yet.
if (key[0] === 0x06 || key[0] === 0x07) {
hybrid = key[0];
key[0] = 0x04;
}
try { try {
result = ec.elliptic.verify(msg, sig, key); result = ec.elliptic.verify(msg, sig, key);
} catch (e) { } catch (e) {
result = false; result = false;
} }
// Reset the byte if we need to.
if (hybrid != null)
key[0] = hybrid;
return result; return result;
}; };
@ -307,25 +277,17 @@ ec.verify = function verify(msg, sig, key, historical, high) {
*/ */
ec.publicKeyVerify = function publicKeyVerify(key) { ec.publicKeyVerify = function publicKeyVerify(key) {
var result, hybrid; var result;
if (secp256k1) if (secp256k1)
return secp256k1.publicKeyVerify(key); return secp256k1.publicKeyVerify(key);
if (key[0] === 0x06 || key[0] === 0x07) {
hybrid = key[0];
key[0] = 0x04;
}
try { try {
result = ec.elliptic.keyPair({ pub: key }).validate(); result = ec.elliptic.keyPair({ pub: key }).validate();
} catch (e) { } catch (e) {
result = false; result = false;
} }
if (hybrid != null)
key[0] = hybrid;
return result; return result;
}; };
@ -413,26 +375,6 @@ ec.normalizeLength = function normalizeLength(sig) {
return data; return data;
}; };
function getLength(buf, p) {
var initial = buf[p.place++];
var octetLen, val, i, off;
if (!(initial & 0x80))
return initial;
octetLen = initial & 0xf;
val = 0;
for (i = 0, off = p.place; i < octetLen; i++, off++) {
val <<= 8;
val |= buf[off];
}
p.place = off;
return val;
}
/** /**
* Test whether a signature has a low S value. * Test whether a signature has a low S value.
* @param {Buffer} sig * @param {Buffer} sig
@ -479,3 +421,27 @@ ec.toLowS = function toLowS(sig) {
return new Buffer(sig.toDER()); return new Buffer(sig.toDER());
}; };
/*
* Helpers
*/
function getLength(buf, p) {
var initial = buf[p.place++];
var octetLen, val, i, off;
if (!(initial & 0x80))
return initial;
octetLen = initial & 0xf;
val = 0;
for (i = 0, off = p.place; i < octetLen; i++, off++) {
val <<= 8;
val |= buf[off];
}
p.place = off;
return val;
}