bitcore/lib/pubkey.js

117 lines
3.2 KiB
JavaScript
Raw Normal View History

2014-08-13 12:23:06 -07:00
var Point = require('./point');
2014-08-07 16:18:17 -07:00
var bn = require('./bn');
2014-08-28 20:19:30 -07:00
var privkey = require('./privkey');
2014-08-07 16:18:17 -07:00
2014-09-01 21:16:10 -07:00
var Pubkey = function Pubkey(point) {
if (!(this instanceof Pubkey))
2014-09-02 12:07:18 -07:00
return new Pubkey(point);
2014-09-01 21:16:10 -07:00
if (point instanceof Point)
this.point = point;
else if (point) {
var obj = point;
2014-08-28 17:41:38 -07:00
this.set(obj);
2014-09-01 21:16:10 -07:00
}
2014-08-28 17:41:38 -07:00
};
Pubkey.prototype.set = function(obj) {
if (obj.point && !obj.point.getX() && !obj.point.getY())
throw new Error('Invalid point');
2014-08-28 17:41:38 -07:00
this.point = obj.point || this.point;
this.compressed = typeof obj.compressed !== 'undefined' ? obj.compressed : this.compressed;
return this;
2014-08-07 16:18:17 -07:00
};
2014-08-28 20:19:30 -07:00
Pubkey.prototype.fromPrivkey = function(privkey) {
this.set({
point: Point.getG().mul(privkey.bn),
compressed: privkey.compressed}
);
return this;
};
Pubkey.prototype.fromBuffer = function(buf) {
return this.fromDER(buf);
};
2014-08-07 16:18:17 -07:00
Pubkey.prototype.fromDER = function(buf) {
if (buf[0] == 0x04) {
var xbuf = buf.slice(1, 33);
var ybuf = buf.slice(33, 65);
if (xbuf.length !== 32 || ybuf.length !== 32 || buf.length !== 65)
throw new Error('Length of x and y must be 32 bytes');
2014-08-07 16:18:17 -07:00
var x = bn(xbuf);
var y = bn(ybuf);
2014-08-13 12:23:06 -07:00
this.point = Point(x, y);
this.compressed = false;
2014-08-07 16:18:17 -07:00
} else if (buf[0] == 0x03) {
var xbuf = buf.slice(1);
var x = bn(xbuf);
this.fromX(true, x);
this.compressed = true;
2014-08-07 16:18:17 -07:00
} else if (buf[0] == 0x02) {
var xbuf = buf.slice(1);
var x = bn(xbuf);
this.fromX(false, x);
this.compressed = true;
2014-08-07 16:18:17 -07:00
} else {
throw new Error('Invalid DER format pubkey');
2014-08-07 16:18:17 -07:00
}
return this;
2014-08-07 16:18:17 -07:00
};
Pubkey.prototype.fromString = function(str) {
this.fromDER(new Buffer(str, 'hex'));
};
Pubkey.prototype.fromX = function(odd, x) {
if (typeof odd !== 'boolean')
throw new Error('Must specify whether y is odd or not (true or false)');
2014-08-13 12:23:06 -07:00
this.point = Point.fromX(odd, x);
2014-08-07 16:18:17 -07:00
};
Pubkey.prototype.toBuffer = function() {
var compressed = typeof this.compressed === 'undefined' ? true : this.compressed;
return this.toDER(compressed);
};
2014-08-07 16:18:17 -07:00
Pubkey.prototype.toDER = function(compressed) {
compressed = typeof this.compressed === 'undefined' ? compressed : this.compressed;
2014-08-07 16:18:17 -07:00
if (typeof compressed !== 'boolean')
throw new Error('Must specify whether the public key is compressed or not (true or false)');
2014-08-07 16:18:17 -07:00
2014-08-13 12:23:06 -07:00
var x = this.point.getX();
var y = this.point.getY();
2014-08-07 16:18:17 -07:00
var xbuf = x.toBuffer({size: 32});
var ybuf = y.toBuffer({size: 32});
if (!compressed) {
var prefix = new Buffer([0x04]);
return Buffer.concat([prefix, xbuf, ybuf]);
} else {
var odd = ybuf[ybuf.length - 1] % 2;
if (odd)
var prefix = new Buffer([0x03]);
else
var prefix = new Buffer([0x02]);
return Buffer.concat([prefix, xbuf]);
}
};
Pubkey.prototype.toString = function() {
var compressed = typeof this.compressed === 'undefined' ? true : this.compressed;
return this.toDER(compressed).toString('hex');
2014-08-07 16:18:17 -07:00
};
2014-08-09 17:43:24 -07:00
//https://www.iacr.org/archive/pkc2003/25670211/25670211.pdf
Pubkey.prototype.validate = function() {
2014-08-13 12:23:06 -07:00
if (this.point.isInfinity())
2014-08-09 17:43:24 -07:00
throw new Error('point: Point cannot be equal to Infinity');
2014-08-13 12:23:06 -07:00
if (this.point.eq(Point(bn(0), bn(0))))
2014-08-09 17:43:24 -07:00
throw new Error('point: Point cannot be equal to 0, 0');
2014-08-13 12:23:06 -07:00
this.point.validate();
2014-08-09 17:43:24 -07:00
return this;
};
2014-08-07 16:18:17 -07:00
module.exports = Pubkey;