From 205682235a3c90b81049c0b226eb1e529ab3e4da Mon Sep 17 00:00:00 2001 From: Nicholas Dudfield Date: Mon, 20 Jul 2015 11:17:48 +0700 Subject: [PATCH] Add generateWallet, walletFromSeed --- packages/ripple-keypairs/package.json | 3 +- packages/ripple-keypairs/src/index.js | 37 +++++++++++++++++- .../ripple-keypairs/test/keypairs-test.js | 38 ++++++++++++++++++- 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/packages/ripple-keypairs/package.json b/packages/ripple-keypairs/package.json index 90445492..23f3c190 100644 --- a/packages/ripple-keypairs/package.json +++ b/packages/ripple-keypairs/package.json @@ -16,6 +16,7 @@ "dependencies": { "babel-runtime": "^5.3.2", "bn.js": "^3.1.1", + "brorand": "^1.0.5", "elliptic": "^5.1.0", "hash.js": "^1.0.3", "ripple-address-codec": "^1.3.0" @@ -29,7 +30,7 @@ "eslint": "^0.23.0", "eventemitter2": "^0.4.14", "istanbul": "~0.3.5", - "lodash": "^3.9.3", + "lodash": "^3.10.0", "map-stream": "~0.1.0", "mocha": "~2.1.0", "nock": "^0.34.1", diff --git a/packages/ripple-keypairs/src/index.js b/packages/ripple-keypairs/src/index.js index 583fe9a1..23507f98 100644 --- a/packages/ripple-keypairs/src/index.js +++ b/packages/ripple-keypairs/src/index.js @@ -3,9 +3,11 @@ /* -------------------------------- REQUIRES -------------------------------- */ const util = require('util'); +const assert = require('assert'); const elliptic = require('elliptic'); const hashjs = require('hash.js'); const codec = require('ripple-address-codec'); +const rand = require('brorand'); // elliptic const secp256k1 = elliptic.ec('secp256k1'); @@ -233,6 +235,37 @@ function keyPairFromSeed(seedString) { return pair.fromSeed(decoded.bytes); } +function deriveWallet(type, seedBytes) { + assert(type === 'secp256k1' || type === 'ed25519'); + + let pair; + let seed; + + if (type === 'secp256k1') { + seed = codec.encodeK256Seed(seedBytes); + pair = K256Pair.fromSeed(seedBytes); + } else { + seed = codec.encodeEdSeed(seedBytes); + pair = Ed25519Pair.fromSeed(seedBytes); + } + + return { + seed, + accountID: pair.accountID(), + publicKey: pair.pubKeyHex() + }; +} + +function generateWallet({type='secp256k1', randGen=rand}) { + const seedBytes = randGen(16); + return deriveWallet(type, seedBytes); +} + +function walletFromSeed(seed) { + const {type, bytes} = codec.decodeSeed(seed); + return deriveWallet(type, bytes); +} + module.exports = { KeyPair, K256Pair, @@ -240,5 +273,7 @@ module.exports = { KeyType, seedFromPhrase, createAccountID, - keyPairFromSeed + keyPairFromSeed, + generateWallet, + walletFromSeed }; diff --git a/packages/ripple-keypairs/test/keypairs-test.js b/packages/ripple-keypairs/test/keypairs-test.js index 8280beee..f8e81a67 100644 --- a/packages/ripple-keypairs/test/keypairs-test.js +++ b/packages/ripple-keypairs/test/keypairs-test.js @@ -1,15 +1,18 @@ 'use strict'; -const assert = require('assert'); +const assert = require('assert-diff'); const utils = require('../src/utils'); const keypairs = require('../src'); +const _ = require('lodash'); const { KeyType, K256Pair, seedFromPhrase, Ed25519Pair, - keyPairFromSeed + keyPairFromSeed, + generateWallet, + walletFromSeed } = keypairs; const {SerializedObject} = require('ripple-lib'); @@ -87,6 +90,37 @@ describe('keyPairFromSeed', function() { }); }); +describe('generateWallet', function() { + function randGen(len) { + return _.fill(Array(len), 0); + } + + it('can generate ed25519 wallets', function() { + const expected = { + seed: 'sEdSJHS4oiAdz7w2X2ni1gFiqtbJHqE', + accountID: 'r9zRhGr7b6xPekLvT6wP4qNdWMryaumZS7', + publicKey: + 'ED' + + '1A7C082846CFF58FF9A892BA4BA2593151CCF1DBA59F37714CC9ED39824AF85F' + }; + const actual = generateWallet({type: 'ed25519', randGen}); + assert.deepEqual(actual, expected); + assert.deepEqual(walletFromSeed(actual.seed), expected); + }); + it('can generate secp256k1 wallets (by default)', function() { + const expected = { + seed: 'sp6JS7f14BuwFY8Mw6bTtLKWauoUs', + accountID: 'rGCkuB7PBr5tNy68tPEABEtcdno4hE6Y7f', + publicKey: + '03' + + '90A196799EE412284A5D80BF78C3E84CBB80E1437A0AECD9ADF94D7FEAAFA284' + }; + const actual = generateWallet({type: undefined, randGen}); + assert.deepEqual(actual, expected); + assert.deepEqual(walletFromSeed(actual.seed), expected); + }); +}); + describe('K256Pair', function() { describe('generated tests', function() { /*eslint-disable max-len*/