fix: add buffer, cleanup, reduce size (#170)

* fix: add buffer, cleanup, reduce size

- add buffer related to https://github.com/ipfs/js-ipfs/issues/2924
- remove unnecessary eslint ignore
- remove tweelnacl and use node-forge
- remove browserify-aes  and use node-forge
- use multibase to encode b58
- require only sha256 from multihashing
- reduce bundle size

after all the deps here https://github.com/ipfs/js-ipfs/issues/2924 are merged libp2p-crypto will be able to be bundle with `node: false` 🎉

* fix: reduce bundle size

* fix: use new secp

* fix: bundle size

* chore: update secp

Co-Authored-By: Jacob Heun <jacobheun@gmail.com>

Co-authored-by: Jacob Heun <jacobheun@gmail.com>
This commit is contained in:
Hugo Dias 2020-03-23 15:55:35 +00:00 committed by GitHub
parent d3601fa936
commit c956d1ad2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 69 additions and 80 deletions

View File

@ -1,3 +1,3 @@
module.exports = { module.exports = {
bundlesize: { maxSize: '155kB' } bundlesize: { maxSize: '124kB' }
} }

View File

@ -1 +0,0 @@
src/keys/keys.proto.js

View File

@ -37,25 +37,20 @@
], ],
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"asmcrypto.js": "^2.3.2", "buffer": "^5.5.0",
"bn.js": "^5.0.0",
"browserify-aes": "^1.2.0",
"bs58": "^4.0.1",
"err-code": "^2.0.0", "err-code": "^2.0.0",
"iso-random-stream": "^1.1.0", "iso-random-stream": "^1.1.0",
"keypair": "^1.0.1", "keypair": "^1.0.1",
"libp2p-crypto-secp256k1": "~0.4.0", "libp2p-crypto-secp256k1": "^0.4.2",
"multihashing-async": "~0.8.0", "multibase": "^0.6.0",
"multihashing-async": "^0.8.1",
"node-forge": "~0.9.1", "node-forge": "~0.9.1",
"pem-jwk": "^2.0.0", "pem-jwk": "^2.0.0",
"protons": "^1.0.1", "protons": "^1.0.1",
"rsa-pem-to-jwk": "^1.1.3",
"tweetnacl": "^1.0.1",
"ursa-optional": "~0.10.1" "ursa-optional": "~0.10.1"
}, },
"devDependencies": { "devDependencies": {
"@types/bn.js": "^4.11.6", "@types/chai": "^4.2.11",
"@types/chai": "^4.2.7",
"@types/chai-string": "^1.4.2", "@types/chai-string": "^1.4.2",
"@types/dirty-chai": "^2.0.2", "@types/dirty-chai": "^2.0.2",
"@types/mocha": "^7.0.1", "@types/mocha": "^7.0.1",

View File

@ -1,8 +1,27 @@
'use strict' 'use strict'
const { Buffer } = require('buffer')
const crypto = require('browserify-aes') require('node-forge/lib/aes')
const forge = require('node-forge/lib/forge')
module.exports = { module.exports = {
createCipheriv: crypto.createCipheriv, createCipheriv: (mode, key, iv) => {
createDecipheriv: crypto.createDecipheriv const cipher2 = forge.cipher.createCipher('AES-CTR', key.toString('binary'))
cipher2.start({ iv: iv.toString('binary') })
return {
update: (data) => {
cipher2.update(forge.util.createBuffer(data.toString('binary')))
return Buffer.from(cipher2.output.getBytes(), 'binary')
}
}
},
createDecipheriv: (mode, key, iv) => {
const cipher2 = forge.cipher.createDecipher('AES-CTR', key.toString('binary'))
cipher2.start({ iv: iv.toString('binary') })
return {
update: (data) => {
cipher2.update(forge.util.createBuffer(data.toString('binary')))
return Buffer.from(cipher2.output.getBytes(), 'binary')
}
}
}
} }

View File

@ -1,34 +0,0 @@
'use strict'
const asm = require('asmcrypto.js')
const validateCipherMode = require('./cipher-mode')
exports.create = async function (key, iv) { // eslint-disable-line require-await
// Throws an error if mode is invalid
validateCipherMode(key)
const enc = new asm.AES_CTR.Encrypt({
key: key,
nonce: iv
})
const dec = new asm.AES_CTR.Decrypt({
key: key,
nonce: iv
})
const res = {
async encrypt (data) { // eslint-disable-line require-await
return Buffer.from(
enc.process(data).result
)
},
async decrypt (data) { // eslint-disable-line require-await
return Buffer.from(
dec.process(data).result
)
}
}
return res
}

View File

@ -1,5 +1,5 @@
'use strict' 'use strict'
const { Buffer } = require('buffer')
const webcrypto = require('../webcrypto') const webcrypto = require('../webcrypto')
const lengths = require('./lengths') const lengths = require('./lengths')

View File

@ -1,8 +1,9 @@
'use strict' 'use strict'
const multihashing = require('multihashing-async') const { Buffer } = require('buffer')
const sha = require('multihashing-async/src/sha')
const protobuf = require('protons') const protobuf = require('protons')
const bs58 = require('bs58') const multibase = require('multibase')
const errcode = require('err-code') const errcode = require('err-code')
const crypto = require('./ed25519') const crypto = require('./ed25519')
@ -33,7 +34,7 @@ class Ed25519PublicKey {
} }
async hash () { // eslint-disable-line require-await async hash () { // eslint-disable-line require-await
return multihashing(this.bytes, 'sha2-256') return sha.multihashing(this.bytes, 'sha2-256')
} }
} }
@ -69,7 +70,7 @@ class Ed25519PrivateKey {
} }
async hash () { // eslint-disable-line require-await async hash () { // eslint-disable-line require-await
return multihashing(this.bytes, 'sha2-256') return sha.multihashing(this.bytes, 'sha2-256')
} }
/** /**
@ -83,7 +84,7 @@ class Ed25519PrivateKey {
*/ */
async id () { async id () {
const hash = await this.public.hash() const hash = await this.public.hash()
return bs58.encode(hash) return multibase.encode('base58btc', hash).toString().slice(1)
} }
} }
@ -100,13 +101,13 @@ function unmarshalEd25519PublicKey (bytes) {
} }
async function generateKeyPair () { async function generateKeyPair () {
const { secretKey, publicKey } = await crypto.generateKey() const { privateKey, publicKey } = await crypto.generateKey()
return new Ed25519PrivateKey(secretKey, publicKey) return new Ed25519PrivateKey(privateKey, publicKey)
} }
async function generateKeyPairFromSeed (seed) { async function generateKeyPairFromSeed (seed) {
const { secretKey, publicKey } = await crypto.generateKeyFromSeed(seed) const { privateKey, publicKey } = await crypto.generateKeyFromSeed(seed)
return new Ed25519PrivateKey(secretKey, publicKey) return new Ed25519PrivateKey(privateKey, publicKey)
} }
function ensureKey (key, length) { function ensureKey (key, length) {

View File

@ -1,23 +1,24 @@
'use strict' 'use strict'
const nacl = require('tweetnacl') require('node-forge/lib/ed25519')
const forge = require('node-forge/lib/forge')
exports.publicKeyLength = nacl.sign.publicKeyLength exports.publicKeyLength = forge.pki.ed25519.constants.PUBLIC_KEY_BYTE_LENGTH
exports.privateKeyLength = nacl.sign.secretKeyLength exports.privateKeyLength = forge.pki.ed25519.constants.PRIVATE_KEY_BYTE_LENGTH
exports.generateKey = async function () { // eslint-disable-line require-await exports.generateKey = async function () { // eslint-disable-line require-await
return nacl.sign.keyPair() return forge.pki.ed25519.generateKeyPair()
} }
// seed should be a 32 byte uint8array // seed should be a 32 byte uint8array
exports.generateKeyFromSeed = async function (seed) { // eslint-disable-line require-await exports.generateKeyFromSeed = async function (seed) { // eslint-disable-line require-await
return nacl.sign.keyPair.fromSeed(seed) return forge.pki.ed25519.generateKeyPair({ seed })
} }
exports.hashAndSign = async function (key, msg) { // eslint-disable-line require-await exports.hashAndSign = async function (key, msg) { // eslint-disable-line require-await
return Buffer.from(nacl.sign.detached(msg, key)) return forge.pki.ed25519.sign({ message: msg, privateKey: key })
// return Buffer.from(nacl.sign.detached(msg, key))
} }
exports.hashAndVerify = async function (key, sig, msg) { // eslint-disable-line require-await exports.hashAndVerify = async function (key, sig, msg) { // eslint-disable-line require-await
return nacl.sign.detached.verify(msg, sig, key) return forge.pki.ed25519.verify({ signature: sig, message: msg, publicKey: key })
} }

