From 5e2a9f0c261486025116389abcc51dca4c5369e6 Mon Sep 17 00:00:00 2001 From: vub Date: Mon, 18 Nov 2013 23:47:56 -0500 Subject: [PATCH] Added BIP32 support --- bitcoinjs-min.js | 6 +- src/base58.js | 4 +- src/bip32.js | 139 +++++++++++++++++++++++ src/bitcoin.js | 165 --------------------------- src/convert.js | 2 +- src/crypto-js/crypto.js | 2 + src/crypto-js/hmac.js | 38 +++++++ src/crypto-js/sha256.js | 28 ++--- src/crypto-js/sha512.js | 240 ++++++++++++++++++++++++++++++++++++++++ src/eckey.js | 173 +++++++++++------------------ src/index.js | 1 + src/jsbn/ec.js | 33 ++++-- src/message.js | 4 +- src/script.js | 2 +- src/util.js | 18 ++- src/wallet.js | 2 +- 16 files changed, 545 insertions(+), 312 deletions(-) create mode 100644 src/bip32.js delete mode 100644 src/bitcoin.js create mode 100644 src/crypto-js/hmac.js create mode 100644 src/crypto-js/sha512.js diff --git a/bitcoinjs-min.js b/bitcoinjs-min.js index 2d4f99d..9b7d124 100644 --- a/bitcoinjs-min.js +++ b/bitcoinjs-min.js @@ -1,3 +1,3 @@ -!function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.Bitcoin=e():"undefined"!=typeof global?global.Bitcoin=e():"undefined"!=typeof self&&(self.Bitcoin=e())}(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o=0){var mod=bi.mod(base);chars.push(alphabet[mod.intValue()]);bi=bi.subtract(mod).divide(base)}chars.push(alphabet[bi.intValue()]);for(var i=0;i0){bytes.unshift(0)}return bytes};module.exports.decodeHex=function(input){return module.exports.decode(Crypto.util.hexToBytes(input))};module.exports.checkEncode=function(input,vbyte){vbyte=vbyte||0;var front=[vbyte].concat(input);var checksum=Crypto.SHA256(Crypto.SHA256(front,{asBytes:true}),{asBytes:true}).slice(0,4);return module.exports.encode(front.concat(checksum))};module.exports.checkEncodeHex=function(input,vbyte){return conv.bytesToHex(module.exports.encode(input))};module.exports.checkDecode=function(input){var bytes=module.exports.decode(input),front=bytes.slice(0,bytes.length-4),back=bytes.slice(bytes.length-4);var checksum=Crypto.SHA256(Crypto.SHA256(front,{asBytes:true}),{asBytes:true}).slice(0,4);if(""+checksum!=""+back){throw new Error("Checksum failed")}var o=front.slice(1);o.version=front[0];return o};module.exports.checkDecodeHex=function(input){return module.exports.checkDecode(Crypto.util.hexToBytes(input))}},{"./convert":3,"./crypto-js/crypto":4,"./jsbn/jsbn":11}],3:[function(require,module,exports){var base64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";String.prototype.lpad=function(padString,length){var str=this;while(str.length>>6*(3-j)&63));else base64.push("=")}}return base64.join("")};module.exports.base64ToBytes=function(base64){base64=base64.replace(/[^A-Z0-9+\/]/gi,"");for(var bytes=[],i=0,imod4=0;i>>6-imod4*2)}return bytes};module.exports.coerceToBytes=function(input){if(typeof input=="string")return Crypto.util.hexToBytes(input);return input};module.exports.binToBytes=function(bin){return bin.match(/......../g).map(function(x){return parseInt(x,2)})};module.exports.bytesToBin=function(bytes){return bytes.map(function(x){return x.toString(2).lpad("0",8)}).join("")};module.exports.bytesToString=function(bytes){return bytes.map(function(x){return String.fromCharCode(x)}).join("")};module.exports.stringToBytes=function(string){return string.split("").map(function(x){return x.charCodeAt(0)})}},{}],4:[function(require,module,exports){var Crypto=module.exports={};var util=Crypto.util={randomBytes:function(n){for(var bytes=[];n>0;n--)bytes.push(Math.floor(Math.random()*256));return bytes}};Crypto.mode={};var charenc=Crypto.charenc={};var UTF8=charenc.UTF8={stringToBytes:function(str){return Binary.stringToBytes(unescape(encodeURIComponent(str)))},bytesToString:function(bytes){return decodeURIComponent(escape(Binary.bytesToString(bytes)))}};var Binary=charenc.Binary={stringToBytes:function(str){for(var bytes=[],i=0;i>>5]|=bytes[i]<<24-b%32}return words};var wordsToBytes=function(words){var bytes=[];for(var b=0;b>>5]>>>24-b%32&255)}return bytes};var processBlock=function(H,M,offset){for(var i=0;i<16;i++){var offset_i=offset+i;var M_offset_i=M[offset_i];M[offset_i]=(M_offset_i<<8|M_offset_i>>>24)&16711935|(M_offset_i<<24|M_offset_i>>>8)&4278255360}var al,bl,cl,dl,el;var ar,br,cr,dr,er;ar=al=H[0];br=bl=H[1];cr=cl=H[2];dr=dl=H[3];er=el=H[4];var t;for(var i=0;i<80;i+=1){t=al+M[offset+zl[i]]|0;if(i<16){t+=f1(bl,cl,dl)+hl[0]}else if(i<32){t+=f2(bl,cl,dl)+hl[1]}else if(i<48){t+=f3(bl,cl,dl)+hl[2]}else if(i<64){t+=f4(bl,cl,dl)+hl[3]}else{t+=f5(bl,cl,dl)+hl[4]}t=t|0;t=rotl(t,sl[i]);t=t+el|0;al=el;el=dl;dl=rotl(cl,10);cl=bl;bl=t;t=ar+M[offset+zr[i]]|0;if(i<16){t+=f5(br,cr,dr)+hr[0]}else if(i<32){t+=f4(br,cr,dr)+hr[1]}else if(i<48){t+=f3(br,cr,dr)+hr[2]}else if(i<64){t+=f2(br,cr,dr)+hr[3]}else{t+=f1(br,cr,dr)+hr[4]}t=t|0;t=rotl(t,sr[i]);t=t+er|0;ar=er;er=dr;dr=rotl(cr,10);cr=br;br=t}t=H[1]+cl+dr|0;H[1]=H[2]+dl+er|0;H[2]=H[3]+el+ar|0;H[3]=H[4]+al+br|0;H[4]=H[0]+bl+cr|0;H[0]=t};function f1(x,y,z){return x^y^z}function f2(x,y,z){return x&y|~x&z}function f3(x,y,z){return(x|~y)^z}function f4(x,y,z){return x&z|y&~z}function f5(x,y,z){return x^(y|~z)}function rotl(x,n){return x<>>32-n}module.exports=function(message,options){if(message.constructor===String){message=UTF8.stringToBytes(message)}var H=[1732584193,4023233417,2562383102,271733878,3285377520];var m=bytesToWords(message);var nBitsLeft=message.length*8;var nBitsTotal=message.length*8;m[nBitsLeft>>>5]|=128<<24-nBitsLeft%32;m[(nBitsLeft+64>>>9<<4)+14]=(nBitsTotal<<8|nBitsTotal>>>24)&16711935|(nBitsTotal<<24|nBitsTotal>>>8)&4278255360;for(var i=0;i>>24)&16711935|(H_i<<24|H_i>>>8)&4278255360}var digestbytes=wordsToBytes(H);return options&&options.asBytes?digestbytes:options&&options.asString?Binary.bytesToString(digestbytes):conv.bytesToHex(digestbytes)}},{"../convert":3,"./crypto":4}],6:[function(require,module,exports){var conv=require("../convert");var UTF8=require("./crypto").charenc.UTF8;var K=[];(function(){function isPrime(n){var sqrtN=Math.sqrt(n);for(var factor=2;factor<=sqrtN;factor++){if(!(n%factor)){return false}}return true}function getFractionalBits(n){return(n-(n|0))*4294967296|0}var n=2;var nPrime=0;while(nPrime<64){if(isPrime(n)){K[nPrime]=getFractionalBits(Math.pow(n,1/3));nPrime++}n++}})();var bytesToWords=function(bytes){var words=[];for(var i=0,b=0;i>>5]|=bytes[i]<<24-b%32}return words};var wordsToBytes=function(words){var bytes=[];for(var b=0;b>>5]>>>24-b%32&255)}return bytes};var W=[];var processBlock=function(H,M,offset){var a=H[0];var b=H[1];var c=H[2];var d=H[3];var e=H[4];var f=H[5];var g=H[6];var h=H[7];for(var i=0;i<64;i++){if(i<16){W[i]=M[offset+i]|0}else{var gamma0x=W[i-15];var gamma0=(gamma0x<<25|gamma0x>>>7)^(gamma0x<<14|gamma0x>>>18)^gamma0x>>>3;var gamma1x=W[i-2];var gamma1=(gamma1x<<15|gamma1x>>>17)^(gamma1x<<13|gamma1x>>>19)^gamma1x>>>10;W[i]=gamma0+W[i-7]+gamma1+W[i-16]}var ch=e&f^~e&g;var maj=a&b^a&c^b&c;var sigma0=(a<<30|a>>>2)^(a<<19|a>>>13)^(a<<10|a>>>22);var sigma1=(e<<26|e>>>6)^(e<<21|e>>>11)^(e<<7|e>>>25);var t1=h+sigma1+ch+K[i]+W[i];var t2=sigma0+maj;h=g;g=f;f=e;e=d+t1|0;d=c;c=b;b=a;a=t1+t2|0}H[0]=H[0]+a|0;H[1]=H[1]+b|0;H[2]=H[2]+c|0;H[3]=H[3]+d|0;H[4]=H[4]+e|0;H[5]=H[5]+f|0;H[6]=H[6]+g|0;H[7]=H[7]+h|0};module.exports=function(message,options){var H=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];if(message.constructor===String){message=UTF8.stringToBytes(message)}var m=bytesToWords(message);var l=message.length*8;m[l>>5]|=128<<24-l%32;m[(l+64>>9<<4)+15]=l;for(var i=0;i=0;--i){R=R.twice2D();R.z=BigInteger.ONE;if(k.testBit(i)){if(l.testBit(i)){R=R.add2D(Z)}else{R=R.add2D(P)}}else{if(l.testBit(i)){R=R.add2D(Q)}}}return R}var ECDSA={getBigRandom:function(limit){return new BigInteger(limit.bitLength(),rng).mod(limit.subtract(BigInteger.ONE)).add(BigInteger.ONE)},sign:function(hash,priv){var d=priv;var n=ecparams.getN();var e=BigInteger.fromByteArrayUnsigned(hash);do{var k=ECDSA.getBigRandom(n);var G=ecparams.getG();var Q=G.multiply(k);var r=Q.getX().toBigInteger().mod(n)}while(r.compareTo(BigInteger.ZERO)<=0);var s=k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);return ECDSA.serializeSig(r,s)},verify:function(hash,sig,pubkey){var r,s;if(util.isArray(sig)){var obj=ECDSA.parseSig(sig);r=obj.r;s=obj.s}else if("object"===typeof sig&&sig.r&&sig.s){r=sig.r;s=sig.s}else{throw new Error("Invalid value for signature")}var Q;if(pubkey instanceof ECPointFp){Q=pubkey}else if(util.isArray(pubkey)){Q=ECPointFp.decodeFrom(ecparams.getCurve(),pubkey)}else{throw new Error("Invalid format for pubkey value, must be byte array or ECPointFp")}var e=BigInteger.fromByteArrayUnsigned(hash);return ECDSA.verifyRaw(e,r,s,Q)},verifyRaw:function(e,r,s,Q){var n=ecparams.getN();var G=ecparams.getG();if(r.compareTo(BigInteger.ONE)<0||r.compareTo(n)>=0)return false;if(s.compareTo(BigInteger.ONE)<0||s.compareTo(n)>=0)return false;var c=s.modInverse(n);var u1=e.multiply(c).mod(n);var u2=r.multiply(c).mod(n);var point=G.multiply(u1).add(Q.multiply(u2));var v=point.getX().toBigInteger().mod(n);return v.equals(r)},serializeSig:function(r,s){var rBa=r.toByteArraySigned();var sBa=s.toByteArraySigned();var sequence=[];sequence.push(2);sequence.push(rBa.length);sequence=sequence.concat(rBa);sequence.push(2);sequence.push(sBa.length);sequence=sequence.concat(sBa);sequence.unshift(sequence.length);sequence.unshift(48);return sequence},parseSig:function(sig){var cursor;if(sig[0]!=48)throw new Error("Signature not a valid DERSequence");cursor=2;if(sig[cursor]!=2)throw new Error("First element in signature must be a DERInteger");var rBa=sig.slice(cursor+2,cursor+2+sig[cursor+1]);cursor+=2+sig[cursor+1];if(sig[cursor]!=2)throw new Error("Second element in signature must be a DERInteger");var sBa=sig.slice(cursor+2,cursor+2+sig[cursor+1]);cursor+=2+sig[cursor+1];var r=BigInteger.fromByteArrayUnsigned(rBa);var s=BigInteger.fromByteArrayUnsigned(sBa);return{r:r,s:s}},parseSigCompact:function(sig){if(sig.length!==65){throw new Error("Signature has the wrong length")}var i=sig[0]-27;if(i<0||i>7){throw new Error("Invalid signature type")}var n=ecparams.getN();var r=BigInteger.fromByteArrayUnsigned(sig.slice(1,33)).mod(n);var s=BigInteger.fromByteArrayUnsigned(sig.slice(33,65)).mod(n);return{r:r,s:s,i:i}},recoverPubKey:function(r,s,hash,i){i=i&3;var isYEven=i&1;var isSecondKey=i>>1;var n=ecparams.getN();var G=ecparams.getG();var curve=ecparams.getCurve();var p=curve.getQ();var a=curve.getA().toBigInteger();var b=curve.getB().toBigInteger();if(!P_OVER_FOUR){P_OVER_FOUR=p.add(BigInteger.ONE).divide(BigInteger.valueOf(4))}var x=isSecondKey?r.add(n):r;var alpha=x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(p);var beta=alpha.modPow(P_OVER_FOUR,p);var xorOdd=beta.isEven()?i%2:(i+1)%2;var y=(beta.isEven()?!isYEven:isYEven)?beta:p.subtract(beta);var R=new ECPointFp(curve,curve.fromBigInteger(x),curve.fromBigInteger(y));R.validate();var e=BigInteger.fromByteArrayUnsigned(hash);var eNeg=BigInteger.ZERO.subtract(e).mod(n);var rInv=r.modInverse(n);var Q=implShamirsTrick(R,s,G,eNeg).multiply(rInv);Q.validate();if(!ECDSA.verifyRaw(e,r,s,Q)){throw new Error("Pubkey recovery unsuccessful")}var ECKey=require("./eckey");var pubKey=ECKey();pubKey.pub=Q;return pubKey},calcPubkeyRecoveryParam:function(address,r,s,hash){for(var i=0;i<4;i++){var pubkey=ECDSA.recoverPubKey(r,s,hash,i);if(pubkey.getBitcoinAddress().toString()==address){return i}}throw new Error("Unable to find valid recovery factor")}};module.exports=ECDSA},{"./eckey":8,"./jsbn/ec":10,"./jsbn/jsbn":11,"./jsbn/rng":13,"./jsbn/sec":14,"./util":19}],8:[function(require,module,exports){var BigInteger=require("./jsbn/jsbn");var sec=require("./jsbn/sec");var base58=require("./base58");var Crypto=require("./crypto-js/crypto");var util=require("./util");var conv=require("./convert");var Address=require("./address");var ecdsa=require("./ecdsa");var ecparams=sec("secp256k1");var ECKey=function(input){if(!(this instanceof ECKey)){return new ECKey(input)}this.compressed=!!ECKey.compressByDefault;if(!input){var n=ecparams.getN();this.priv=ecdsa.getBigRandom(n)}else if(input instanceof ECKey){this.priv=input.priv}else if(input instanceof BigInteger){this.priv=input}else if(util.isArray(input)){this.priv=BigInteger.fromByteArrayUnsigned(input);this.compressed=false}else if("string"==typeof input){if(input.length==51&&input[0]=="5"){this.priv=BigInteger.fromByteArrayUnsigned(ECKey.decodeString(input));this.compressed=false}else if(input.length==52&&(input[0]==="K"||input[0]==="L")){this.priv=BigInteger.fromByteArrayUnsigned(ECKey.decodeString(input));this.compressed=true}else{this.priv=BigInteger.fromByteArrayUnsigned(conv.hexToBytes(input))}}else if(input.constructor==[].constructor){this.priv=BigInteger.fromByteArrayUnsigned(input)}};ECKey.compressByDefault=false;ECKey.prototype.setCompressed=function(v){this.compressed=!!v};ECKey.prototype.getPub=function(){return this.getPubPoint().getEncoded(this.compressed)};ECKey.prototype.getPubPoint=function(){if(!this.pub)this.pub=ecparams.getG().multiply(this.priv);return this.pub};ECKey.prototype.getPubKeyHash=function(){if(this.pubKeyHash)return this.pubKeyHash;return this.pubKeyHash=util.sha256ripe160(this.getPub())};ECKey.prototype.getBitcoinAddress=function(){var hash=this.getPubKeyHash();var addr=new Address(hash);return addr};ECKey.prototype.getExportedPrivateKey=function(){var hash=this.priv.toByteArrayUnsigned();while(hash.length<32)hash.unshift(0);hash.unshift(128);var checksum=Crypto.SHA256(Crypto.SHA256(hash,{asBytes:true}),{asBytes:true});var bytes=hash.concat(checksum.slice(0,4));return base58.encode(bytes)};ECKey.prototype.setPub=function(pub){this.pub=ECPointFp.decodeFrom(ecparams.getCurve(),pub)};ECKey.prototype.toString=function(format){if(format==="base58"){return base58.checkEncode(this.priv.toByteArrayUnsigned(),128)}else{return conv.bytesToHex(this.priv.toByteArrayUnsigned())}};ECKey.prototype.sign=function(hash){return ecdsa.sign(hash,this.priv)};ECKey.prototype.verify=function(hash,sig){return ecdsa.verify(hash,sig,this.getPub())};ECKey.decodeString=function(string){var bytes=base58.decode(string);if(bytes.length!==37&&bytes.length!==38){throw new Error("not a valid base58 encoded private key")}if(bytes[33]===1){}var hash=bytes.slice(0,33);var version=hash.shift();if(version!=128){throw"Version "+version+" not supported!"}return hash};module.exports=ECKey},{"./address":1,"./base58":2,"./convert":3,"./crypto-js/crypto":4,"./ecdsa":7,"./jsbn/jsbn":11,"./jsbn/sec":14,"./util":19}],9:[function(require,module,exports){var rotl=function(n,b){return n<>>32-b};var rotr=function(n,b){return n<<32-b|n>>>b};var endian=function(n){if(n.constructor==Number){return rotl(n,8)&16711935|rotl(n,24)&4278255360}for(var i=0;i0;--i){R=R.twice();var hBit=h.testBit(i);var eBit=e.testBit(i);if(hBit!=eBit){R=R.add(hBit?this:neg)}}return R}function pointFpMultiplyTwo(j,x,k){var i;if(j.bitLength()>k.bitLength())i=j.bitLength()-1;else i=k.bitLength()-1;var R=this.curve.getInfinity();var both=this.add(x);while(i>=0){R=R.twice();if(j.testBit(i)){if(k.testBit(i)){R=R.add(both)}else{R=R.add(this)}}else{if(k.testBit(i)){R=R.add(x)}}--i}return R}ECPointFp.prototype.getX=pointFpGetX;ECPointFp.prototype.getY=pointFpGetY;ECPointFp.prototype.equals=pointFpEquals;ECPointFp.prototype.isInfinity=pointFpIsInfinity;ECPointFp.prototype.negate=pointFpNegate;ECPointFp.prototype.add=pointFpAdd;ECPointFp.prototype.twice=pointFpTwice;ECPointFp.prototype.multiply=pointFpMultiply;ECPointFp.prototype.multiplyTwo=pointFpMultiplyTwo;function ECCurveFp(q,a,b){this.q=q;this.a=this.fromBigInteger(a);this.b=this.fromBigInteger(b);this.infinity=new ECPointFp(this,null,null)}function curveFpGetQ(){return this.q}function curveFpGetA(){return this.a}function curveFpGetB(){return this.b}function curveFpEquals(other){if(other==this)return true;return this.q.equals(other.q)&&this.a.equals(other.a)&&this.b.equals(other.b)}function curveFpGetInfinity(){return this.infinity}function curveFpFromBigInteger(x){return new ECFieldElementFp(this.q,x)}function curveFpDecodePointHex(s){switch(parseInt(s.substr(0,2),16)){case 0:return this.infinity;case 2:case 3:return null;case 4:case 6:case 7:var len=(s.length-2)/2;var xHex=s.substr(2,len);var yHex=s.substr(len+2,len);return new ECPointFp(this,this.fromBigInteger(new BigInteger(xHex,16)),this.fromBigInteger(new BigInteger(yHex,16)));default:return null}}ECCurveFp.prototype.getQ=curveFpGetQ;ECCurveFp.prototype.getA=curveFpGetA;ECCurveFp.prototype.getB=curveFpGetB;ECCurveFp.prototype.equals=curveFpEquals;ECCurveFp.prototype.getInfinity=curveFpGetInfinity;ECCurveFp.prototype.fromBigInteger=curveFpFromBigInteger;ECCurveFp.prototype.decodePointHex=curveFpDecodePointHex;function integerToBytes(i,len){var bytes=i.toByteArrayUnsigned();if(lenbytes.length){bytes.unshift(0)}return bytes}ECFieldElementFp.prototype.getByteLength=function(){return Math.floor((this.toBigInteger().bitLength()+7)/8)};ECPointFp.prototype.getEncoded=function(compressed){var x=this.getX().toBigInteger();var y=this.getY().toBigInteger();var enc=integerToBytes(x,32);if(compressed){if(y.isEven()){enc.unshift(2)}else{enc.unshift(3)}}else{enc.unshift(4);enc=enc.concat(integerToBytes(y,32))}return enc};ECPointFp.decodeFrom=function(curve,enc){var type=enc[0];var dataLen=enc.length-1;var xBa=enc.slice(1,1+dataLen/2);var yBa=enc.slice(1+dataLen/2,1+dataLen);xBa.unshift(0);yBa.unshift(0);var x=new BigInteger(xBa);var y=new BigInteger(yBa);return new ECPointFp(curve,curve.fromBigInteger(x),curve.fromBigInteger(y))};ECPointFp.prototype.add2D=function(b){if(this.isInfinity())return b;if(b.isInfinity())return this;if(this.x.equals(b.x)){if(this.y.equals(b.y)){return this.twice()}return this.curve.getInfinity()}var x_x=b.x.subtract(this.x);var y_y=b.y.subtract(this.y);var gamma=y_y.divide(x_x);var x3=gamma.square().subtract(this.x).subtract(b.x);var y3=gamma.multiply(this.x.subtract(x3)).subtract(this.y);return new ECPointFp(this.curve,x3,y3)};ECPointFp.prototype.twice2D=function(){if(this.isInfinity())return this;if(this.y.toBigInteger().signum()==0){return this.curve.getInfinity()}var TWO=this.curve.fromBigInteger(BigInteger.valueOf(2));var THREE=this.curve.fromBigInteger(BigInteger.valueOf(3));var gamma=this.x.square().multiply(THREE).add(this.curve.a).divide(this.y.multiply(TWO));var x3=gamma.square().subtract(this.x.multiply(TWO));var y3=gamma.multiply(this.x.subtract(x3)).subtract(this.y);return new ECPointFp(this.curve,x3,y3)};ECPointFp.prototype.multiply2D=function(k){if(this.isInfinity())return this;if(k.signum()==0)return this.curve.getInfinity();var e=k;var h=e.multiply(new BigInteger("3"));var neg=this.negate();var R=this;var i;for(i=h.bitLength()-2;i>0;--i){R=R.twice();var hBit=h.testBit(i);var eBit=e.testBit(i);if(hBit!=eBit){R=R.add2D(hBit?this:neg)}}return R};ECPointFp.prototype.isOnCurve=function(){var x=this.getX().toBigInteger();var y=this.getY().toBigInteger();var a=this.curve.getA().toBigInteger();var b=this.curve.getB().toBigInteger();var n=this.curve.getQ();var lhs=y.multiply(y).mod(n);var rhs=x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(n);return lhs.equals(rhs)};ECPointFp.prototype.toString=function(){return"("+this.getX().toBigInteger().toString()+","+this.getY().toBigInteger().toString()+")"};ECPointFp.prototype.validate=function(){var n=this.curve.getQ();if(this.isInfinity()){throw new Error("Point is at infinity.")}var x=this.getX().toBigInteger();var y=this.getY().toBigInteger();if(x.compareTo(BigInteger.ONE)<0||x.compareTo(n.subtract(BigInteger.ONE))>0){throw new Error("x coordinate out of bounds")}if(y.compareTo(BigInteger.ONE)<0||y.compareTo(n.subtract(BigInteger.ONE))>0){throw new Error("y coordinate out of bounds")}if(!this.isOnCurve()){throw new Error("Point is not on the curve.")}if(this.multiply(n).isInfinity()){throw new Error("Point is not a scalar multiple of G.")}return true};module.exports=ECCurveFp;module.exports.ECPointFp=ECPointFp},{"./jsbn":11}],11:[function(require,module,exports){var dbits;var canary=0xdeadbeefcafe;var j_lm=(canary&16777215)==15715070;function BigInteger(a,b,c){if(!(this instanceof BigInteger)){return new BigInteger(a,b,c)}if(a!=null){if("number"==typeof a)this.fromNumber(a,b,c);else if(b==null&&"string"!=typeof a)this.fromString(a,256);else this.fromString(a,b)}}var proto=BigInteger.prototype;function nbi(){return new BigInteger(null)}function am1(i,x,w,j,c,n){while(--n>=0){var v=x*this[i++]+w[j]+c;c=Math.floor(v/67108864);w[j++]=v&67108863}return c}function am2(i,x,w,j,c,n){var xl=x&32767,xh=x>>15;while(--n>=0){var l=this[i]&32767;var h=this[i++]>>15;var m=xh*l+h*xl;l=xl*l+((m&32767)<<15)+w[j]+(c&1073741823);c=(l>>>30)+(m>>>15)+xh*h+(c>>>30);w[j++]=l&1073741823}return c}function am3(i,x,w,j,c,n){var xl=x&16383,xh=x>>14;while(--n>=0){var l=this[i]&16383;var h=this[i++]>>14;var m=xh*l+h*xl;l=xl*l+((m&16383)<<14)+w[j]+c;c=(l>>28)+(m>>14)+xh*h;w[j++]=l&268435455}return c}BigInteger.prototype.am=am1;dbits=26;BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=(1<=0;--i)r[i]=this[i];r.t=this.t;r.s=this.s}function bnpFromInt(x){this.t=1;this.s=x<0?-1:0;if(x>0)this[0]=x;else if(x<-1)this[0]=x+DV;else this.t=0}function nbv(i){var r=nbi();r.fromInt(i);return r}function bnpFromString(s,b){var self=this;var k;if(b==16)k=4; -else if(b==8)k=3;else if(b==256)k=8;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else{self.fromRadix(s,b);return}self.t=0;self.s=0;var i=s.length,mi=false,sh=0;while(--i>=0){var x=k==8?s[i]&255:intAt(s,i);if(x<0){if(s.charAt(i)=="-")mi=true;continue}mi=false;if(sh==0)self[self.t++]=x;else if(sh+k>self.DB){self[self.t-1]|=(x&(1<>self.DB-sh}else self[self.t-1]|=x<=self.DB)sh-=self.DB}if(k==8&&(s[0]&128)!=0){self.s=-1;if(sh>0)self[self.t-1]|=(1<0&&this[this.t-1]==c)--this.t}function bnToString(b){var self=this;if(self.s<0)return"-"+self.negate().toString(b);var k;if(b==16)k=4;else if(b==8)k=3;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else return self.toRadix(b);var km=(1<0){if(p>p)>0){m=true;r=int2char(d)}while(i>=0){if(p>(p+=self.DB-k)}else{d=self[i]>>(p-=k)&km;if(p<=0){p+=self.DB;--i}}if(d>0)m=true;if(m)r+=int2char(d)}}return m?r:"0"}function bnNegate(){var r=nbi();BigInteger.ZERO.subTo(this,r);return r}function bnAbs(){return this.s<0?this.negate():this}function bnCompareTo(a){var r=this.s-a.s;if(r!=0)return r;var i=this.t;r=i-a.t;if(r!=0)return this.s<0?-r:r;while(--i>=0)if((r=this[i]-a[i])!=0)return r;return 0}function nbits(x){var r=1,t;if((t=x>>>16)!=0){x=t;r+=16}if((t=x>>8)!=0){x=t;r+=8}if((t=x>>4)!=0){x=t;r+=4}if((t=x>>2)!=0){x=t;r+=2}if((t=x>>1)!=0){x=t;r+=1}return r}function bnBitLength(){if(this.t<=0)return 0;return this.DB*(this.t-1)+nbits(this[this.t-1]^this.s&this.DM)}function bnpDLShiftTo(n,r){var i;for(i=this.t-1;i>=0;--i)r[i+n]=this[i];for(i=n-1;i>=0;--i)r[i]=0;r.t=this.t+n;r.s=this.s}function bnpDRShiftTo(n,r){for(var i=n;i=0;--i){r[i+ds+1]=self[i]>>cbs|c;c=(self[i]&bm)<=0;--i)r[i]=0;r[ds]=c;r.t=self.t+ds+1;r.s=self.s;r.clamp()}function bnpRShiftTo(n,r){var self=this;r.s=self.s;var ds=Math.floor(n/self.DB);if(ds>=self.t){r.t=0;return}var bs=n%self.DB;var cbs=self.DB-bs;var bm=(1<>bs;for(var i=ds+1;i>bs}if(bs>0)r[self.t-ds-1]|=(self.s&bm)<>=self.DB}if(a.t>=self.DB}c+=self.s}else{c+=self.s;while(i>=self.DB}c-=a.s}r.s=c<0?-1:0;if(c<-1)r[i++]=self.DV+c;else if(c>0)r[i++]=c;r.t=i;r.clamp()}function bnpMultiplyTo(a,r){var x=this.abs(),y=a.abs();var i=x.t;r.t=i+y.t;while(--i>=0)r[i]=0;for(i=0;i=0)r[i]=0;for(i=0;i=x.DV){r[i+x.t]-=x.DV;r[i+x.t+1]=1}}if(r.t>0)r[r.t-1]+=x.am(i,x[i],r,2*i,0,1);r.s=0;r.clamp()}function bnpDivRemTo(m,q,r){var self=this;var pm=m.abs();if(pm.t<=0)return;var pt=self.abs();if(pt.t0){pm.lShiftTo(nsh,y);pt.lShiftTo(nsh,r)}else{pm.copyTo(y);pt.copyTo(r)}var ys=y.t;var y0=y[ys-1];if(y0==0)return;var yt=y0*(1<1?y[ys-2]>>self.F2:0);var d1=self.FV/yt,d2=(1<=0){r[r.t++]=1;r.subTo(t,r)}BigInteger.ONE.dlShiftTo(ys,t);t.subTo(y,y);while(y.t=0){var qd=r[--i]==y0?self.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);if((r[i]+=y.am(0,qd,r,j,0,ys))0)r.rShiftTo(nsh,r);if(ts<0)BigInteger.ZERO.subTo(r,r)}function bnMod(a){var r=nbi();this.abs().divRemTo(a,null,r);if(this.s<0&&r.compareTo(BigInteger.ZERO)>0)a.subTo(r,r);return r}function Classic(m){this.m=m}function cConvert(x){if(x.s<0||x.compareTo(this.m)>=0)return x.mod(this.m);else return x}function cRevert(x){return x}function cReduce(x){x.divRemTo(this.m,null,x)}function cMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}function cSqrTo(x,r){x.squareTo(r);this.reduce(r)}Classic.prototype.convert=cConvert;Classic.prototype.revert=cRevert;Classic.prototype.reduce=cReduce;Classic.prototype.mulTo=cMulTo;Classic.prototype.sqrTo=cSqrTo;function bnpInvDigit(){if(this.t<1)return 0;var x=this[0];if((x&1)==0)return 0;var y=x&3;y=y*(2-(x&15)*y)&15;y=y*(2-(x&255)*y)&255;y=y*(2-((x&65535)*y&65535))&65535;y=y*(2-x*y%this.DV)%this.DV;return y>0?this.DV-y:-y}function Montgomery(m){this.m=m;this.mp=m.invDigit();this.mpl=this.mp&32767;this.mph=this.mp>>15;this.um=(1<0)this.m.subTo(r,r);return r}function montRevert(x){var r=nbi();x.copyTo(r);this.reduce(r);return r}function montReduce(x){while(x.t<=this.mt2)x[x.t++]=0;for(var i=0;i>15)*this.mpl&this.um)<<15)&x.DM;j=i+this.m.t;x[j]+=this.m.am(0,u0,x,i,0,this.m.t);while(x[j]>=x.DV){x[j]-=x.DV;x[++j]++}}x.clamp();x.drShiftTo(this.m.t,x);if(x.compareTo(this.m)>=0)x.subTo(this.m,x)}function montSqrTo(x,r){x.squareTo(r);this.reduce(r)}function montMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}Montgomery.prototype.convert=montConvert;Montgomery.prototype.revert=montRevert;Montgomery.prototype.reduce=montReduce;Montgomery.prototype.mulTo=montMulTo;Montgomery.prototype.sqrTo=montSqrTo;function bnpIsEven(){return(this.t>0?this[0]&1:this.s)==0}function bnpExp(e,z){if(e>4294967295||e<1)return BigInteger.ONE;var r=nbi(),r2=nbi(),g=z.convert(this),i=nbits(e)-1;g.copyTo(r);while(--i>=0){z.sqrTo(r,r2);if((e&1<0)z.mulTo(r2,g,r);else{var t=r;r=r2;r2=t}}return z.revert(r)}function bnModPowInt(e,m){var z;if(e<256||m.isEven())z=new Classic(m);else z=new Montgomery(m);return this.exp(e,z)}proto.copyTo=bnpCopyTo;proto.fromInt=bnpFromInt;proto.fromString=bnpFromString;proto.clamp=bnpClamp;proto.dlShiftTo=bnpDLShiftTo;proto.drShiftTo=bnpDRShiftTo;proto.lShiftTo=bnpLShiftTo;proto.rShiftTo=bnpRShiftTo;proto.subTo=bnpSubTo;proto.multiplyTo=bnpMultiplyTo;proto.squareTo=bnpSquareTo;proto.divRemTo=bnpDivRemTo;proto.invDigit=bnpInvDigit;proto.isEven=bnpIsEven;proto.exp=bnpExp;proto.toString=bnToString;proto.negate=bnNegate;proto.abs=bnAbs;proto.compareTo=bnCompareTo;proto.bitLength=bnBitLength;proto.mod=bnMod;proto.modPowInt=bnModPowInt;function nbi(){return new BigInteger(null)}function bnClone(){var r=nbi();this.copyTo(r);return r}function bnIntValue(){if(this.s<0){if(this.t==1)return this[0]-this.DV;else if(this.t==0)return-1}else if(this.t==1)return this[0];else if(this.t==0)return 0;return(this[1]&(1<<32-this.DB)-1)<>24}function bnShortValue(){return this.t==0?this.s:this[0]<<16>>16}function bnpChunkSize(r){return Math.floor(Math.LN2*this.DB/Math.log(r))}function bnSigNum(){if(this.s<0)return-1;else if(this.t<=0||this.t==1&&this[0]<=0)return 0;else return 1}function bnpToRadix(b){if(b==null)b=10;if(this.signum()==0||b<2||b>36)return"0";var cs=this.chunkSize(b);var a=Math.pow(b,cs);var d=nbv(a),y=nbi(),z=nbi(),r="";this.divRemTo(d,y,z);while(y.signum()>0){r=(a+z.intValue()).toString(b).substr(1)+r;y.divRemTo(d,y,z)}return z.intValue().toString(b)+r}function bnpFromRadix(s,b){var self=this;self.fromInt(0);if(b==null)b=10;var cs=self.chunkSize(b);var d=Math.pow(b,cs),mi=false,j=0,w=0;for(var i=0;i=cs){self.dMultiply(d);self.dAddOffset(w,0);j=0;w=0}}if(j>0){self.dMultiply(Math.pow(b,j));self.dAddOffset(w,0)}if(mi)BigInteger.ZERO.subTo(self,self)}function bnpFromNumber(a,b,c){var self=this;if("number"==typeof b){if(a<2)self.fromInt(1);else{self.fromNumber(a,c);if(!self.testBit(a-1))self.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,self);if(self.isEven())self.dAddOffset(1,0);while(!self.isProbablePrime(b)){self.dAddOffset(2,0);if(self.bitLength()>a)self.subTo(BigInteger.ONE.shiftLeft(a-1),self)}}}else{var x=new Array,t=a&7;x.length=(a>>3)+1;b.nextBytes(x);if(t>0)x[0]&=(1<0){if(p>p)!=(self.s&self.DM)>>p)r[k++]=d|self.s<=0){if(p<8){d=(self[i]&(1<>(p+=self.DB-8)}else{d=self[i]>>(p-=8)&255;if(p<=0){p+=self.DB;--i}}if((d&128)!=0)d|=-256;if(k===0&&(self.s&128)!=(d&128))++k;if(k>0||d!=self.s)r[k++]=d}}return r}function bnEquals(a){return this.compareTo(a)==0}function bnMin(a){return this.compareTo(a)<0?this:a}function bnMax(a){return this.compareTo(a)>0?this:a}function bnpBitwiseTo(a,op,r){var self=this;var i,f,m=Math.min(a.t,self.t);for(i=0;i>=16;r+=16}if((x&255)==0){x>>=8;r+=8}if((x&15)==0){x>>=4;r+=4}if((x&3)==0){x>>=2;r+=2}if((x&1)==0)++r;return r}function bnGetLowestSetBit(){for(var i=0;i=this.t)return this.s!=0;return(this[j]&1<>=self.DB}if(a.t>=self.DB}c+=self.s}else{c+=self.s;while(i>=self.DB}c+=a.s}r.s=c<0?-1:0;if(c>0)r[i++]=c;else if(c<-1)r[i++]=self.DV+c;r.t=i;r.clamp()}function bnAdd(a){var r=nbi();this.addTo(a,r);return r}function bnSubtract(a){var r=nbi();this.subTo(a,r);return r}function bnMultiply(a){var r=nbi();this.multiplyTo(a,r);return r}function bnSquare(){var r=nbi();this.squareTo(r);return r}function bnDivide(a){var r=nbi();this.divRemTo(a,r,null);return r}function bnRemainder(a){var r=nbi();this.divRemTo(a,null,r);return r}function bnDivideAndRemainder(a){var q=nbi(),r=nbi();this.divRemTo(a,q,r);return new Array(q,r)}function bnpDMultiply(n){this[this.t]=this.am(0,n-1,this,0,0,this.t);++this.t;this.clamp()}function bnpDAddOffset(n,w){if(n==0)return;while(this.t<=w)this[this.t++]=0;this[w]+=n;while(this[w]>=this.DV){this[w]-=this.DV;if(++w>=this.t)this[this.t++]=0;++this[w]}}function NullExp(){}function nNop(x){return x}function nMulTo(x,y,r){x.multiplyTo(y,r)}function nSqrTo(x,r){x.squareTo(r)}NullExp.prototype.convert=nNop;NullExp.prototype.revert=nNop;NullExp.prototype.mulTo=nMulTo;NullExp.prototype.sqrTo=nSqrTo;function bnPow(e){return this.exp(e,new NullExp)}function bnpMultiplyLowerTo(a,n,r){var i=Math.min(this.t+a.t,n);r.s=0;r.t=i;while(i>0)r[--i]=0;var j;for(j=r.t-this.t;i=0)r[i]=0;for(i=Math.max(n-this.t,0);i2*this.m.t)return x.mod(this.m);else if(x.compareTo(this.m)<0)return x;else{var r=nbi();x.copyTo(r);this.reduce(r);return r}}function barrettRevert(x){return x}function barrettReduce(x){var self=this;x.drShiftTo(self.m.t-1,self.r2);if(x.t>self.m.t+1){x.t=self.m.t+1;x.clamp()}self.mu.multiplyUpperTo(self.r2,self.m.t+1,self.q3);self.m.multiplyLowerTo(self.q3,self.m.t+1,self.r2);while(x.compareTo(self.r2)<0)x.dAddOffset(1,self.m.t+1);x.subTo(self.r2,x);while(x.compareTo(self.m)>=0)x.subTo(self.m,x)}function barrettSqrTo(x,r){x.squareTo(r);this.reduce(r)}function barrettMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}Barrett.prototype.convert=barrettConvert;Barrett.prototype.revert=barrettRevert;Barrett.prototype.reduce=barrettReduce;Barrett.prototype.mulTo=barrettMulTo;Barrett.prototype.sqrTo=barrettSqrTo;function bnModPow(e,m){var i=e.bitLength(),k,r=nbv(1),z;if(i<=0)return r;else if(i<18)k=1;else if(i<48)k=3;else if(i<144)k=4;else if(i<768)k=5;else k=6;if(i<8)z=new Classic(m);else if(m.isEven())z=new Barrett(m);else z=new Montgomery(m);var g=new Array,n=3,k1=k-1,km=(1<1){var g2=nbi();z.sqrTo(g[1],g2);while(n<=km){g[n]=nbi();z.mulTo(g2,g[n-2],g[n]);n+=2}}var j=e.t-1,w,is1=true,r2=nbi(),t;i=nbits(e[j])-1;while(j>=0){if(i>=k1)w=e[j]>>i-k1&km;else{w=(e[j]&(1<0)w|=e[j-1]>>this.DB+i-k1}n=k;while((w&1)==0){w>>=1;--n}if((i-=n)<0){i+=this.DB;--j}if(is1){g[w].copyTo(r);is1=false}else{while(n>1){z.sqrTo(r,r2);z.sqrTo(r2,r);n-=2}if(n>0)z.sqrTo(r,r2);else{t=r;r=r2;r2=t}z.mulTo(r2,g[w],r)}while(j>=0&&(e[j]&1<0){x.rShiftTo(g,x);y.rShiftTo(g,y)}while(x.signum()>0){if((i=x.getLowestSetBit())>0)x.rShiftTo(i,x);if((i=y.getLowestSetBit())>0)y.rShiftTo(i,y);if(x.compareTo(y)>=0){x.subTo(y,x);x.rShiftTo(1,x)}else{y.subTo(x,y);y.rShiftTo(1,y)}}if(g>0)y.lShiftTo(g,y);return y}function bnpModInt(n){if(n<=0)return 0;var d=this.DV%n,r=this.s<0?n-1:0;if(this.t>0)if(d==0)r=this[0]%n;else for(var i=this.t-1;i>=0;--i)r=(d*r+this[i])%n;return r}function bnModInverse(m){var ac=m.isEven();if(this.isEven()&&ac||m.signum()==0)return BigInteger.ZERO;var u=m.clone(),v=this.clone();var a=nbv(1),b=nbv(0),c=nbv(0),d=nbv(1);while(u.signum()!=0){while(u.isEven()){u.rShiftTo(1,u);if(ac){if(!a.isEven()||!b.isEven()){a.addTo(this,a);b.subTo(m,b)}a.rShiftTo(1,a)}else if(!b.isEven())b.subTo(m,b);b.rShiftTo(1,b)}while(v.isEven()){v.rShiftTo(1,v);if(ac){if(!c.isEven()||!d.isEven()){c.addTo(this,c);d.subTo(m,d)}c.rShiftTo(1,c)}else if(!d.isEven())d.subTo(m,d);d.rShiftTo(1,d)}if(u.compareTo(v)>=0){u.subTo(v,u);if(ac)a.subTo(c,a);b.subTo(d,b)}else{v.subTo(u,v);if(ac)c.subTo(a,c);d.subTo(b,d)}}if(v.compareTo(BigInteger.ONE)!=0)return BigInteger.ZERO;if(d.compareTo(m)>=0)return d.subtract(m);if(d.signum()<0)d.addTo(m,d);else return d;if(d.signum()<0)return d.add(m);else return d}proto.chunkSize=bnpChunkSize;proto.toRadix=bnpToRadix;proto.fromRadix=bnpFromRadix;proto.fromNumber=bnpFromNumber;proto.bitwiseTo=bnpBitwiseTo;proto.changeBit=bnpChangeBit;proto.addTo=bnpAddTo;proto.dMultiply=bnpDMultiply;proto.dAddOffset=bnpDAddOffset;proto.multiplyLowerTo=bnpMultiplyLowerTo;proto.multiplyUpperTo=bnpMultiplyUpperTo;proto.modInt=bnpModInt;proto.clone=bnClone;proto.intValue=bnIntValue;proto.byteValue=bnByteValue;proto.shortValue=bnShortValue;proto.signum=bnSigNum;proto.toByteArray=bnToByteArray;proto.equals=bnEquals;proto.min=bnMin;proto.max=bnMax;proto.and=bnAnd;proto.or=bnOr;proto.xor=bnXor;proto.andNot=bnAndNot;proto.not=bnNot;proto.shiftLeft=bnShiftLeft;proto.shiftRight=bnShiftRight;proto.getLowestSetBit=bnGetLowestSetBit;proto.bitCount=bnBitCount;proto.testBit=bnTestBit;proto.setBit=bnSetBit;proto.clearBit=bnClearBit;proto.flipBit=bnFlipBit;proto.add=bnAdd;proto.subtract=bnSubtract;proto.multiply=bnMultiply;proto.divide=bnDivide;proto.remainder=bnRemainder;proto.divideAndRemainder=bnDivideAndRemainder;proto.modPow=bnModPow;proto.modInverse=bnModInverse;proto.pow=bnPow;proto.gcd=bnGCD;proto.square=bnSquare;BigInteger.ZERO=nbv(0);BigInteger.ONE=nbv(1);BigInteger.valueOf=nbv;BigInteger.fromByteArrayUnsigned=function(ba){if(!ba.length){return new BigInteger.valueOf(0)}else if(ba[0]&128){return new BigInteger([0].concat(ba))}else{return new BigInteger(ba)}};BigInteger.fromByteArraySigned=function(ba){if(ba[0]&128){ba[0]&=127;return BigInteger.fromByteArrayUnsigned(ba).negate()}else{return BigInteger.fromByteArrayUnsigned(ba)}};BigInteger.prototype.toByteArrayUnsigned=function(){var ba=this.abs().toByteArray();if(!ba.length){return ba}if(ba[0]===0){ba=ba.slice(1)}for(var i=0;i>8&255;rng_pool[rng_pptr++]^=x>>16&255;rng_pool[rng_pptr++]^=x>>24&255;if(rng_pptr>=rng_psize)rng_pptr-=rng_psize}function rng_seed_time(){rng_seed_int((new Date).getTime())}if(rng_pool==null){rng_pool=new Array;rng_pptr=0;var t;while(rng_pptr>>8;rng_pool[rng_pptr++]=t&255}rng_pptr=0;rng_seed_time()}function rng_get_byte(){if(rng_state==null){rng_seed_time();rng_state=prng_newstate();rng_state.init(rng_pool);for(rng_pptr=0;rng_pptr=240){opcode=opcode<<8|this.buffer[i++]}var len;if(opcode>0&&opcode>>8&255)}else{this.buffer.push(Opcode.map.OP_PUSHDATA4);this.buffer.push(data.length&255);this.buffer.push(data.length>>>8&255);this.buffer.push(data.length>>>16&255);this.buffer.push(data.length>>>24&255)}this.buffer=this.buffer.concat(data);this.chunks.push(data)};Script.createOutputScript=function(address){var script=new Script; -address=new Address(address);if(!address.version){script.writeOp(Opcode.map.OP_DUP);script.writeOp(Opcode.map.OP_HASH160);script.writeBytes(address.hash);script.writeOp(Opcode.map.OP_EQUALVERIFY);script.writeOp(Opcode.map.OP_CHECKSIG)}else{script.writeOp(Opcode.map.OP_HASH160);script.writeBytes(address.hash);script.writeOp(Opcode.map.OP_EQUAL)}return script};Script.prototype.extractPubkeys=function(){return this.chunks.filter(function(chunk){return chunk[0]==4&&chunk.length==65||chunk[0]<4&&chunk.length==33})};Script.createMultiSigOutputScript=function(m,pubkeys){var script=new Script;pubkeys=pubkeys.sort();script.writeOp(Opcode.map.OP_1+m-1);for(var i=0;i65){var args=arguments[0].split(":");return this.addInput(args[0],args[1])}else{this.ins.push(new TransactionIn({outpoint:{hash:tx.hash||tx,index:outIndex},script:new Script,sequence:4294967295}))}};Transaction.prototype.addOutput=function(address,value){if(arguments[0]instanceof TransactionOut){this.outs.push(arguments[0]);return}if(arguments[0].indexOf(":")>=0){var args=arguments[0].split(":");address=args[0];value=parseInt(args[1])}this.outs.push(new TransactionOut({value:value,script:Script.createOutputScript(address)}))};var bytesToWords=function(bytes){for(var words=[],i=0,b=0;i>>5]|=bytes[i]<<24-b%32;return words};var wordsToBytes=function(words){for(var bytes=[],b=0;b>>5]>>>24-b%32&255);return bytes};Transaction.prototype.serialize=function(){var buffer=[];buffer=buffer.concat(util.numToBytes(parseInt(this.version),4));buffer=buffer.concat(util.numToVarInt(this.ins.length));for(var i=0;i=0;i--){var txout=this.outs[i];var hash=txout.script.simpleOutPubKeyHash();if(!wallet.hasHash(hash)){allToMe=false}else{firstMeRecvHash=hash}firstRecvHash=hash}for(var i=this.ins.length-1;i>=0;i--){var txin=this.ins[i];firstSendHash=txin.script.simpleInPubKeyHash();if(!wallet.hasHash(firstSendHash)){allFromMe=false;break}}var impact=this.calcImpact(wallet);var analysis={};analysis.impact=impact;if(impact.sign>0&&impact.value>0){analysis.type="recv";analysis.addr=new Address(firstMeRecvHash)}else if(allFromMe&&allToMe){analysis.type="self"}else if(allFromMe){analysis.type="sent";analysis.addr=new Address(firstRecvHash)}else{analysis.type="other"}return analysis};Transaction.prototype.getDescription=function(wallet){var analysis=this.analyze(wallet);if(!analysis)return"";switch(analysis.type){case"recv":return"Received with "+analysis.addr;break;case"sent":return"Payment to "+analysis.addr;break;case"self":return"Payment to yourself";break;case"other":default:return""}};Transaction.prototype.getTotalOutValue=function(){return this.outs.reduce(function(t,o){return t+o.value},0)};Transaction.prototype.getTotalValue=Transaction.prototype.getTotalOutValue;Transaction.prototype.calcImpact=function(wallet){if(!(wallet instanceof Wallet))return 0;var valueOut=this.outs.filter(function(o){return wallet.hasHash(conv.bytesToHex(o.script.simpleOutPubKeyHash()))}).reduce(function(t,o){return t+o.value},0);var valueIn=this.ins.filter(function(i){return wallet.hasHash(conv.bytesToHex(i.script.simpleInPubKeyHash()))&&wallet.txIndex[i.outpoint.hash]}).reduce(function(t,i){return t+wallet.txIndex[i.outpoint.hash].outs[i.outpoint.index].value},0);if(valueOut>valueIn){return{sign:1,value:valueOut-valueIn}}else{return{sign:-1,value:valueIn-valueOut}}};Transaction.deserialize=function(buffer){if(typeof buffer=="string"){buffer=conv.hexToBytes(buffer)}var pos=0;var readAsInt=function(bytes){if(bytes==0)return 0;pos++;return buffer[pos-1]+readAsInt(bytes-1)*256};var readVarInt=function(){pos++;if(buffer[pos-1]<253){return buffer[pos-1]}return readAsInt(buffer[pos-1]-251)};var readBytes=function(bytes){pos+=bytes;return buffer.slice(pos-bytes,pos)};var readVarString=function(){var size=readVarInt();return readBytes(size)};var obj={ins:[],outs:[]};obj.version=readAsInt(4);var ins=readVarInt();for(var i=0;i0)this.address=this.script.toAddress();this.value=util.isArray(data.value)?util.bytesToNum(data.value):"string"==typeof data.value?parseInt(data.value):data.value instanceof BigInteger?parseInt(data.value.toString()):data.value};TransactionOut.prototype.clone=function(){var newTxout=new TransactionOut({script:this.script.clone(),value:this.value});return newTxout};module.exports.Transaction=Transaction;module.exports.TransactionIn=TransactionIn;module.exports.TransactionOut=TransactionOut},{"./address":1,"./convert":3,"./crypto-js/crypto":4,"./ecdsa":7,"./eckey":8,"./jsbn/jsbn":11,"./script":17,"./util":19,"./wallet":20}],19:[function(require,module,exports){var BigInteger=require("./jsbn/jsbn");var Crypto=require("./crypto-js/crypto");module.exports={isArray:Array.isArray||function(o){return Object.prototype.toString.call(o)==="[object Array]"},makeFilledArray:function(len,val){var array=[];var i=0;while(i8?value.substr(0,value.length-8):"0";var decimalPart=value.length>8?value.substr(value.length-8):value;while(decimalPart.length<8)decimalPart="0"+decimalPart;decimalPart=decimalPart.replace(/0*$/,"");while(decimalPart.length<2)decimalPart+="0";return integerPart+"."+decimalPart},parseValue:function(valueString){var valueComp=valueString.split(".");var integralPart=valueComp[0];var fractionalPart=valueComp[1]||"0";while(fractionalPart.length<8)fractionalPart+="0";fractionalPart=fractionalPart.replace(/^0+/g,"");var value=BigInteger.valueOf(parseInt(integralPart));value=value.multiply(BigInteger.valueOf(1e8));value=value.add(BigInteger.valueOf(parseInt(fractionalPart)));return value},sha256ripe160:function(data){return Crypto.RIPEMD160(Crypto.SHA256(data,{asBytes:true}),{asBytes:true})},error:function(msg){throw new Error(msg)}}},{"./crypto-js/crypto":4,"./jsbn/jsbn":11}],20:[function(require,module,exports){var Script=require("./script");var ECKey=require("./eckey");var conv=require("./convert");var util=require("./util");var BigInteger=require("./jsbn/jsbn");var Transaction=require("./transaction").Transaction;var TransactionIn=require("./transaction").TransactionIn;var TransactionOut=require("./transaction").TransactionOut;var Wallet=function(){var keys=[];this.addressHashes=[];this.txIndex={};this.unspentOuts=[];this.addressPointer=0;this.addKey=function(key,pub){if(!(key instanceof ECKey)){key=new ECKey(key)}keys.push(key);if(pub){if("string"===typeof pub){pub=Crypto.util.hexToBytes(pub)}key.setPub(pub)}this.addressHashes.push(key.getBitcoinAddress().getHash())};this.addKeys=function(keys,pubs){if("string"===typeof keys){keys=keys.split(",")}if("string"===typeof pubs){pubs=pubs.split(",")}var i;if(Array.isArray(pubs)&&keys.length==pubs.length){for(i=0;i=txValue)break}if(availableValue0){sendTx.addOutput(this.getNextAddress(),changeValue)}var hashType=1;for(i=0;i=0){var mod=bi.mod(base);chars.push(alphabet[mod.intValue()]);bi=bi.subtract(mod).divide(base)}chars.push(alphabet[bi.intValue()]);for(var i=0;i0){bytes.unshift(0)}return bytes};module.exports.decodeHex=function(input){return module.exports.decode(conv.hexToBytes(input))};module.exports.checkEncode=function(input,vbyte){vbyte=vbyte||0;var front=[vbyte].concat(input);var checksum=Crypto.SHA256(Crypto.SHA256(front,{asBytes:true}),{asBytes:true}).slice(0,4);return module.exports.encode(front.concat(checksum))};module.exports.checkEncodeHex=function(input,vbyte){return conv.bytesToHex(module.exports.encode(input))};module.exports.checkDecode=function(input){var bytes=module.exports.decode(input),front=bytes.slice(0,bytes.length-4),back=bytes.slice(bytes.length-4);var checksum=Crypto.SHA256(Crypto.SHA256(front,{asBytes:true}),{asBytes:true}).slice(0,4);if(""+checksum!=""+back){throw new Error("Checksum failed")}var o=front.slice(1);o.version=front[0];return o};module.exports.checkDecodeHex=function(input){return module.exports.checkDecode(conv.hexToBytes(input))}},{"./convert":4,"./crypto-js/crypto":5,"./jsbn/jsbn":14}],3:[function(require,module,exports){var Script=require("./script"),util=require("./util"),conv=require("./convert"),key=require("./eckey"),base58=require("./base58"),Crypto=require("./crypto-js/crypto"),ECPointFp=require("./jsbn/ec").ECPointFp,sec=require("./jsbn/sec"),ecparams=sec("secp256k1");var BIP32key=function(opts){if(!opts)opts={};if(typeof opts=="string"){try{opts=BIP32key.prototype.deserialize(opts)}catch(e){opts=BIP32key.prototype.fromMasterKey(opts)}}this.vbytes=opts.vbytes;this.depth=opts.depth;this.fingerprint=opts.fingerprint;this.i=opts.i;this.chaincode=opts.chaincode;this.key=opts.key;this.type=conv.bytesToString(this.vbytes)==PRIVDERIV?"priv":"pub";return this};var PRIVDERIV=BIP32key.PRIVDERIV="ˆ­ä";var PUBDERIV=BIP32key.PUBDERIV="ˆ²";BIP32key.prototype.deserialize=function(str){var bytes=base58.decode(str);var front=bytes.slice(0,bytes.length-4),back=bytes.slice(bytes.length-4);var checksum=Crypto.SHA256(Crypto.SHA256(front,{asBytes:true}),{asBytes:true}).slice(0,4);if(""+checksum!=""+back){throw new Error("Checksum failed")}var type=conv.bytesToString(bytes.slice(0,4))==PRIVDERIV?"priv":"pub";return new BIP32key({type:type,vbytes:bytes.slice(0,4),depth:bytes[4],fingerprint:bytes.slice(5,9),i:util.bytesToNum(bytes.slice(9,13).reverse()),chaincode:bytes.slice(13,45),key:new key(type=="priv"?bytes.slice(46,78).concat([1]):bytes.slice(45,78))})};BIP32key.prototype.serialize=function(){var bytes=this.vbytes.concat([this.depth],this.fingerprint,util.numToBytes(this.i,4).reverse(),this.chaincode,this.type=="priv"?[0].concat(this.key.export("bytes").slice(0,32)):this.key);var checksum=Crypto.SHA256(Crypto.SHA256(bytes,{asBytes:true}),{asBytes:true}).slice(0,4);return base58.encode(bytes.concat(checksum))};BIP32key.prototype.ckd=function(i){var priv,pub,newkey,fingerprint,blob,I;if(this.type=="priv"){priv=this.key.export("bytes");pub=this.key.getPub()}else pub=this.key;if(i>=2147483648){if(this.priv)throw new Error("Can't do private derivation on public key!");blob=[0].concat(priv.slice(0,32),util.numToBytes(this.i,4).reverse())}else blob=pub.concat(util.numToBytes(this.i,4).reverse());I=Crypto.HMAC(Crypto.SHA512,blob,this.chaincode,{asBytes:true});if(this.type=="priv"){Ikey=Bitcoin.BigInteger.fromByteArrayUnsigned(I.slice(0,32));newkey=new key(this.key.priv.add(Ikey));newkey.compressed=true;fingerprint=util.sha256ripe160(this.key.getPub()).slice(0,4)}else{newkey=ECPointFp.decodeFrom(ecparams.getCurve(),this.key).add(new key(I.slice(0,32).concat([1])).getPubPoint()).getEncoded(true);fingerprint=util.sha256ripe160(this.key).slice(0,4)}return new BIP32key({vbytes:this.vbytes,type:this.type,depth:this.depth+1,fingerprint:fingerprint,i:i,chaincode:I.slice(32),key:newkey})};BIP32key.prototype.clone=function(){return new BIP32key(this)};BIP32key.prototype.privtopub=BIP32key.prototype.getPub=function(){if(this.type=="pub")return this.clone();return new BIP32key({vbytes:conv.stringToBytes(PUBDERIV),type:"pub",depth:this.depth,fingerprint:this.fingerprint,i:this.i,chaincode:this.chaincode,key:this.key.getPub()})};BIP32key.prototype.fromMasterKey=function(seed){var I=Bitcoin.Crypto.HMAC(Bitcoin.Crypto.SHA512,seed,"Bitcoin seed",{asBytes:true});return new BIP32key({vbytes:conv.stringToBytes(PRIVDERIV),type:"priv",depth:0,fingerprint:[0,0,0,0],i:0,chaincode:I.slice(32),key:new key(I.slice(0,32).concat([1]))})};BIP32key.prototype.getKey=function(){return this.key};module.exports=BIP32key},{"./base58":2,"./convert":4,"./crypto-js/crypto":5,"./eckey":11,"./jsbn/ec":13,"./jsbn/sec":17,"./script":20,"./util":22}],4:[function(require,module,exports){var base64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";String.prototype.lpad=function(padString,length){var str=this;while(str.length>>6*(3-j)&63));else base64.push("=")}}return base64.join("")};module.exports.base64ToBytes=function(base64){base64=base64.replace(/[^A-Z0-9+\/]/gi,"");for(var bytes=[],i=0,imod4=0;i>>6-imod4*2)}return bytes};module.exports.coerceToBytes=function(input){if(typeof input=="string")return module.exports.hexToBytes(input);return input};module.exports.binToBytes=function(bin){return bin.match(/......../g).map(function(x){return parseInt(x,2)})};module.exports.bytesToBin=function(bytes){return bytes.map(function(x){return x.toString(2).lpad("0",8)}).join("")};module.exports.bytesToString=function(bytes){return bytes.map(function(x){return String.fromCharCode(x)}).join("")};module.exports.stringToBytes=function(string){return string.split("").map(function(x){return x.charCodeAt(0)})}},{}],5:[function(require,module,exports){var Crypto=module.exports={};var util=Crypto.util={randomBytes:function(n){for(var bytes=[];n>0;n--)bytes.push(Math.floor(Math.random()*256));return bytes}};Crypto.mode={};var charenc=Crypto.charenc={};var UTF8=charenc.UTF8={stringToBytes:function(str){return Binary.stringToBytes(unescape(encodeURIComponent(str)))},bytesToString:function(bytes){return decodeURIComponent(escape(Binary.bytesToString(bytes)))}};var Binary=charenc.Binary={stringToBytes:function(str){for(var bytes=[],i=0;ihasher._blocksize)key=hasher(key,{asBytes:true});var okey=key.slice(0),ikey=key.slice(0);for(var i=0;i>>5]|=bytes[i]<<24-b%32}return words};var wordsToBytes=function(words){var bytes=[];for(var b=0;b>>5]>>>24-b%32&255)}return bytes};var processBlock=function(H,M,offset){for(var i=0;i<16;i++){var offset_i=offset+i;var M_offset_i=M[offset_i];M[offset_i]=(M_offset_i<<8|M_offset_i>>>24)&16711935|(M_offset_i<<24|M_offset_i>>>8)&4278255360}var al,bl,cl,dl,el;var ar,br,cr,dr,er;ar=al=H[0];br=bl=H[1];cr=cl=H[2];dr=dl=H[3];er=el=H[4];var t;for(var i=0;i<80;i+=1){t=al+M[offset+zl[i]]|0;if(i<16){t+=f1(bl,cl,dl)+hl[0]}else if(i<32){t+=f2(bl,cl,dl)+hl[1]}else if(i<48){t+=f3(bl,cl,dl)+hl[2]}else if(i<64){t+=f4(bl,cl,dl)+hl[3]}else{t+=f5(bl,cl,dl)+hl[4]}t=t|0;t=rotl(t,sl[i]);t=t+el|0;al=el;el=dl;dl=rotl(cl,10);cl=bl;bl=t;t=ar+M[offset+zr[i]]|0;if(i<16){t+=f5(br,cr,dr)+hr[0]}else if(i<32){t+=f4(br,cr,dr)+hr[1]}else if(i<48){t+=f3(br,cr,dr)+hr[2]}else if(i<64){t+=f2(br,cr,dr)+hr[3]}else{t+=f1(br,cr,dr)+hr[4]}t=t|0;t=rotl(t,sr[i]);t=t+er|0;ar=er;er=dr;dr=rotl(cr,10);cr=br;br=t}t=H[1]+cl+dr|0;H[1]=H[2]+dl+er|0;H[2]=H[3]+el+ar|0;H[3]=H[4]+al+br|0;H[4]=H[0]+bl+cr|0;H[0]=t};function f1(x,y,z){return x^y^z}function f2(x,y,z){return x&y|~x&z}function f3(x,y,z){return(x|~y)^z}function f4(x,y,z){return x&z|y&~z}function f5(x,y,z){return x^(y|~z)}function rotl(x,n){return x<>>32-n}module.exports=function(message,options){if(message.constructor===String){message=UTF8.stringToBytes(message)}var H=[1732584193,4023233417,2562383102,271733878,3285377520];var m=bytesToWords(message);var nBitsLeft=message.length*8;var nBitsTotal=message.length*8;m[nBitsLeft>>>5]|=128<<24-nBitsLeft%32;m[(nBitsLeft+64>>>9<<4)+14]=(nBitsTotal<<8|nBitsTotal>>>24)&16711935|(nBitsTotal<<24|nBitsTotal>>>8)&4278255360;for(var i=0;i>>24)&16711935|(H_i<<24|H_i>>>8)&4278255360}var digestbytes=wordsToBytes(H);return options&&options.asBytes?digestbytes:options&&options.asString?Binary.bytesToString(digestbytes):conv.bytesToHex(digestbytes)}},{"../convert":4,"./crypto":5}],8:[function(require,module,exports){var conv=require("../convert"),util=require("../util");var K=[];(function(){function isPrime(n){var sqrtN=Math.sqrt(n);for(var factor=2;factor<=sqrtN;factor++){if(!(n%factor)){return false}}return true}function getFractionalBits(n){return(n-(n|0))*4294967296|0}var n=2;var nPrime=0;while(nPrime<64){if(isPrime(n)){K[nPrime]=getFractionalBits(Math.pow(n,1/3));nPrime++}n++}})();var W=[];var processBlock=function(H,M,offset){var a=H[0];var b=H[1];var c=H[2];var d=H[3];var e=H[4];var f=H[5];var g=H[6];var h=H[7];for(var i=0;i<64;i++){if(i<16){W[i]=M[offset+i]|0}else{var gamma0x=W[i-15];var gamma0=(gamma0x<<25|gamma0x>>>7)^(gamma0x<<14|gamma0x>>>18)^gamma0x>>>3;var gamma1x=W[i-2];var gamma1=(gamma1x<<15|gamma1x>>>17)^(gamma1x<<13|gamma1x>>>19)^gamma1x>>>10;W[i]=gamma0+W[i-7]+gamma1+W[i-16]}var ch=e&f^~e&g;var maj=a&b^a&c^b&c;var sigma0=(a<<30|a>>>2)^(a<<19|a>>>13)^(a<<10|a>>>22);var sigma1=(e<<26|e>>>6)^(e<<21|e>>>11)^(e<<7|e>>>25);var t1=h+sigma1+ch+K[i]+W[i];var t2=sigma0+maj;h=g;g=f;f=e;e=d+t1|0;d=c;c=b;b=a;a=t1+t2|0}H[0]=H[0]+a|0;H[1]=H[1]+b|0;H[2]=H[2]+c|0;H[3]=H[3]+d|0;H[4]=H[4]+e|0;H[5]=H[5]+f|0;H[6]=H[6]+g|0;H[7]=H[7]+h|0};module.exports=function(message,options){var H=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];if(message.constructor===String){message=conv.stringToBytes(message)}var m=util.bytesToWords(message);var l=message.length*8;m[l>>5]|=128<<24-l%32;m[(l+64>>9<<4)+15]=l;for(var i=0;i>>1|gamma0xl<<31)^(gamma0xh>>>8|gamma0xl<<24)^gamma0xh>>>7;var gamma0l=(gamma0xl>>>1|gamma0xh<<31)^(gamma0xl>>>8|gamma0xh<<24)^(gamma0xl>>>7|gamma0xh<<25);var gamma1x=W[i-2];var gamma1xh=gamma1x[0];var gamma1xl=gamma1x[1];var gamma1h=(gamma1xh>>>19|gamma1xl<<13)^(gamma1xh<<3|gamma1xl>>>29)^gamma1xh>>>6;var gamma1l=(gamma1xl>>>19|gamma1xh<<13)^(gamma1xl<<3|gamma1xh>>>29)^(gamma1xl>>>6|gamma1xh<<26);var Wi7=W[i-7];var Wi7h=Wi7[0];var Wi7l=Wi7[1];var Wi16=W[i-16];var Wi16h=Wi16[0];var Wi16l=Wi16[1];var Wil=gamma0l+Wi7l;var Wih=gamma0h+Wi7h+(Wil>>>0>>0?1:0);var Wil=Wil+gamma1l;var Wih=Wih+gamma1h+(Wil>>>0>>0?1:0);var Wil=Wil+Wi16l;var Wih=Wih+Wi16h+(Wil>>>0>>0?1:0);Wi[0]=Wih;Wi[1]=Wil}var chh=eh&fh^~eh&gh;var chl=el&fl^~el≷var majh=ah&bh^ah&ch^bh&ch;var majl=al&bl^al&cl^bl&cl;var sigma0h=(ah>>>28|al<<4)^(ah<<30|al>>>2)^(ah<<25|al>>>7);var sigma0l=(al>>>28|ah<<4)^(al<<30|ah>>>2)^(al<<25|ah>>>7);var sigma1h=(eh>>>14|el<<18)^(eh>>>18|el<<14)^(eh<<23|el>>>9);var sigma1l=(el>>>14|eh<<18)^(el>>>18|eh<<14)^(el<<23|eh>>>9);var Ki=K[i];var Kih=Ki[0];var Kil=Ki[1];var t1l=hl+sigma1l;var t1h=hh+sigma1h+(t1l>>>0>>0?1:0);var t1l=t1l+chl;var t1h=t1h+chh+(t1l>>>0>>0?1:0);var t1l=t1l+Kil;var t1h=t1h+Kih+(t1l>>>0>>0?1:0);var t1l=t1l+Wil;var t1h=t1h+Wih+(t1l>>>0>>0?1:0);var t2l=sigma0l+majl;var t2h=sigma0h+majh+(t2l>>>0>>0?1:0);hh=gh;hl=gl;gh=fh;gl=fl;fh=eh;fl=el;el=dl+t1l|0;eh=dh+t1h+(el>>>0
>>0?1:0)|0;dh=ch;dl=cl;ch=bh;cl=bl;bh=ah;bl=al;al=t1l+t2l|0;ah=t1h+t2h+(al>>>0>>0?1:0)|0}H0l=H0[1]=H0l+al;H0[0]=H0h+ah+(H0l>>>0>>0?1:0);H1l=H1[1]=H1l+bl;H1[0]=H1h+bh+(H1l>>>0>>0?1:0);H2l=H2[1]=H2l+cl;H2[0]=H2h+ch+(H2l>>>0>>0?1:0);H3l=H3[1]=H3l+dl;H3[0]=H3h+dh+(H3l>>>0
>>0?1:0);H4l=H4[1]=H4l+el;H4[0]=H4h+eh+(H4l>>>0>>0?1:0);H5l=H5[1]=H5l+fl;H5[0]=H5h+fh+(H5l>>>0>>0?1:0);H6l=H6[1]=H6l+gl;H6[0]=H6h+gh+(H6l>>>0>>0?1:0);H7l=H7[1]=H7l+hl;H7[0]=H7h+hh+(H7l>>>0>>0?1:0);return H};module.exports=function(message,options){var H=[[1779033703,4089235720],[3144134277,2227873595],[1013904242,4271175723],[2773480762,1595750129],[1359893119,2917565137],[2600822924,725511199],[528734635,4215389547],[1541459225,327033209]];if(message.constructor===String){message=conv.stringToBytes(message)}var m=util.bytesToWords(message);var l=message.length*8;m[l>>5]|=128<<24-l%32;m[(l+64>>10<<5)+31]=l;for(var i=0;i=0;--i){R=R.twice2D();R.z=BigInteger.ONE;if(k.testBit(i)){if(l.testBit(i)){R=R.add2D(Z)}else{R=R.add2D(P)}}else{if(l.testBit(i)){R=R.add2D(Q)}}}return R}var ECDSA={getBigRandom:function(limit){return new BigInteger(limit.bitLength(),rng).mod(limit.subtract(BigInteger.ONE)).add(BigInteger.ONE)},sign:function(hash,priv){var d=priv;var n=ecparams.getN();var e=BigInteger.fromByteArrayUnsigned(hash);do{var k=ECDSA.getBigRandom(n);var G=ecparams.getG();var Q=G.multiply(k);var r=Q.getX().toBigInteger().mod(n)}while(r.compareTo(BigInteger.ZERO)<=0);var s=k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);return ECDSA.serializeSig(r,s)},verify:function(hash,sig,pubkey){var r,s;if(util.isArray(sig)){var obj=ECDSA.parseSig(sig);r=obj.r;s=obj.s}else if("object"===typeof sig&&sig.r&&sig.s){r=sig.r;s=sig.s}else{throw new Error("Invalid value for signature")}var Q;if(pubkey instanceof ECPointFp){Q=pubkey}else if(util.isArray(pubkey)){Q=ECPointFp.decodeFrom(ecparams.getCurve(),pubkey)}else{throw new Error("Invalid format for pubkey value, must be byte array or ECPointFp")}var e=BigInteger.fromByteArrayUnsigned(hash);return ECDSA.verifyRaw(e,r,s,Q)},verifyRaw:function(e,r,s,Q){var n=ecparams.getN();var G=ecparams.getG();if(r.compareTo(BigInteger.ONE)<0||r.compareTo(n)>=0)return false;if(s.compareTo(BigInteger.ONE)<0||s.compareTo(n)>=0)return false;var c=s.modInverse(n);var u1=e.multiply(c).mod(n);var u2=r.multiply(c).mod(n);var point=G.multiply(u1).add(Q.multiply(u2));var v=point.getX().toBigInteger().mod(n);return v.equals(r)},serializeSig:function(r,s){var rBa=r.toByteArraySigned();var sBa=s.toByteArraySigned();var sequence=[];sequence.push(2);sequence.push(rBa.length);sequence=sequence.concat(rBa);sequence.push(2);sequence.push(sBa.length);sequence=sequence.concat(sBa);sequence.unshift(sequence.length);sequence.unshift(48);return sequence},parseSig:function(sig){var cursor;if(sig[0]!=48)throw new Error("Signature not a valid DERSequence");cursor=2;if(sig[cursor]!=2)throw new Error("First element in signature must be a DERInteger");var rBa=sig.slice(cursor+2,cursor+2+sig[cursor+1]);cursor+=2+sig[cursor+1];if(sig[cursor]!=2)throw new Error("Second element in signature must be a DERInteger");var sBa=sig.slice(cursor+2,cursor+2+sig[cursor+1]);cursor+=2+sig[cursor+1];var r=BigInteger.fromByteArrayUnsigned(rBa);var s=BigInteger.fromByteArrayUnsigned(sBa);return{r:r,s:s}},parseSigCompact:function(sig){if(sig.length!==65){throw new Error("Signature has the wrong length")}var i=sig[0]-27;if(i<0||i>7){throw new Error("Invalid signature type")}var n=ecparams.getN();var r=BigInteger.fromByteArrayUnsigned(sig.slice(1,33)).mod(n);var s=BigInteger.fromByteArrayUnsigned(sig.slice(33,65)).mod(n);return{r:r,s:s,i:i}},recoverPubKey:function(r,s,hash,i){i=i&3;var isYEven=i&1;var isSecondKey=i>>1;var n=ecparams.getN();var G=ecparams.getG();var curve=ecparams.getCurve();var p=curve.getQ();var a=curve.getA().toBigInteger();var b=curve.getB().toBigInteger();if(!P_OVER_FOUR){P_OVER_FOUR=p.add(BigInteger.ONE).divide(BigInteger.valueOf(4))}var x=isSecondKey?r.add(n):r;var alpha=x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(p);var beta=alpha.modPow(P_OVER_FOUR,p);var xorOdd=beta.isEven()?i%2:(i+1)%2;var y=(beta.isEven()?!isYEven:isYEven)?beta:p.subtract(beta);var R=new ECPointFp(curve,curve.fromBigInteger(x),curve.fromBigInteger(y));R.validate();var e=BigInteger.fromByteArrayUnsigned(hash);var eNeg=BigInteger.ZERO.subtract(e).mod(n);var rInv=r.modInverse(n);var Q=implShamirsTrick(R,s,G,eNeg).multiply(rInv);Q.validate();if(!ECDSA.verifyRaw(e,r,s,Q)){throw new Error("Pubkey recovery unsuccessful")}var ECKey=require("./eckey");var pubKey=ECKey();pubKey.pub=Q;return pubKey},calcPubkeyRecoveryParam:function(address,r,s,hash){for(var i=0;i<4;i++){var pubkey=ECDSA.recoverPubKey(r,s,hash,i);if(pubkey.getBitcoinAddress().toString()==address){return i}}throw new Error("Unable to find valid recovery factor")}};module.exports=ECDSA},{"./eckey":11,"./jsbn/ec":13,"./jsbn/jsbn":14,"./jsbn/rng":16,"./jsbn/sec":17,"./util":22}],11:[function(require,module,exports){var BigInteger=require("./jsbn/jsbn");var sec=require("./jsbn/sec");var base58=require("./base58");var Crypto=require("./crypto-js/crypto");var util=require("./util");var conv=require("./convert");var Address=require("./address");var ecdsa=require("./ecdsa");var ECPointFp=require("./jsbn/ec").ECPointFp;var ecparams=sec("secp256k1");var ECKey=function(input){if(!(this instanceof ECKey)){return new ECKey(input)}this.compressed=!!ECKey.compressByDefault;if(!input){var n=ecparams.getN();this.priv=ecdsa.getBigRandom(n)}else this.import(input)};ECKey.compressByDefault=false;ECKey.prototype.setCompressed=function(v){this.compressed=!!v};ECKey.prototype.getPub=function(){return this.getPubPoint().getEncoded(this.compressed)};ECKey.prototype.getPubPoint=function(){if(!this.pub)this.pub=ecparams.getG().multiply(this.priv);return this.pub};ECKey.prototype.getPubKeyHash=function(){if(this.pubKeyHash)return this.pubKeyHash;return this.pubKeyHash=util.sha256ripe160(this.getPub())};ECKey.prototype.getBitcoinAddress=function(){var hash=this.getPubKeyHash();var addr=new Address(hash);return addr};ECKey.prototype.setPub=function(pub){this.pub=ECPointFp.decodeFrom(ecparams.getCurve(),pub);this.compressed=pub[0]<4;return this};ECKey.prototype.export=function(format){var bytes=this.priv.toByteArrayUnsigned();if(this.compressed)bytes.push(1);return format==="base58"?base58.checkEncode(bytes,128):format==="bin"?conv.bytesToString(bytes):format==="bytes"?bytes:format==="hex"?conv.bytesToHex(bytes):bytes};ECKey.prototype.getExportedPrivateKey=ECKey.prototype.export;ECKey.prototype.toString=function(format){return""+this.export(format)};ECKey.prototype.sign=function(hash){return ecdsa.sign(hash,this.priv)};ECKey.prototype.verify=function(hash,sig){return ecdsa.verify(hash,sig,this.getPub())};ECKey.prototype.import=function(input){if(input instanceof ECKey){this.priv=input.priv;this.compressed=input.compressed}else if(input instanceof BigInteger){this.priv=input;this.compressed=ECKey.compressByDefault}else if(util.isArray(input)){this.priv=BigInteger.fromByteArrayUnsigned(input.slice(0,32));this.compressed=input.length==33}else if("string"==typeof input){if(input.length==51&&input[0]=="5"){this.priv=BigInteger.fromByteArrayUnsigned(base58.checkDecode(input));this.compressed=false}else if(input.length==52&&(input[0]==="K"||input[0]==="L")){this.priv=BigInteger.fromByteArrayUnsigned(base58.checkDecode(input));this.compressed=true}else if(input.length>=64){this.priv=BigInteger.fromByteArrayUnsigned(conv.hexToBytes(input.slice(0,64)));this.compressed=input.length==66}}};module.exports=ECKey},{"./address":1,"./base58":2,"./convert":4,"./crypto-js/crypto":5,"./ecdsa":10,"./jsbn/ec":13,"./jsbn/jsbn":14,"./jsbn/sec":17,"./util":22}],12:[function(require,module,exports){var rotl=function(n,b){return n<>>32-b};var rotr=function(n,b){return n<<32-b|n>>>b};var endian=function(n){if(n.constructor==Number){return rotl(n,8)&16711935|rotl(n,24)&4278255360}for(var i=0;i0;--i){R=R.twice();var hBit=h.testBit(i);var eBit=e.testBit(i);if(hBit!=eBit){R=R.add(hBit?this:neg)}}return R}function pointFpMultiplyTwo(j,x,k){var i;if(j.bitLength()>k.bitLength())i=j.bitLength()-1;else i=k.bitLength()-1;var R=this.curve.getInfinity();var both=this.add(x);while(i>=0){R=R.twice();if(j.testBit(i)){if(k.testBit(i)){R=R.add(both)}else{R=R.add(this)}}else{if(k.testBit(i)){R=R.add(x)}}--i}return R}ECPointFp.prototype.getX=pointFpGetX;ECPointFp.prototype.getY=pointFpGetY;ECPointFp.prototype.equals=pointFpEquals;ECPointFp.prototype.isInfinity=pointFpIsInfinity;ECPointFp.prototype.negate=pointFpNegate;ECPointFp.prototype.add=pointFpAdd;ECPointFp.prototype.twice=pointFpTwice;ECPointFp.prototype.multiply=pointFpMultiply;ECPointFp.prototype.multiplyTwo=pointFpMultiplyTwo;function ECCurveFp(q,a,b){this.q=q;this.a=this.fromBigInteger(a);this.b=this.fromBigInteger(b);this.infinity=new ECPointFp(this,null,null)}function curveFpGetQ(){return this.q}function curveFpGetA(){return this.a}function curveFpGetB(){return this.b}function curveFpEquals(other){if(other==this)return true;return this.q.equals(other.q)&&this.a.equals(other.a)&&this.b.equals(other.b)}function curveFpGetInfinity(){return this.infinity}function curveFpFromBigInteger(x){return new ECFieldElementFp(this.q,x)}function curveFpDecodePointHex(s){switch(parseInt(s.substr(0,2),16)){case 0:return this.infinity;case 2:case 3:return null;case 4:case 6:case 7:var len=(s.length-2)/2;var xHex=s.substr(2,len);var yHex=s.substr(len+2,len);return new ECPointFp(this,this.fromBigInteger(new BigInteger(xHex,16)),this.fromBigInteger(new BigInteger(yHex,16)));default:return null}}ECCurveFp.prototype.getQ=curveFpGetQ;ECCurveFp.prototype.getA=curveFpGetA;ECCurveFp.prototype.getB=curveFpGetB;ECCurveFp.prototype.equals=curveFpEquals;ECCurveFp.prototype.getInfinity=curveFpGetInfinity;ECCurveFp.prototype.fromBigInteger=curveFpFromBigInteger;ECCurveFp.prototype.decodePointHex=curveFpDecodePointHex;function integerToBytes(i,len){var bytes=i.toByteArrayUnsigned();if(lenbytes.length){bytes.unshift(0)}return bytes}ECFieldElementFp.prototype.getByteLength=function(){return Math.floor((this.toBigInteger().bitLength()+7)/8)};ECPointFp.prototype.getEncoded=function(compressed){var x=this.getX().toBigInteger();var y=this.getY().toBigInteger();var enc=integerToBytes(x,32);if(compressed){if(y.isEven()){enc.unshift(2)}else{enc.unshift(3)}}else{enc.unshift(4);enc=enc.concat(integerToBytes(y,32))}return enc};ECPointFp.decodeFrom=function(ecparams,enc){var type=enc[0];var dataLen=enc.length-1;if(type==4){var xBa=enc.slice(1,1+dataLen/2),yBa=enc.slice(1+dataLen/2,1+dataLen),x=BigInteger.fromByteArrayUnsigned(xBa),y=BigInteger.fromByteArrayUnsigned(yBa)}else{var xBa=enc.slice(1),x=BigInteger.fromByteArrayUnsigned(xBa),p=ecparams.getQ(),xCubedPlus7=x.multiply(x).multiply(x).add(new Bitcoin.BigInteger("7")).mod(p),pPlus1Over4=p.add(new Bitcoin.BigInteger("1")).divide(new Bitcoin.BigInteger("4")),y=xCubedPlus7.modPow(pPlus1Over4,p);if(y.mod(new Bitcoin.BigInteger("2")).toString()!=""+type%2){y=p.subtract(y)}}return new ECPointFp(ecparams,ecparams.fromBigInteger(x),ecparams.fromBigInteger(y))};ECPointFp.prototype.add2D=function(b){if(this.isInfinity())return b;if(b.isInfinity())return this;if(this.x.equals(b.x)){if(this.y.equals(b.y)){return this.twice()}return this.curve.getInfinity()}var x_x=b.x.subtract(this.x);var y_y=b.y.subtract(this.y);var gamma=y_y.divide(x_x);var x3=gamma.square().subtract(this.x).subtract(b.x);var y3=gamma.multiply(this.x.subtract(x3)).subtract(this.y);return new ECPointFp(this.curve,x3,y3)};ECPointFp.prototype.twice2D=function(){if(this.isInfinity())return this;if(this.y.toBigInteger().signum()==0){return this.curve.getInfinity()}var TWO=this.curve.fromBigInteger(BigInteger.valueOf(2));var THREE=this.curve.fromBigInteger(BigInteger.valueOf(3));var gamma=this.x.square().multiply(THREE).add(this.curve.a).divide(this.y.multiply(TWO));var x3=gamma.square().subtract(this.x.multiply(TWO));var y3=gamma.multiply(this.x.subtract(x3)).subtract(this.y);return new ECPointFp(this.curve,x3,y3)};ECPointFp.prototype.multiply2D=function(k){if(this.isInfinity())return this;if(k.signum()==0)return this.curve.getInfinity();var e=k;var h=e.multiply(new BigInteger("3"));var neg=this.negate();var R=this;var i;for(i=h.bitLength()-2;i>0;--i){R=R.twice();var hBit=h.testBit(i);var eBit=e.testBit(i);if(hBit!=eBit){R=R.add2D(hBit?this:neg)}}return R};ECPointFp.prototype.isOnCurve=function(){var x=this.getX().toBigInteger();var y=this.getY().toBigInteger();var a=this.curve.getA().toBigInteger();var b=this.curve.getB().toBigInteger();var n=this.curve.getQ();var lhs=y.multiply(y).mod(n);var rhs=x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(n);return lhs.equals(rhs)};ECPointFp.prototype.toString=function(){return"("+this.getX().toBigInteger().toString()+","+this.getY().toBigInteger().toString()+")"};ECPointFp.prototype.validate=function(){var n=this.curve.getQ();if(this.isInfinity()){throw new Error("Point is at infinity.")}var x=this.getX().toBigInteger();var y=this.getY().toBigInteger();if(x.compareTo(BigInteger.ONE)<0||x.compareTo(n.subtract(BigInteger.ONE))>0){throw new Error("x coordinate out of bounds")}if(y.compareTo(BigInteger.ONE)<0||y.compareTo(n.subtract(BigInteger.ONE))>0){throw new Error("y coordinate out of bounds")}if(!this.isOnCurve()){throw new Error("Point is not on the curve.")}if(this.multiply(n).isInfinity()){throw new Error("Point is not a scalar multiple of G.")}return true};module.exports=ECCurveFp;module.exports.ECPointFp=ECPointFp},{"./jsbn":14,"./sec":17}],14:[function(require,module,exports){var dbits;var canary=0xdeadbeefcafe;var j_lm=(canary&16777215)==15715070;function BigInteger(a,b,c){if(!(this instanceof BigInteger)){return new BigInteger(a,b,c)}if(a!=null){if("number"==typeof a)this.fromNumber(a,b,c);else if(b==null&&"string"!=typeof a)this.fromString(a,256);else this.fromString(a,b)}}var proto=BigInteger.prototype;function nbi(){return new BigInteger(null)}function am1(i,x,w,j,c,n){while(--n>=0){var v=x*this[i++]+w[j]+c;c=Math.floor(v/67108864);w[j++]=v&67108863}return c}function am2(i,x,w,j,c,n){var xl=x&32767,xh=x>>15;while(--n>=0){var l=this[i]&32767;var h=this[i++]>>15;var m=xh*l+h*xl;l=xl*l+((m&32767)<<15)+w[j]+(c&1073741823);c=(l>>>30)+(m>>>15)+xh*h+(c>>>30);w[j++]=l&1073741823}return c}function am3(i,x,w,j,c,n){var xl=x&16383,xh=x>>14;while(--n>=0){var l=this[i]&16383;var h=this[i++]>>14;var m=xh*l+h*xl;l=xl*l+((m&16383)<<14)+w[j]+c;c=(l>>28)+(m>>14)+xh*h;w[j++]=l&268435455}return c}BigInteger.prototype.am=am1;dbits=26;BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=(1<=0;--i)r[i]=this[i];r.t=this.t;r.s=this.s}function bnpFromInt(x){this.t=1;this.s=x<0?-1:0;if(x>0)this[0]=x;else if(x<-1)this[0]=x+DV;else this.t=0}function nbv(i){var r=nbi();r.fromInt(i);return r}function bnpFromString(s,b){var self=this;var k;if(b==16)k=4;else if(b==8)k=3;else if(b==256)k=8;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else{self.fromRadix(s,b);return}self.t=0;self.s=0;var i=s.length,mi=false,sh=0;while(--i>=0){var x=k==8?s[i]&255:intAt(s,i);if(x<0){if(s.charAt(i)=="-")mi=true;continue}mi=false;if(sh==0)self[self.t++]=x;else if(sh+k>self.DB){self[self.t-1]|=(x&(1<>self.DB-sh}else self[self.t-1]|=x<=self.DB)sh-=self.DB}if(k==8&&(s[0]&128)!=0){self.s=-1;if(sh>0)self[self.t-1]|=(1<0&&this[this.t-1]==c)--this.t}function bnToString(b){var self=this;if(self.s<0)return"-"+self.negate().toString(b);var k;if(b==16)k=4;else if(b==8)k=3;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else return self.toRadix(b);var km=(1<0){if(p>p)>0){m=true;r=int2char(d)}while(i>=0){if(p>(p+=self.DB-k)}else{d=self[i]>>(p-=k)&km;if(p<=0){p+=self.DB;--i}}if(d>0)m=true;if(m)r+=int2char(d)}}return m?r:"0"}function bnNegate(){var r=nbi();BigInteger.ZERO.subTo(this,r);return r}function bnAbs(){return this.s<0?this.negate():this}function bnCompareTo(a){var r=this.s-a.s;if(r!=0)return r;var i=this.t;r=i-a.t;if(r!=0)return this.s<0?-r:r;while(--i>=0)if((r=this[i]-a[i])!=0)return r;return 0}function nbits(x){var r=1,t;if((t=x>>>16)!=0){x=t;r+=16}if((t=x>>8)!=0){x=t;r+=8}if((t=x>>4)!=0){x=t;r+=4}if((t=x>>2)!=0){x=t;r+=2}if((t=x>>1)!=0){x=t;r+=1}return r}function bnBitLength(){if(this.t<=0)return 0;return this.DB*(this.t-1)+nbits(this[this.t-1]^this.s&this.DM)}function bnpDLShiftTo(n,r){var i;for(i=this.t-1;i>=0;--i)r[i+n]=this[i];for(i=n-1;i>=0;--i)r[i]=0;r.t=this.t+n;r.s=this.s}function bnpDRShiftTo(n,r){for(var i=n;i=0;--i){r[i+ds+1]=self[i]>>cbs|c;c=(self[i]&bm)<=0;--i)r[i]=0;r[ds]=c;r.t=self.t+ds+1;r.s=self.s;r.clamp()}function bnpRShiftTo(n,r){var self=this;r.s=self.s;var ds=Math.floor(n/self.DB);if(ds>=self.t){r.t=0;return}var bs=n%self.DB;var cbs=self.DB-bs;var bm=(1<>bs;for(var i=ds+1;i>bs}if(bs>0)r[self.t-ds-1]|=(self.s&bm)<>=self.DB}if(a.t>=self.DB}c+=self.s}else{c+=self.s;while(i>=self.DB}c-=a.s}r.s=c<0?-1:0;if(c<-1)r[i++]=self.DV+c;else if(c>0)r[i++]=c;r.t=i;r.clamp()}function bnpMultiplyTo(a,r){var x=this.abs(),y=a.abs();var i=x.t;r.t=i+y.t;while(--i>=0)r[i]=0;for(i=0;i=0)r[i]=0;for(i=0;i=x.DV){r[i+x.t]-=x.DV;r[i+x.t+1]=1}}if(r.t>0)r[r.t-1]+=x.am(i,x[i],r,2*i,0,1);r.s=0;r.clamp()}function bnpDivRemTo(m,q,r){var self=this;var pm=m.abs();if(pm.t<=0)return;var pt=self.abs();if(pt.t0){pm.lShiftTo(nsh,y);pt.lShiftTo(nsh,r)}else{pm.copyTo(y);pt.copyTo(r)}var ys=y.t;var y0=y[ys-1];if(y0==0)return;var yt=y0*(1<1?y[ys-2]>>self.F2:0);var d1=self.FV/yt,d2=(1<=0){r[r.t++]=1;r.subTo(t,r)}BigInteger.ONE.dlShiftTo(ys,t);t.subTo(y,y);while(y.t=0){var qd=r[--i]==y0?self.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);if((r[i]+=y.am(0,qd,r,j,0,ys))0)r.rShiftTo(nsh,r);if(ts<0)BigInteger.ZERO.subTo(r,r)}function bnMod(a){var r=nbi();this.abs().divRemTo(a,null,r);if(this.s<0&&r.compareTo(BigInteger.ZERO)>0)a.subTo(r,r);return r}function Classic(m){this.m=m}function cConvert(x){if(x.s<0||x.compareTo(this.m)>=0)return x.mod(this.m);else return x}function cRevert(x){return x}function cReduce(x){x.divRemTo(this.m,null,x)}function cMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}function cSqrTo(x,r){x.squareTo(r);this.reduce(r)}Classic.prototype.convert=cConvert;Classic.prototype.revert=cRevert;Classic.prototype.reduce=cReduce;Classic.prototype.mulTo=cMulTo;Classic.prototype.sqrTo=cSqrTo;function bnpInvDigit(){if(this.t<1)return 0;var x=this[0];if((x&1)==0)return 0;var y=x&3;y=y*(2-(x&15)*y)&15;y=y*(2-(x&255)*y)&255;y=y*(2-((x&65535)*y&65535))&65535;y=y*(2-x*y%this.DV)%this.DV;return y>0?this.DV-y:-y}function Montgomery(m){this.m=m;this.mp=m.invDigit();this.mpl=this.mp&32767;this.mph=this.mp>>15;this.um=(1<0)this.m.subTo(r,r);return r}function montRevert(x){var r=nbi();x.copyTo(r);this.reduce(r);return r}function montReduce(x){while(x.t<=this.mt2)x[x.t++]=0;for(var i=0;i>15)*this.mpl&this.um)<<15)&x.DM;j=i+this.m.t;x[j]+=this.m.am(0,u0,x,i,0,this.m.t);while(x[j]>=x.DV){x[j]-=x.DV;x[++j]++}}x.clamp();x.drShiftTo(this.m.t,x);if(x.compareTo(this.m)>=0)x.subTo(this.m,x)}function montSqrTo(x,r){x.squareTo(r);this.reduce(r)}function montMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}Montgomery.prototype.convert=montConvert;Montgomery.prototype.revert=montRevert;Montgomery.prototype.reduce=montReduce;Montgomery.prototype.mulTo=montMulTo;Montgomery.prototype.sqrTo=montSqrTo;function bnpIsEven(){return(this.t>0?this[0]&1:this.s)==0}function bnpExp(e,z){if(e>4294967295||e<1)return BigInteger.ONE;var r=nbi(),r2=nbi(),g=z.convert(this),i=nbits(e)-1;g.copyTo(r);while(--i>=0){z.sqrTo(r,r2);if((e&1<0)z.mulTo(r2,g,r);else{var t=r;r=r2;r2=t}}return z.revert(r)}function bnModPowInt(e,m){var z;if(e<256||m.isEven())z=new Classic(m);else z=new Montgomery(m);return this.exp(e,z)}proto.copyTo=bnpCopyTo;proto.fromInt=bnpFromInt;proto.fromString=bnpFromString;proto.clamp=bnpClamp;proto.dlShiftTo=bnpDLShiftTo;proto.drShiftTo=bnpDRShiftTo;proto.lShiftTo=bnpLShiftTo;proto.rShiftTo=bnpRShiftTo;proto.subTo=bnpSubTo;proto.multiplyTo=bnpMultiplyTo;proto.squareTo=bnpSquareTo;proto.divRemTo=bnpDivRemTo;proto.invDigit=bnpInvDigit;proto.isEven=bnpIsEven;proto.exp=bnpExp;proto.toString=bnToString;proto.negate=bnNegate;proto.abs=bnAbs;proto.compareTo=bnCompareTo;proto.bitLength=bnBitLength;proto.mod=bnMod;proto.modPowInt=bnModPowInt;function nbi(){return new BigInteger(null)}function bnClone(){var r=nbi();this.copyTo(r);return r}function bnIntValue(){if(this.s<0){if(this.t==1)return this[0]-this.DV;else if(this.t==0)return-1}else if(this.t==1)return this[0];else if(this.t==0)return 0;return(this[1]&(1<<32-this.DB)-1)<>24}function bnShortValue(){return this.t==0?this.s:this[0]<<16>>16}function bnpChunkSize(r){return Math.floor(Math.LN2*this.DB/Math.log(r))}function bnSigNum(){if(this.s<0)return-1;else if(this.t<=0||this.t==1&&this[0]<=0)return 0;else return 1}function bnpToRadix(b){if(b==null)b=10;if(this.signum()==0||b<2||b>36)return"0";var cs=this.chunkSize(b);var a=Math.pow(b,cs);var d=nbv(a),y=nbi(),z=nbi(),r="";this.divRemTo(d,y,z);while(y.signum()>0){r=(a+z.intValue()).toString(b).substr(1)+r;y.divRemTo(d,y,z)}return z.intValue().toString(b)+r}function bnpFromRadix(s,b){var self=this;self.fromInt(0);if(b==null)b=10;var cs=self.chunkSize(b);var d=Math.pow(b,cs),mi=false,j=0,w=0;for(var i=0;i=cs){self.dMultiply(d);self.dAddOffset(w,0);j=0;w=0}}if(j>0){self.dMultiply(Math.pow(b,j));self.dAddOffset(w,0)}if(mi)BigInteger.ZERO.subTo(self,self)}function bnpFromNumber(a,b,c){var self=this;if("number"==typeof b){if(a<2)self.fromInt(1);else{self.fromNumber(a,c);if(!self.testBit(a-1))self.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,self);if(self.isEven())self.dAddOffset(1,0);while(!self.isProbablePrime(b)){self.dAddOffset(2,0);if(self.bitLength()>a)self.subTo(BigInteger.ONE.shiftLeft(a-1),self)}}}else{var x=new Array,t=a&7;x.length=(a>>3)+1;b.nextBytes(x);if(t>0)x[0]&=(1<0){if(p>p)!=(self.s&self.DM)>>p)r[k++]=d|self.s<=0){if(p<8){d=(self[i]&(1<>(p+=self.DB-8)}else{d=self[i]>>(p-=8)&255;if(p<=0){p+=self.DB;--i}}if((d&128)!=0)d|=-256;if(k===0&&(self.s&128)!=(d&128))++k;if(k>0||d!=self.s)r[k++]=d}}return r}function bnEquals(a){return this.compareTo(a)==0}function bnMin(a){return this.compareTo(a)<0?this:a}function bnMax(a){return this.compareTo(a)>0?this:a}function bnpBitwiseTo(a,op,r){var self=this;var i,f,m=Math.min(a.t,self.t);for(i=0;i>=16;r+=16}if((x&255)==0){x>>=8;r+=8}if((x&15)==0){x>>=4;r+=4}if((x&3)==0){x>>=2;r+=2}if((x&1)==0)++r;return r}function bnGetLowestSetBit(){for(var i=0;i=this.t)return this.s!=0;return(this[j]&1<>=self.DB}if(a.t>=self.DB}c+=self.s}else{c+=self.s;while(i>=self.DB}c+=a.s}r.s=c<0?-1:0;if(c>0)r[i++]=c;else if(c<-1)r[i++]=self.DV+c;r.t=i;r.clamp()}function bnAdd(a){var r=nbi();this.addTo(a,r);return r}function bnSubtract(a){var r=nbi();this.subTo(a,r);return r}function bnMultiply(a){var r=nbi();this.multiplyTo(a,r);return r}function bnSquare(){var r=nbi();this.squareTo(r);return r}function bnDivide(a){var r=nbi();this.divRemTo(a,r,null);return r}function bnRemainder(a){var r=nbi();this.divRemTo(a,null,r);return r}function bnDivideAndRemainder(a){var q=nbi(),r=nbi();this.divRemTo(a,q,r);return new Array(q,r)}function bnpDMultiply(n){this[this.t]=this.am(0,n-1,this,0,0,this.t);++this.t;this.clamp()}function bnpDAddOffset(n,w){if(n==0)return;while(this.t<=w)this[this.t++]=0;this[w]+=n;while(this[w]>=this.DV){this[w]-=this.DV;if(++w>=this.t)this[this.t++]=0;++this[w]}}function NullExp(){}function nNop(x){return x}function nMulTo(x,y,r){x.multiplyTo(y,r)}function nSqrTo(x,r){x.squareTo(r)}NullExp.prototype.convert=nNop;NullExp.prototype.revert=nNop;NullExp.prototype.mulTo=nMulTo;NullExp.prototype.sqrTo=nSqrTo;function bnPow(e){return this.exp(e,new NullExp)}function bnpMultiplyLowerTo(a,n,r){var i=Math.min(this.t+a.t,n);r.s=0;r.t=i;while(i>0)r[--i]=0;var j;for(j=r.t-this.t;i=0)r[i]=0;for(i=Math.max(n-this.t,0);i2*this.m.t)return x.mod(this.m);else if(x.compareTo(this.m)<0)return x;else{var r=nbi();x.copyTo(r);this.reduce(r);return r}}function barrettRevert(x){return x}function barrettReduce(x){var self=this;x.drShiftTo(self.m.t-1,self.r2);if(x.t>self.m.t+1){x.t=self.m.t+1;x.clamp()}self.mu.multiplyUpperTo(self.r2,self.m.t+1,self.q3);self.m.multiplyLowerTo(self.q3,self.m.t+1,self.r2);while(x.compareTo(self.r2)<0)x.dAddOffset(1,self.m.t+1);x.subTo(self.r2,x);while(x.compareTo(self.m)>=0)x.subTo(self.m,x)}function barrettSqrTo(x,r){x.squareTo(r);this.reduce(r)}function barrettMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}Barrett.prototype.convert=barrettConvert;Barrett.prototype.revert=barrettRevert;Barrett.prototype.reduce=barrettReduce;Barrett.prototype.mulTo=barrettMulTo;Barrett.prototype.sqrTo=barrettSqrTo;function bnModPow(e,m){var i=e.bitLength(),k,r=nbv(1),z;if(i<=0)return r;else if(i<18)k=1;else if(i<48)k=3;else if(i<144)k=4;else if(i<768)k=5;else k=6;if(i<8)z=new Classic(m);else if(m.isEven())z=new Barrett(m);else z=new Montgomery(m);var g=new Array,n=3,k1=k-1,km=(1<1){var g2=nbi();z.sqrTo(g[1],g2);while(n<=km){g[n]=nbi();z.mulTo(g2,g[n-2],g[n]);n+=2}}var j=e.t-1,w,is1=true,r2=nbi(),t;i=nbits(e[j])-1;while(j>=0){if(i>=k1)w=e[j]>>i-k1&km;else{w=(e[j]&(1<0)w|=e[j-1]>>this.DB+i-k1}n=k;while((w&1)==0){w>>=1;--n}if((i-=n)<0){i+=this.DB;--j}if(is1){g[w].copyTo(r);is1=false}else{while(n>1){z.sqrTo(r,r2);z.sqrTo(r2,r);n-=2}if(n>0)z.sqrTo(r,r2);else{t=r;r=r2;r2=t}z.mulTo(r2,g[w],r)}while(j>=0&&(e[j]&1<0){x.rShiftTo(g,x);y.rShiftTo(g,y)}while(x.signum()>0){if((i=x.getLowestSetBit())>0)x.rShiftTo(i,x);if((i=y.getLowestSetBit())>0)y.rShiftTo(i,y);if(x.compareTo(y)>=0){x.subTo(y,x);x.rShiftTo(1,x)}else{y.subTo(x,y);y.rShiftTo(1,y)}}if(g>0)y.lShiftTo(g,y);return y}function bnpModInt(n){if(n<=0)return 0;var d=this.DV%n,r=this.s<0?n-1:0;if(this.t>0)if(d==0)r=this[0]%n;else for(var i=this.t-1;i>=0;--i)r=(d*r+this[i])%n;return r}function bnModInverse(m){var ac=m.isEven();if(this.isEven()&&ac||m.signum()==0)return BigInteger.ZERO;var u=m.clone(),v=this.clone();var a=nbv(1),b=nbv(0),c=nbv(0),d=nbv(1);while(u.signum()!=0){while(u.isEven()){u.rShiftTo(1,u);if(ac){if(!a.isEven()||!b.isEven()){a.addTo(this,a);b.subTo(m,b)}a.rShiftTo(1,a)}else if(!b.isEven())b.subTo(m,b);b.rShiftTo(1,b)}while(v.isEven()){v.rShiftTo(1,v);if(ac){if(!c.isEven()||!d.isEven()){c.addTo(this,c);d.subTo(m,d)}c.rShiftTo(1,c)}else if(!d.isEven())d.subTo(m,d);d.rShiftTo(1,d)}if(u.compareTo(v)>=0){u.subTo(v,u);if(ac)a.subTo(c,a);b.subTo(d,b)}else{v.subTo(u,v);if(ac)c.subTo(a,c);d.subTo(b,d)}}if(v.compareTo(BigInteger.ONE)!=0)return BigInteger.ZERO;if(d.compareTo(m)>=0)return d.subtract(m);if(d.signum()<0)d.addTo(m,d);else return d;if(d.signum()<0)return d.add(m);else return d}proto.chunkSize=bnpChunkSize;proto.toRadix=bnpToRadix;proto.fromRadix=bnpFromRadix;proto.fromNumber=bnpFromNumber;proto.bitwiseTo=bnpBitwiseTo;proto.changeBit=bnpChangeBit;proto.addTo=bnpAddTo;proto.dMultiply=bnpDMultiply;proto.dAddOffset=bnpDAddOffset;proto.multiplyLowerTo=bnpMultiplyLowerTo;proto.multiplyUpperTo=bnpMultiplyUpperTo;proto.modInt=bnpModInt;proto.clone=bnClone;proto.intValue=bnIntValue;proto.byteValue=bnByteValue;proto.shortValue=bnShortValue;proto.signum=bnSigNum;proto.toByteArray=bnToByteArray;proto.equals=bnEquals;proto.min=bnMin;proto.max=bnMax;proto.and=bnAnd;proto.or=bnOr;proto.xor=bnXor;proto.andNot=bnAndNot;proto.not=bnNot;proto.shiftLeft=bnShiftLeft;proto.shiftRight=bnShiftRight;proto.getLowestSetBit=bnGetLowestSetBit;proto.bitCount=bnBitCount;proto.testBit=bnTestBit;proto.setBit=bnSetBit;proto.clearBit=bnClearBit;proto.flipBit=bnFlipBit;proto.add=bnAdd;proto.subtract=bnSubtract;proto.multiply=bnMultiply;proto.divide=bnDivide;proto.remainder=bnRemainder;proto.divideAndRemainder=bnDivideAndRemainder;proto.modPow=bnModPow;proto.modInverse=bnModInverse;proto.pow=bnPow;proto.gcd=bnGCD;proto.square=bnSquare;BigInteger.ZERO=nbv(0);BigInteger.ONE=nbv(1);BigInteger.valueOf=nbv;BigInteger.fromByteArrayUnsigned=function(ba){if(!ba.length){return new BigInteger.valueOf(0)}else if(ba[0]&128){return new BigInteger([0].concat(ba))}else{return new BigInteger(ba)}};BigInteger.fromByteArraySigned=function(ba){if(ba[0]&128){ba[0]&=127;return BigInteger.fromByteArrayUnsigned(ba).negate()}else{return BigInteger.fromByteArrayUnsigned(ba)}};BigInteger.prototype.toByteArrayUnsigned=function(){var ba=this.abs().toByteArray();if(!ba.length){return ba}if(ba[0]===0){ba=ba.slice(1)}for(var i=0;i>8&255;rng_pool[rng_pptr++]^=x>>16&255;rng_pool[rng_pptr++]^=x>>24&255;if(rng_pptr>=rng_psize)rng_pptr-=rng_psize}function rng_seed_time(){rng_seed_int((new Date).getTime())}if(rng_pool==null){rng_pool=new Array;rng_pptr=0;var t;while(rng_pptr>>8;rng_pool[rng_pptr++]=t&255}rng_pptr=0;rng_seed_time()}function rng_get_byte(){if(rng_state==null){rng_seed_time();rng_state=prng_newstate();rng_state.init(rng_pool);for(rng_pptr=0;rng_pptr=240){opcode=opcode<<8|this.buffer[i++]}var len;if(opcode>0&&opcode>>8&255)}else{this.buffer.push(Opcode.map.OP_PUSHDATA4);this.buffer.push(data.length&255);this.buffer.push(data.length>>>8&255);this.buffer.push(data.length>>>16&255);this.buffer.push(data.length>>>24&255)}this.buffer=this.buffer.concat(data);this.chunks.push(data)};Script.createOutputScript=function(address){var script=new Script;address=new Address(address);if(!address.version){script.writeOp(Opcode.map.OP_DUP);script.writeOp(Opcode.map.OP_HASH160);script.writeBytes(address.hash);script.writeOp(Opcode.map.OP_EQUALVERIFY);script.writeOp(Opcode.map.OP_CHECKSIG)}else{script.writeOp(Opcode.map.OP_HASH160);script.writeBytes(address.hash);script.writeOp(Opcode.map.OP_EQUAL)}return script};Script.prototype.extractPubkeys=function(){return this.chunks.filter(function(chunk){return chunk[0]==4&&chunk.length==65||chunk[0]<4&&chunk.length==33})};Script.createMultiSigOutputScript=function(m,pubkeys){var script=new Script;pubkeys=pubkeys.sort();script.writeOp(Opcode.map.OP_1+m-1);for(var i=0;i65){var args=arguments[0].split(":");return this.addInput(args[0],args[1])}else{this.ins.push(new TransactionIn({outpoint:{hash:tx.hash||tx,index:outIndex},script:new Script,sequence:4294967295}))}};Transaction.prototype.addOutput=function(address,value){if(arguments[0]instanceof TransactionOut){this.outs.push(arguments[0]);return}if(arguments[0].indexOf(":")>=0){var args=arguments[0].split(":");address=args[0];value=parseInt(args[1])}this.outs.push(new TransactionOut({value:value,script:Script.createOutputScript(address)}))};var bytesToWords=function(bytes){for(var words=[],i=0,b=0;i>>5]|=bytes[i]<<24-b%32;return words};var wordsToBytes=function(words){for(var bytes=[],b=0;b>>5]>>>24-b%32&255);return bytes};Transaction.prototype.serialize=function(){var buffer=[];buffer=buffer.concat(util.numToBytes(parseInt(this.version),4));buffer=buffer.concat(util.numToVarInt(this.ins.length));for(var i=0;i=0;i--){var txout=this.outs[i];var hash=txout.script.simpleOutPubKeyHash();if(!wallet.hasHash(hash)){allToMe=false}else{firstMeRecvHash=hash}firstRecvHash=hash}for(var i=this.ins.length-1;i>=0;i--){var txin=this.ins[i];firstSendHash=txin.script.simpleInPubKeyHash();if(!wallet.hasHash(firstSendHash)){allFromMe=false;break}}var impact=this.calcImpact(wallet);var analysis={};analysis.impact=impact;if(impact.sign>0&&impact.value>0){analysis.type="recv";analysis.addr=new Address(firstMeRecvHash)}else if(allFromMe&&allToMe){analysis.type="self"}else if(allFromMe){analysis.type="sent";analysis.addr=new Address(firstRecvHash)}else{analysis.type="other"}return analysis};Transaction.prototype.getDescription=function(wallet){var analysis=this.analyze(wallet);if(!analysis)return"";switch(analysis.type){case"recv":return"Received with "+analysis.addr;break;case"sent":return"Payment to "+analysis.addr;break;case"self":return"Payment to yourself";break;case"other":default:return""}};Transaction.prototype.getTotalOutValue=function(){return this.outs.reduce(function(t,o){return t+o.value},0)};Transaction.prototype.getTotalValue=Transaction.prototype.getTotalOutValue;Transaction.prototype.calcImpact=function(wallet){if(!(wallet instanceof Wallet))return 0;var valueOut=this.outs.filter(function(o){return wallet.hasHash(conv.bytesToHex(o.script.simpleOutPubKeyHash()))}).reduce(function(t,o){return t+o.value},0);var valueIn=this.ins.filter(function(i){return wallet.hasHash(conv.bytesToHex(i.script.simpleInPubKeyHash()))&&wallet.txIndex[i.outpoint.hash]}).reduce(function(t,i){return t+wallet.txIndex[i.outpoint.hash].outs[i.outpoint.index].value},0);if(valueOut>valueIn){return{sign:1,value:valueOut-valueIn}}else{return{sign:-1,value:valueIn-valueOut}}};Transaction.deserialize=function(buffer){if(typeof buffer=="string"){buffer=conv.hexToBytes(buffer)}var pos=0;var readAsInt=function(bytes){if(bytes==0)return 0;pos++;return buffer[pos-1]+readAsInt(bytes-1)*256};var readVarInt=function(){pos++;if(buffer[pos-1]<253){return buffer[pos-1]}return readAsInt(buffer[pos-1]-251)};var readBytes=function(bytes){pos+=bytes;return buffer.slice(pos-bytes,pos)};var readVarString=function(){var size=readVarInt();return readBytes(size)};var obj={ins:[],outs:[]};obj.version=readAsInt(4);var ins=readVarInt();for(var i=0;i0)this.address=this.script.toAddress();this.value=util.isArray(data.value)?util.bytesToNum(data.value):"string"==typeof data.value?parseInt(data.value):data.value instanceof BigInteger?parseInt(data.value.toString()):data.value};TransactionOut.prototype.clone=function(){var newTxout=new TransactionOut({script:this.script.clone(),value:this.value});return newTxout};module.exports.Transaction=Transaction;module.exports.TransactionIn=TransactionIn;module.exports.TransactionOut=TransactionOut},{"./address":1,"./convert":4,"./crypto-js/crypto":5,"./ecdsa":10,"./eckey":11,"./jsbn/jsbn":14,"./script":20,"./util":22,"./wallet":23}],22:[function(require,module,exports){var BigInteger=require("./jsbn/jsbn");var Crypto=require("./crypto-js/crypto");module.exports={isArray:Array.isArray||function(o){return Object.prototype.toString.call(o)==="[object Array]"},makeFilledArray:function(len,val){var array=[];var i=0;while(i8?value.substr(0,value.length-8):"0";var decimalPart=value.length>8?value.substr(value.length-8):value;while(decimalPart.length<8)decimalPart="0"+decimalPart;decimalPart=decimalPart.replace(/0*$/,"");while(decimalPart.length<2)decimalPart+="0";return integerPart+"."+decimalPart},parseValue:function(valueString){var valueComp=valueString.split(".");var integralPart=valueComp[0];var fractionalPart=valueComp[1]||"0";while(fractionalPart.length<8)fractionalPart+="0";fractionalPart=fractionalPart.replace(/^0+/g,"");var value=BigInteger.valueOf(parseInt(integralPart));value=value.multiply(BigInteger.valueOf(1e8));value=value.add(BigInteger.valueOf(parseInt(fractionalPart)));return value},bytesToWords:function(bytes){var words=[];for(var i=0,b=0;i>>5]|=bytes[i]<<24-b%32}return words},wordsToBytes:function(words){var bytes=[];for(var b=0;b>>5]>>>24-b%32&255)}return bytes},sha256ripe160:function(data){return Crypto.RIPEMD160(Crypto.SHA256(data,{asBytes:true}),{asBytes:true})},error:function(msg){throw new Error(msg)}}},{"./crypto-js/crypto":5,"./jsbn/jsbn":14}],23:[function(require,module,exports){var Script=require("./script");var ECKey=require("./eckey");var conv=require("./convert");var util=require("./util");var BigInteger=require("./jsbn/jsbn");var Transaction=require("./transaction").Transaction;var TransactionIn=require("./transaction").TransactionIn;var TransactionOut=require("./transaction").TransactionOut;var Wallet=function(){var keys=[];this.addressHashes=[];this.txIndex={};this.unspentOuts=[];this.addressPointer=0;this.addKey=function(key,pub){if(!(key instanceof ECKey)){key=new ECKey(key)}keys.push(key);if(pub){if("string"===typeof pub){pub=conv.hexToBytes(pub)}key.setPub(pub)}this.addressHashes.push(key.getBitcoinAddress().getHash())};this.addKeys=function(keys,pubs){if("string"===typeof keys){keys=keys.split(",")}if("string"===typeof pubs){pubs=pubs.split(",")}var i;if(Array.isArray(pubs)&&keys.length==pubs.length){for(i=0;i=txValue)break}if(availableValue0){sendTx.addOutput(this.getNextAddress(),changeValue)}var hashType=1;for(i=0;i= 2147483648) { + if (this.priv) throw new Error("Can't do private derivation on public key!") + blob = [0].concat(priv.slice(0,32),util.numToBytes(this.i,4).reverse()) + } + else blob = pub.concat(util.numToBytes(this.i,4).reverse()) + + I = Crypto.HMAC(Crypto.SHA512,blob,this.chaincode,{ asBytes: true }) + + if (this.type == 'priv') { + Ikey = Bitcoin.BigInteger.fromByteArrayUnsigned(I.slice(0,32)) + newkey = new key(this.key.priv.add(Ikey)) + newkey.compressed = true + fingerprint = util.sha256ripe160(this.key.getPub()).slice(0,4) + } + else { + newkey = ECPointFp.decodeFrom(ecparams.getCurve(),this.key) + .add(new key(I.slice(0,32).concat([1])).getPubPoint()) + .getEncoded(true); + fingerprint = util.sha256ripe160(this.key).slice(0,4) + } + return new BIP32key({ + vbytes: this.vbytes, + type: this.type, + depth: this.depth + 1, + fingerprint: fingerprint, + i: i, + chaincode: I.slice(32), + key: newkey + }) +} + +BIP32key.prototype.clone = function() { + return new BIP32key(this); +} + +BIP32key.prototype.privtopub = BIP32key.prototype.getPub = function() { + if (this.type == 'pub') return this.clone() + return new BIP32key({ + vbytes: conv.stringToBytes(PUBDERIV), + type: 'pub', + depth: this.depth, + fingerprint: this.fingerprint, + i: this.i, + chaincode: this.chaincode, + key: this.key.getPub() + }) +} + +BIP32key.prototype.fromMasterKey = function(seed) { + var I = Bitcoin.Crypto.HMAC(Bitcoin.Crypto.SHA512,seed,"Bitcoin seed",{ asBytes: true }) + return new BIP32key({ + vbytes: conv.stringToBytes(PRIVDERIV), + type: 'priv', + depth: 0, + fingerprint: [0,0,0,0], + i: 0, + chaincode: I.slice(32), + key: new key(I.slice(0,32).concat([1])) + }) +} + +BIP32key.prototype.getKey = function() { return this.key } + +module.exports = BIP32key; diff --git a/src/bitcoin.js b/src/bitcoin.js deleted file mode 100644 index 8789467..0000000 --- a/src/bitcoin.js +++ /dev/null @@ -1,165 +0,0 @@ -/* - function makeKeypair() - { - // Generate private key - var n = ecparams.getN(); - var n1 = n.subtract(BigInteger.ONE); - var r = new BigInteger(n.bitLength(), rng); - - var privateKey = r.mod(n1).add(BigInteger.ONE); - - // Generate public key - var G = ecparams.getG(); - var publicPoint = G.multiply(privateKey); - - return {priv: privateKey, pubkey: publicPoint}; - }; - - function serializeTransaction(tx) - { - var buffer = []; - buffer = buffer.concat(Crypto.util.wordsToBytes([parseInt(tx.version)])); - buffer = buffer.concat(numToVarInt(tx.ins.length)); - for (var i = 0; i < tx.ins.length; i++) { - var txin = tx.ins[i]; - buffer = buffer.concat(Crypto.util.hexToBytes(txin.outpoint.hash)); - buffer = buffer.concat(Crypto.util.wordsToBytes([parseInt(txin.index)])); - var scriptBytes = Crypto.util.hexToBytes(txin.script); - buffer = buffer.concat(numToVarInt(scriptBytes.length)); - buffer = buffer.concat(scriptBytes); - buffer = buffer.concat(Crypto.util.wordsToBytes([parseInt(txin.sequence)])); - } - buffer = buffer.concat(numToVarInt(tx.outs.length)); - for (var i = 0; i < tx.outs.length; i++) { - var txout = tx.outs[i]; - var valueHex = txout.value.toString(16); - while (valueHex.length < 16) valueHex = "0" + valueHex; - buffer = buffer.concat(Crypto.util.hexToBytes(valueHex)); - var scriptBytes = Crypto.util.hexToBytes(txout.script); - buffer = buffer.concat(numToVarInt(scriptBytes.length)); - buffer = buffer.concat(scriptBytes); - } - buffer = buffer.concat(Crypto.util.wordsToBytes([parseInt(tx.lock_time)])); - - return buffer; - }; - - var OP_CODESEPARATOR = 171; - - var SIGHASH_ALL = 1; - var SIGHASH_NONE = 2; - var SIGHASH_SINGLE = 3; - var SIGHASH_ANYONECANPAY = 80; - - function hashTransactionForSignature(scriptCode, tx, inIndex, hashType) - { - // TODO: We need to actually deep copy here - var txTmp = tx; - - // In case concatenating two scripts ends up with two codeseparators, - // or an extra one at the end, this prevents all those possible incompatibilities. - scriptCode = scriptCode.filter(function (val) { - return val !== OP_CODESEPARATOR; - }); - - // Blank out other inputs' signatures - for (var i = 0; i < txTmp.ins.length; i++) { - txTmp.ins[i].script = Crypto.util.bytesToHex([]); - } - txTmp.ins[inIndex].script = Crypto.util.bytesToHex(scriptCode); - - // Blank out some of the outputs - if ((hashType & 0x1f) == SIGHASH_NONE) { - txTmp.outs = []; - - // Let the others update at will - for (var i = 0; i < txTmp.ins.length; i++) - if (i != inIndex) - txTmp.ins[i].sequence = 0; - } else if ((hashType & 0x1f) == SIGHASH_SINGLE) { - // TODO: Implement - } - - // Blank out other inputs completely, not recommended for open transactions - if (hashType & SIGHASH_ANYONECANPAY) { - txTmp.ins = [txTmp.ins[inIndex]]; - } - - var buffer = serializeTransaction(txTmp); - - buffer.concat(Crypto.util.wordsToBytes([parseInt(hashType)])); - - console.log(buffer); - - return Crypto.SHA256(Crypto.SHA256(buffer, {asBytes: true}), {asBytes: true}); - }; - - function verifyTransactionSignature(tx) { - var hash = hashTransactionForSignature([], tx, 0, 0); - return Crypto.util.bytesToHex(hash); - }; - - function numToVarInt(i) - { - // TODO: THIS IS TOTALLY UNTESTED! - if (i < 0xfd) { - // unsigned char - return [i]; - } else if (i <= 1<<16) { - // unsigned short (LE) - return [0xfd, i >>> 8, i & 255]; - } else if (i <= 1<<32) { - // unsigned int (LE) - return [0xfe].concat(Crypto.util.wordsToBytes([i])); - } else { - // unsigned long long (LE) - return [0xff].concat(Crypto.util.wordsToBytes([i >>> 32, i])); - } - }; - - var testTx = { - "version":"1", - "lock_time":"0", - "block": { - "hash":"N/A", - "height":115806 - }, - "index":6, - "hash":"WUFzjKubG1kqfJWMb4qZdlhU2F3l5NGXN7AUg8Jwl14=", - "ins":[{ - "outpoint":{ - "hash":"nqcbMM1oRhfLdZga11q7x0CpUMujm+vtxHXO9V0gnwE=", - "index":0 - }, - "script":"RzBEAiB2XXkx1pca9SlfCmCGNUVf+h2sAFBttcxG1VnypIcvEgIgXrOp7LSdYBYp3nPsQAz8BOLD3K4pAlXfZImP1rkzk2EBQQRi7NcODzNfnVqLtG79Axp5UF6EhFIhCmzqKqssfKpfCIOmzCuXEeDFUFvFzeGLJx5N+wp2qRS1TqYezGD3yERk", - "sequence":4294967295 - }], - "outs":[{ - "value":"3000000000", - "script":"dqkUBLZwqhAPRVgZvwI8MN5gLHbU8NOIrA==" - },{ - "value":"25937000000", - "script":"dqkUQ82gJ0O5vOBg6yK5/yorLLV5zLKIrA==" - }] - }; - - TODO: Make this stuff into test cases ;) - $(function () { - var key = new Bitcoin.ECKey(Crypto.util.hexToBytes("5c0b98e524ad188ddef35dc6abba13c34a351a05409e5d285403718b93336a4a")); - key = new Bitcoin.ECKey(Crypto.util.hexToBytes("180cb41c7c600be951b5d3d0a7334acc7506173875834f7a6c4c786a28fcbb19")); - //console.log(key.getBitcoinAddress().toString()); - //var message = Crypto.util.hexToBytes("2aec28d323ee7b06a799d540d224b351161fe48967174ca5e43164e86137da11"); - //message = [0]; - //var out = key.sign(message); - //console.log("pubkey: "+Crypto.util.bytesToHex(key.getPub())); - //console.log("sig: "+Crypto.util.bytesToHex(out)); - - //console.log(key.verify(message, out)); - - //console.log(Bitcoin.ECDSA.verify(message, Crypto.util.hexToBytes("3046022100dffbc26774fc841bbe1c1362fd643609c6e42dcb274763476d87af2c0597e89e022100c59e3c13b96b316cae9fa0ab0260612c7a133a6fe2b3445b6bf80b3123bf274d"), Crypto.util.hexToBytes("0401de173aa944eacf7e44e5073baca93fb34fe4b7897a1c82c92dfdc8a1f75ef58cd1b06e8052096980cb6e1ad6d3df143c34b3d7394bae2782a4df570554c2fb"))); - - //console.log(Bitcoin.ECDSA.verify(Crypto.util.hexToBytes("230aba77ccde46bb17fcb0295a92c0cc42a6ea9f439aaadeb0094625f49e6ed8"), Crypto.util.hexToBytes("3046022100a3ee5408f0003d8ef00ff2e0537f54ba09771626ff70dca1f01296b05c510e85022100d4dc70a5bb50685b65833a97e536909a6951dd247a2fdbde6688c33ba6d6407501"),Crypto.util.hexToBytes("04a19c1f07c7a0868d86dbb37510305843cc730eb3bea8a99d92131f44950cecd923788419bfef2f635fad621d753f30d4b4b63b29da44b4f3d92db974537ad5a4"))); - //console.log(Bitcoin.ECDSA.verify(Crypto.util.hexToBytes("c2c75bb77d7a5acddceb1d45ceef58e7451fd0d3abc9d4c16df7848eefafe00d"), Crypto.util.hexToBytes("3045022100ff9362dadcbf1f6ef954bc8eb27144bbb4f49abd32be1eb04c311151dcf4bcf802205112c2ca6a25aefb8be98bf460c5a9056c01253f31e118d80b81ec9604e3201a01"),Crypto.util.hexToBytes("04fe62ce7892ec209310c176ef7f06565865e286e8699e884603657efa9aa51086785099d544d4e04f1f7b4b065205c1783fade8daf4ba1e0d1962292e8eb722cd"))); - }); - // -*/ diff --git a/src/convert.js b/src/convert.js index 40e11f6..0079145 100644 --- a/src/convert.js +++ b/src/convert.js @@ -51,7 +51,7 @@ module.exports.base64ToBytes = function(base64) { // Hex only (allowing bin would be potentially risky, as 01010101 = \x01 * 4 or 85) module.exports.coerceToBytes = function(input) { - if (typeof input == "string") return Crypto.util.hexToBytes(input); + if (typeof input == "string") return module.exports.hexToBytes(input); return input; } diff --git a/src/crypto-js/crypto.js b/src/crypto-js/crypto.js index 68ab38b..da96cb1 100644 --- a/src/crypto-js/crypto.js +++ b/src/crypto-js/crypto.js @@ -61,4 +61,6 @@ var Binary = charenc.Binary = { }; module.exports.SHA256 = require('./sha256'); +module.exports.SHA512 = require('./sha512'); module.exports.RIPEMD160 = require('./ripemd160'); +module.exports.HMAC = require('./hmac'); diff --git a/src/crypto-js/hmac.js b/src/crypto-js/hmac.js new file mode 100644 index 0000000..d849992 --- /dev/null +++ b/src/crypto-js/hmac.js @@ -0,0 +1,38 @@ +/*! + * Crypto-JS v2.0.0 + * http://code.google.com/p/crypto-js/ + * Copyright (c) 2009, Jeff Mott. All rights reserved. + * http://code.google.com/p/crypto-js/wiki/License + */ + +var conv = require('../convert'), + util = require('../util'); + +// Shortcuts + +module.exports = function (hasher, message, key, options) { + + // Convert to byte arrays + if (message.constructor == String) message = conv.stringToBytes(message); + if (key.constructor == String) key = conv.stringToBytes(key); + /* else, assume byte arrays already */ + + // Allow arbitrary length keys + if (key.length > hasher._blocksize) + key = hasher(key, { asBytes: true }); + + // XOR keys with pad constants + var okey = key.slice(0), + ikey = key.slice(0); + for (var i = 0; i < hasher._blocksize; i++) { + okey[i] ^= 0x5C; + ikey[i] ^= 0x36; + } + + var hmacbytes = hasher(okey.concat(hasher(ikey.concat(message), { asBytes: true })), { asBytes: true }); + + return options && options.asBytes ? hmacbytes : + options && options.asString ? conv.bytesToString(hmacbytes) : + conv.bytesToHex(hmacbytes); + +}; diff --git a/src/crypto-js/sha256.js b/src/crypto-js/sha256.js index b9ecb4d..ce9f87b 100644 --- a/src/crypto-js/sha256.js +++ b/src/crypto-js/sha256.js @@ -5,8 +5,8 @@ code.google.com/p/crypto-js code.google.com/p/crypto-js/wiki/License */ -var conv = require('../convert'); -var UTF8 = require('./crypto').charenc.UTF8; +var conv = require('../convert'), + util = require('../util'); // Initialization round constants tables var K = []; @@ -40,22 +40,6 @@ var K = []; } }()); -var bytesToWords = function (bytes) { - var words = []; - for (var i = 0, b = 0; i < bytes.length; i++, b += 8) { - words[b >>> 5] |= bytes[i] << (24 - b % 32); - } - return words; -}; - -var wordsToBytes = function (words) { - var bytes = []; - for (var b = 0; b < words.length * 32; b += 8) { - bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF); - } - return bytes; -}; - // Reusable object var W = []; @@ -128,10 +112,10 @@ module.exports = function(message, options) {; 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ]; if (message.constructor === String) { - message = UTF8.stringToBytes(message); + message = conv.stringToBytes(message); } - var m = bytesToWords(message); + var m = util.bytesToWords(message); var l = message.length * 8; m[l >> 5] |= 0x80 << (24 - l % 32); @@ -141,8 +125,10 @@ module.exports = function(message, options) {; processBlock(H, m, i); } - var digestbytes = wordsToBytes(H); + var digestbytes = util.wordsToBytes(H); return options && options.asBytes ? digestbytes : options && options.asString ? Binary.bytesToString(digestbytes) : conv.bytesToHex(digestbytes); }; + +module.exports._blocksize = 64 diff --git a/src/crypto-js/sha512.js b/src/crypto-js/sha512.js new file mode 100644 index 0000000..42dd446 --- /dev/null +++ b/src/crypto-js/sha512.js @@ -0,0 +1,240 @@ + +var conv = require('../convert'); +var util = require('../util'); + + var K = [ + [0x428a2f98, 0xd728ae22], [0x71374491, 0x23ef65cd], + [0xb5c0fbcf, 0xec4d3b2f], [0xe9b5dba5, 0x8189dbbc], + [0x3956c25b, 0xf348b538], [0x59f111f1, 0xb605d019], + [0x923f82a4, 0xaf194f9b], [0xab1c5ed5, 0xda6d8118], + [0xd807aa98, 0xa3030242], [0x12835b01, 0x45706fbe], + [0x243185be, 0x4ee4b28c], [0x550c7dc3, 0xd5ffb4e2], + [0x72be5d74, 0xf27b896f], [0x80deb1fe, 0x3b1696b1], + [0x9bdc06a7, 0x25c71235], [0xc19bf174, 0xcf692694], + [0xe49b69c1, 0x9ef14ad2], [0xefbe4786, 0x384f25e3], + [0x0fc19dc6, 0x8b8cd5b5], [0x240ca1cc, 0x77ac9c65], + [0x2de92c6f, 0x592b0275], [0x4a7484aa, 0x6ea6e483], + [0x5cb0a9dc, 0xbd41fbd4], [0x76f988da, 0x831153b5], + [0x983e5152, 0xee66dfab], [0xa831c66d, 0x2db43210], + [0xb00327c8, 0x98fb213f], [0xbf597fc7, 0xbeef0ee4], + [0xc6e00bf3, 0x3da88fc2], [0xd5a79147, 0x930aa725], + [0x06ca6351, 0xe003826f], [0x14292967, 0x0a0e6e70], + [0x27b70a85, 0x46d22ffc], [0x2e1b2138, 0x5c26c926], + [0x4d2c6dfc, 0x5ac42aed], [0x53380d13, 0x9d95b3df], + [0x650a7354, 0x8baf63de], [0x766a0abb, 0x3c77b2a8], + [0x81c2c92e, 0x47edaee6], [0x92722c85, 0x1482353b], + [0xa2bfe8a1, 0x4cf10364], [0xa81a664b, 0xbc423001], + [0xc24b8b70, 0xd0f89791], [0xc76c51a3, 0x0654be30], + [0xd192e819, 0xd6ef5218], [0xd6990624, 0x5565a910], + [0xf40e3585, 0x5771202a], [0x106aa070, 0x32bbd1b8], + [0x19a4c116, 0xb8d2d0c8], [0x1e376c08, 0x5141ab53], + [0x2748774c, 0xdf8eeb99], [0x34b0bcb5, 0xe19b48a8], + [0x391c0cb3, 0xc5c95a63], [0x4ed8aa4a, 0xe3418acb], + [0x5b9cca4f, 0x7763e373], [0x682e6ff3, 0xd6b2b8a3], + [0x748f82ee, 0x5defb2fc], [0x78a5636f, 0x43172f60], + [0x84c87814, 0xa1f0ab72], [0x8cc70208, 0x1a6439ec], + [0x90befffa, 0x23631e28], [0xa4506ceb, 0xde82bde9], + [0xbef9a3f7, 0xb2c67915], [0xc67178f2, 0xe372532b], + [0xca273ece, 0xea26619c], [0xd186b8c7, 0x21c0c207], + [0xeada7dd6, 0xcde0eb1e], [0xf57d4f7f, 0xee6ed178], + [0x06f067aa, 0x72176fba], [0x0a637dc5, 0xa2c898a6], + [0x113f9804, 0xbef90dae], [0x1b710b35, 0x131c471b], + [0x28db77f5, 0x23047d84], [0x32caab7b, 0x40c72493], + [0x3c9ebe0a, 0x15c9bebc], [0x431d67c4, 0x9c100d4c], + [0x4cc5d4be, 0xcb3e42b6], [0x597f299c, 0xfc657e2a], + [0x5fcb6fab, 0x3ad6faec], [0x6c44198c, 0x4a475817] + ]; + // Reusable objects + var W = []; + for (var i = 0; i < 80; i++) W.push([0,0]) + + /** + * SHA-512 hash algorithm. + */ + var processBlock = function (H, M, offset) { + // Shortcuts + var H0 = H[0]; + var H1 = H[1]; + var H2 = H[2]; + var H3 = H[3]; + var H4 = H[4]; + var H5 = H[5]; + var H6 = H[6]; + var H7 = H[7]; + + var H0h = H0[0]; + var H0l = H0[1]; + var H1h = H1[0]; + var H1l = H1[1]; + var H2h = H2[0]; + var H2l = H2[1]; + var H3h = H3[0]; + var H3l = H3[1]; + var H4h = H4[0]; + var H4l = H4[1]; + var H5h = H5[0]; + var H5l = H5[1]; + var H6h = H6[0]; + var H6l = H6[1]; + var H7h = H7[0]; + var H7l = H7[1]; + + // Working variables + var ah = H0h; + var al = H0l; + var bh = H1h; + var bl = H1l; + var ch = H2h; + var cl = H2l; + var dh = H3h; + var dl = H3l; + var eh = H4h; + var el = H4l; + var fh = H5h; + var fl = H5l; + var gh = H6h; + var gl = H6l; + var hh = H7h; + var hl = H7l; + + // Rounds + for (var i = 0; i < 80; i++) { + // Shortcut + var Wi = W[i]; + + // Extend message + if (i < 16) { + var Wih = Wi[0] = M[offset + i * 2] | 0; + var Wil = Wi[1] = M[offset + i * 2 + 1] | 0; + } else { + // Gamma0 + var gamma0x = W[i - 15]; + var gamma0xh = gamma0x[0]; + var gamma0xl = gamma0x[1]; + var gamma0h = ((gamma0xh >>> 1) | (gamma0xl << 31)) ^ ((gamma0xh >>> 8) | (gamma0xl << 24)) ^ (gamma0xh >>> 7); + var gamma0l = ((gamma0xl >>> 1) | (gamma0xh << 31)) ^ ((gamma0xl >>> 8) | (gamma0xh << 24)) ^ ((gamma0xl >>> 7) | (gamma0xh << 25)); + + // Gamma1 + var gamma1x = W[i - 2]; + var gamma1xh = gamma1x[0]; + var gamma1xl = gamma1x[1]; + var gamma1h = ((gamma1xh >>> 19) | (gamma1xl << 13)) ^ ((gamma1xh << 3) | (gamma1xl >>> 29)) ^ (gamma1xh >>> 6); + var gamma1l = ((gamma1xl >>> 19) | (gamma1xh << 13)) ^ ((gamma1xl << 3) | (gamma1xh >>> 29)) ^ ((gamma1xl >>> 6) | (gamma1xh << 26)); + + // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16] + var Wi7 = W[i - 7]; + var Wi7h = Wi7[0]; + var Wi7l = Wi7[1]; + + var Wi16 = W[i - 16]; + var Wi16h = Wi16[0]; + var Wi16l = Wi16[1]; + + var Wil = gamma0l + Wi7l; + var Wih = gamma0h + Wi7h + ((Wil >>> 0) < (gamma0l >>> 0) ? 1 : 0); + var Wil = Wil + gamma1l; + var Wih = Wih + gamma1h + ((Wil >>> 0) < (gamma1l >>> 0) ? 1 : 0); + var Wil = Wil + Wi16l; + var Wih = Wih + Wi16h + ((Wil >>> 0) < (Wi16l >>> 0) ? 1 : 0); + + Wi[0] = Wih; + Wi[1] = Wil; + } + + var chh = (eh & fh) ^ (~eh & gh); + var chl = (el & fl) ^ (~el & gl); + var majh = (ah & bh) ^ (ah & ch) ^ (bh & ch); + var majl = (al & bl) ^ (al & cl) ^ (bl & cl); + + var sigma0h = ((ah >>> 28) | (al << 4)) ^ ((ah << 30) | (al >>> 2)) ^ ((ah << 25) | (al >>> 7)); + var sigma0l = ((al >>> 28) | (ah << 4)) ^ ((al << 30) | (ah >>> 2)) ^ ((al << 25) | (ah >>> 7)); + var sigma1h = ((eh >>> 14) | (el << 18)) ^ ((eh >>> 18) | (el << 14)) ^ ((eh << 23) | (el >>> 9)); + var sigma1l = ((el >>> 14) | (eh << 18)) ^ ((el >>> 18) | (eh << 14)) ^ ((el << 23) | (eh >>> 9)); + + // t1 = h + sigma1 + ch + K[i] + W[i] + var Ki = K[i]; + var Kih = Ki[0]; + var Kil = Ki[1]; + + var t1l = hl + sigma1l; + var t1h = hh + sigma1h + ((t1l >>> 0) < (hl >>> 0) ? 1 : 0); + var t1l = t1l + chl; + var t1h = t1h + chh + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0); + var t1l = t1l + Kil; + var t1h = t1h + Kih + ((t1l >>> 0) < (Kil >>> 0) ? 1 : 0); + var t1l = t1l + Wil; + var t1h = t1h + Wih + ((t1l >>> 0) < (Wil >>> 0) ? 1 : 0); + + // t2 = sigma0 + maj + var t2l = sigma0l + majl; + var t2h = sigma0h + majh + ((t2l >>> 0) < (sigma0l >>> 0) ? 1 : 0); + + // Update working variables + hh = gh; + hl = gl; + gh = fh; + gl = fl; + fh = eh; + fl = el; + el = (dl + t1l) | 0; + eh = (dh + t1h + ((el >>> 0) < (dl >>> 0) ? 1 : 0)) | 0; + dh = ch; + dl = cl; + ch = bh; + cl = bl; + bh = ah; + bl = al; + al = (t1l + t2l) | 0; + ah = (t1h + t2h + ((al >>> 0) < (t1l >>> 0) ? 1 : 0)) | 0; + } + + // Intermediate hash value + H0l = H0[1] = (H0l + al); + H0[0] = (H0h + ah + ((H0l >>> 0) < (al >>> 0) ? 1 : 0)); + H1l = H1[1] = (H1l + bl); + H1[0] = (H1h + bh + ((H1l >>> 0) < (bl >>> 0) ? 1 : 0)); + H2l = H2[1] = (H2l + cl); + H2[0] = (H2h + ch + ((H2l >>> 0) < (cl >>> 0) ? 1 : 0)); + H3l = H3[1] = (H3l + dl); + H3[0] = (H3h + dh + ((H3l >>> 0) < (dl >>> 0) ? 1 : 0)); + H4l = H4[1] = (H4l + el); + H4[0] = (H4h + eh + ((H4l >>> 0) < (el >>> 0) ? 1 : 0)); + H5l = H5[1] = (H5l + fl); + H5[0] = (H5h + fh + ((H5l >>> 0) < (fl >>> 0) ? 1 : 0)); + H6l = H6[1] = (H6l + gl); + H6[0] = (H6h + gh + ((H6l >>> 0) < (gl >>> 0) ? 1 : 0)); + H7l = H7[1] = (H7l + hl); + H7[0] = (H7h + hh + ((H7l >>> 0) < (hl >>> 0) ? 1 : 0)); + return H + } + +module.exports = function(message, options) {; + + var H = [ + [0x6a09e667, 0xf3bcc908], [0xbb67ae85, 0x84caa73b], + [0x3c6ef372, 0xfe94f82b], [0xa54ff53a, 0x5f1d36f1], + [0x510e527f, 0xade682d1], [0x9b05688c, 0x2b3e6c1f], + [0x1f83d9ab, 0xfb41bd6b], [0x5be0cd19, 0x137e2179] + ]; + + if (message.constructor === String) { + message = conv.stringToBytes(message); + } + + var m = util.bytesToWords(message); + var l = message.length * 8; + + m[l >> 5] |= 0x80 << (24 - l % 32); + m[((l + 64 >> 10) << 5) + 31] = l; + + for (var i=0 ; i= 64) { + // hex string? + this.priv = BigInteger.fromByteArrayUnsigned(conv.hexToBytes(input.slice(0,64))); + this.compressed = (input.length == 66) + } + } }; module.exports = ECKey; diff --git a/src/index.js b/src/index.js index b439930..4a5d79c 100644 --- a/src/index.js +++ b/src/index.js @@ -38,6 +38,7 @@ module.exports = { Wallet: require('./wallet'), ecdsa: require('./ecdsa'), + BIP32key: require('./bip32'), // base58 encoding/decoding to bytes base58: require('./base58'), diff --git a/src/jsbn/ec.js b/src/jsbn/ec.js index 6c9fbe1..0bfc111 100644 --- a/src/jsbn/ec.js +++ b/src/jsbn/ec.js @@ -2,7 +2,8 @@ // Ported loosely from BouncyCastle's Java EC code // Only Fp curves implemented for now -var BigInteger = require('./jsbn'); +var BigInteger = require('./jsbn'), + sec = require('./sec'); // ---------------- // ECFieldElementFp @@ -360,24 +361,38 @@ ECPointFp.prototype.getEncoded = function (compressed) { return enc; }; -ECPointFp.decodeFrom = function (curve, enc) { +ECPointFp.decodeFrom = function (ecparams, enc) { var type = enc[0]; var dataLen = enc.length-1; // Extract x and y as byte arrays - var xBa = enc.slice(1, 1 + dataLen/2); - var yBa = enc.slice(1 + dataLen/2, 1 + dataLen); + if (type == 4) { + var xBa = enc.slice(1, 1 + dataLen/2), + yBa = enc.slice(1 + dataLen/2, 1 + dataLen), + x = BigInteger.fromByteArrayUnsigned(xBa), + y = BigInteger.fromByteArrayUnsigned(yBa); + } + else { + var xBa = enc.slice(1), + x = BigInteger.fromByteArrayUnsigned(xBa), + p = ecparams.getQ(), + xCubedPlus7 = x.multiply(x).multiply(x).add(new Bitcoin.BigInteger('7')).mod(p), + pPlus1Over4 = p.add(new Bitcoin.BigInteger('1')) + .divide(new Bitcoin.BigInteger('4')), + y = xCubedPlus7.modPow(pPlus1Over4,p); + if (y.mod(new Bitcoin.BigInteger('2')).toString() != ''+(type % 2)) { + y = p.subtract(y) + } + } // Prepend zero byte to prevent interpretation as negative integer - xBa.unshift(0); - yBa.unshift(0); // Convert to BigIntegers - var x = new BigInteger(xBa); - var y = new BigInteger(yBa); // Return point - return new ECPointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y)); + return new ECPointFp(ecparams, + ecparams.fromBigInteger(x), + ecparams.fromBigInteger(y)); }; ECPointFp.prototype.add2D = function (b) { diff --git a/src/message.js b/src/message.js index 2de699d..abc2da5 100644 --- a/src/message.js +++ b/src/message.js @@ -10,8 +10,8 @@ var Message = {}; Message.magicPrefix = "Bitcoin Signed Message:\n"; Message.makeMagicMessage = function (message) { - var magicBytes = Crypto.charenc.UTF8.stringToBytes(Message.magicPrefix); - var messageBytes = Crypto.charenc.UTF8.stringToBytes(message); + var magicBytes = conv.stringToBytes(Message.magicPrefix); + var messageBytes = conv.stringToBytes(message); var buffer = []; buffer = buffer.concat(util.numToVarInt(magicBytes.length)); diff --git a/src/script.js b/src/script.js index 35fa05f..9469af1 100644 --- a/src/script.js +++ b/src/script.js @@ -7,7 +7,7 @@ var Script = function (data) { if (!data) { this.buffer = []; } else if ("string" == typeof data) { - this.buffer = Crypto.util.hexToBytes(data); + this.buffer = conv.hexToBytes(data); } else if (util.isArray(data)) { this.buffer = data; } else if (data instanceof Script) { diff --git a/src/util.js b/src/util.js index 2b4c7d9..64fc644 100644 --- a/src/util.js +++ b/src/util.js @@ -32,7 +32,7 @@ module.exports = { }, /** - * Create a byte array representing a number with the given length + * Convert a byte array to the number that it represents */ bytesToNum: function(bytes) { if (bytes.length == 0) return 0; @@ -106,6 +106,22 @@ module.exports = { return value; }, + bytesToWords: function (bytes) { + var words = []; + for (var i = 0, b = 0; i < bytes.length; i++, b += 8) { + words[b >>> 5] |= bytes[i] << (24 - b % 32); + } + return words; + }, + + wordsToBytes: function (words) { + var bytes = []; + for (var b = 0; b < words.length * 32; b += 8) { + bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF); + } + return bytes; + }, + /** * Calculate RIPEMD160(SHA256(data)). * diff --git a/src/wallet.js b/src/wallet.js index abf1d27..4ec5ee4 100644 --- a/src/wallet.js +++ b/src/wallet.js @@ -44,7 +44,7 @@ var Wallet = function () { if (pub) { if ("string" === typeof pub) { - pub = Crypto.util.hexToBytes(pub); + pub = conv.hexToBytes(pub); } key.setPub(pub); }