Fix eslint errors

This was done by:
- updating some devDependencies
- running:
    node_modules/.bin/eslint -c ./eslintrc --fix src/ test/
- adding where necessary:
    // eslint-disable-line strict
This commit is contained in:
Elliot Lee
2017-09-08 11:38:44 -07:00
parent 98c42c200b
commit 30400e6e92
7 changed files with 183 additions and 179 deletions

View File

@@ -24,18 +24,18 @@
"assert-diff": "^1.0.1", "assert-diff": "^1.0.1",
"babel": "^5.8.20", "babel": "^5.8.20",
"babel-core": "^5.8.20", "babel-core": "^5.8.20",
"babel-eslint": "^4.0.5", "babel-eslint": "^6.0.0",
"babel-loader": "^5.3.2", "babel-loader": "^5.3.2",
"codecov.io": "^0.1.6", "codecov.io": "^0.1.6",
"coveralls": "~2.11.4", "coveralls": "~2.11.4",
"eslint": "^1.2.1", "eslint": "2.7.0",
"eventemitter2": "^0.4.14", "eventemitter2": "^0.4.14",
"istanbul": "~0.3.5", "istanbul": "~0.3.5",
"lodash": "^3.10.0", "lodash": "^3.10.0",
"map-stream": "~0.1.0", "map-stream": "~0.1.0",
"mocha": "~2.3.3", "mocha": "~2.3.3",
"nock": "^2.13.0", "nock": "^2.13.0",
"ripple-lib": "^0.12.4" "ripple-lib": "^0.17.0"
}, },
"scripts": { "scripts": {
"build": "gulp", "build": "gulp",

View File

@@ -1,109 +1,110 @@
'use strict'; 'use strict' // eslint-disable-line strict
const assert = require('assert');
const brorand = require('brorand'); const assert = require('assert')
const hashjs = require('hash.js'); const brorand = require('brorand')
const elliptic = require('elliptic'); const hashjs = require('hash.js')
const Ed25519 = elliptic.eddsa('ed25519'); const elliptic = require('elliptic')
const Secp256k1 = elliptic.ec('secp256k1'); const Ed25519 = elliptic.eddsa('ed25519')
const addressCodec = require('ripple-address-codec'); const Secp256k1 = elliptic.ec('secp256k1')
const derivePrivateKey = require('./secp256k1').derivePrivateKey; const addressCodec = require('ripple-address-codec')
const derivePrivateKey = require('./secp256k1').derivePrivateKey
const accountPublicFromPublicGenerator = require('./secp256k1') const accountPublicFromPublicGenerator = require('./secp256k1')
.accountPublicFromPublicGenerator; .accountPublicFromPublicGenerator
const utils = require('./utils'); const utils = require('./utils')
const hexToBytes = utils.hexToBytes; const hexToBytes = utils.hexToBytes
const bytesToHex = utils.bytesToHex; const bytesToHex = utils.bytesToHex
function generateSeed(options = {}) { function generateSeed(options = {}) {
assert(!options.entropy || options.entropy.length >= 16, 'entropy too short'); assert(!options.entropy || options.entropy.length >= 16, 'entropy too short')
const entropy = options.entropy ? options.entropy.slice(0, 16) : brorand(16); const entropy = options.entropy ? options.entropy.slice(0, 16) : brorand(16)
const type = options.algorithm === 'ed25519' ? 'ed25519' : 'secp256k1'; const type = options.algorithm === 'ed25519' ? 'ed25519' : 'secp256k1'
return addressCodec.encodeSeed(entropy, type); return addressCodec.encodeSeed(entropy, type)
} }
function hash(message) { function hash(message) {
return hashjs.sha512().update(message).digest().slice(0, 32); return hashjs.sha512().update(message).digest().slice(0, 32)
} }
const secp256k1 = { const secp256k1 = {
deriveKeypair: function(entropy, options) { deriveKeypair: function(entropy, options) {
const prefix = '00'; const prefix = '00'
const privateKey = prefix + derivePrivateKey(entropy, options) const privateKey = prefix + derivePrivateKey(entropy, options)
.toString(16, 64).toUpperCase(); .toString(16, 64).toUpperCase()
const publicKey = bytesToHex(Secp256k1.keyFromPrivate( const publicKey = bytesToHex(Secp256k1.keyFromPrivate(
privateKey.slice(2)).getPublic().encodeCompressed()); privateKey.slice(2)).getPublic().encodeCompressed())
return {privateKey, publicKey}; return {privateKey, publicKey}
}, },
sign: function(message, privateKey) { sign: function(message, privateKey) {
return bytesToHex(Secp256k1.sign(hash(message), return bytesToHex(Secp256k1.sign(hash(message),
hexToBytes(privateKey), {canonical: true}).toDER()); hexToBytes(privateKey), {canonical: true}).toDER())
}, },
verify: function(message, signature, publicKey) { verify: function(message, signature, publicKey) {
return Secp256k1.verify(hash(message), signature, hexToBytes(publicKey)); return Secp256k1.verify(hash(message), signature, hexToBytes(publicKey))
} }
}; }
const ed25519 = { const ed25519 = {
deriveKeypair: function(entropy) { deriveKeypair: function(entropy) {
const prefix = 'ED'; const prefix = 'ED'
const rawPrivateKey = hash(entropy); const rawPrivateKey = hash(entropy)
const privateKey = prefix + bytesToHex(rawPrivateKey); const privateKey = prefix + bytesToHex(rawPrivateKey)
const publicKey = prefix + bytesToHex( const publicKey = prefix + bytesToHex(
Ed25519.keyFromSecret(rawPrivateKey).pubBytes()); Ed25519.keyFromSecret(rawPrivateKey).pubBytes())
return {privateKey, publicKey}; return {privateKey, publicKey}
}, },
sign: function(message, privateKey) { sign: function(message, privateKey) {
// caution: Ed25519.sign interprets all strings as hex, stripping // caution: Ed25519.sign interprets all strings as hex, stripping
// any non-hex characters without warning // any non-hex characters without warning
assert(Array.isArray(message), 'message must be array of octets'); assert(Array.isArray(message), 'message must be array of octets')
return bytesToHex(Ed25519.sign( return bytesToHex(Ed25519.sign(
message, hexToBytes(privateKey).slice(1)).toBytes()); message, hexToBytes(privateKey).slice(1)).toBytes())
}, },
verify: function(message, signature, publicKey) { verify: function(message, signature, publicKey) {
return Ed25519.verify(message, hexToBytes(signature), return Ed25519.verify(message, hexToBytes(signature),
hexToBytes(publicKey).slice(1)); hexToBytes(publicKey).slice(1))
} }
}; }
function select(algorithm) { function select(algorithm) {
const methods = {'ecdsa-secp256k1': secp256k1, ed25519}; const methods = {'ecdsa-secp256k1': secp256k1, ed25519}
return methods[algorithm]; return methods[algorithm]
} }
function deriveKeypair(seed, options) { function deriveKeypair(seed, options) {
const decoded = addressCodec.decodeSeed(seed); const decoded = addressCodec.decodeSeed(seed)
const algorithm = decoded.type === 'ed25519' ? 'ed25519' : 'ecdsa-secp256k1'; const algorithm = decoded.type === 'ed25519' ? 'ed25519' : 'ecdsa-secp256k1'
return select(algorithm).deriveKeypair(decoded.bytes, options); return select(algorithm).deriveKeypair(decoded.bytes, options)
} }
function getAlgorithmFromKey(key) { function getAlgorithmFromKey(key) {
const bytes = hexToBytes(key); const bytes = hexToBytes(key)
return (bytes.length === 33 && bytes[0] === 0xED) ? return (bytes.length === 33 && bytes[0] === 0xED) ?
'ed25519' : 'ecdsa-secp256k1'; 'ed25519' : 'ecdsa-secp256k1'
} }
function sign(messageHex, privateKey) { function sign(messageHex, privateKey) {
const algorithm = getAlgorithmFromKey(privateKey); const algorithm = getAlgorithmFromKey(privateKey)
return select(algorithm).sign(hexToBytes(messageHex), privateKey); return select(algorithm).sign(hexToBytes(messageHex), privateKey)
} }
function verify(messageHex, signature, publicKey) { function verify(messageHex, signature, publicKey) {
const algorithm = getAlgorithmFromKey(publicKey); const algorithm = getAlgorithmFromKey(publicKey)
return select(algorithm).verify(hexToBytes(messageHex), signature, publicKey); return select(algorithm).verify(hexToBytes(messageHex), signature, publicKey)
} }
function deriveAddressFromBytes(publicKeyBytes) { function deriveAddressFromBytes(publicKeyBytes) {
return addressCodec.encodeAccountID( return addressCodec.encodeAccountID(
utils.computePublicKeyHash(publicKeyBytes)); utils.computePublicKeyHash(publicKeyBytes))
} }
function deriveAddress(publicKey) { function deriveAddress(publicKey) {
return deriveAddressFromBytes(hexToBytes(publicKey)); return deriveAddressFromBytes(hexToBytes(publicKey))
} }
function deriveNodeAddress(publicKey) { function deriveNodeAddress(publicKey) {
const generatorBytes = addressCodec.decodeNodePublic(publicKey); const generatorBytes = addressCodec.decodeNodePublic(publicKey)
const accountPublicBytes = accountPublicFromPublicGenerator(generatorBytes); const accountPublicBytes = accountPublicFromPublicGenerator(generatorBytes)
return deriveAddressFromBytes(accountPublicBytes); return deriveAddressFromBytes(accountPublicBytes)
} }
module.exports = { module.exports = {
@@ -113,4 +114,4 @@ module.exports = {
verify, verify,
deriveAddress, deriveAddress,
deriveNodeAddress deriveNodeAddress
}; }

View File

@@ -1,26 +1,26 @@
'use strict'; 'use strict' // eslint-disable-line strict
const elliptic = require('elliptic'); const elliptic = require('elliptic')
const secp256k1 = elliptic.ec('secp256k1'); const secp256k1 = elliptic.ec('secp256k1')
const Sha512 = require('./sha512'); const Sha512 = require('./sha512')
function deriveScalar(bytes, discrim) { function deriveScalar(bytes, discrim) {
const order = secp256k1.curve.n; const order = secp256k1.curve.n
for (let i = 0; i <= 0xFFFFFFFF; i++) { for (let i = 0; i <= 0xFFFFFFFF; i++) {
// We hash the bytes to find a 256 bit number, looping until we are sure it // We hash the bytes to find a 256 bit number, looping until we are sure it
// is less than the order of the curve. // is less than the order of the curve.
const hasher = new Sha512().add(bytes); const hasher = new Sha512().add(bytes)
// If the optional discriminator index was passed in, update the hash. // If the optional discriminator index was passed in, update the hash.
if (discrim !== undefined) { if (discrim !== undefined) {
hasher.addU32(discrim); hasher.addU32(discrim)
} }
hasher.addU32(i); hasher.addU32(i)
const key = hasher.first256BN(); const key = hasher.first256BN()
if (key.cmpn(0) > 0 && key.cmp(order) < 0) { if (key.cmpn(0) > 0 && key.cmp(order) < 0) {
return key; return key
} }
} }
throw new Error('impossible unicorn ;)'); throw new Error('impossible unicorn ;)')
} }
/** /**
@@ -33,33 +33,33 @@ function deriveScalar(bytes, discrim) {
* *
*/ */
function derivePrivateKey(seed, opts = {}) { function derivePrivateKey(seed, opts = {}) {
const root = opts.validator; const root = opts.validator
const order = secp256k1.curve.n; const order = secp256k1.curve.n
// This private generator represents the `root` private key, and is what's // This private generator represents the `root` private key, and is what's
// used by validators for signing when a keypair is generated from a seed. // used by validators for signing when a keypair is generated from a seed.
const privateGen = deriveScalar(seed); const privateGen = deriveScalar(seed)
if (root) { if (root) {
// As returned by validation_create for a given seed // As returned by validation_create for a given seed
return privateGen; return privateGen
} }
const publicGen = secp256k1.g.mul(privateGen); const publicGen = secp256k1.g.mul(privateGen)
// A seed can generate many keypairs as a function of the seed and a uint32. // A seed can generate many keypairs as a function of the seed and a uint32.
// Almost everyone just uses the first account, `0`. // Almost everyone just uses the first account, `0`.
const accountIndex = opts.accountIndex || 0; const accountIndex = opts.accountIndex || 0
return deriveScalar(publicGen.encodeCompressed(), accountIndex) return deriveScalar(publicGen.encodeCompressed(), accountIndex)
.add(privateGen).mod(order); .add(privateGen).mod(order)
} }
function accountPublicFromPublicGenerator(publicGenBytes) { function accountPublicFromPublicGenerator(publicGenBytes) {
const rootPubPoint = secp256k1.curve.decodePoint(publicGenBytes); const rootPubPoint = secp256k1.curve.decodePoint(publicGenBytes)
const scalar = deriveScalar(publicGenBytes, 0); const scalar = deriveScalar(publicGenBytes, 0)
const point = secp256k1.g.mul(scalar); const point = secp256k1.g.mul(scalar)
const offset = rootPubPoint.add(point); const offset = rootPubPoint.add(point)
return offset.encodeCompressed(); return offset.encodeCompressed()
} }
module.exports = { module.exports = {
derivePrivateKey, derivePrivateKey,
accountPublicFromPublicGenerator accountPublicFromPublicGenerator
}; }

View File

@@ -1,27 +1,27 @@
'use strict'; 'use strict' // eslint-disable-line strict
const hashjs = require('hash.js'); const hashjs = require('hash.js')
const BigNum = require('bn.js'); const BigNum = require('bn.js')
module.exports = class Sha512 { module.exports = class Sha512 {
constructor() { constructor() {
this.hash = hashjs.sha512(); this.hash = hashjs.sha512()
} }
add(bytes) { add(bytes) {
this.hash.update(bytes); this.hash.update(bytes)
return this; return this
} }
addU32(i) { addU32(i) {
return this.add([(i >>> 24) & 0xFF, (i >>> 16) & 0xFF, return this.add([(i >>> 24) & 0xFF, (i >>> 16) & 0xFF,
(i >>> 8) & 0xFF, i & 0xFF]); (i >>> 8) & 0xFF, i & 0xFF])
} }
finish() { finish() {
return this.hash.digest(); return this.hash.digest()
} }
first256() { first256() {
return this.finish().slice(0, 32); return this.finish().slice(0, 32)
} }
first256BN() { first256BN() {
return new BigNum(this.first256()); return new BigNum(this.first256())
} }
}; }

View File

@@ -1,28 +1,29 @@
'use strict'; 'use strict' // eslint-disable-line strict
const assert = require('assert');
const hashjs = require('hash.js'); const assert = require('assert')
const BN = require('bn.js'); const hashjs = require('hash.js')
const BN = require('bn.js')
function bytesToHex(a) { function bytesToHex(a) {
return a.map(function(byteValue) { return a.map(function(byteValue) {
const hex = byteValue.toString(16).toUpperCase(); const hex = byteValue.toString(16).toUpperCase()
return hex.length > 1 ? hex : '0' + hex; return hex.length > 1 ? hex : '0' + hex
}).join(''); }).join('')
} }
function hexToBytes(a) { function hexToBytes(a) {
assert(a.length % 2 === 0); assert(a.length % 2 === 0)
return (new BN(a, 16)).toArray(null, a.length / 2); return (new BN(a, 16)).toArray(null, a.length / 2)
} }
function computePublicKeyHash(publicKeyBytes) { function computePublicKeyHash(publicKeyBytes) {
const hash256 = hashjs.sha256().update(publicKeyBytes).digest(); const hash256 = hashjs.sha256().update(publicKeyBytes).digest()
const hash160 = hashjs.ripemd160().update(hash256).digest(); const hash160 = hashjs.ripemd160().update(hash256).digest()
return hash160; return hash160
} }
function seedFromPhrase(phrase) { function seedFromPhrase(phrase) {
return hashjs.sha512().update(phrase).digest().slice(0, 16); return hashjs.sha512().update(phrase).digest().slice(0, 16)
} }
module.exports = { module.exports = {
@@ -30,4 +31,4 @@ module.exports = {
hexToBytes, hexToBytes,
computePublicKeyHash, computePublicKeyHash,
seedFromPhrase seedFromPhrase
}; }

View File

@@ -1,98 +1,99 @@
'use strict'; 'use strict' // eslint-disable-line strict
const assert = require('assert');
const fixtures = require('./fixtures/api.json'); const assert = require('assert')
const api = require('../src'); const fixtures = require('./fixtures/api.json')
const decodeSeed = require('ripple-address-codec').decodeSeed; const api = require('../src')
const entropy = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; const decodeSeed = require('ripple-address-codec').decodeSeed
const entropy = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
describe('api', () => { describe('api', () => {
it('generateSeed - secp256k1', () => { it('generateSeed - secp256k1', () => {
assert.strictEqual(api.generateSeed({entropy}), fixtures.secp256k1.seed); assert.strictEqual(api.generateSeed({entropy}), fixtures.secp256k1.seed)
}); })
it('generateSeed - secp256k1, random', () => { it('generateSeed - secp256k1, random', () => {
const seed = api.generateSeed(); const seed = api.generateSeed()
assert(seed.charAt(0) === 's'); assert(seed.charAt(0) === 's')
const {type, bytes} = decodeSeed(seed); const {type, bytes} = decodeSeed(seed)
assert(type === 'secp256k1'); assert(type === 'secp256k1')
assert(bytes.length === 16); assert(bytes.length === 16)
}); })
it('generateSeed - ed25519', () => { it('generateSeed - ed25519', () => {
assert.strictEqual(api.generateSeed({entropy, algorithm: 'ed25519'}), assert.strictEqual(api.generateSeed({entropy, algorithm: 'ed25519'}),
fixtures.ed25519.seed); fixtures.ed25519.seed)
}); })
it('generateSeed - ed25519, random', () => { it('generateSeed - ed25519, random', () => {
const seed = api.generateSeed({algorithm: 'ed25519'}); const seed = api.generateSeed({algorithm: 'ed25519'})
assert(seed.slice(0, 3) === 'sEd'); assert(seed.slice(0, 3) === 'sEd')
const {type, bytes} = decodeSeed(seed); const {type, bytes} = decodeSeed(seed)
assert(type === 'ed25519'); assert(type === 'ed25519')
assert(bytes.length === 16); assert(bytes.length === 16)
}); })
it('deriveKeypair - secp256k1', () => { it('deriveKeypair - secp256k1', () => {
const keypair = api.deriveKeypair(fixtures.secp256k1.seed); const keypair = api.deriveKeypair(fixtures.secp256k1.seed)
assert.deepEqual(keypair, fixtures.secp256k1.keypair); assert.deepEqual(keypair, fixtures.secp256k1.keypair)
}); })
it('deriveKeypair - ed25519', () => { it('deriveKeypair - ed25519', () => {
const keypair = api.deriveKeypair(fixtures.ed25519.seed); const keypair = api.deriveKeypair(fixtures.ed25519.seed)
assert.deepEqual(keypair, fixtures.ed25519.keypair); assert.deepEqual(keypair, fixtures.ed25519.keypair)
}); })
it('deriveAddress - secp256k1 public key', () => { it('deriveAddress - secp256k1 public key', () => {
const address = api.deriveAddress(fixtures.secp256k1.keypair.publicKey); const address = api.deriveAddress(fixtures.secp256k1.keypair.publicKey)
assert.strictEqual(address, fixtures.secp256k1.address); assert.strictEqual(address, fixtures.secp256k1.address)
}); })
it('deriveAddress - ed25519 public key', () => { it('deriveAddress - ed25519 public key', () => {
const address = api.deriveAddress(fixtures.ed25519.keypair.publicKey); const address = api.deriveAddress(fixtures.ed25519.keypair.publicKey)
assert.strictEqual(address, fixtures.ed25519.address); assert.strictEqual(address, fixtures.ed25519.address)
}); })
it('sign - secp256k1', () => { it('sign - secp256k1', () => {
const privateKey = fixtures.secp256k1.keypair.privateKey; const privateKey = fixtures.secp256k1.keypair.privateKey
const message = fixtures.secp256k1.message; const message = fixtures.secp256k1.message
const messageHex = (new Buffer(message, 'utf8')).toString('hex'); const messageHex = (new Buffer(message, 'utf8')).toString('hex')
const signature = api.sign(messageHex, privateKey); const signature = api.sign(messageHex, privateKey)
assert.strictEqual(signature, fixtures.secp256k1.signature); assert.strictEqual(signature, fixtures.secp256k1.signature)
}); })
it('verify - secp256k1', () => { it('verify - secp256k1', () => {
const signature = fixtures.secp256k1.signature; const signature = fixtures.secp256k1.signature
const publicKey = fixtures.secp256k1.keypair.publicKey; const publicKey = fixtures.secp256k1.keypair.publicKey
const message = fixtures.secp256k1.message; const message = fixtures.secp256k1.message
const messageHex = (new Buffer(message, 'utf8')).toString('hex'); const messageHex = (new Buffer(message, 'utf8')).toString('hex')
assert(api.verify(messageHex, signature, publicKey)); assert(api.verify(messageHex, signature, publicKey))
}); })
it('sign - ed25519', () => { it('sign - ed25519', () => {
const privateKey = fixtures.ed25519.keypair.privateKey; const privateKey = fixtures.ed25519.keypair.privateKey
const message = fixtures.ed25519.message; const message = fixtures.ed25519.message
const messageHex = (new Buffer(message, 'utf8')).toString('hex'); const messageHex = (new Buffer(message, 'utf8')).toString('hex')
const signature = api.sign(messageHex, privateKey); const signature = api.sign(messageHex, privateKey)
assert.strictEqual(signature, fixtures.ed25519.signature); assert.strictEqual(signature, fixtures.ed25519.signature)
}); })
it('verify - ed25519', () => { it('verify - ed25519', () => {
const signature = fixtures.ed25519.signature; const signature = fixtures.ed25519.signature
const publicKey = fixtures.ed25519.keypair.publicKey; const publicKey = fixtures.ed25519.keypair.publicKey
const message = fixtures.ed25519.message; const message = fixtures.ed25519.message
const messageHex = (new Buffer(message, 'utf8')).toString('hex'); const messageHex = (new Buffer(message, 'utf8')).toString('hex')
assert(api.verify(messageHex, signature, publicKey)); assert(api.verify(messageHex, signature, publicKey))
}); })
it('deriveNodeAddress', () => { it('deriveNodeAddress', () => {
const x = 'n9KHn8NfbBsZV5q8bLfS72XyGqwFt5mgoPbcTV4c6qKiuPTAtXYk'; const x = 'n9KHn8NfbBsZV5q8bLfS72XyGqwFt5mgoPbcTV4c6qKiuPTAtXYk'
const y = 'rU7bM9ENDkybaxNrefAVjdLTyNLuue1KaJ'; const y = 'rU7bM9ENDkybaxNrefAVjdLTyNLuue1KaJ'
assert.strictEqual(api.deriveNodeAddress(x), y); assert.strictEqual(api.deriveNodeAddress(x), y)
}); })
it('Random Address', () => { it('Random Address', () => {
const seed = api.generateSeed(); const seed = api.generateSeed()
const keypair = api.deriveKeypair(seed); const keypair = api.deriveKeypair(seed)
const address = api.deriveAddress(keypair.publicKey); const address = api.deriveAddress(keypair.publicKey)
assert(address[0] === 'r'); assert(address[0] === 'r')
}); })
}); })

View File

@@ -1,13 +1,14 @@
'use strict'; 'use strict' // eslint-disable-line strict
const assert = require('assert');
const utils = require('../src/utils'); const assert = require('assert')
const utils = require('../src/utils')
describe('utils', () => { describe('utils', () => {
it('hexToBytes - zero', () => { it('hexToBytes - zero', () => {
assert.deepEqual(utils.hexToBytes('000000'), [0, 0, 0]); assert.deepEqual(utils.hexToBytes('000000'), [0, 0, 0])
}); })
it('hexToBytes - DEADBEEF', () => { it('hexToBytes - DEADBEEF', () => {
assert.deepEqual(utils.hexToBytes('DEADBEEF'), [222, 173, 190, 239]); assert.deepEqual(utils.hexToBytes('DEADBEEF'), [222, 173, 190, 239])
}); })
}); })