View File

@ -1,9 +1,9 @@
'use strict' 'use strict'
const { Buffer } = require('buffer')
const protobuf = require('protons') const protobuf = require('protons')
const keysPBM = protobuf(require('./keys.proto')) const keysPBM = protobuf(require('./keys.proto'))
require('node-forge/lib/asn1') require('node-forge/lib/asn1')
require('node-forge/lib/rsa')
require('node-forge/lib/pbe') require('node-forge/lib/pbe')
const forge = require('node-forge/lib/forge') const forge = require('node-forge/lib/forge')
const errcode = require('err-code') const errcode = require('err-code')

View File

@ -1,5 +1,5 @@
'use strict' 'use strict'
const { Buffer } = require('buffer')
const errcode = require('err-code') const errcode = require('err-code')
const hmac = require('../hmac') const hmac = require('../hmac')

View File

@ -1,5 +1,6 @@
'use strict' 'use strict'
const { Buffer } = require('buffer')
const webcrypto = require('../webcrypto') const webcrypto = require('../webcrypto')
const randomBytes = require('../random-bytes') const randomBytes = require('../random-bytes')

View File

@ -1,14 +1,14 @@
'use strict' 'use strict'
const multihashing = require('multihashing-async') const sha = require('multihashing-async/src/sha')
const protobuf = require('protons') const protobuf = require('protons')
const bs58 = require('bs58') const multibase = require('multibase')
const errcode = require('err-code') const errcode = require('err-code')
const crypto = require('./rsa') const crypto = require('./rsa')
const pbm = protobuf(require('./keys.proto')) const pbm = protobuf(require('./keys.proto'))
require('node-forge/lib/sha512') require('node-forge/lib/sha512')
require('node-forge/lib/pbe') require('node-forge/lib/ed25519')
const forge = require('node-forge/lib/forge') const forge = require('node-forge/lib/forge')
class RsaPublicKey { class RsaPublicKey {
@ -40,7 +40,7 @@ class RsaPublicKey {
} }
async hash () { // eslint-disable-line require-await async hash () { // eslint-disable-line require-await
return multihashing(this.bytes, 'sha2-256') return sha.multihashing(this.bytes, 'sha2-256')
} }
} }
@ -88,7 +88,7 @@ class RsaPrivateKey {
} }
async hash () { // eslint-disable-line require-await async hash () { // eslint-disable-line require-await
return multihashing(this.bytes, 'sha2-256') return sha.multihashing(this.bytes, 'sha2-256')
} }
/** /**
@ -102,7 +102,7 @@ class RsaPrivateKey {
*/ */
async id () { async id () {
const hash = await this.public.hash() const hash = await this.public.hash()
return bs58.encode(hash) return multibase.encode('base58btc', hash).toString().slice(1)
} }
/** /**

View File

@ -2,7 +2,7 @@
/* eslint-disable valid-jsdoc */ /* eslint-disable valid-jsdoc */
/* eslint-env mocha */ /* eslint-env mocha */
'use strict' 'use strict'
const { Buffer } = require('buffer')
const chai = require('chai') const chai = require('chai')
const dirtyChai = require('dirty-chai') const dirtyChai = require('dirty-chai')
const expect = chai.expect const expect = chai.expect

View File

@ -1,4 +1,5 @@
'use strict' 'use strict'
const { Buffer } = require('buffer')
module.exports = { module.exports = {
curve: 'P-256', curve: 'P-256',

View File

@ -1,4 +1,5 @@
'use strict' 'use strict'
const { Buffer } = require('buffer')
module.exports = { module.exports = {
// These were generated in a gore (https://github.com/motemen/gore) repl session: // These were generated in a gore (https://github.com/motemen/gore) repl session:

View File

@ -1,5 +1,5 @@
'use strict' 'use strict'
const { Buffer } = require('buffer')
module.exports = { module.exports = {
private: { private: {
hash: Buffer.from([ hash: Buffer.from([

View File

@ -1,5 +1,5 @@
'use strict' 'use strict'
const { Buffer } = require('buffer')
module.exports = [{ module.exports = [{
cipher: 'AES-256', cipher: 'AES-256',
hash: 'SHA256', hash: 'SHA256',

View File

@ -1,5 +1,6 @@
'use strict' 'use strict'
const { Buffer } = require('buffer')
module.exports = { module.exports = {
// protobuf marshaled key pair generated with libp2p-crypto-secp256k1 // protobuf marshaled key pair generated with libp2p-crypto-secp256k1
// and marshaled with libp2p-crypto.marshalPublicKey / marshalPrivateKey // and marshaled with libp2p-crypto.marshalPublicKey / marshalPrivateKey

View File

@ -1,6 +1,7 @@
/* eslint-env mocha */ /* eslint-env mocha */
'use strict' 'use strict'
const { Buffer } = require('buffer')
const util = require('util') const util = require('util')
const garbage = [Buffer.from('00010203040506070809', 'hex'), {}, null, false, undefined, true, 1, 0, Buffer.from(''), 'aGVsbG93b3JsZA==', 'helloworld', ''] const garbage = [Buffer.from('00010203040506070809', 'hex'), {}, null, false, undefined, true, 1, 0, Buffer.from(''), 'aGVsbG93b3JsZA==', 'helloworld', '']

View File

@ -1,7 +1,7 @@
/* eslint max-nested-callbacks: ["error", 8] */ /* eslint max-nested-callbacks: ["error", 8] */
/* eslint-env mocha */ /* eslint-env mocha */
'use strict' 'use strict'
const { Buffer } = require('buffer')
const chai = require('chai') const chai = require('chai')
const dirtyChai = require('dirty-chai') const dirtyChai = require('dirty-chai')
const expect = chai.expect const expect = chai.expect

View File

@ -1,6 +1,7 @@
/* eslint-env mocha */ /* eslint-env mocha */
'use strict' 'use strict'
const { Buffer } = require('buffer')
const chai = require('chai') const chai = require('chai')
const dirtyChai = require('dirty-chai') const dirtyChai = require('dirty-chai')
const expect = chai.expect const expect = chai.expect

View File

@ -2,6 +2,7 @@
/* eslint-env mocha */ /* eslint-env mocha */
'use strict' 'use strict'
const { Buffer } = require('buffer')
const chai = require('chai') const chai = require('chai')
const dirtyChai = require('dirty-chai') const dirtyChai = require('dirty-chai')
const expect = chai.expect const expect = chai.expect

View File

@ -3,6 +3,7 @@
'use strict' 'use strict'
const chai = require('chai') const chai = require('chai')
const { Buffer } = require('buffer')
const dirtyChai = require('dirty-chai') const dirtyChai = require('dirty-chai')
const expect = chai.expect const expect = chai.expect
chai.use(dirtyChai) chai.use(dirtyChai)