pubkey compression.

This commit is contained in:
Christopher Jeffrey 2016-07-01 16:58:41 -07:00
parent 745e89131c
commit 6c419cc754
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -86,6 +86,135 @@ ec.publicKeyCreate = function publicKeyCreate(priv, compressed) {
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.
* @param {Buffer} pub
* @returns {Buffer}
*/
ec.publicKeyConvert = function(key, compressed) {
var point;
if (secp256k1)
return secp256k1.publicKeyConvert(key, compressed);
switch (key[0]) {
case 0x02:
case 0x03:
if (compressed)
return key;
point = ec.decodePoint(key);
return new Buffer(point.encode('array', false));
case 0x04:
case 0x06:
case 0x07:
if (compressed) {
point = ec.decodePoint(key);
return new Buffer(point.encode('array', true));
}
return key;
default:
throw new Error('Bad point format.');
}
};
/**
* Compress a public key to coins compression format.
* @param {Buffer} key
* @returns {Buffer}
*/
ec.compress = function compress(key) {
var out;
// We can't compress it if it's not valid.
if (!ec.publicKeyVerify(key))
return;
switch (key[0]) {
case 0x02:
case 0x03:
// Key is already compressed.
out = key;
break;
case 0x04:
case 0x06:
case 0x07:
// Compress the key normally.
out = ec.publicKeyConvert(key, true);
// Store the original format (which
// may be a hybrid byte) in the hi
// 3 bits so we can restore it later.
// The hi bits being set also lets us
// know that this key was originally
// decompressed.
out[0] |= key[0] << 2;
break;
default:
throw new Error('Bad point format.');
}
assert(out.length === 33);
return out;
};
/**
* Decompress a public key from the coins compression format.
* @param {Buffer} key
* @returns {Buffer}
*/
ec.decompress = function decompress(key) {
var format = key[0] >>> 2;
var out;
assert(key.length === 33);
// Hi bits are not set. This key
// is not meant to be decompressed.
if (format === 0)
return key;
// Decompress the key, and off the
// low bits so publicKeyConvert
// actually understands it.
key[0] &= 0x03;
out = ec.publicKeyConvert(key, false);
// Reset the hi bits so as not to
// mutate the original buffer.
key[0] |= format << 2;
// Set the original format, which
// may have been a hybrid prefix byte.
out[0] = format;
return out;
};
/**
* Create an ecdh.
* @param {Buffer} pub
@ -211,9 +340,26 @@ ec.verify = function verify(msg, sig, key, historical, high) {
*/
ec.publicKeyVerify = function publicKeyVerify(key) {
var result, hybrid;
if (secp256k1)
return secp256k1.publicKeyVerify(key);
return ec.elliptic.keyPair({ pub: key }).validate();
if (key[0] === 0x06 || key[0] === 0x07) {
hybrid = key[0];
key[0] = 0x04;
}
try {
result = ec.elliptic.keyPair({ pub: key }).validate();
} catch (e) {
result = false;
}
if (hybrid != null)
key[0] = hybrid;
return result;
};
/**