diff --git a/CHANGELOG.md b/CHANGELOG.md index dce8d1f..4744dc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,9 @@ Stable version, interobable with go-libp2p-noise! - fix types to be compatible with rest of libp2p typescript projects - update it-pb-rpc to 0.1.8 (contains proper typescript types) +### Bugfixes +- changed bcrypto imports to use pure js versions (web bundle size reduction) + ## [1.0.0-rc.9] - 2019-03-11 ### Bugfixes diff --git a/package.json b/package.json index 8c430ff..0eccbf7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "libp2p-noise", - "version": "1.1.0-rc1", + "version": "1.0.0", "main": "dist/index.js", "types": "dist/index.d.ts", "module": "lib/index.js", @@ -20,6 +20,7 @@ "scripts": { "prebuild": "rm -rf lib && rm -rf dist", "build": "yarn run build:node && yarn run build:web && yarn run build:types", + "bundle": "webpack --config webpack.bundle.config.js", "build:node": "babel --no-babelrc --config-file ./babel.config.json src --copy-files -x .ts -d dist --source-maps", "build:web": "babel --no-babelrc --config-file ./babel.web.config.json src --copy-files -x .ts -d lib --source-maps", "build:types": "tsc --declaration --outDir dist --emitDeclarationOnly", @@ -47,6 +48,7 @@ "@types/mocha": "^5.2.7", "@typescript-eslint/eslint-plugin": "^2.6.0", "@typescript-eslint/parser": "^2.6.0", + "babel-loader": "^8.1.0", "chai": "^4.2.0", "eslint": "^6.6.0", "karma": "^4.4.1", @@ -60,10 +62,11 @@ "sinon": "^8.1.0", "ts-loader": "^6.2.1", "typescript": "^3.6.4", - "webpack": "^4.41.5" + "webpack": "^4.41.5", + "webpack-bundle-analyzer": "^3.6.1", + "webpack-cli": "^3.3.11" }, "dependencies": { - "@types/bn.js": "^4.11.6", "bcrypto": "5.1.0", "bn.js": "^5.0.0", "buffer": "^5.4.3", diff --git a/src/@types/basic.ts b/src/@types/basic.ts index 0e9ba27..03f9451 100644 --- a/src/@types/basic.ts +++ b/src/@types/basic.ts @@ -1,9 +1,8 @@ -import BN from 'bn.js'; -import { Buffer } from 'buffer'; +import {Buffer} from 'buffer'; export type bytes = Buffer; export type bytes32 = Buffer; export type bytes16 = Buffer; export type uint32 = number; -export type uint64 = BN; +export type uint64 = number; diff --git a/src/handshakes/abstract-handshake.ts b/src/handshakes/abstract-handshake.ts index c9db6df..85d63b7 100644 --- a/src/handshakes/abstract-handshake.ts +++ b/src/handshakes/abstract-handshake.ts @@ -1,5 +1,7 @@ import {Buffer} from "buffer"; -import { AEAD, x25519, SHA256 } from 'bcrypto'; +import AEAD from 'bcrypto/lib/js/aead'; +import x25519 from 'bcrypto/lib/js/x25519'; +import SHA256 from 'bcrypto/lib/js/sha256'; import {bytes, bytes32, uint32} from "../@types/basic"; import {CipherState, MessageBuffer, SymmetricState} from "../@types/handshake"; diff --git a/src/handshakes/ik.ts b/src/handshakes/ik.ts index b94f7a2..56dd8b0 100644 --- a/src/handshakes/ik.ts +++ b/src/handshakes/ik.ts @@ -1,6 +1,4 @@ import {Buffer} from "buffer"; -import BN from "bn.js"; - import {CipherState, HandshakeState, MessageBuffer, NoiseSession} from "../@types/handshake"; import {bytes, bytes32} from "../@types/basic"; import {generateKeypair, isValidPublicKey} from "../utils"; @@ -22,21 +20,21 @@ export class IK extends AbstractHandshake { return { hs, i: initiator, - mc: new BN(0), + mc: 0, }; } public sendMessage(session: NoiseSession, message: bytes): MessageBuffer { let messageBuffer: MessageBuffer; - if (session.mc.eqn(0)) { + if (session.mc === 0) { messageBuffer = this.writeMessageA(session.hs, message); - } else if (session.mc.eqn(1)) { + } else if (session.mc === 1) { const { messageBuffer: mb, h, cs1, cs2 } = this.writeMessageB(session.hs, message); messageBuffer = mb; session.h = h; session.cs1 = cs1; session.cs2 = cs2; - } else if (session.mc.gtn(1)) { + } else if (session.mc > 1) { if (session.i) { if (!session.cs1) { throw new Error("CS1 (cipher state) is not defined") @@ -54,16 +52,16 @@ export class IK extends AbstractHandshake { throw new Error("Session invalid.") } - session.mc = session.mc.add(new BN(1)); + session.mc++; return messageBuffer; } public recvMessage(session: NoiseSession, message: MessageBuffer): {plaintext: bytes; valid: boolean} { let plaintext = Buffer.alloc(0), valid = false; - if (session.mc.eqn(0)) { + if (session.mc === 0) { ({plaintext, valid} = this.readMessageA(session.hs, message)); } - if (session.mc.eqn(1)) { + if (session.mc === 1) { const { plaintext: pt, valid: v, h, cs1, cs2 } = this.readMessageB(session.hs, message); plaintext = pt; valid = v; @@ -71,7 +69,7 @@ export class IK extends AbstractHandshake { session.cs1 = cs1; session.cs2 = cs2; } - session.mc = session.mc.add(new BN(1)); + session.mc++; return {plaintext, valid}; } diff --git a/src/handshakes/xx.ts b/src/handshakes/xx.ts index 0caf6bc..4e608d0 100644 --- a/src/handshakes/xx.ts +++ b/src/handshakes/xx.ts @@ -1,6 +1,4 @@ import { Buffer } from 'buffer'; -import BN from 'bn.js'; - import { bytes32, bytes } from '../@types/basic' import { KeyPair } from '../@types/libp2p' import {generateKeypair, isValidPublicKey} from '../utils'; @@ -129,23 +127,23 @@ export class XX extends AbstractHandshake { return { hs, i: initiator, - mc: new BN(0), + mc: 0, }; } public sendMessage(session: NoiseSession, message: bytes, ephemeral?: KeyPair): MessageBuffer { let messageBuffer: MessageBuffer; - if (session.mc.eqn(0)) { + if (session.mc === 0) { messageBuffer = this.writeMessageA(session.hs, message, ephemeral); - } else if (session.mc.eqn(1)) { + } else if (session.mc === 1) { messageBuffer = this.writeMessageB(session.hs, message); - } else if (session.mc.eqn(2)) { + } else if (session.mc === 2) { const { h, messageBuffer: resultingBuffer, cs1, cs2 } = this.writeMessageC(session.hs, message); messageBuffer = resultingBuffer; session.h = h; session.cs1 = cs1; session.cs2 = cs2; - } else if (session.mc.gtn(2)) { + } else if (session.mc > 2) { if (session.i) { if (!session.cs1) { throw new Error("CS1 (cipher state) is not defined") @@ -163,18 +161,18 @@ export class XX extends AbstractHandshake { throw new Error("Session invalid.") } - session.mc = session.mc.add(new BN(1)); + session.mc++; return messageBuffer; } public recvMessage(session: NoiseSession, message: MessageBuffer): {plaintext: bytes; valid: boolean} { let plaintext: bytes = Buffer.alloc(0); let valid = false; - if (session.mc.eqn(0)) { + if (session.mc === 0) { ({plaintext, valid} = this.readMessageA(session.hs, message)); - } else if (session.mc.eqn(1)) { + } else if (session.mc === 1) { ({plaintext, valid} = this.readMessageB(session.hs, message)); - } else if (session.mc.eqn(2)) { + } else if (session.mc === 2) { const { h, plaintext: resultingPlaintext, valid: resultingValid, cs1, cs2 } = this.readMessageC(session.hs, message); plaintext = resultingPlaintext; valid = resultingValid; @@ -182,7 +180,7 @@ export class XX extends AbstractHandshake { session.cs1 = cs1; session.cs2 = cs2; } - session.mc = session.mc.add(new BN(1)); + session.mc++; return {plaintext, valid}; } } diff --git a/src/noise.ts b/src/noise.ts index 777b3e0..cd58ec2 100644 --- a/src/noise.ts +++ b/src/noise.ts @@ -1,4 +1,4 @@ -import {x25519} from 'bcrypto'; +import x25519 from 'bcrypto/lib/js/x25519'; import {Buffer} from "buffer"; import Wrap from 'it-pb-rpc'; import DuplexPair from 'it-pair/duplex'; diff --git a/src/utils.ts b/src/utils.ts index a4004f9..4be4951 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,9 @@ -import {HKDF, SHA256, x25519} from 'bcrypto'; +import HKDF from 'bcrypto/lib/hkdf'; +import x25519 from 'bcrypto/lib/js/x25519'; +import SHA256 from 'bcrypto/lib/js/sha256'; import {Buffer} from "buffer"; import PeerId from "peer-id"; -import * as crypto from 'libp2p-crypto'; +import {keys} from 'libp2p-crypto'; import {KeyPair} from "./@types/libp2p"; import {bytes, bytes32} from "./@types/basic"; import {Hkdf, INoisePayload} from "./@types/handshake"; @@ -91,7 +93,7 @@ export async function verifySignedPayload( } const generatedPayload = getHandshakePayload(noiseStaticKey); // Unmarshaling from PublicKey protobuf - const publicKey = crypto.keys.unmarshalPublicKey(identityKey); + const publicKey = keys.unmarshalPublicKey(identityKey); if (!publicKey.verify(generatedPayload, payload.identitySig)) { throw new Error("Static key doesn't match to peer that signed payload!"); } diff --git a/test/utils.ts b/test/utils.ts index 2ac5b7b..29a5b06 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -1,8 +1,9 @@ -import * as crypto from 'libp2p-crypto'; -import {KeyPair, PeerId} from "../src/@types/libp2p"; +import {keys} from 'libp2p-crypto'; +import {KeyPair} from "../src/@types/libp2p"; +import PeerId from "peer-id"; export async function generateEd25519Keys() { - return await crypto.keys.generateKeyPair('ed25519'); + return await keys.generateKeyPair('ed25519'); } export function getKeyPairFromPeerId(peerId: PeerId): KeyPair { diff --git a/webpack.bundle.config.js b/webpack.bundle.config.js new file mode 100644 index 0000000..ade3a72 --- /dev/null +++ b/webpack.bundle.config.js @@ -0,0 +1,24 @@ + +const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; + +module.exports = { + entry: "./src/index.ts", + mode: "production", + output: { + filename: "../bundle/bundle.js" + }, + node: { + fs: "empty" + }, + resolve: { + extensions: [".ts", ".js"], + }, + module: { + rules: [ + {test: /\.ts$/, exclude: [/node_modules/], use: {loader: "babel-loader", options: require("./babel.web.config")}} + ], + }, + plugins: [ + new BundleAnalyzerPlugin() + ] +}; diff --git a/yarn.lock b/yarn.lock index ea8033e..7f4c6dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1056,13 +1056,6 @@ dependencies: "@types/node" "*" -"@types/bn.js@^4.11.6": - version "4.11.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" - integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== - dependencies: - "@types/node" "*" - "@types/chai@^4.2.4": version "4.2.4" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.4.tgz#8936cffad3c96ec470a2dc26a38c3ba8b9b6f619" @@ -1098,6 +1091,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.3.tgz#65a8d9a6a0f6af55595a2d0020617959130d6495" integrity sha512-QZ9CjUB3QoA3f2afw3utKlfRPhpmufB7jC2+oDhLWnXqoyx333fhKSQDLQu2EK7OE0a15X67eYiRAaJsHXrpMA== +"@types/node@^10.12.12": + version "10.17.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.2.tgz#41b5afbcde1a5a805302a4da3cf399499f1bbf64" + integrity sha512-sAh60KDol+MpwOr1RTK0+HgBEYejKsxdpmrOS1Wts5bI03dLzq8F7T0sRXDKeaEK8iWDlGfdzxrzg6vx/c5pNA== + "@typescript-eslint/eslint-plugin@^2.6.0": version "2.6.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.6.0.tgz#e82ed43fc4527b21bfe35c20a2d6e4ed49fc7957" @@ -1585,13 +1583,14 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" -bcrypto@5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/bcrypto/-/bcrypto-5.1.0.tgz#1ca3d0b1bd1ffe6bb18cfcf2a7d7fc19423b68e6" - integrity sha512-WEs5g7WHdEdLLcsvhE7Z1AXv0G+hb+bJhSUYM7samFNrH051XhcFVWxAbAZDmIU1HWjpjhmQ+HqBar7UC/qrzQ== +bcrypto@5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/bcrypto/-/bcrypto-5.0.3.tgz#086b62d660e545c34ddf980fd4a5fc0001d4708b" + integrity sha512-wqATA9cenjBLDjih4Pey6H47G4RIpDzX4V3gvPTxsQkvVovYoERKyHR/BuUuxYllw5Xpi7novrogb/F/wN7xjA== dependencies: bufio "~1.0.6" loady "~0.0.1" + nan "^2.14.0" better-assert@~1.0.0: version "1.0.2" @@ -1636,15 +1635,6 @@ bl@^4.0.0: dependencies: readable-stream "^3.4.0" -bl@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.2.tgz#52b71e9088515d0606d9dd9cc7aa48dc1f98e73a" - integrity sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - blakejs@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.1.0.tgz#69df92ef953aa88ca51a32df6ab1c54a155fc7a5" @@ -1660,6 +1650,13 @@ bluebird@^3.3.0, bluebird@^3.5.5: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== +bn.js-typings@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bn.js-typings/-/bn.js-typings-1.0.1.tgz#00faef56401850b763cee041c0728a9aaf091e7e" + integrity sha512-PdV3AEpI5A8mHCt3KgBobIJ+3rhoxxkRl8b0dCGDgGtJNYmN4KTPLHYq7xOSmKF1Kv06aZ5k8QhXbyG73IyhdQ== + dependencies: + "@types/node" "^10.12.12" + bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.8, bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" @@ -1847,14 +1844,6 @@ buffer@^5.2.1, buffer@^5.4.3: base64-js "^1.0.2" ieee754 "^1.1.4" -buffer@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.5.0.tgz#9c3caa3d623c33dd1c7ef584b89b88bf9c9bc1ce" - integrity sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - bufio@~1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/bufio/-/bufio-1.0.6.tgz#e0eb6d70b2efcc997b6f8872173540967f90fa4d" @@ -3306,7 +3295,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -3385,7 +3374,7 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-buffer@^2.0.4, is-buffer@~2.0.3: +is-buffer@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== @@ -3610,15 +3599,6 @@ it-length-prefixed@^3.0.0: buffer "^5.4.3" varint "^5.0.0" -it-length-prefixed@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/it-length-prefixed/-/it-length-prefixed-3.0.1.tgz#8c4d829576f941eb17b94bc83ed0c3c78bf0a05a" - integrity sha512-QnfnFkpklDhWpyPQ2al6pdqmsQbwZAUpa7066e8S9RQxXo0s4o21ceqCG0n/0wdmvgfRSYsW5g2dYgchqtLZYw== - dependencies: - bl "^4.0.2" - buffer "^5.5.0" - varint "^5.0.0" - it-pair@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/it-pair/-/it-pair-1.0.0.tgz#b1add81f49af16a10b2939dbef7b1974fae87d6a" @@ -3626,14 +3606,13 @@ it-pair@^1.0.0: dependencies: get-iterator "^1.0.2" -it-pb-rpc@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/it-pb-rpc/-/it-pb-rpc-0.1.8.tgz#eed8ffdcba2a322a20a45c9db9ec5644499ccaf2" - integrity sha512-YePzUUonithCTIdVKcOeQEn5mpipCg7ZoWsq7jfjXXtAS6gm6R7KzCe6YBV97i6bljU8hGllTG67FiGfweKNKg== +it-pb-rpc@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/it-pb-rpc/-/it-pb-rpc-0.1.6.tgz#f6dba92f44a6ce5df8fc71ca08aefe472b552a02" + integrity sha512-4srJH8iK976tlAEv0wBnud78hxjQsDvrl71lPG7zquNiaqZ3409oqzukC05f6z0UeYwi4M80Bm+gHy/642lJ/g== dependencies: - is-buffer "^2.0.4" it-handshake "^1.0.1" - it-length-prefixed "^3.0.1" + it-length-prefixed "^3.0.0" it-pipe@^1.1.0: version "1.1.0"