var Keypair = require('../keypair'); var Privkey = require('../privkey'); var Pubkey = require('../pubkey'); var Point = require('../point'); var Hash = require('../hash'); var KDF = require('../kdf'); var base58check = require('../base58check'); var Stealthkey = function Stealthkey(obj) { if (!(this instanceof Stealthkey)) return new Stealthkey(obj); if (obj) this.set(obj); }; Stealthkey.prototype.set = function(obj) { this.payloadKeypair = obj.payloadKeypair || this.payloadKeypair; this.scanKeypair = obj.scanKeypair || this.scanKeypair; return this; }; Stealthkey.prototype.fromAddressBuffer = function(buf) { if (!Buffer.isBuffer(buf) || buf.length !== 66) throw new Error('stealthkey: A stealthkey address must have length 66'); var pPubBuf = buf.slice(0, 33); var sPubBuf = buf.slice(33, 66); var payloadPubkey = Pubkey().fromDER(pPubBuf); this.payloadKeypair = Keypair({pubkey: payloadPubkey}); var scanPubkey = Pubkey().fromDER(sPubBuf); this.scanKeypair = Keypair({pubkey: scanPubkey}); return this; }; Stealthkey.prototype.fromAddressString = function(str) { var buf = base58check.decode(str); this.fromAddressBuffer(buf); return this; }; Stealthkey.prototype.fromRandom = function() { this.payloadKeypair = Keypair().fromRandom(); this.scanKeypair = Keypair().fromRandom(); return this; }; Stealthkey.prototype.getSharedKeypairAsReceiver = function(senderPubkey) { var sharedSecretPoint = senderPubkey.point.mul(this.scanKeypair.privkey.bn); var sharedSecretPubkey = Pubkey({point: sharedSecretPoint}); var buf = sharedSecretPubkey.toDER(true); var sharedKeypair = KDF.sha256hmac2keypair(buf); return sharedKeypair; }; Stealthkey.prototype.getSharedKeypairAsSender = function(senderKeypair) { var sharedSecretPoint = this.scanKeypair.pubkey.point.mul(senderKeypair.privkey.bn); var sharedSecretPubkey = Pubkey({point: sharedSecretPoint}); var buf = sharedSecretPubkey.toDER(true); var sharedKeypair = KDF.sha256hmac2keypair(buf); return sharedKeypair; }; Stealthkey.prototype.getReceivePubkeyAsReceiver = function(senderPubkey) { var sharedKeypair = this.getSharedKeypairAsReceiver(senderPubkey); var pubkey = Pubkey({point: this.payloadKeypair.pubkey.point.add(sharedKeypair.pubkey.point)}); return pubkey; }; Stealthkey.prototype.getReceivePubkeyAsSender = function(senderKeypair) { var sharedKeypair = this.getSharedKeypairAsSender(senderKeypair); var pubkey = Pubkey({point: this.payloadKeypair.pubkey.point.add(sharedKeypair.pubkey.point)}); return pubkey; }; Stealthkey.prototype.getReceiveKeypair = function(senderPubkey) { var sharedKeypair = this.getSharedKeypairAsReceiver(senderPubkey); var privkey = Privkey({bn: this.payloadKeypair.privkey.bn.add(sharedKeypair.privkey.bn).mod(Point.getN())}); var key = Keypair({privkey: privkey}); key.privkey2pubkey(); return key; }; Stealthkey.prototype.isForMe = function(senderPubkey, myPossiblePubkeyhash) { var pubkey = this.getReceivePubkeyAsReceiver(senderPubkey); var pubkeybuf = pubkey.toDER(true); var pubkeyhash = Hash.sha256ripemd160(pubkeybuf); if (pubkeyhash.toString('hex') === myPossiblePubkeyhash.toString('hex')) return true; else return false; }; Stealthkey.prototype.toAddressBuffer = function() { var pBuf = this.payloadKeypair.pubkey.toDER(true); var sBuf = this.scanKeypair.pubkey.toDER(true); return Buffer.concat([pBuf, sBuf]); }; Stealthkey.prototype.toAddressString = function() { var buf = this.toAddressBuffer(); var b58 = base58check.encode(buf); return b58; }; module.exports = Stealthkey;