Address.fromPassphrase
This commit is contained in:
parent
09f7be7062
commit
bc3fef1aea
|
@ -51,12 +51,8 @@ API documentation is available [here](https://bitchan.github.io/bitmessage/docs/
|
|||
- [ ] broadcast
|
||||
- [x] WIF
|
||||
- [x] POW
|
||||
- [ ] High-level classes
|
||||
- [ ] Address
|
||||
- [x] encode
|
||||
- [x] decode
|
||||
- [x] fromRandom
|
||||
- [ ] fromPassphrase
|
||||
- [x] High-level classes
|
||||
- [x] Address
|
||||
- [x] UserAgent
|
||||
- [ ] Parse PyBitmessage configs
|
||||
- [ ] keys.dat
|
||||
|
|
|
@ -216,27 +216,21 @@ Address.fromRandom = function(opts) {
|
|||
var version = opts.version = opts.version || 4;
|
||||
var ripelen = popkey(opts, "ripelen") || 19;
|
||||
assertripelen(ripelen, version);
|
||||
// Should the generated ripe length be strictly equal to the specified
|
||||
// (less or equal by default).
|
||||
var strictripelen = !!popkey(opts, "strictripelen");
|
||||
|
||||
// TODO(Kagami): Speed it up using web workers in Browser.
|
||||
// TODO(Kagami): Bind to C++ version of this code in Node.
|
||||
var encPrivateKey, encPublicKey, ripe;
|
||||
var encPrivateKey, encPublicKey, ripe, len;
|
||||
var signPrivateKey = bmcrypto.getPrivate();
|
||||
var signPublicKey = bmcrypto.getPublic(signPrivateKey);
|
||||
var keysbuf = Buffer(130);
|
||||
var keysbuf = new Buffer(130);
|
||||
signPublicKey.copy(keysbuf);
|
||||
while (true) {
|
||||
encPrivateKey = bmcrypto.getPrivate();
|
||||
encPublicKey = bmcrypto.getPublic(encPrivateKey);
|
||||
encPublicKey.copy(keysbuf, 65);
|
||||
ripe = bmcrypto.ripemd160(bmcrypto.sha512(keysbuf));
|
||||
var len = getripelen(ripe);
|
||||
if (
|
||||
(strictripelen && len === ripelen) ||
|
||||
(!strictripelen && len <= ripelen && checkripelen(ripelen, version))
|
||||
) {
|
||||
len = getripelen(ripe);
|
||||
if (len <= ripelen && checkripelen(len, version)) {
|
||||
// TODO(Kagami): Do we need to put all these properties or compute
|
||||
// them manually via ECMA5 getters/setters instead?
|
||||
opts.signPrivateKey = signPrivateKey;
|
||||
|
@ -249,4 +243,55 @@ Address.fromRandom = function(opts) {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create new Bitmessage address from passphrase.
|
||||
* @param {?Object} opts - Address options
|
||||
* @return {Address} Generated address object.
|
||||
*/
|
||||
Address.fromPassphrase = function(opts) {
|
||||
opts = objectAssign({}, opts);
|
||||
var version = opts.version = opts.version || 4;
|
||||
var ripelen = popkey(opts, "ripelen") || 19;
|
||||
assertripelen(ripelen, version);
|
||||
var passphrase = popkey(opts, "passphrase");
|
||||
|
||||
// TODO(Kagami): Speed it up using web workers in Browser.
|
||||
// TODO(Kagami): Bind to C++ version of this code in Node.
|
||||
var signPrivateKey, signPublicKey, encPrivateKey, encPublicKey;
|
||||
var ripe, len, tmp;
|
||||
var signnonce = 0;
|
||||
var encnonce = 1;
|
||||
var keysbuf = new Buffer(130);
|
||||
// XXX(Kagami): Spec doesn't mention encoding, using UTF-8.
|
||||
var phrasebuf = new Buffer(passphrase, "utf8");
|
||||
while (true) {
|
||||
// TODO(Kagami): We may slightly optimize it and pre-create tmp
|
||||
// buffers based on the encoded nonce size (1, 3, 5 and 9 bytes).
|
||||
tmp = Buffer.concat([phrasebuf, var_int.encode(signnonce)]);
|
||||
signPrivateKey = bmcrypto.sha512(tmp).slice(0, 32);
|
||||
signPublicKey = bmcrypto.getPublic(signPrivateKey);
|
||||
signPublicKey.copy(keysbuf);
|
||||
|
||||
tmp = Buffer.concat([phrasebuf, var_int.encode(encnonce)]);
|
||||
encPrivateKey = bmcrypto.sha512(tmp).slice(0, 32);
|
||||
encPublicKey = bmcrypto.getPublic(encPrivateKey);
|
||||
encPublicKey.copy(keysbuf, 65);
|
||||
|
||||
ripe = bmcrypto.ripemd160(bmcrypto.sha512(keysbuf));
|
||||
len = getripelen(ripe);
|
||||
if (len <= ripelen && checkripelen(len, version)) {
|
||||
// TODO(Kagami): Do we need to put all these properties or compute
|
||||
// them manually via ECMA5 getters/setters instead?
|
||||
opts.signPrivateKey = signPrivateKey;
|
||||
opts.signPublicKey = signPublicKey;
|
||||
opts.encPrivateKey = encPrivateKey;
|
||||
opts.encPublicKey = encPublicKey;
|
||||
opts.ripe = ripe;
|
||||
return new Address(opts);
|
||||
}
|
||||
signnonce += 2;
|
||||
encnonce += 2;
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = Address;
|
||||
|
|
13
test.js
13
test.js
|
@ -525,7 +525,7 @@ describe("High-level classes", function() {
|
|||
expect(addr.ripe.toString("hex")).to.equal("003ab6655de4bd8c603eba9b00dd5970725fdd56");
|
||||
});
|
||||
|
||||
it("should allow to generate new Bitmessage address", function() {
|
||||
it("should allow to create random Bitmessage address", function() {
|
||||
this.timeout(60000);
|
||||
var addr = Address.fromRandom();
|
||||
expect(addr.version).to.equal(4);
|
||||
|
@ -541,6 +541,17 @@ describe("High-level classes", function() {
|
|||
expect(addr2.ripe[0]).to.equal(0);
|
||||
});
|
||||
|
||||
it("should allow to create Bitmessage address from passphrase", function() {
|
||||
this.timeout(60000);
|
||||
var addr = Address.fromPassphrase({passphrase: "test"});
|
||||
expect(addr.version).to.equal(4);
|
||||
expect(addr.stream).to.equal(1);
|
||||
expect(bufferEqual(addr.signPrivateKey, WIF.decode("5JY1CFeeyN4eyfL35guWAuUqu5VLmd7LojtkNP6wmt5msZxxZ57"))).to.be.true;
|
||||
expect(bufferEqual(addr.encPrivateKey, WIF.decode("5J1oDgZDicNhUgbfzBDQqi2m5jUPnDrfZinnTqEEEaLv63jVFTM"))).to.be.true;
|
||||
expect(addr.getRipe().toString("hex")).to.equal("00ac14944b00decea5628eb40d0ff4b0f9ee9eca");
|
||||
expect(addr.encode()).to.equal("BM-2cWFkyuXXFw6d393RGnin2RpSXj8wxtt6F");
|
||||
});
|
||||
|
||||
it("should calculate tag", function() {
|
||||
var addr = Address.decode("2cTux3PGRqHTEH6wyUP2sWeT4LrsGgy63z");
|
||||
expect(addr.getTag().toString("hex")).to.equal("facf1e3e6c74916203b7f714ca100d4d60604f0917696d0f09330f82f52bed1a");
|
||||
|
|
Loading…
Reference in New Issue
Block a user