You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
3.7 KiB
134 lines
3.7 KiB
Bitcoin.ECKey = (function () {
|
|
var ECDSA = Bitcoin.ECDSA;
|
|
var ecparams = getSECCurveByName("secp256k1");
|
|
var rng = new SecureRandom();
|
|
|
|
var ECKey = function (input) {
|
|
if (!input) {
|
|
// Generate new key
|
|
var n = ecparams.getN();
|
|
this.priv = ECDSA.getBigRandom(n);
|
|
} else if (input instanceof BigInteger) {
|
|
// Input is a private key value
|
|
this.priv = input;
|
|
} else if (Bitcoin.Util.isArray(input)) {
|
|
// Prepend zero byte to prevent interpretation as negative integer
|
|
this.priv = BigInteger.fromByteArrayUnsigned(input);
|
|
} else if ("string" == typeof input) {
|
|
if (input.length == 51 && input[0] == '5') {
|
|
// Base58 encoded private key
|
|
this.priv = BigInteger.fromByteArrayUnsigned(ECKey.decodeString(input));
|
|
} else {
|
|
// Prepend zero byte to prevent interpretation as negative integer
|
|
this.priv = BigInteger.fromByteArrayUnsigned(Crypto.util.hexToBytes(input));
|
|
}
|
|
}
|
|
this.compressed = !!ECKey.compressByDefault;
|
|
};
|
|
|
|
/**
|
|
* Whether public keys should be returned compressed by default.
|
|
*/
|
|
ECKey.compressByDefault = false;
|
|
|
|
/**
|
|
* Set whether the public key should be returned compressed or not.
|
|
*/
|
|
ECKey.prototype.setCompressed = function (v) {
|
|
this.compressed = !!v;
|
|
};
|
|
|
|
/**
|
|
* Return public key in DER encoding.
|
|
*/
|
|
ECKey.prototype.getPub = function () {
|
|
return this.getPubPoint().getEncoded(this.compressed);
|
|
};
|
|
|
|
/**
|
|
* Return public point as ECPoint object.
|
|
*/
|
|
ECKey.prototype.getPubPoint = function () {
|
|
if (!this.pub) this.pub = ecparams.getG().multiply(this.priv);
|
|
|
|
return this.pub;
|
|
};
|
|
|
|
/**
|
|
* Get the pubKeyHash for this key.
|
|
*
|
|
* This is calculated as RIPE160(SHA256([encoded pubkey])) and returned as
|
|
* a byte array.
|
|
*/
|
|
ECKey.prototype.getPubKeyHash = function () {
|
|
if (this.pubKeyHash) return this.pubKeyHash;
|
|
|
|
return this.pubKeyHash = Bitcoin.Util.sha256ripe160(this.getPub());
|
|
};
|
|
|
|
ECKey.prototype.getBitcoinAddress = function () {
|
|
var hash = this.getPubKeyHash();
|
|
var addr = new Bitcoin.Address(hash);
|
|
return addr;
|
|
};
|
|
|
|
ECKey.prototype.getExportedPrivateKey = function () {
|
|
var hash = this.priv.toByteArrayUnsigned();
|
|
while (hash.length < 32) hash.unshift(0);
|
|
hash.unshift(0x80);
|
|
var checksum = Crypto.SHA256(Crypto.SHA256(hash, {asBytes: true}), {asBytes: true});
|
|
var bytes = hash.concat(checksum.slice(0,4));
|
|
return Bitcoin.Base58.encode(bytes);
|
|
};
|
|
|
|
ECKey.prototype.setPub = function (pub) {
|
|
this.pub = ECPointFp.decodeFrom(ecparams.getCurve(), pub);
|
|
};
|
|
|
|
ECKey.prototype.toString = function (format) {
|
|
if (format === "base64") {
|
|
return Crypto.util.bytesToBase64(this.priv.toByteArrayUnsigned());
|
|
} else {
|
|
return Crypto.util.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());
|
|
};
|
|
|
|
/**
|
|
* Parse an exported private key contained in a string.
|
|
*/
|
|
ECKey.decodeString = function (string) {
|
|
var bytes = Bitcoin.Base58.decode(string);
|
|
|
|
var hash = bytes.slice(0, 33);
|
|
|
|
var checksum = Crypto.SHA256(Crypto.SHA256(hash, {asBytes: true}), {asBytes: true});
|
|
|
|
if (checksum[0] != bytes[33] ||
|
|
checksum[1] != bytes[34] ||
|
|
checksum[2] != bytes[35] ||
|
|
checksum[3] != bytes[36]) {
|
|
throw "Checksum validation failed!";
|
|
}
|
|
|
|
var version = hash.shift();
|
|
|
|
if (version != 0x80) {
|
|
throw "Version "+version+" not supported!";
|
|
}
|
|
|
|
return hash;
|
|
};
|
|
|
|
return ECKey;
|
|
})();
|
|
|
|
|
|
module.exports.ECKey = Bitcoin.ECKey;
|
|
|