flocore/lib/expmt/stealthaddress.js
Ryan X. Charles 79d79012d4 fix bug where you can't use isForMe without payloadKeypair
It should be possible to check to see if a message isForMe with only the
scanKeypair, and not the payloadKeypair. There was a bug where only the
scanKeypair was being used to produce the receiveKeypair, but this was a
mistake. Both the scanPubkey and payloadPubkey should be necessary to produce
the receivePubkey, and both the scanPrivkey and payloadPrivkey should be
necessary to produce the receivePrivkey. If an online computer has only the
public keys of both (and the scanPrivkey), then that is good enough to check
for isForMe.
2014-09-12 17:24:00 -07:00

88 lines
2.3 KiB
JavaScript

var Stealthkey = require('./stealthkey');
var Base58check = require('../base58check');
var Pubkey = require('../pubkey');
var KDF = require('../kdf');
var StealthAddress = function StealthAddress(addrstr) {
if (!(this instanceof StealthAddress))
return new StealthAddress(addrstr);
if (typeof addrstr === 'string') {
this.fromString(addrstr)
}
else if (Buffer.isBuffer(addrstr)) {
var buf = addrstr;
this.fromBuffer(buf);
}
else if (addrstr) {
var obj = addrstr;
this.set(obj);
}
};
StealthAddress.prototype.set = function(obj) {
this.payloadPubkey = obj.payloadPubkey || this.payloadPubkey;
this.scanPubkey = obj.scanPubkey || this.scanPubkey;
return this;
};
StealthAddress.prototype.fromStealthkey = function(stealthkey) {
this.set({
payloadPubkey: stealthkey.payloadKeypair.pubkey,
scanPubkey: stealthkey.scanKeypair.pubkey
});
return this;
};
StealthAddress.prototype.fromBuffer = function(buf) {
if (!Buffer.isBuffer(buf) || buf.length !== 66)
throw new Error('stealthkey: A stealth address must have length 66');
var pPubBuf = buf.slice(0, 33);
var sPubBuf = buf.slice(33, 66);
this.payloadPubkey = Pubkey().fromDER(pPubBuf);
this.scanPubkey = Pubkey().fromDER(sPubBuf);
return this;
};
StealthAddress.prototype.fromString = function(str) {
var buf = Base58check.decode(str);
this.fromBuffer(buf);
return this;
};
StealthAddress.prototype.getSharedKeypair = function(senderKeypair) {
var sharedSecretPoint = this.scanPubkey.point.mul(senderKeypair.privkey.bn);
var sharedSecretPubkey = Pubkey(sharedSecretPoint);
var buf = sharedSecretPubkey.toDER(true);
var sharedKeypair = KDF.sha256hmac2keypair(buf);
return sharedKeypair;
};
StealthAddress.prototype.getReceivePubkey = function(senderKeypair) {
var sharedKeypair = this.getSharedKeypair(senderKeypair);
var pubkey = Pubkey(this.scanPubkey.point.add(sharedKeypair.pubkey.point).add(this.payloadPubkey.point));
return pubkey;
};
StealthAddress.prototype.toBuffer = function() {
var pBuf = this.payloadPubkey.toDER(true);
var sBuf = this.scanPubkey.toDER(true);
return Buffer.concat([pBuf, sBuf]);
};
StealthAddress.prototype.toString = function() {
var buf = this.toBuffer();
var b58 = Base58check.encode(buf);
return b58;
};
module.exports = StealthAddress;