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.
This commit is contained in:
Ryan X. Charles 2014-09-12 17:24:00 -07:00
parent a095341a07
commit 79d79012d4
5 changed files with 28 additions and 6 deletions

View File

@ -48,3 +48,16 @@ console.log('Is the message for me? ' + (StealthMessage.isForMe(encbuf, sk) ? "y
var messagebuf2 = StealthMessage.decrypt(encbuf, sk);
console.log('Decrypted message: ' + messagebuf2.toString());
//If you do not have the payload privkey, you can still use isForMe.
sk.payloadKeypair.privkey = undefined;
console.log('Without payload privkey, is the message for me? ' + (StealthMessage.isForMe(encbuf, sk) ? "yes" : "no"));
//...but not decrypt
try {
StealthMessage.decrypt(encbuf, sk);
} catch (e) {
console.log("...but without the payload privkey, I can't decrypt.");
}

View File

@ -65,7 +65,7 @@ StealthAddress.prototype.getSharedKeypair = function(senderKeypair) {
StealthAddress.prototype.getReceivePubkey = function(senderKeypair) {
var sharedKeypair = this.getSharedKeypair(senderKeypair);
var pubkey = Pubkey(this.payloadPubkey.point.add(sharedKeypair.pubkey.point));
var pubkey = Pubkey(this.scanPubkey.point.add(sharedKeypair.pubkey.point).add(this.payloadPubkey.point));
return pubkey;
};

View File

@ -46,14 +46,14 @@ Stealthkey.prototype.getSharedKeypair = function(senderPubkey) {
Stealthkey.prototype.getReceivePubkey = function(senderPubkey) {
var sharedKeypair = this.getSharedKeypair(senderPubkey);
var pubkey = Pubkey({point: this.payloadKeypair.pubkey.point.add(sharedKeypair.pubkey.point)});
var pubkey = Pubkey({point: this.scanKeypair.pubkey.point.add(sharedKeypair.pubkey.point).add(this.payloadKeypair.pubkey.point)});
return pubkey;
};
Stealthkey.prototype.getReceiveKeypair = function(senderPubkey) {
var sharedKeypair = this.getSharedKeypair(senderPubkey);
var privkey = Privkey({bn: this.payloadKeypair.privkey.bn.add(sharedKeypair.privkey.bn).mod(Point.getN())});
var privkey = Privkey({bn: this.scanKeypair.privkey.bn.add(sharedKeypair.privkey.bn).add(this.payloadKeypair.privkey.bn).mod(Point.getN())});
var key = Keypair({privkey: privkey});
key.privkey2pubkey();

View File

@ -103,12 +103,12 @@ describe('Stealthkey', function() {
describe('#isForMe', function() {
it('should return true if it (the transaction or message) is for me', function() {
var pubkeyhash = new Buffer('3cb64fa6ee9b3e8754e3e2bd033bf61048604a99', 'hex');
var pubkeyhash = new Buffer('0db7f06cffb913322e211e8b0688efe8ff52aa8d', 'hex');
stealthkey.isForMe(senderKeypair.pubkey, pubkeyhash).should.equal(true);
});
it('should return false if it (the transaction or message) is not for me', function() {
var pubkeyhash = new Buffer('00b64fa6ee9b3e8754e3e2bd033bf61048604a99', 'hex');
var pubkeyhash = new Buffer('ffb7f06cffb913322e211e8b0688efe8ff52aa8d', 'hex');
stealthkey.isForMe(senderKeypair.pubkey, pubkeyhash).should.equal(false);
});

View File

@ -1,3 +1,4 @@
var Keypair = require('../lib/keypair');
var StealthMessage = require('../lib/expmt/stealthmessage');
var Stealthkey = require('../lib/expmt/stealthkey');
var StealthAddress = require('../lib/expmt/stealthAddress');
@ -11,7 +12,7 @@ describe('StealthMessage', function() {
var payloadKeypair = KDF.buf2keypair(new Buffer('key1'));
var scanKeypair = KDF.buf2keypair(new Buffer('key2'));
var fromKeypair = KDF.buf2keypair(new Buffer('key3'));
var enchex = 'f557994f16d0d628fa4fdb4ab3d7e0bc5f2754f20381c7831a20c7c9ec88dcf092ea3683261798ccda991ed65a3a54a036d8125dec0381c7831a20c7c9ec88dcf092ea3683261798ccda991ed65a3a54a036d8125dec9f86d081884c7d659a2feaa0c55ad01560ba2904d3bc8395b6c4a6f87648edb33db6a22170e5e26f340c7ba943169210234cd6a753ad13919b0ab7d678b47b5e7d63e452382de2c2590fb57ef048f7b3';
var enchex = '3867dce7be22e8551512b25f329b51fd5fe8ecfe0381c7831a20c7c9ec88dcf092ea3683261798ccda991ed65a3a54a036d8125dec0381c7831a20c7c9ec88dcf092ea3683261798ccda991ed65a3a54a036d8125dec9f86d081884c7d659a2feaa0c55ad015aca97de5af3a34a0f47eee0a1f7774dcb759187555003282bd23b047bceb5b2f2c1ee35b8f0be1fda7a41424f6cc8030559c8c32ea8cc812860f4c8123f1417a';
var encbuf = new Buffer(enchex, 'hex');
var ivbuf = Hash.sha256(new Buffer('test')).slice(0, 128 / 8);
var sk = Stealthkey().set({payloadKeypair: payloadKeypair, scanKeypair: scanKeypair});
@ -73,6 +74,14 @@ describe('StealthMessage', function() {
StealthMessage.isForMe(encbuf, sk).should.equal(true);
});
it('should know that this message is for me even if my payloadPrivkey is not present', function() {
var sk2 = new Stealthkey();
sk2.scanKeypair = sk.scanKeypair;
sk2.payloadKeypair = Keypair().set({pubkey: sk.payloadKeypair.pubkey});
should.not.exist(sk2.payloadKeypair.privkey);
StealthMessage.isForMe(encbuf, sk2).should.equal(true);
});
});
describe('#encrypt', function() {