New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@chainsafe/libp2p-noise

Package Overview
Dependencies
Maintainers
2
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@chainsafe/libp2p-noise - npm Package Compare versions

Comparing version 15.1.2 to 16.0.0

dist/typedoc-urls.json

5

dist/src/errors.d.ts

@@ -1,6 +0,1 @@

export declare class UnexpectedPeerError extends Error {
code: string;
constructor(message?: string);
static readonly code = "ERR_UNEXPECTED_PEER";
}
export declare class InvalidCryptoExchangeError extends Error {

@@ -7,0 +2,0 @@ code: string;

@@ -1,9 +0,1 @@

export class UnexpectedPeerError extends Error {
code;
constructor(message = 'Unexpected Peer') {
super(message);
this.code = UnexpectedPeerError.code;
}
static code = 'ERR_UNEXPECTED_PEER';
}
export class InvalidCryptoExchangeError extends Error {

@@ -10,0 +2,0 @@ code;

40

dist/src/index.d.ts

@@ -0,4 +1,41 @@

/**
* @packageDocumentation
*
* This repository contains TypeScript implementation of noise protocol, an encryption protocol used in libp2p.
*
* ## Usage
*
* Install with `yarn add @chainsafe/libp2p-noise` or `npm i @chainsafe/libp2p-noise`.
*
* Example of using default noise configuration and passing it to the libp2p config:
*
* ```ts
* import {createLibp2p} from "libp2p"
* import {noise} from "@chainsafe/libp2p-noise"
*
* //custom noise configuration, pass it instead of `noise()`
* //x25519 private key
* const n = noise({ staticNoiseKey });
*
* const libp2p = await createLibp2p({
* connectionEncrypters: [noise()],
* //... other options
* })
* ```
*
* See the [NoiseInit](https://github.com/ChainSafe/js-libp2p-noise/blob/master/src/noise.ts#L22-L30) interface for noise configuration options.
*
* ## API
*
* This module exposes an implementation of the [ConnectionEncrypter](https://libp2p.github.io/js-libp2p/interfaces/_libp2p_interface.ConnectionEncrypter.html) interface.
*
* ## Bring your own crypto
*
* You can provide a custom crypto implementation (instead of the default, based on [@noble](https://paulmillr.com/noble/)) by adding a `crypto` field to the init argument passed to the `Noise` factory.
*
* The implementation must conform to the `ICryptoInterface`, defined in <https://github.com/ChainSafe/js-libp2p-noise/blob/master/src/crypto.ts>
*/
import type { NoiseInit } from './noise.js';
import type { NoiseExtensions } from './proto/payload.js';
import type { ComponentLogger, ConnectionEncrypter, Metrics, PeerId } from '@libp2p/interface';
import type { ComponentLogger, ConnectionEncrypter, Metrics, PeerId, PrivateKey } from '@libp2p/interface';
export type { ICryptoInterface } from './crypto.js';

@@ -8,2 +45,3 @@ export { pureJsCrypto } from './crypto/js.js';

peerId: PeerId;
privateKey: PrivateKey;
logger: ComponentLogger;

@@ -10,0 +48,0 @@ metrics?: Metrics;

@@ -0,1 +1,38 @@

/**
* @packageDocumentation
*
* This repository contains TypeScript implementation of noise protocol, an encryption protocol used in libp2p.
*
* ## Usage
*
* Install with `yarn add @chainsafe/libp2p-noise` or `npm i @chainsafe/libp2p-noise`.
*
* Example of using default noise configuration and passing it to the libp2p config:
*
* ```ts
* import {createLibp2p} from "libp2p"
* import {noise} from "@chainsafe/libp2p-noise"
*
* //custom noise configuration, pass it instead of `noise()`
* //x25519 private key
* const n = noise({ staticNoiseKey });
*
* const libp2p = await createLibp2p({
* connectionEncrypters: [noise()],
* //... other options
* })
* ```
*
* See the [NoiseInit](https://github.com/ChainSafe/js-libp2p-noise/blob/master/src/noise.ts#L22-L30) interface for noise configuration options.
*
* ## API
*
* This module exposes an implementation of the [ConnectionEncrypter](https://libp2p.github.io/js-libp2p/interfaces/_libp2p_interface.ConnectionEncrypter.html) interface.
*
* ## Bring your own crypto
*
* You can provide a custom crypto implementation (instead of the default, based on [@noble](https://paulmillr.com/noble/)) by adding a `crypto` field to the init argument passed to the `Noise` factory.
*
* The implementation must conform to the `ICryptoInterface`, defined in <https://github.com/ChainSafe/js-libp2p-noise/blob/master/src/crypto.ts>
*/
import { Noise } from './noise.js';

@@ -2,0 +39,0 @@ export { pureJsCrypto } from './crypto/js.js';

@@ -1,2 +0,2 @@

import { type MultiaddrConnection, type SecuredConnection, type PeerId, serviceCapabilities } from '@libp2p/interface';
import { serviceCapabilities } from '@libp2p/interface';
import { type ICryptoInterface } from './crypto.js';

@@ -6,2 +6,3 @@ import type { NoiseComponents } from './index.js';

import type { ICrypto, INoiseConnection } from './types.js';
import type { MultiaddrConnection, SecuredConnection, PeerId } from '@libp2p/interface';
import type { Duplex } from 'it-stream-types';

@@ -32,5 +33,6 @@ import type { Uint8ArrayList } from 'uint8arraylist';

*
* @param localPeer - PeerId of the receiving peer
* @param connection - streaming iterable duplex that will be encrypted
* @param remotePeer - PeerId of the remote peer. Used to validate the integrity of the remote peer.
* @param options
* @param options.remotePeer - PeerId of the remote peer. Used to validate the integrity of the remote peer
* @param options.signal - Used to abort the operation
*/

@@ -41,9 +43,9 @@ secureOutbound<Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection>(connection: Stream, options?: {

}): Promise<SecuredConnection<Stream, NoiseExtensions>>;
secureOutbound<Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection>(localPeer: PeerId, connection: Stream, remotePeer?: PeerId): Promise<SecuredConnection<Stream, NoiseExtensions>>;
/**
* Decrypt incoming data (handshake as responder).
*
* @param localPeer - PeerId of the receiving peer.
* @param connection - streaming iterable duplex that will be encrypted.
* @param remotePeer - optional PeerId of the initiating peer, if known. This may only exist during transport upgrades.
* @param connection - streaming iterable duplex that will be encrypted
* @param options
* @param options.remotePeer - PeerId of the remote peer. Used to validate the integrity of the remote peer
* @param options.signal - Used to abort the operation
*/

@@ -54,3 +56,2 @@ secureInbound<Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection>(connection: Stream, options?: {

}): Promise<SecuredConnection<Stream, NoiseExtensions>>;
secureInbound<Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection>(localPeer: PeerId, connection: Stream, remotePeer?: PeerId): Promise<SecuredConnection<Stream, NoiseExtensions>>;
/**

@@ -65,10 +66,3 @@ * Perform XX handshake as initiator.

private createSecureConnection;
/**
* Detect call signature in `libp2p@1.x.x` or `libp2p@2.x.x` style.
*
* TODO: remove this after `libp2p@2.x.x` is released and only support the
* newer style
*/
private parseArgs;
}
//# sourceMappingURL=noise.d.ts.map

@@ -1,4 +0,4 @@

import { unmarshalPrivateKey } from '@libp2p/crypto/keys';
import { CodeError, serviceCapabilities, isPeerId } from '@libp2p/interface';
import { peerIdFromKeys } from '@libp2p/peer-id';
import { publicKeyFromProtobuf } from '@libp2p/crypto/keys';
import { serviceCapabilities } from '@libp2p/interface';
import { peerIdFromPublicKey } from '@libp2p/peer-id';
import { decode } from 'it-length-prefixed';

@@ -46,4 +46,11 @@ import { lpStream } from 'it-length-prefixed-stream';

];
async secureOutbound(...args) {
const { localPeer, connection, remotePeer, signal } = this.parseArgs(args);
/**
* Encrypt outgoing data to the remote party (handshake as initiator)
*
* @param connection - streaming iterable duplex that will be encrypted
* @param options
* @param options.remotePeer - PeerId of the remote peer. Used to validate the integrity of the remote peer
* @param options.signal - Used to abort the operation
*/
async secureOutbound(connection, options) {
const wrappedConnection = lpStream(connection, {

@@ -54,21 +61,22 @@ lengthEncoder: uint16BEEncode,

});
if (!localPeer.privateKey) {
throw new CodeError('local peerId does not contain private key', 'ERR_NO_PRIVATE_KEY');
}
const privateKey = await unmarshalPrivateKey(localPeer.privateKey);
const remoteIdentityKey = remotePeer?.publicKey;
const handshake = await this.performHandshakeInitiator(wrappedConnection, privateKey, remoteIdentityKey, {
signal
});
const handshake = await this.performHandshakeInitiator(wrappedConnection, this.components.privateKey, options?.remotePeer?.publicKey, options);
const conn = await this.createSecureConnection(wrappedConnection, handshake);
connection.source = conn.source;
connection.sink = conn.sink;
const publicKey = publicKeyFromProtobuf(handshake.payload.identityKey);
return {
conn: connection,
remoteExtensions: handshake.payload.extensions,
remotePeer: await peerIdFromKeys(handshake.payload.identityKey)
remotePeer: peerIdFromPublicKey(publicKey)
};
}
async secureInbound(...args) {
const { localPeer, connection, remotePeer, signal } = this.parseArgs(args);
/**
* Decrypt incoming data (handshake as responder).
*
* @param connection - streaming iterable duplex that will be encrypted
* @param options
* @param options.remotePeer - PeerId of the remote peer. Used to validate the integrity of the remote peer
* @param options.signal - Used to abort the operation
*/
async secureInbound(connection, options) {
const wrappedConnection = lpStream(connection, {

@@ -79,17 +87,11 @@ lengthEncoder: uint16BEEncode,

});
if (!localPeer.privateKey) {
throw new CodeError('local peerId does not contain private key', 'ERR_NO_PRIVATE_KEY');
}
const privateKey = await unmarshalPrivateKey(localPeer.privateKey);
const remoteIdentityKey = remotePeer?.publicKey;
const handshake = await this.performHandshakeResponder(wrappedConnection, privateKey, remoteIdentityKey, {
signal
});
const handshake = await this.performHandshakeResponder(wrappedConnection, this.components.privateKey, options?.remotePeer?.publicKey, options);
const conn = await this.createSecureConnection(wrappedConnection, handshake);
connection.source = conn.source;
connection.sink = conn.sink;
const publicKey = publicKeyFromProtobuf(handshake.payload.identityKey);
return {
conn: connection,
remoteExtensions: handshake.payload.extensions,
remotePeer: await peerIdFromKeys(handshake.payload.identityKey)
remotePeer: peerIdFromPublicKey(publicKey)
};

@@ -126,5 +128,3 @@ }

*/
async performHandshakeResponder(connection,
// TODO: pass private key in noise constructor via Components
privateKey, remoteIdentityKey, options) {
async performHandshakeResponder(connection, privateKey, remoteIdentityKey, options) {
let result;

@@ -163,30 +163,3 @@ try {

}
/**
* Detect call signature in `libp2p@1.x.x` or `libp2p@2.x.x` style.
*
* TODO: remove this after `libp2p@2.x.x` is released and only support the
* newer style
*/
parseArgs(args) {
// if the first argument is a peer id, we're using the libp2p@1.x.x style
if (isPeerId(args[0])) {
return {
localPeer: args[0],
connection: args[1],
remotePeer: args[2]
};
}
else {
// handle upcoming changes in libp2p@2.x.x where the first argument is the
// connection and the second is optionally the remote peer
// @see https://github.com/libp2p/js-libp2p/pull/2304
return {
localPeer: this.components.peerId,
connection: args[0],
remotePeer: args[1]?.remotePeer,
signal: args[1]?.signal
};
}
}
}
//# sourceMappingURL=noise.js.map
import type { Nonce } from './nonce';
import type { NoiseExtensions, NoiseHandshakePayload } from './proto/payload';
import type { ConnectionEncrypter, Logger, PrivateKey } from '@libp2p/interface';
import type { ConnectionEncrypter, Logger, PrivateKey, PublicKey } from '@libp2p/interface';
import type { LengthPrefixedStream } from 'it-length-prefixed-stream';

@@ -23,3 +23,3 @@ import type { Uint8ArrayList } from 'uint8arraylist';

s: KeyPair;
remoteIdentityKey?: Uint8Array | Uint8ArrayList;
remoteIdentityKey?: PublicKey;
extensions?: NoiseExtensions;

@@ -26,0 +26,0 @@ }

@@ -0,7 +1,7 @@

import { type PrivateKey, type PublicKey } from '@libp2p/interface';
import { type Uint8ArrayList } from 'uint8arraylist';
import { type NoiseExtensions, NoiseHandshakePayload } from './proto/payload.js';
import type { PrivateKey } from '@libp2p/interface';
export declare function createHandshakePayload(privateKey: PrivateKey, staticPublicKey: Uint8Array | Uint8ArrayList, extensions?: NoiseExtensions): Promise<Uint8Array | Uint8ArrayList>;
export declare function decodeHandshakePayload(payloadBytes: Uint8Array | Uint8ArrayList, remoteStaticKey?: Uint8Array | Uint8ArrayList, remoteIdentityKey?: Uint8Array | Uint8ArrayList): Promise<NoiseHandshakePayload>;
export declare function decodeHandshakePayload(payloadBytes: Uint8Array | Uint8ArrayList, remoteStaticKey?: Uint8Array | Uint8ArrayList, remoteIdentityKey?: PublicKey): Promise<NoiseHandshakePayload>;
export declare function getSignaturePayload(publicKey: Uint8Array | Uint8ArrayList): Uint8Array | Uint8ArrayList;
//# sourceMappingURL=utils.d.ts.map

@@ -1,7 +0,6 @@

import { unmarshalPublicKey } from '@libp2p/crypto/keys';
import { publicKeyFromProtobuf, publicKeyToProtobuf } from '@libp2p/crypto/keys';
import { UnexpectedPeerError } from '@libp2p/interface';
import {} from 'uint8arraylist';
import { equals, toString } from 'uint8arrays';
import { concat as uint8ArrayConcat } from 'uint8arrays/concat';
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
import { UnexpectedPeerError } from './errors.js';
import { NoiseHandshakePayload } from './proto/payload.js';

@@ -11,3 +10,3 @@ export async function createHandshakePayload(privateKey, staticPublicKey, extensions) {

return NoiseHandshakePayload.encode({
identityKey: privateKey.public.bytes,
identityKey: publicKeyToProtobuf(privateKey.publicKey),
identitySig,

@@ -20,7 +19,5 @@ extensions

const payload = NoiseHandshakePayload.decode(payloadBytes);
if (remoteIdentityKey) {
const remoteIdentityKeyBytes = remoteIdentityKey.subarray();
if (!equals(remoteIdentityKeyBytes, payload.identityKey)) {
throw new Error(`Payload identity key ${toString(payload.identityKey, 'hex')} does not match expected remote identity key ${toString(remoteIdentityKeyBytes, 'hex')}`);
}
const publicKey = publicKeyFromProtobuf(payload.identityKey);
if (remoteIdentityKey?.equals(publicKey) === false) {
throw new Error(`Payload identity key ${publicKey} does not match expected remote identity key ${remoteIdentityKey}`);
}

@@ -31,3 +28,2 @@ if (!remoteStaticKey) {

const signaturePayload = getSignaturePayload(remoteStaticKey);
const publicKey = unmarshalPublicKey(payload.identityKey);
if (!(await publicKey.verify(signaturePayload, payload.identitySig))) {

@@ -34,0 +30,0 @@ throw new Error('Invalid payload signature');

{
"name": "@chainsafe/libp2p-noise",
"version": "15.1.2",
"version": "16.0.0",
"description": "Noise libp2p handshake for js-libp2p",
"author": "ChainSafe <info@chainsafe.io>",

@@ -14,2 +15,6 @@ "license": "Apache-2.0 OR MIT",

},
"publishConfig": {
"access": "public",
"provenance": true
},
"keywords": [

@@ -20,6 +25,2 @@ "crypto",

],
"engines": {
"node": ">=16.0.0",
"npm": ">=7.0.0"
},
"type": "module",

@@ -42,2 +43,3 @@ "types": "./dist/src/index.d.ts",

"parserOptions": {
"project": true,
"sourceType": "module"

@@ -56,2 +58,87 @@ },

},
"release": {
"branches": [
"master"
],
"plugins": [
[
"@semantic-release/commit-analyzer",
{
"preset": "conventionalcommits",
"releaseRules": [
{
"breaking": true,
"release": "major"
},
{
"revert": true,
"release": "patch"
},
{
"type": "feat",
"release": "minor"
},
{
"type": "fix",
"release": "patch"
},
{
"type": "docs",
"release": "patch"
},
{
"type": "test",
"release": "patch"
},
{
"type": "deps",
"release": "patch"
},
{
"scope": "no-release",
"release": false
}
]
}
],
[
"@semantic-release/release-notes-generator",
{
"preset": "conventionalcommits",
"presetConfig": {
"types": [
{
"type": "feat",
"section": "Features"
},
{
"type": "fix",
"section": "Bug Fixes"
},
{
"type": "chore",
"section": "Trivial Changes"
},
{
"type": "docs",
"section": "Documentation"
},
{
"type": "deps",
"section": "Dependencies"
},
{
"type": "test",
"section": "Tests"
}
]
}
}
],
"@semantic-release/changelog",
"@semantic-release/npm",
"@semantic-release/github",
"@semantic-release/git"
]
},
"scripts": {

@@ -71,3 +158,4 @@ "bench": "node benchmarks/benchmark.js",

"proto:gen": "protons ./src/proto/payload.proto",
"prepublish": "npm run build"
"prepublish": "npm run build",
"release": "aegir release"
},

@@ -77,5 +165,5 @@ "dependencies": {

"@chainsafe/as-sha256": "^0.4.1",
"@libp2p/crypto": "^4.0.0",
"@libp2p/interface": "^1.5.0",
"@libp2p/peer-id": "^4.0.0",
"@libp2p/crypto": "^5.0.0",
"@libp2p/interface": "^2.0.0",
"@libp2p/peer-id": "^5.0.0",
"@noble/ciphers": "^0.6.0",

@@ -89,3 +177,3 @@ "@noble/curves": "^1.1.0",

"it-stream-types": "^2.0.1",
"protons-runtime": "^5.0.0",
"protons-runtime": "^5.5.0",
"uint8arraylist": "^2.4.3",

@@ -96,10 +184,9 @@ "uint8arrays": "^5.0.0",

"devDependencies": {
"@chainsafe/libp2p-yamux": "^6.0.1",
"@libp2p/daemon-client": "^8.0.1",
"@libp2p/daemon-server": "^7.0.1",
"@libp2p/interface-compliance-tests": "^5.0.5",
"@libp2p/interop": "^12.1.0",
"@libp2p/logger": "^4.0.0",
"@libp2p/peer-id-factory": "^4.0.4",
"@libp2p/tcp": "^9.0.0",
"@chainsafe/libp2p-yamux": "^7.0.0",
"@libp2p/daemon-client": "^9.0.0",
"@libp2p/daemon-server": "^8.0.0",
"@libp2p/interface-compliance-tests": "^6.0.0",
"@libp2p/interop": "^13.0.0",
"@libp2p/logger": "^5.0.0",
"@libp2p/tcp": "^10.0.0",
"@multiformats/multiaddr": "^12.1.0",

@@ -113,6 +200,7 @@ "@types/sinon": "^17.0.1",

"it-byte-stream": "^1.0.0",
"libp2p": "^1.0.8",
"libp2p": "^2.0.0",
"mkdirp": "^3.0.0",
"multiformats": "^13.2.2",
"p-defer": "^4.0.0",
"protons": "^7.0.0",
"protons": "^7.6.0",
"sinon": "^18.0.0"

@@ -119,0 +207,0 @@ },

@@ -1,2 +0,2 @@

# js-libp2p-noise
# @chainsafe/libp2p-noise

@@ -13,11 +13,25 @@ ![npm](https://img.shields.io/npm/v/@chainsafe/libp2p-noise)

[![Twitter](https://img.shields.io/twitter/follow/ChainSafeth.svg?label=Twitter)](https://twitter.com/ChainSafeth)
[![Discord](https://img.shields.io/discord/593655374469660673.svg?label=Discord&logo=discord)](https://discord.gg/Q6A3YA2)
[![Discord](https://img.shields.io/discord/593655374469660673.svg?label=Discord\&logo=discord)](https://discord.gg/Q6A3YA2)
> Noise libp2p handshake for js-libp2p
# About
<!--
!IMPORTANT!
Everything in this README between "# About" and "# Install" is automatically
generated and will be overwritten the next time the doc generator is run.
To make changes to this section, please update the @packageDocumentation section
of src/index.js or src/index.ts
To experiment with formatting, please run "npm run docs" from the root of this
repo and examine the changes made.
-->
This repository contains TypeScript implementation of noise protocol, an encryption protocol used in libp2p.
##### Warning: Even though this package works in browser, it will bundle around 600Kb (200Kb gzipped) of code
https://bundlephobia.com/result?p=@chainsafe/libp2p-noise@latest
## Usage

@@ -29,3 +43,3 @@

```js
```ts
import {createLibp2p} from "libp2p"

@@ -39,3 +53,3 @@ import {noise} from "@chainsafe/libp2p-noise"

const libp2p = await createLibp2p({
connectionEncryption: [noise()],
connectionEncrypters: [noise()],
//... other options

@@ -45,25 +59,41 @@ })

See the [NoiseInit](https://github.com/ChainSafe/js-libp2p-noise/blob/master/src/noise.ts#L29-L38) interface for noise configuration options.
See the [NoiseInit](https://github.com/ChainSafe/js-libp2p-noise/blob/master/src/noise.ts#L22-L30) interface for noise configuration options.
## API
This module exposes an implementation of the [ConnectionEncrypter](https://libp2p.github.io/js-libp2p/interfaces/_libp2p_interface.connection_encrypter.ConnectionEncrypter.html) interface.
This module exposes an implementation of the [ConnectionEncrypter](https://libp2p.github.io/js-libp2p/interfaces/_libp2p_interface.ConnectionEncrypter.html) interface.
## Bring your own crypto
You can provide a custom crypto implementation (instead of the default, based on [@noble](https://paulmillr.com/noble/)) by adding a `crypto` field to the init argument passed to the `Noise` factory.
You can provide a custom crypto implementation (instead of the default, based on [@noble](https://paulmillr.com/noble/)) by adding a `crypto` field to the init argument passed to the `Noise` factory.
The implementation must conform to the `ICryptoInterface`, defined in https://github.com/ChainSafe/js-libp2p-noise/blob/master/src/crypto.ts
The implementation must conform to the `ICryptoInterface`, defined in <https://github.com/ChainSafe/js-libp2p-noise/blob/master/src/crypto.ts>
## Contribute
# Install
Feel free to join in. All welcome. Open an issue!
```console
$ npm i @chainsafe/libp2p-noise
```
[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md)
## Browser `<script>` tag
## License
Loading this module through a script tag will make its exports available as `ChainsafeLibp2pNoise` in the global namespace.
```html
<script src="https://unpkg.com/@chainsafe/libp2p-noise/dist/index.min.js"></script>
```
# API Docs
- <https://ChainSafe.github.io/js-libp2p-noise>
# License
Licensed under either of
* Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / http://www.apache.org/licenses/LICENSE-2.0)
* MIT ([LICENSE-MIT](LICENSE-MIT) / http://opensource.org/licenses/MIT)
- Apache 2.0, ([LICENSE-APACHE](https://github.com/ChainSafe/js-libp2p-noise/LICENSE-APACHE) / <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT ([LICENSE-MIT](https://github.com/ChainSafe/js-libp2p-noise/LICENSE-MIT) / <http://opensource.org/licenses/MIT>)
# Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

@@ -1,12 +0,1 @@

export class UnexpectedPeerError extends Error {
public code: string
constructor (message = 'Unexpected Peer') {
super(message)
this.code = UnexpectedPeerError.code
}
static readonly code = 'ERR_UNEXPECTED_PEER'
}
export class InvalidCryptoExchangeError extends Error {

@@ -13,0 +2,0 @@ public code: string

@@ -0,5 +1,43 @@

/**
* @packageDocumentation
*
* This repository contains TypeScript implementation of noise protocol, an encryption protocol used in libp2p.
*
* ## Usage
*
* Install with `yarn add @chainsafe/libp2p-noise` or `npm i @chainsafe/libp2p-noise`.
*
* Example of using default noise configuration and passing it to the libp2p config:
*
* ```ts
* import {createLibp2p} from "libp2p"
* import {noise} from "@chainsafe/libp2p-noise"
*
* //custom noise configuration, pass it instead of `noise()`
* //x25519 private key
* const n = noise({ staticNoiseKey });
*
* const libp2p = await createLibp2p({
* connectionEncrypters: [noise()],
* //... other options
* })
* ```
*
* See the [NoiseInit](https://github.com/ChainSafe/js-libp2p-noise/blob/master/src/noise.ts#L22-L30) interface for noise configuration options.
*
* ## API
*
* This module exposes an implementation of the [ConnectionEncrypter](https://libp2p.github.io/js-libp2p/interfaces/_libp2p_interface.ConnectionEncrypter.html) interface.
*
* ## Bring your own crypto
*
* You can provide a custom crypto implementation (instead of the default, based on [@noble](https://paulmillr.com/noble/)) by adding a `crypto` field to the init argument passed to the `Noise` factory.
*
* The implementation must conform to the `ICryptoInterface`, defined in <https://github.com/ChainSafe/js-libp2p-noise/blob/master/src/crypto.ts>
*/
import { Noise } from './noise.js'
import type { NoiseInit } from './noise.js'
import type { NoiseExtensions } from './proto/payload.js'
import type { ComponentLogger, ConnectionEncrypter, Metrics, PeerId } from '@libp2p/interface'
import type { ComponentLogger, ConnectionEncrypter, Metrics, PeerId, PrivateKey } from '@libp2p/interface'
export type { ICryptoInterface } from './crypto.js'

@@ -10,2 +48,3 @@ export { pureJsCrypto } from './crypto/js.js'

peerId: PeerId
privateKey: PrivateKey
logger: ComponentLogger

@@ -12,0 +51,0 @@ metrics?: Metrics

@@ -1,4 +0,4 @@

import { unmarshalPrivateKey } from '@libp2p/crypto/keys'
import { type MultiaddrConnection, type SecuredConnection, type PeerId, CodeError, type PrivateKey, serviceCapabilities, isPeerId, type AbortOptions } from '@libp2p/interface'
import { peerIdFromKeys } from '@libp2p/peer-id'
import { publicKeyFromProtobuf } from '@libp2p/crypto/keys'
import { serviceCapabilities } from '@libp2p/interface'
import { peerIdFromPublicKey } from '@libp2p/peer-id'
import { decode } from 'it-length-prefixed'

@@ -19,2 +19,3 @@ import { lpStream, type LengthPrefixedStream } from 'it-length-prefixed-stream'

import type { HandshakeResult, ICrypto, INoiseConnection, KeyPair } from './types.js'
import type { MultiaddrConnection, SecuredConnection, PeerId, PrivateKey, PublicKey, AbortOptions } from '@libp2p/interface'
import type { Duplex } from 'it-stream-types'

@@ -72,11 +73,8 @@ import type { Uint8ArrayList } from 'uint8arraylist'

*
* @param localPeer - PeerId of the receiving peer
* @param connection - streaming iterable duplex that will be encrypted
* @param remotePeer - PeerId of the remote peer. Used to validate the integrity of the remote peer.
* @param options
* @param options.remotePeer - PeerId of the remote peer. Used to validate the integrity of the remote peer
* @param options.signal - Used to abort the operation
*/
public async secureOutbound <Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection> (connection: Stream, options?: { remotePeer?: PeerId, signal?: AbortSignal }): Promise<SecuredConnection<Stream, NoiseExtensions>>
public async secureOutbound <Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection> (localPeer: PeerId, connection: Stream, remotePeer?: PeerId): Promise<SecuredConnection<Stream, NoiseExtensions>>
public async secureOutbound <Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection> (...args: any[]): Promise<SecuredConnection<Stream, NoiseExtensions>> {
const { localPeer, connection, remotePeer, signal } = this.parseArgs<Stream>(args)
public async secureOutbound <Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection> (connection: Stream, options?: { remotePeer?: PeerId, signal?: AbortSignal }): Promise<SecuredConnection<Stream, NoiseExtensions>> {
const wrappedConnection = lpStream(

@@ -91,15 +89,7 @@ connection,

if (!localPeer.privateKey) {
throw new CodeError('local peerId does not contain private key', 'ERR_NO_PRIVATE_KEY')
}
const privateKey = await unmarshalPrivateKey(localPeer.privateKey)
const remoteIdentityKey = remotePeer?.publicKey
const handshake = await this.performHandshakeInitiator(
wrappedConnection,
privateKey,
remoteIdentityKey, {
signal
}
this.components.privateKey,
options?.remotePeer?.publicKey,
options
)

@@ -111,6 +101,8 @@ const conn = await this.createSecureConnection(wrappedConnection, handshake)

const publicKey = publicKeyFromProtobuf(handshake.payload.identityKey)
return {
conn: connection,
remoteExtensions: handshake.payload.extensions,
remotePeer: await peerIdFromKeys(handshake.payload.identityKey)
remotePeer: peerIdFromPublicKey(publicKey)
}

@@ -122,11 +114,8 @@ }

*
* @param localPeer - PeerId of the receiving peer.
* @param connection - streaming iterable duplex that will be encrypted.
* @param remotePeer - optional PeerId of the initiating peer, if known. This may only exist during transport upgrades.
* @param connection - streaming iterable duplex that will be encrypted
* @param options
* @param options.remotePeer - PeerId of the remote peer. Used to validate the integrity of the remote peer
* @param options.signal - Used to abort the operation
*/
public async secureInbound <Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection> (connection: Stream, options?: { remotePeer?: PeerId, signal?: AbortSignal }): Promise<SecuredConnection<Stream, NoiseExtensions>>
public async secureInbound <Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection> (localPeer: PeerId, connection: Stream, remotePeer?: PeerId): Promise<SecuredConnection<Stream, NoiseExtensions>>
public async secureInbound <Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection> (...args: any[]): Promise<SecuredConnection<Stream, NoiseExtensions>> {
const { localPeer, connection, remotePeer, signal } = this.parseArgs<Stream>(args)
public async secureInbound <Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection> (connection: Stream, options?: { remotePeer?: PeerId, signal?: AbortSignal }): Promise<SecuredConnection<Stream, NoiseExtensions>> {
const wrappedConnection = lpStream(

@@ -141,15 +130,7 @@ connection,

if (!localPeer.privateKey) {
throw new CodeError('local peerId does not contain private key', 'ERR_NO_PRIVATE_KEY')
}
const privateKey = await unmarshalPrivateKey(localPeer.privateKey)
const remoteIdentityKey = remotePeer?.publicKey
const handshake = await this.performHandshakeResponder(
wrappedConnection,
privateKey,
remoteIdentityKey, {
signal
}
this.components.privateKey,
options?.remotePeer?.publicKey,
options
)

@@ -161,6 +142,8 @@ const conn = await this.createSecureConnection(wrappedConnection, handshake)

const publicKey = publicKeyFromProtobuf(handshake.payload.identityKey)
return {
conn: connection,
remoteExtensions: handshake.payload.extensions,
remotePeer: await peerIdFromKeys(handshake.payload.identityKey)
remotePeer: peerIdFromPublicKey(publicKey)
}

@@ -176,3 +159,3 @@ }

privateKey: PrivateKey,
remoteIdentityKey?: Uint8Array | Uint8ArrayList,
remoteIdentityKey?: PublicKey,
options?: AbortOptions

@@ -206,5 +189,4 @@ ): Promise<HandshakeResult> {

connection: LengthPrefixedStream,
// TODO: pass private key in noise constructor via Components
privateKey: PrivateKey,
remoteIdentityKey?: Uint8Array | Uint8ArrayList,
remoteIdentityKey?: PublicKey,
options?: AbortOptions

@@ -252,29 +234,2 @@ ): Promise<HandshakeResult> {

}
/**
* Detect call signature in `libp2p@1.x.x` or `libp2p@2.x.x` style.
*
* TODO: remove this after `libp2p@2.x.x` is released and only support the
* newer style
*/
private parseArgs <Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection> (args: any[]): { localPeer: PeerId, connection: Stream, remotePeer?: PeerId, signal?: AbortSignal } {
// if the first argument is a peer id, we're using the libp2p@1.x.x style
if (isPeerId(args[0])) {
return {
localPeer: args[0],
connection: args[1],
remotePeer: args[2]
}
} else {
// handle upcoming changes in libp2p@2.x.x where the first argument is the
// connection and the second is optionally the remote peer
// @see https://github.com/libp2p/js-libp2p/pull/2304
return {
localPeer: this.components.peerId,
connection: args[0],
remotePeer: args[1]?.remotePeer,
signal: args[1]?.signal
}
}
}
}
import type { Nonce } from './nonce'
import type { NoiseExtensions, NoiseHandshakePayload } from './proto/payload'
import type { ConnectionEncrypter, Logger, PrivateKey } from '@libp2p/interface'
import type { ConnectionEncrypter, Logger, PrivateKey, PublicKey } from '@libp2p/interface'
import type { LengthPrefixedStream } from 'it-length-prefixed-stream'

@@ -25,3 +25,3 @@ import type { Uint8ArrayList } from 'uint8arraylist'

s: KeyPair
remoteIdentityKey?: Uint8Array | Uint8ArrayList
remoteIdentityKey?: PublicKey
extensions?: NoiseExtensions

@@ -28,0 +28,0 @@ }

@@ -1,9 +0,7 @@

import { unmarshalPublicKey } from '@libp2p/crypto/keys'
import { publicKeyFromProtobuf, publicKeyToProtobuf } from '@libp2p/crypto/keys'
import { UnexpectedPeerError, type PrivateKey, type PublicKey } from '@libp2p/interface'
import { type Uint8ArrayList } from 'uint8arraylist'
import { equals, toString } from 'uint8arrays'
import { concat as uint8ArrayConcat } from 'uint8arrays/concat'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import { UnexpectedPeerError } from './errors.js'
import { type NoiseExtensions, NoiseHandshakePayload } from './proto/payload.js'
import type { PrivateKey } from '@libp2p/interface'

@@ -18,3 +16,3 @@ export async function createHandshakePayload (

return NoiseHandshakePayload.encode({
identityKey: privateKey.public.bytes,
identityKey: publicKeyToProtobuf(privateKey.publicKey),
identitySig,

@@ -28,11 +26,10 @@ extensions

remoteStaticKey?: Uint8Array | Uint8ArrayList,
remoteIdentityKey?: Uint8Array | Uint8ArrayList
remoteIdentityKey?: PublicKey
): Promise<NoiseHandshakePayload> {
try {
const payload = NoiseHandshakePayload.decode(payloadBytes)
if (remoteIdentityKey) {
const remoteIdentityKeyBytes = remoteIdentityKey.subarray()
if (!equals(remoteIdentityKeyBytes, payload.identityKey)) {
throw new Error(`Payload identity key ${toString(payload.identityKey, 'hex')} does not match expected remote identity key ${toString(remoteIdentityKeyBytes, 'hex')}`)
}
const publicKey = publicKeyFromProtobuf(payload.identityKey)
if (remoteIdentityKey?.equals(publicKey) === false) {
throw new Error(`Payload identity key ${publicKey} does not match expected remote identity key ${remoteIdentityKey}`)
}

@@ -45,3 +42,2 @@

const signaturePayload = getSignaturePayload(remoteStaticKey)
const publicKey = unmarshalPublicKey(payload.identityKey)

@@ -48,0 +44,0 @@ if (!(await publicKey.verify(signaturePayload, payload.identitySig))) {

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc