2014-08-21 15:50:38 -07:00
|
|
|
var ECDSA = require('./ecdsa');
|
2014-08-29 14:18:56 -07:00
|
|
|
var Keypair = require('./keypair');
|
2014-08-21 15:50:38 -07:00
|
|
|
var Privkey = require('./privkey');
|
|
|
|
var Pubkey = require('./pubkey');
|
|
|
|
var BufferWriter = require('./bufferwriter');
|
|
|
|
var Hash = require('./hash');
|
|
|
|
var Address = require('./address');
|
2014-08-22 16:15:44 -07:00
|
|
|
var Signature = require('./signature');
|
2014-08-21 15:50:38 -07:00
|
|
|
|
2014-08-28 16:42:47 -07:00
|
|
|
var Message = function Message(obj) {
|
2014-08-21 15:50:38 -07:00
|
|
|
if (!(this instanceof Message))
|
2014-08-28 16:42:47 -07:00
|
|
|
return new Message(obj);
|
|
|
|
if (obj)
|
|
|
|
this.set(obj);
|
|
|
|
};
|
|
|
|
|
|
|
|
Message.prototype.set = function(obj) {
|
|
|
|
this.messagebuf = obj.messagebuf || this.messagebuf;
|
2014-09-02 16:36:21 -07:00
|
|
|
this.keypair = obj.keypair || this.keypair;
|
2014-08-28 16:42:47 -07:00
|
|
|
this.sig = obj.sig || this.sig;
|
|
|
|
this.address = obj.address || this.address;
|
|
|
|
this.verified = typeof obj.verified !== 'undefined' ? obj.verified : this.verified;
|
|
|
|
return this;
|
2014-08-21 15:50:38 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
Message.magicBytes = new Buffer('Bitcoin Signed Message:\n');
|
|
|
|
|
|
|
|
Message.magicHash = function(messagebuf) {
|
|
|
|
if (!Buffer.isBuffer(messagebuf))
|
|
|
|
throw new Error('messagebuf must be a buffer');
|
|
|
|
var bw = new BufferWriter();
|
|
|
|
bw.writeVarInt(Message.magicBytes.length);
|
|
|
|
bw.write(Message.magicBytes);
|
|
|
|
bw.writeVarInt(messagebuf.length);
|
|
|
|
bw.write(messagebuf);
|
|
|
|
var buf = bw.concat();
|
|
|
|
|
|
|
|
var hashbuf = Hash.sha256sha256(buf);
|
|
|
|
|
|
|
|
return hashbuf;
|
|
|
|
};
|
|
|
|
|
2014-09-02 16:36:21 -07:00
|
|
|
Message.sign = function(messagebuf, keypair) {
|
|
|
|
var m = Message({messagebuf: messagebuf, keypair: keypair});
|
2014-08-24 14:27:47 -07:00
|
|
|
m.sign();
|
|
|
|
var sigbuf = m.sig.toCompact();
|
|
|
|
var sigstr = sigbuf.toString('base64');
|
|
|
|
return sigstr;
|
|
|
|
};
|
|
|
|
|
|
|
|
Message.verify = function(messagebuf, sigstr, address) {
|
|
|
|
var sigbuf = new Buffer(sigstr, 'base64');
|
|
|
|
var message = new Message();
|
|
|
|
message.messagebuf = messagebuf;
|
|
|
|
message.sig = Signature().fromCompact(sigbuf);
|
|
|
|
message.address = address;
|
|
|
|
|
|
|
|
return message.verify().verified;
|
|
|
|
};
|
|
|
|
|
2014-08-21 15:50:38 -07:00
|
|
|
Message.prototype.sign = function() {
|
|
|
|
var hashbuf = Message.magicHash(this.messagebuf);
|
2014-09-02 16:36:21 -07:00
|
|
|
var ecdsa = ECDSA({hashbuf: hashbuf, keypair: this.keypair});
|
2014-08-21 15:50:38 -07:00
|
|
|
ecdsa.signRandomK();
|
|
|
|
ecdsa.calci();
|
|
|
|
this.sig = ecdsa.sig;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
Message.prototype.verify = function() {
|
|
|
|
var hashbuf = Message.magicHash(this.messagebuf);
|
|
|
|
|
|
|
|
var ecdsa = new ECDSA();
|
|
|
|
ecdsa.hashbuf = hashbuf;
|
|
|
|
ecdsa.sig = this.sig;
|
2014-09-02 16:36:21 -07:00
|
|
|
ecdsa.keypair = new Keypair();
|
|
|
|
ecdsa.keypair.pubkey = ecdsa.sig2pubkey();
|
2014-08-21 15:50:38 -07:00
|
|
|
|
|
|
|
if (!ecdsa.verify()) {
|
|
|
|
this.verified = false;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2014-09-02 16:36:21 -07:00
|
|
|
var address = Address().fromPubkey(ecdsa.keypair.pubkey, undefined, this.sig.compressed);
|
2014-08-21 15:50:38 -07:00
|
|
|
//TODO: what if livenet/testnet mismatch?
|
|
|
|
if (address.hashbuf.toString('hex') === this.address.hashbuf.toString('hex'))
|
|
|
|
this.verified = true;
|
|
|
|
else
|
|
|
|
this.verified = false;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = Message;
|