StealthMessage
This code should be regarded as being a proof-of-concept, and needs more review before being used in production code. At least one thing is guaranteed to change, and that is the format of a stealth address.
This commit is contained in:
parent
74549a53ec
commit
5a86a1a5c6
3
index.js
3
index.js
|
@ -28,8 +28,9 @@ bitcore.expmt.AES = require('./lib/expmt/aes');
|
|||
bitcore.expmt.AESCBC = require('./lib/expmt/aescbc');
|
||||
bitcore.expmt.CBC = require('./lib/expmt/cbc');
|
||||
bitcore.expmt.ECIES = require('./lib/expmt/ecies');
|
||||
bitcore.expmt.Stealthkey = require('./lib/expmt/stealthkey');
|
||||
bitcore.expmt.StealthAddress = require('./lib/expmt/stealthaddress');
|
||||
bitcore.expmt.Stealthkey = require('./lib/expmt/stealthkey');
|
||||
bitcore.expmt.StealthMessage = require('./lib/expmt/stealthmessage');
|
||||
|
||||
//dependencies, subject to change
|
||||
bitcore.deps = {};
|
||||
|
|
|
@ -60,12 +60,12 @@ Stealthkey.prototype.getReceiveKeypair = function(senderPubkey) {
|
|||
return key;
|
||||
};
|
||||
|
||||
Stealthkey.prototype.isForMe = function(senderPubkey, myPossiblePubkeyhash) {
|
||||
Stealthkey.prototype.isForMe = function(senderPubkey, myPossiblePubkeyhashbuf) {
|
||||
var pubkey = this.getReceivePubkey(senderPubkey);
|
||||
var pubkeybuf = pubkey.toDER(true);
|
||||
var pubkeyhash = Hash.sha256ripemd160(pubkeybuf);
|
||||
|
||||
if (pubkeyhash.toString('hex') === myPossiblePubkeyhash.toString('hex'))
|
||||
if (pubkeyhash.toString('hex') === myPossiblePubkeyhashbuf.toString('hex'))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
var Stealthkey = require('./stealthkey');
|
||||
var StealthAddress = require('./stealthaddress');
|
||||
var ECIES = require('./ecies');
|
||||
var Message = require('../message');
|
||||
var Keypair = require('../keypair');
|
||||
var Address = require('../address');
|
||||
var Pubkey = require('../pubkey');
|
||||
|
||||
var StealthMessage = function StealthMessage(obj) {
|
||||
if (!(this instanceof StealthMessage))
|
||||
return new StealthMessage(obj);
|
||||
if (obj)
|
||||
this.set(obj);
|
||||
};
|
||||
|
||||
StealthMessage.prototype.set = function(obj) {
|
||||
this.messagebuf = obj.messagebuf || this.messagebuf;
|
||||
this.encbuf = obj.encbuf || this.encbuf;
|
||||
this.toStealthAddress = obj.toStealthAddress || this.toStealthAddress;
|
||||
this.toStealthkey = obj.toStealthkey || this.toStealthkey;
|
||||
this.fromKeypair = obj.fromKeypair || this.fromKeypair;
|
||||
this.receiveAddress = obj.receiveAddress || this.receiveAddress;
|
||||
return this;
|
||||
};
|
||||
|
||||
StealthMessage.encrypt = function(messagebuf, toStealthAddress, fromKeypair, ivbuf) {
|
||||
var sm = StealthMessage().set({
|
||||
messagebuf: messagebuf,
|
||||
toStealthAddress: toStealthAddress,
|
||||
fromKeypair: fromKeypair
|
||||
});
|
||||
sm.encrypt(ivbuf);
|
||||
var buf = Buffer.concat([
|
||||
sm.receiveAddress.hashbuf,
|
||||
sm.fromKeypair.pubkey.toDER(true),
|
||||
sm.encbuf
|
||||
]);
|
||||
return buf;
|
||||
};
|
||||
|
||||
StealthMessage.decrypt = function(buf, toStealthkey) {
|
||||
var sm = StealthMessage().set({
|
||||
toStealthkey: toStealthkey,
|
||||
receiveAddress: Address().set({hashbuf: buf.slice(0, 20)}),
|
||||
fromKeypair: Keypair().set({pubkey: Pubkey().fromDER(buf.slice(20, 20 + 33))}),
|
||||
encbuf: buf.slice(20 + 33)
|
||||
});
|
||||
return sm.decrypt().messagebuf;
|
||||
};
|
||||
|
||||
StealthMessage.isForMe = function(buf, toStealthkey) {
|
||||
var sm = StealthMessage().set({
|
||||
toStealthkey: toStealthkey,
|
||||
receiveAddress: Address().set({hashbuf: buf.slice(0, 20)}),
|
||||
fromKeypair: Keypair().set({pubkey: Pubkey().fromDER(buf.slice(20, 20 + 33))}),
|
||||
encbuf: buf.slice(20 + 33)
|
||||
});
|
||||
return sm.isForMe();
|
||||
};
|
||||
|
||||
StealthMessage.prototype.encrypt = function(ivbuf) {
|
||||
if (!this.fromKeypair)
|
||||
this.fromKeypair = Keypair().fromRandom();
|
||||
var receivePubkey = this.toStealthAddress.getReceivePubkey(this.fromKeypair);
|
||||
this.receiveAddress = Address().fromPubkey(receivePubkey);
|
||||
this.encbuf = ECIES.encrypt(this.messagebuf, Keypair().set({pubkey: receivePubkey}), this.fromKeypair, ivbuf);
|
||||
return this;
|
||||
};
|
||||
|
||||
StealthMessage.prototype.decrypt = function() {
|
||||
var receiveKeypair = this.toStealthkey.getReceiveKeypair(this.fromKeypair.pubkey);
|
||||
this.messagebuf = ECIES.decrypt(this.encbuf, receiveKeypair);
|
||||
return this;
|
||||
};
|
||||
|
||||
StealthMessage.prototype.isForMe = function() {
|
||||
var receivePubkey = this.toStealthkey.getReceivePubkey(this.fromKeypair.pubkey);
|
||||
var receiveAddress = Address().fromPubkey(receivePubkey);
|
||||
if (receiveAddress.toString('hex') === this.receiveAddress.toString('hex'))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
|
||||
module.exports = StealthMessage;
|
|
@ -0,0 +1,130 @@
|
|||
var StealthMessage = require('../lib/expmt/stealthmessage');
|
||||
var Stealthkey = require('../lib/expmt/stealthkey');
|
||||
var StealthAddress = require('../lib/expmt/stealthAddress');
|
||||
var KDF = require('../lib/kdf');
|
||||
var Hash = require('../lib/hash');
|
||||
var should = require('chai').should();
|
||||
var Address = require('../lib/address');
|
||||
|
||||
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 encbuf = new Buffer(enchex, 'hex');
|
||||
var ivbuf = Hash.sha256(new Buffer('test')).slice(0, 128 / 8);
|
||||
var sk = Stealthkey().set({payloadKeypair: payloadKeypair, scanKeypair: scanKeypair});
|
||||
var sa = StealthAddress().fromStealthkey(sk);
|
||||
var messagebuf = new Buffer('this is my message');
|
||||
|
||||
it('should make a new stealthmessage', function() {
|
||||
var sm = new StealthMessage();
|
||||
should.exist(sm);
|
||||
sm = StealthMessage()
|
||||
should.exist(sm);
|
||||
});
|
||||
|
||||
it('should allow "set" style syntax', function() {
|
||||
var encbuf = StealthMessage().set({
|
||||
messagebuf: messagebuf,
|
||||
toStealthAddress: sa
|
||||
}).encrypt().encbuf;
|
||||
should.exist(encbuf);
|
||||
encbuf.length.should.equal(113);
|
||||
});
|
||||
|
||||
describe('#set', function() {
|
||||
|
||||
it('should set the messagebuf', function() {
|
||||
var sm = StealthMessage().set({messagebuf: messagebuf});
|
||||
should.exist(sm.messagebuf);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('@encrypt', function() {
|
||||
|
||||
it('should encrypt a message', function() {
|
||||
var encbuf = StealthMessage.encrypt(messagebuf, sa);
|
||||
encbuf.length.should.equal(166);
|
||||
});
|
||||
|
||||
it('should encrypt a message with this fromKeypair and ivbuf the same each time', function() {
|
||||
var encbuf = StealthMessage.encrypt(messagebuf, sa, fromKeypair, ivbuf);
|
||||
encbuf.length.should.equal(166);
|
||||
encbuf.toString('hex').should.equal(enchex);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('@decrypt', function() {
|
||||
|
||||
it('should decrypt this known message correctly', function() {
|
||||
var messagebuf2 = StealthMessage.decrypt(encbuf, sk);
|
||||
messagebuf2.toString('hex').should.equal(messagebuf.toString('hex'));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('@isForMe', function() {
|
||||
|
||||
it('should know that this message is for me', function() {
|
||||
StealthMessage.isForMe(encbuf, sk).should.equal(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#encrypt', function() {
|
||||
|
||||
it('should encrypt this message', function() {
|
||||
var sm = StealthMessage().set({
|
||||
messagebuf: messagebuf,
|
||||
toStealthAddress: sa,
|
||||
fromKeypair: fromKeypair
|
||||
});
|
||||
sm.encrypt().encbuf.length.should.equal(113);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#decrypt', function() {
|
||||
|
||||
it('should decrypt that which was encrypted', function() {
|
||||
var sm = StealthMessage().set({
|
||||
messagebuf: messagebuf,
|
||||
toStealthAddress: sa
|
||||
}).encrypt();
|
||||
var messagebuf2 = StealthMessage().set({
|
||||
encbuf: sm.encbuf,
|
||||
fromKeypair: sm.fromKeypair,
|
||||
toStealthkey: sk
|
||||
}).decrypt().messagebuf;
|
||||
messagebuf2.toString('hex').should.equal(messagebuf.toString('hex'));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#isForMe', function() {
|
||||
|
||||
it('should know that this message is for me', function() {
|
||||
StealthMessage().set({
|
||||
encbuf: encbuf,
|
||||
toStealthkey: sk,
|
||||
fromKeypair: fromKeypair,
|
||||
receiveAddress: Address().set({hashbuf: encbuf.slice(0, 20)})
|
||||
}).isForMe().should.equal(true);
|
||||
});
|
||||
|
||||
it('should know that this message is not for me', function() {
|
||||
StealthMessage().set({
|
||||
encbuf: encbuf,
|
||||
toStealthkey: sk,
|
||||
fromKeypair: fromKeypair,
|
||||
receiveAddress: Address().set({hashbuf: encbuf.slice(0, 20)})
|
||||
}).isForMe().should.equal(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
Loading…
Reference in New Issue