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
|
- [ ] broadcast
|
||||||
- [x] WIF
|
- [x] WIF
|
||||||
- [x] POW
|
- [x] POW
|
||||||
- [ ] High-level classes
|
- [x] High-level classes
|
||||||
- [ ] Address
|
- [x] Address
|
||||||
- [x] encode
|
|
||||||
- [x] decode
|
|
||||||
- [x] fromRandom
|
|
||||||
- [ ] fromPassphrase
|
|
||||||
- [x] UserAgent
|
- [x] UserAgent
|
||||||
- [ ] Parse PyBitmessage configs
|
- [ ] Parse PyBitmessage configs
|
||||||
- [ ] keys.dat
|
- [ ] keys.dat
|
||||||
|
|
|
@ -216,27 +216,21 @@ Address.fromRandom = function(opts) {
|
||||||
var version = opts.version = opts.version || 4;
|
var version = opts.version = opts.version || 4;
|
||||||
var ripelen = popkey(opts, "ripelen") || 19;
|
var ripelen = popkey(opts, "ripelen") || 19;
|
||||||
assertripelen(ripelen, version);
|
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): Speed it up using web workers in Browser.
|
||||||
// TODO(Kagami): Bind to C++ version of this code in Node.
|
// 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 signPrivateKey = bmcrypto.getPrivate();
|
||||||
var signPublicKey = bmcrypto.getPublic(signPrivateKey);
|
var signPublicKey = bmcrypto.getPublic(signPrivateKey);
|
||||||
var keysbuf = Buffer(130);
|
var keysbuf = new Buffer(130);
|
||||||
signPublicKey.copy(keysbuf);
|
signPublicKey.copy(keysbuf);
|
||||||
while (true) {
|
while (true) {
|
||||||
encPrivateKey = bmcrypto.getPrivate();
|
encPrivateKey = bmcrypto.getPrivate();
|
||||||
encPublicKey = bmcrypto.getPublic(encPrivateKey);
|
encPublicKey = bmcrypto.getPublic(encPrivateKey);
|
||||||
encPublicKey.copy(keysbuf, 65);
|
encPublicKey.copy(keysbuf, 65);
|
||||||
ripe = bmcrypto.ripemd160(bmcrypto.sha512(keysbuf));
|
ripe = bmcrypto.ripemd160(bmcrypto.sha512(keysbuf));
|
||||||
var len = getripelen(ripe);
|
len = getripelen(ripe);
|
||||||
if (
|
if (len <= ripelen && checkripelen(len, version)) {
|
||||||
(strictripelen && len === ripelen) ||
|
|
||||||
(!strictripelen && len <= ripelen && checkripelen(ripelen, version))
|
|
||||||
) {
|
|
||||||
// TODO(Kagami): Do we need to put all these properties or compute
|
// TODO(Kagami): Do we need to put all these properties or compute
|
||||||
// them manually via ECMA5 getters/setters instead?
|
// them manually via ECMA5 getters/setters instead?
|
||||||
opts.signPrivateKey = signPrivateKey;
|
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;
|
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");
|
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);
|
this.timeout(60000);
|
||||||
var addr = Address.fromRandom();
|
var addr = Address.fromRandom();
|
||||||
expect(addr.version).to.equal(4);
|
expect(addr.version).to.equal(4);
|
||||||
|
@ -541,6 +541,17 @@ describe("High-level classes", function() {
|
||||||
expect(addr2.ripe[0]).to.equal(0);
|
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() {
|
it("should calculate tag", function() {
|
||||||
var addr = Address.decode("2cTux3PGRqHTEH6wyUP2sWeT4LrsGgy63z");
|
var addr = Address.decode("2cTux3PGRqHTEH6wyUP2sWeT4LrsGgy63z");
|
||||||
expect(addr.getTag().toString("hex")).to.equal("facf1e3e6c74916203b7f714ca100d4d60604f0917696d0f09330f82f52bed1a");
|
expect(addr.getTag().toString("hex")).to.equal("facf1e3e6c74916203b7f714ca100d4d60604f0917696d0f09330f82f52bed1a");
|
||||||
|
|
Loading…
Reference in New Issue
Block a user