diff --git a/lib/expmt/stealthaddress.js b/lib/expmt/stealthaddress.js new file mode 100644 index 0000000..b7d58a6 --- /dev/null +++ b/lib/expmt/stealthaddress.js @@ -0,0 +1,61 @@ +var Stealthkey = require('./stealthkey'); +var Base58check = require('../base58check'); +var Pubkey = require('../pubkey'); + +var StealthAddress = function StealthAddress(obj) { + if (!(this instanceof StealthAddress)) + return new StealthAddress(obj); + + if (obj) + 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.payloadPubkey, + scanPubkey: stealthkey.scanPubkey + }); + 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.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; diff --git a/test/stealthaddress.js b/test/stealthaddress.js new file mode 100644 index 0000000..a976b6c --- /dev/null +++ b/test/stealthaddress.js @@ -0,0 +1,77 @@ +var StealthAddress = require('../lib/expmt/stealthaddress'); +var should = require('chai').should(); +var Stealthkey = require('../lib/expmt/stealthkey'); +var Keypair = require('../lib/keypair'); +var Privkey = require('../lib/privkey'); +var Pubkey = require('../lib/pubkey'); +var BN = require('../lib/bn'); +var Hash = require('../lib/Hash'); +var Base58check = require('../lib/base58check'); + +describe('StealthAddress', function() { + + var stealthkey = Stealthkey(); + stealthkey.payloadKeypair = Keypair(); + stealthkey.payloadKeypair.privkey = Privkey(); + stealthkey.payloadKeypair.privkey.bn = BN().fromBuffer(Hash.sha256(new Buffer('test 1'))); + stealthkey.payloadKeypair.privkey2pubkey(); + stealthkey.scanKeypair = Keypair(); + stealthkey.scanKeypair.privkey = Privkey(); + stealthkey.scanKeypair.privkey.bn = BN().fromBuffer(Hash.sha256(new Buffer('test 2'))); + stealthkey.scanKeypair.privkey2pubkey(); + + var senderKeypair = Keypair(); + senderKeypair.privkey = Privkey(); + senderKeypair.privkey.bn = BN().fromBuffer(Hash.sha256(new Buffer('test 3'))); + senderKeypair.privkey2pubkey(); + + var addressString = '9dDbC9FzZ74r8njQkXD6W27gtrxLiWaeFPHxeo1fynQRXPicqxVt7u95ozbwoVVMXyrzaHKN9owsteg63FgwDfrxWx82SAW'; + + it('should make a new stealth address', function() { + var sa = new StealthAddress(); + should.exist(sa); + sa = StealthAddress(); + should.exist(sa); + }); + + describe('#fromBuffer', function() { + + it('should give a stealthkey address with the right pubkeys', function() { + var sa = new StealthAddress(); + var buf = Base58check.decode(addressString); + sa.fromBuffer(buf); + sa.payloadPubkey.toString().should.equal(stealthkey.payloadKeypair.pubkey.toString()); + sa.scanPubkey.toString().should.equal(stealthkey.scanKeypair.pubkey.toString()); + }); + + }); + + describe('#fromString', function() { + + it('should give a stealthkey address with the right pubkeys', function() { + var sa = new StealthAddress(); + sa.fromString(addressString); + sa.payloadPubkey.toString().should.equal(stealthkey.payloadKeypair.pubkey.toString()); + sa.scanPubkey.toString().should.equal(stealthkey.scanKeypair.pubkey.toString()); + }); + + }); + + describe('#toBuffer', function() { + + it('should return this known address buffer', function() { + var buf = Base58check.decode(addressString); + StealthAddress().fromBuffer(buf).toBuffer().toString('hex').should.equal(buf.toString('hex')); + }); + + }); + + describe('#toString', function() { + + it('should return this known address string', function() { + StealthAddress().fromString(addressString).toString().should.equal(addressString); + }); + + }); + +});