pubkey compression.
This commit is contained in:
parent
745e89131c
commit
6c419cc754
148
lib/bcoin/ec.js
148
lib/bcoin/ec.js
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user