@libp2p/noise 12.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/index.min.js +27 -0
  2. package/dist/src/@types/basic.d.ts +5 -0
  3. package/dist/src/@types/basic.d.ts.map +1 -0
  4. package/dist/src/@types/basic.js +2 -0
  5. package/dist/src/@types/basic.js.map +1 -0
  6. package/dist/src/@types/handshake-interface.d.ts +15 -0
  7. package/dist/src/@types/handshake-interface.d.ts.map +1 -0
  8. package/dist/src/@types/handshake-interface.js +2 -0
  9. package/dist/src/@types/handshake-interface.js.map +1 -0
  10. package/dist/src/@types/handshake.d.ts +40 -0
  11. package/dist/src/@types/handshake.d.ts.map +1 -0
  12. package/dist/src/@types/handshake.js +2 -0
  13. package/dist/src/@types/handshake.js.map +1 -0
  14. package/dist/src/@types/libp2p.d.ts +10 -0
  15. package/dist/src/@types/libp2p.d.ts.map +1 -0
  16. package/dist/src/@types/libp2p.js +2 -0
  17. package/dist/src/@types/libp2p.js.map +1 -0
  18. package/dist/src/constants.d.ts +4 -0
  19. package/dist/src/constants.d.ts.map +1 -0
  20. package/dist/src/constants.js +4 -0
  21. package/dist/src/constants.js.map +1 -0
  22. package/dist/src/crypto/js.d.ts +3 -0
  23. package/dist/src/crypto/js.d.ts.map +1 -0
  24. package/dist/src/crypto/js.js +42 -0
  25. package/dist/src/crypto/js.js.map +1 -0
  26. package/dist/src/crypto/streaming.d.ts +7 -0
  27. package/dist/src/crypto/streaming.d.ts.map +1 -0
  28. package/dist/src/crypto/streaming.js +50 -0
  29. package/dist/src/crypto/streaming.js.map +1 -0
  30. package/dist/src/crypto.d.ts +13 -0
  31. package/dist/src/crypto.d.ts.map +1 -0
  32. package/dist/src/crypto.js +2 -0
  33. package/dist/src/crypto.js.map +1 -0
  34. package/dist/src/encoder.d.ts +15 -0
  35. package/dist/src/encoder.d.ts.map +1 -0
  36. package/dist/src/encoder.js +63 -0
  37. package/dist/src/encoder.js.map +1 -0
  38. package/dist/src/handshake-xx.d.ts +33 -0
  39. package/dist/src/handshake-xx.d.ts.map +1 -0
  40. package/dist/src/handshake-xx.js +139 -0
  41. package/dist/src/handshake-xx.js.map +1 -0
  42. package/dist/src/handshakes/abstract-handshake.d.ts +36 -0
  43. package/dist/src/handshakes/abstract-handshake.d.ts.map +1 -0
  44. package/dist/src/handshakes/abstract-handshake.js +140 -0
  45. package/dist/src/handshakes/abstract-handshake.js.map +1 -0
  46. package/dist/src/handshakes/xx.d.ts +18 -0
  47. package/dist/src/handshakes/xx.d.ts.map +1 -0
  48. package/dist/src/handshakes/xx.js +161 -0
  49. package/dist/src/handshakes/xx.js.map +1 -0
  50. package/dist/src/index.d.ts +7 -0
  51. package/dist/src/index.d.ts.map +1 -0
  52. package/dist/src/index.js +6 -0
  53. package/dist/src/index.js.map +1 -0
  54. package/dist/src/logger.d.ts +11 -0
  55. package/dist/src/logger.d.ts.map +1 -0
  56. package/dist/src/logger.js +45 -0
  57. package/dist/src/logger.js.map +1 -0
  58. package/dist/src/metrics.d.ts +4 -0
  59. package/dist/src/metrics.d.ts.map +1 -0
  60. package/dist/src/metrics.js +20 -0
  61. package/dist/src/metrics.js.map +1 -0
  62. package/dist/src/noise.d.ts +55 -0
  63. package/dist/src/noise.d.ts.map +1 -0
  64. package/dist/src/noise.js +130 -0
  65. package/dist/src/noise.js.map +1 -0
  66. package/dist/src/nonce.d.ts +18 -0
  67. package/dist/src/nonce.d.ts.map +1 -0
  68. package/dist/src/nonce.js +41 -0
  69. package/dist/src/nonce.js.map +1 -0
  70. package/dist/src/proto/payload.d.ts +21 -0
  71. package/dist/src/proto/payload.d.ts.map +1 -0
  72. package/dist/src/proto/payload.js +114 -0
  73. package/dist/src/proto/payload.js.map +1 -0
  74. package/dist/src/utils.d.ts +20 -0
  75. package/dist/src/utils.d.ts.map +1 -0
  76. package/dist/src/utils.js +74 -0
  77. package/dist/src/utils.js.map +1 -0
  78. package/package.json +99 -0
  79. package/src/@types/basic.ts +5 -0
  80. package/src/@types/handshake-interface.ts +12 -0
  81. package/src/@types/handshake.ts +48 -0
  82. package/src/@types/libp2p.ts +10 -0
  83. package/src/constants.ts +4 -0
  84. package/src/crypto/js.ts +58 -0
  85. package/src/crypto/streaming.ts +58 -0
  86. package/src/crypto.ts +16 -0
  87. package/src/encoder.ts +81 -0
  88. package/src/handshake-xx.ts +177 -0
  89. package/src/handshakes/abstract-handshake.ts +180 -0
  90. package/src/handshakes/xx.ts +184 -0
  91. package/src/index.ts +10 -0
  92. package/src/logger.ts +51 -0
  93. package/src/metrics.ts +32 -0
  94. package/src/noise.ts +192 -0
  95. package/src/nonce.ts +49 -0
  96. package/src/proto/payload.proto +11 -0
  97. package/src/proto/payload.ts +148 -0
  98. package/src/utils.ts +111 -0
@@ -0,0 +1,130 @@
1
+ import { decode } from 'it-length-prefixed';
2
+ import { lpStream } from 'it-length-prefixed-stream';
3
+ import { duplexPair } from 'it-pair/duplex';
4
+ import { pipe } from 'it-pipe';
5
+ import { NOISE_MSG_MAX_LENGTH_BYTES } from './constants.js';
6
+ import { pureJsCrypto } from './crypto/js.js';
7
+ import { decryptStream, encryptStream } from './crypto/streaming.js';
8
+ import { uint16BEDecode, uint16BEEncode } from './encoder.js';
9
+ import { XXHandshake } from './handshake-xx.js';
10
+ import { registerMetrics } from './metrics.js';
11
+ import { getPayload } from './utils.js';
12
+ export class Noise {
13
+ protocol = '/noise';
14
+ crypto;
15
+ prologue;
16
+ staticKeys;
17
+ extensions;
18
+ metrics;
19
+ constructor(init = {}) {
20
+ const { staticNoiseKey, extensions, crypto, prologueBytes, metrics } = init;
21
+ this.crypto = crypto ?? pureJsCrypto;
22
+ this.extensions = extensions;
23
+ this.metrics = metrics ? registerMetrics(metrics) : undefined;
24
+ if (staticNoiseKey) {
25
+ // accepts x25519 private key of length 32
26
+ this.staticKeys = this.crypto.generateX25519KeyPairFromSeed(staticNoiseKey);
27
+ }
28
+ else {
29
+ this.staticKeys = this.crypto.generateX25519KeyPair();
30
+ }
31
+ this.prologue = prologueBytes ?? new Uint8Array(0);
32
+ }
33
+ /**
34
+ * Encrypt outgoing data to the remote party (handshake as initiator)
35
+ *
36
+ * @param {PeerId} localPeer - PeerId of the receiving peer
37
+ * @param {Duplex<AsyncGenerator<Uint8Array>, AsyncIterable<Uint8Array>, Promise<void>>} connection - streaming iterable duplex that will be encrypted
38
+ * @param {PeerId} remotePeer - PeerId of the remote peer. Used to validate the integrity of the remote peer.
39
+ * @returns {Promise<SecuredConnection>}
40
+ */
41
+ async secureOutbound(localPeer, connection, remotePeer) {
42
+ const wrappedConnection = lpStream(connection, {
43
+ lengthEncoder: uint16BEEncode,
44
+ lengthDecoder: uint16BEDecode,
45
+ maxDataLength: NOISE_MSG_MAX_LENGTH_BYTES
46
+ });
47
+ const handshake = await this.performHandshake({
48
+ connection: wrappedConnection,
49
+ isInitiator: true,
50
+ localPeer,
51
+ remotePeer
52
+ });
53
+ const conn = await this.createSecureConnection(wrappedConnection, handshake);
54
+ return {
55
+ conn,
56
+ remoteExtensions: handshake.remoteExtensions,
57
+ remotePeer: handshake.remotePeer
58
+ };
59
+ }
60
+ /**
61
+ * Decrypt incoming data (handshake as responder).
62
+ *
63
+ * @param {PeerId} localPeer - PeerId of the receiving peer.
64
+ * @param {Duplex<AsyncGenerator<Uint8Array>, AsyncIterable<Uint8Array>, Promise<void>>} connection - streaming iterable duplex that will be encryption.
65
+ * @param {PeerId} remotePeer - optional PeerId of the initiating peer, if known. This may only exist during transport upgrades.
66
+ * @returns {Promise<SecuredConnection>}
67
+ */
68
+ async secureInbound(localPeer, connection, remotePeer) {
69
+ const wrappedConnection = lpStream(connection, {
70
+ lengthEncoder: uint16BEEncode,
71
+ lengthDecoder: uint16BEDecode,
72
+ maxDataLength: NOISE_MSG_MAX_LENGTH_BYTES
73
+ });
74
+ const handshake = await this.performHandshake({
75
+ connection: wrappedConnection,
76
+ isInitiator: false,
77
+ localPeer,
78
+ remotePeer
79
+ });
80
+ const conn = await this.createSecureConnection(wrappedConnection, handshake);
81
+ return {
82
+ conn,
83
+ remotePeer: handshake.remotePeer,
84
+ remoteExtensions: handshake.remoteExtensions
85
+ };
86
+ }
87
+ /**
88
+ * If Noise pipes supported, tries IK handshake first with XX as fallback if it fails.
89
+ * If noise pipes disabled or remote peer static key is unknown, use XX.
90
+ *
91
+ * @param {HandshakeParams} params
92
+ */
93
+ async performHandshake(params) {
94
+ const payload = await getPayload(params.localPeer, this.staticKeys.publicKey, this.extensions);
95
+ // run XX handshake
96
+ return this.performXXHandshake(params, payload);
97
+ }
98
+ async performXXHandshake(params, payload) {
99
+ const { isInitiator, remotePeer, connection } = params;
100
+ const handshake = new XXHandshake(isInitiator, payload, this.prologue, this.crypto, this.staticKeys, connection, remotePeer);
101
+ try {
102
+ await handshake.propose();
103
+ await handshake.exchange();
104
+ await handshake.finish();
105
+ this.metrics?.xxHandshakeSuccesses.increment();
106
+ }
107
+ catch (e) {
108
+ this.metrics?.xxHandshakeErrors.increment();
109
+ if (e instanceof Error) {
110
+ e.message = `Error occurred during XX handshake: ${e.message}`;
111
+ throw e;
112
+ }
113
+ }
114
+ return handshake;
115
+ }
116
+ async createSecureConnection(connection, handshake) {
117
+ // Create encryption box/unbox wrapper
118
+ const [secure, user] = duplexPair();
119
+ const network = connection.unwrap();
120
+ await pipe(secure, // write to wrapper
121
+ encryptStream(handshake, this.metrics), // encrypt data + prefix with message length
122
+ network, // send to the remote peer
123
+ (source) => decode(source, { lengthDecoder: uint16BEDecode }), // read message length prefix
124
+ decryptStream(handshake, this.metrics), // decrypt the incoming data
125
+ secure // pipe to the wrapper
126
+ );
127
+ return user;
128
+ }
129
+ }
130
+ //# sourceMappingURL=noise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noise.js","sourceRoot":"","sources":["../../src/noise.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { bytes, uint64 } from './@types/basic.js';
2
+ export declare const MIN_NONCE = 0;
3
+ export declare const MAX_NONCE = 4294967295;
4
+ /**
5
+ * The nonce is an uint that's increased over time.
6
+ * Maintaining different representations help improve performance.
7
+ */
8
+ export declare class Nonce {
9
+ private n;
10
+ private readonly bytes;
11
+ private readonly view;
12
+ constructor(n?: number);
13
+ increment(): void;
14
+ getBytes(): bytes;
15
+ getUint64(): uint64;
16
+ assertValue(): void;
17
+ }
18
+ //# sourceMappingURL=nonce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nonce.d.ts","sourceRoot":"","sources":["../../src/nonce.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAEtD,eAAO,MAAM,SAAS,IAAI,CAAA;AAO1B,eAAO,MAAM,SAAS,aAAa,CAAA;AAInC;;;GAGG;AACH,qBAAa,KAAK;IAChB,OAAO,CAAC,CAAC,CAAQ;IACjB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAO;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAU;gBAElB,CAAC,SAAY;IAO1B,SAAS,IAAK,IAAI;IAMlB,QAAQ,IAAK,KAAK;IAIlB,SAAS,IAAK,MAAM;IAIpB,WAAW,IAAK,IAAI;CAKrB"}
@@ -0,0 +1,41 @@
1
+ export const MIN_NONCE = 0;
2
+ // For performance reasons, the nonce is represented as a JS `number`
3
+ // Although JS `number` can safely represent integers up to 2 ** 53 - 1, we choose to only use
4
+ // 4 bytes to store the data for performance reason.
5
+ // This is a slight deviation from the noise spec, which describes the max nonce as 2 ** 64 - 2
6
+ // The effect is that this implementation will need a new handshake to be performed after fewer messages are exchanged than other implementations with full uint64 nonces.
7
+ // this MAX_NONCE is still a large number of messages, so the practical effect of this is negligible.
8
+ export const MAX_NONCE = 0xffffffff;
9
+ const ERR_MAX_NONCE = 'Cipherstate has reached maximum n, a new handshake must be performed';
10
+ /**
11
+ * The nonce is an uint that's increased over time.
12
+ * Maintaining different representations help improve performance.
13
+ */
14
+ export class Nonce {
15
+ n;
16
+ bytes;
17
+ view;
18
+ constructor(n = MIN_NONCE) {
19
+ this.n = n;
20
+ this.bytes = new Uint8Array(12);
21
+ this.view = new DataView(this.bytes.buffer, this.bytes.byteOffset, this.bytes.byteLength);
22
+ this.view.setUint32(4, n, true);
23
+ }
24
+ increment() {
25
+ this.n++;
26
+ // Even though we're treating the nonce as 8 bytes, RFC7539 specifies 12 bytes for a nonce.
27
+ this.view.setUint32(4, this.n, true);
28
+ }
29
+ getBytes() {
30
+ return this.bytes;
31
+ }
32
+ getUint64() {
33
+ return this.n;
34
+ }
35
+ assertValue() {
36
+ if (this.n > MAX_NONCE) {
37
+ throw new Error(ERR_MAX_NONCE);
38
+ }
39
+ }
40
+ }
41
+ //# sourceMappingURL=nonce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nonce.js","sourceRoot":"","sources":["../../src/nonce.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAA;AAC1B,qEAAqE;AACrE,8FAA8F;AAC9F,oDAAoD;AACpD,+FAA+F;AAC/F,0KAA0K;AAC1K,qGAAqG;AACrG,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CAAA;AAEnC,MAAM,aAAa,GAAG,sEAAsE,CAAA;AAE5F;;;GAGG;AACH,MAAM,OAAO,KAAK;IACR,CAAC,CAAQ;IACA,KAAK,CAAO;IACZ,IAAI,CAAU;IAE/B,YAAa,CAAC,GAAG,SAAS;QACxB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QACV,IAAI,CAAC,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAA;QAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;QACzF,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAA;IACjC,CAAC;IAED,SAAS;QACP,IAAI,CAAC,CAAC,EAAE,CAAA;QACR,2FAA2F;QAC3F,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;IACtC,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,CAAC,CAAA;IACf,CAAC;IAED,WAAW;QACT,IAAI,IAAI,CAAC,CAAC,GAAG,SAAS,EAAE;YACtB,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAA;SAC/B;IACH,CAAC;CACF"}
@@ -0,0 +1,21 @@
1
+ import type { Codec } from 'protons-runtime';
2
+ import type { Uint8ArrayList } from 'uint8arraylist';
3
+ export interface NoiseExtensions {
4
+ webtransportCerthashes: Uint8Array[];
5
+ }
6
+ export declare namespace NoiseExtensions {
7
+ const codec: () => Codec<NoiseExtensions>;
8
+ const encode: (obj: Partial<NoiseExtensions>) => Uint8Array;
9
+ const decode: (buf: Uint8Array | Uint8ArrayList) => NoiseExtensions;
10
+ }
11
+ export interface NoiseHandshakePayload {
12
+ identityKey: Uint8Array;
13
+ identitySig: Uint8Array;
14
+ extensions?: NoiseExtensions;
15
+ }
16
+ export declare namespace NoiseHandshakePayload {
17
+ const codec: () => Codec<NoiseHandshakePayload>;
18
+ const encode: (obj: Partial<NoiseHandshakePayload>) => Uint8Array;
19
+ const decode: (buf: Uint8Array | Uint8ArrayList) => NoiseHandshakePayload;
20
+ }
21
+ //# sourceMappingURL=payload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../../../src/proto/payload.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD,MAAM,WAAW,eAAe;IAC9B,sBAAsB,EAAE,UAAU,EAAE,CAAA;CACrC;AAED,yBAAiB,eAAe,CAAC;IAGxB,MAAM,KAAK,QAAO,MAAM,eAAe,CA0C7C,CAAA;IAEM,MAAM,MAAM,QAAS,QAAQ,eAAe,CAAC,KAAG,UAEtD,CAAA;IAEM,MAAM,MAAM,QAAS,UAAU,GAAG,cAAc,KAAG,eAEzD,CAAA;CACF;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,UAAU,CAAA;IACvB,WAAW,EAAE,UAAU,CAAA;IACvB,UAAU,CAAC,EAAE,eAAe,CAAA;CAC7B;AAED,yBAAiB,qBAAqB,CAAC;IAG9B,MAAM,KAAK,QAAO,MAAM,qBAAqB,CA2DnD,CAAA;IAEM,MAAM,MAAM,QAAS,QAAQ,qBAAqB,CAAC,KAAG,UAE5D,CAAA;IAEM,MAAM,MAAM,QAAS,UAAU,GAAG,cAAc,KAAG,qBAEzD,CAAA;CACF"}
@@ -0,0 +1,114 @@
1
+ /* eslint-disable import/export */
2
+ /* eslint-disable complexity */
3
+ /* eslint-disable @typescript-eslint/no-namespace */
4
+ /* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
5
+ /* eslint-disable @typescript-eslint/no-empty-interface */
6
+ import { encodeMessage, decodeMessage, message } from 'protons-runtime';
7
+ export var NoiseExtensions;
8
+ (function (NoiseExtensions) {
9
+ let _codec;
10
+ NoiseExtensions.codec = () => {
11
+ if (_codec == null) {
12
+ _codec = message((obj, w, opts = {}) => {
13
+ if (opts.lengthDelimited !== false) {
14
+ w.fork();
15
+ }
16
+ if (obj.webtransportCerthashes != null) {
17
+ for (const value of obj.webtransportCerthashes) {
18
+ w.uint32(10);
19
+ w.bytes(value);
20
+ }
21
+ }
22
+ if (opts.lengthDelimited !== false) {
23
+ w.ldelim();
24
+ }
25
+ }, (reader, length) => {
26
+ const obj = {
27
+ webtransportCerthashes: []
28
+ };
29
+ const end = length == null ? reader.len : reader.pos + length;
30
+ while (reader.pos < end) {
31
+ const tag = reader.uint32();
32
+ switch (tag >>> 3) {
33
+ case 1:
34
+ obj.webtransportCerthashes.push(reader.bytes());
35
+ break;
36
+ default:
37
+ reader.skipType(tag & 7);
38
+ break;
39
+ }
40
+ }
41
+ return obj;
42
+ });
43
+ }
44
+ return _codec;
45
+ };
46
+ NoiseExtensions.encode = (obj) => {
47
+ return encodeMessage(obj, NoiseExtensions.codec());
48
+ };
49
+ NoiseExtensions.decode = (buf) => {
50
+ return decodeMessage(buf, NoiseExtensions.codec());
51
+ };
52
+ })(NoiseExtensions || (NoiseExtensions = {}));
53
+ export var NoiseHandshakePayload;
54
+ (function (NoiseHandshakePayload) {
55
+ let _codec;
56
+ NoiseHandshakePayload.codec = () => {
57
+ if (_codec == null) {
58
+ _codec = message((obj, w, opts = {}) => {
59
+ if (opts.lengthDelimited !== false) {
60
+ w.fork();
61
+ }
62
+ if (opts.writeDefaults === true || (obj.identityKey != null && obj.identityKey.byteLength > 0)) {
63
+ w.uint32(10);
64
+ w.bytes(obj.identityKey ?? new Uint8Array(0));
65
+ }
66
+ if (opts.writeDefaults === true || (obj.identitySig != null && obj.identitySig.byteLength > 0)) {
67
+ w.uint32(18);
68
+ w.bytes(obj.identitySig ?? new Uint8Array(0));
69
+ }
70
+ if (obj.extensions != null) {
71
+ w.uint32(34);
72
+ NoiseExtensions.codec().encode(obj.extensions, w, {
73
+ writeDefaults: false
74
+ });
75
+ }
76
+ if (opts.lengthDelimited !== false) {
77
+ w.ldelim();
78
+ }
79
+ }, (reader, length) => {
80
+ const obj = {
81
+ identityKey: new Uint8Array(0),
82
+ identitySig: new Uint8Array(0)
83
+ };
84
+ const end = length == null ? reader.len : reader.pos + length;
85
+ while (reader.pos < end) {
86
+ const tag = reader.uint32();
87
+ switch (tag >>> 3) {
88
+ case 1:
89
+ obj.identityKey = reader.bytes();
90
+ break;
91
+ case 2:
92
+ obj.identitySig = reader.bytes();
93
+ break;
94
+ case 4:
95
+ obj.extensions = NoiseExtensions.codec().decode(reader, reader.uint32());
96
+ break;
97
+ default:
98
+ reader.skipType(tag & 7);
99
+ break;
100
+ }
101
+ }
102
+ return obj;
103
+ });
104
+ }
105
+ return _codec;
106
+ };
107
+ NoiseHandshakePayload.encode = (obj) => {
108
+ return encodeMessage(obj, NoiseHandshakePayload.codec());
109
+ };
110
+ NoiseHandshakePayload.decode = (buf) => {
111
+ return decodeMessage(buf, NoiseHandshakePayload.codec());
112
+ };
113
+ })(NoiseHandshakePayload || (NoiseHandshakePayload = {}));
114
+ //# sourceMappingURL=payload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload.js","sourceRoot":"","sources":["../../../src/proto/payload.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { type NoiseExtensions, NoiseHandshakePayload } from './proto/payload.js';
2
+ import type { bytes } from './@types/basic.js';
3
+ import type { PeerId } from '@libp2p/interface/peer-id';
4
+ export declare function getPayload(localPeer: PeerId, staticPublicKey: bytes, extensions?: NoiseExtensions): Promise<bytes>;
5
+ export declare function createHandshakePayload(libp2pPublicKey: Uint8Array, signedPayload: Uint8Array, extensions?: NoiseExtensions): bytes;
6
+ export declare function signPayload(peerId: PeerId, payload: bytes): Promise<bytes>;
7
+ export declare function getPeerIdFromPayload(payload: NoiseHandshakePayload): Promise<PeerId>;
8
+ export declare function decodePayload(payload: bytes | Uint8Array): NoiseHandshakePayload;
9
+ export declare function getHandshakePayload(publicKey: bytes): bytes;
10
+ /**
11
+ * Verifies signed payload, throws on any irregularities.
12
+ *
13
+ * @param {bytes} noiseStaticKey - owner's noise static key
14
+ * @param {bytes} payload - decoded payload
15
+ * @param {PeerId} remotePeer - owner's libp2p peer ID
16
+ * @returns {Promise<PeerId>} - peer ID of payload owner
17
+ */
18
+ export declare function verifySignedPayload(noiseStaticKey: bytes, payload: NoiseHandshakePayload, remotePeer: PeerId): Promise<PeerId>;
19
+ export declare function isValidPublicKey(pk: bytes): boolean;
20
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,eAAe,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAChF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAEvD,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,KAAK,EACtB,UAAU,CAAC,EAAE,eAAe,GAC3B,OAAO,CAAC,KAAK,CAAC,CAYhB;AAED,wBAAgB,sBAAsB,CACpC,eAAe,EAAE,UAAU,EAC3B,aAAa,EAAE,UAAU,EACzB,UAAU,CAAC,EAAE,eAAe,GAC3B,KAAK,CAMP;AAED,wBAAsB,WAAW,CAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAQjF;AAED,wBAAsB,oBAAoB,CAAE,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,CAE3F;AAED,wBAAgB,aAAa,CAAE,OAAO,EAAE,KAAK,GAAG,UAAU,GAAG,qBAAqB,CAEjF;AAED,wBAAgB,mBAAmB,CAAE,SAAS,EAAE,KAAK,GAAG,KAAK,CAG5D;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,cAAc,EAAE,KAAK,EACrB,OAAO,EAAE,qBAAqB,EAC9B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAyBjB;AAED,wBAAgB,gBAAgB,CAAE,EAAE,EAAE,KAAK,GAAG,OAAO,CAUpD"}
@@ -0,0 +1,74 @@
1
+ import { unmarshalPublicKey, unmarshalPrivateKey } from '@libp2p/crypto/keys';
2
+ import { peerIdFromKeys } from '@libp2p/peer-id';
3
+ import { concat as uint8ArrayConcat } from 'uint8arrays/concat';
4
+ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
5
+ import { NoiseHandshakePayload } from './proto/payload.js';
6
+ export async function getPayload(localPeer, staticPublicKey, extensions) {
7
+ const signedPayload = await signPayload(localPeer, getHandshakePayload(staticPublicKey));
8
+ if (localPeer.publicKey == null) {
9
+ throw new Error('PublicKey was missing from local PeerId');
10
+ }
11
+ return createHandshakePayload(localPeer.publicKey, signedPayload, extensions);
12
+ }
13
+ export function createHandshakePayload(libp2pPublicKey, signedPayload, extensions) {
14
+ return NoiseHandshakePayload.encode({
15
+ identityKey: libp2pPublicKey,
16
+ identitySig: signedPayload,
17
+ extensions: extensions ?? { webtransportCerthashes: [] }
18
+ }).subarray();
19
+ }
20
+ export async function signPayload(peerId, payload) {
21
+ if (peerId.privateKey == null) {
22
+ throw new Error('PrivateKey was missing from PeerId');
23
+ }
24
+ const privateKey = await unmarshalPrivateKey(peerId.privateKey);
25
+ return privateKey.sign(payload);
26
+ }
27
+ export async function getPeerIdFromPayload(payload) {
28
+ return peerIdFromKeys(payload.identityKey);
29
+ }
30
+ export function decodePayload(payload) {
31
+ return NoiseHandshakePayload.decode(payload);
32
+ }
33
+ export function getHandshakePayload(publicKey) {
34
+ const prefix = uint8ArrayFromString('noise-libp2p-static-key:');
35
+ return uint8ArrayConcat([prefix, publicKey], prefix.length + publicKey.length);
36
+ }
37
+ /**
38
+ * Verifies signed payload, throws on any irregularities.
39
+ *
40
+ * @param {bytes} noiseStaticKey - owner's noise static key
41
+ * @param {bytes} payload - decoded payload
42
+ * @param {PeerId} remotePeer - owner's libp2p peer ID
43
+ * @returns {Promise<PeerId>} - peer ID of payload owner
44
+ */
45
+ export async function verifySignedPayload(noiseStaticKey, payload, remotePeer) {
46
+ // Unmarshaling from PublicKey protobuf
47
+ const payloadPeerId = await peerIdFromKeys(payload.identityKey);
48
+ if (!payloadPeerId.equals(remotePeer)) {
49
+ throw new Error(`Payload identity key ${payloadPeerId.toString()} does not match expected remote peer ${remotePeer.toString()}`);
50
+ }
51
+ const generatedPayload = getHandshakePayload(noiseStaticKey);
52
+ if (payloadPeerId.publicKey == null) {
53
+ throw new Error('PublicKey was missing from PeerId');
54
+ }
55
+ if (payload.identitySig == null) {
56
+ throw new Error('Signature was missing from message');
57
+ }
58
+ const publicKey = unmarshalPublicKey(payloadPeerId.publicKey);
59
+ const valid = await publicKey.verify(generatedPayload, payload.identitySig);
60
+ if (!valid) {
61
+ throw new Error("Static key doesn't match to peer that signed payload!");
62
+ }
63
+ return payloadPeerId;
64
+ }
65
+ export function isValidPublicKey(pk) {
66
+ if (!(pk instanceof Uint8Array)) {
67
+ return false;
68
+ }
69
+ if (pk.length !== 32) {
70
+ return false;
71
+ }
72
+ return true;
73
+ }
74
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,99 @@
1
+ {
2
+ "name": "@libp2p/noise",
3
+ "version": "12.0.1",
4
+ "author": "ChainSafe <info@chainsafe.io>",
5
+ "license": "Apache-2.0 OR MIT",
6
+ "homepage": "https://github.com/ChainSafe/js-libp2p-noise#readme",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/ChainSafe/js-libp2p-noise.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/ChainSafe/js-libp2p-noise/issues"
13
+ },
14
+ "keywords": [
15
+ "crypto",
16
+ "libp2p",
17
+ "noise"
18
+ ],
19
+ "engines": {
20
+ "node": ">=16.0.0",
21
+ "npm": ">=7.0.0"
22
+ },
23
+ "type": "module",
24
+ "types": "./dist/src/index.d.ts",
25
+ "files": [
26
+ "src",
27
+ "dist",
28
+ "!dist/test",
29
+ "!**/*.tsbuildinfo"
30
+ ],
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/src/index.d.ts",
34
+ "import": "./dist/src/index.js"
35
+ }
36
+ },
37
+ "eslintConfig": {
38
+ "extends": "ipfs",
39
+ "parserOptions": {
40
+ "sourceType": "module"
41
+ },
42
+ "rules": {
43
+ "@typescript-eslint/no-unused-vars": "error",
44
+ "@typescript-eslint/explicit-function-return-type": "warn",
45
+ "@typescript-eslint/strict-boolean-expressions": "off"
46
+ },
47
+ "ignorePatterns": [
48
+ "src/proto/payload.js",
49
+ "src/proto/payload.d.ts",
50
+ "test/fixtures/node-globals.js"
51
+ ]
52
+ },
53
+ "scripts": {
54
+ "bench": "node benchmarks/benchmark.js",
55
+ "clean": "aegir clean",
56
+ "dep-check": "aegir dep-check",
57
+ "build": "aegir build",
58
+ "lint": "aegir lint",
59
+ "lint:fix": "aegir lint --fix",
60
+ "test": "aegir test",
61
+ "test:node": "aegir test -t node",
62
+ "test:browser": "aegir test -t browser -t webworker",
63
+ "test:electron-main": "aegir test -t electron-main",
64
+ "docs": "aegir docs",
65
+ "proto:gen": "protons ./src/proto/payload.proto",
66
+ "prepublish": "npm run build"
67
+ },
68
+ "dependencies": {
69
+ "@libp2p/crypto": "^1.0.11",
70
+ "@libp2p/interface": "~0.0.1",
71
+ "@libp2p/logger": "^2.1.1",
72
+ "@libp2p/peer-id": "^2.0.0",
73
+ "@stablelib/chacha20poly1305": "^1.0.1",
74
+ "@noble/hashes": "^1.3.0",
75
+ "@stablelib/x25519": "^1.0.3",
76
+ "it-length-prefixed": "^9.0.1",
77
+ "it-length-prefixed-stream": "^1.0.0",
78
+ "it-byte-stream": "^1.0.0",
79
+ "it-pair": "^2.0.2",
80
+ "it-pipe": "^3.0.1",
81
+ "it-stream-types": "^2.0.1",
82
+ "protons-runtime": "^5.0.0",
83
+ "uint8arraylist": "^2.3.2",
84
+ "uint8arrays": "^4.0.2"
85
+ },
86
+ "devDependencies": {
87
+ "@libp2p/interface-compliance-tests": "^3.0.0",
88
+ "@libp2p/peer-id-factory": "^2.0.0",
89
+ "@types/sinon": "^10.0.14",
90
+ "aegir": "^39.0.5",
91
+ "iso-random-stream": "^2.0.2",
92
+ "protons": "^7.0.0",
93
+ "sinon": "^15.0.0"
94
+ },
95
+ "browser": {
96
+ "./dist/src/alloc-unsafe.js": "./dist/src/alloc-unsafe-browser.js",
97
+ "util": false
98
+ }
99
+ }
@@ -0,0 +1,5 @@
1
+ export type bytes = Uint8Array
2
+ export type bytes32 = Uint8Array
3
+ export type bytes16 = Uint8Array
4
+
5
+ export type uint64 = number
@@ -0,0 +1,12 @@
1
+ import type { bytes } from './basic.js'
2
+ import type { NoiseSession } from './handshake.js'
3
+ import type { NoiseExtensions } from '../proto/payload.js'
4
+ import type { PeerId } from '@libp2p/interface/peer-id'
5
+
6
+ export interface IHandshake {
7
+ session: NoiseSession
8
+ remotePeer: PeerId
9
+ remoteExtensions: NoiseExtensions
10
+ encrypt: (plaintext: bytes, session: NoiseSession) => bytes
11
+ decrypt: (ciphertext: bytes, session: NoiseSession, dst?: Uint8Array) => { plaintext: bytes, valid: boolean }
12
+ }
@@ -0,0 +1,48 @@
1
+ import type { bytes, bytes32, uint64 } from './basic.js'
2
+ import type { KeyPair } from './libp2p.js'
3
+ import type { Nonce } from '../nonce.js'
4
+
5
+ export type Hkdf = [bytes, bytes, bytes]
6
+
7
+ export interface MessageBuffer {
8
+ ne: bytes32
9
+ ns: bytes
10
+ ciphertext: bytes
11
+ }
12
+
13
+ export interface CipherState {
14
+ k: bytes32
15
+ // For performance reasons, the nonce is represented as a Nonce object
16
+ // The nonce is treated as a uint64, even though the underlying `number` only has 52 safely-available bits.
17
+ n: Nonce
18
+ }
19
+
20
+ export interface SymmetricState {
21
+ cs: CipherState
22
+ ck: bytes32 // chaining key
23
+ h: bytes32 // handshake hash
24
+ }
25
+
26
+ export interface HandshakeState {
27
+ ss: SymmetricState
28
+ s: KeyPair
29
+ e?: KeyPair
30
+ rs: bytes32
31
+ re: bytes32
32
+ psk: bytes32
33
+ }
34
+
35
+ export interface NoiseSession {
36
+ hs: HandshakeState
37
+ h?: bytes32
38
+ cs1?: CipherState
39
+ cs2?: CipherState
40
+ mc: uint64
41
+ i: boolean
42
+ }
43
+
44
+ export interface INoisePayload {
45
+ identityKey: bytes
46
+ identitySig: bytes
47
+ data: bytes
48
+ }
@@ -0,0 +1,10 @@
1
+ import type { bytes32 } from './basic.js'
2
+ import type { NoiseExtensions } from '../proto/payload.js'
3
+ import type { ConnectionEncrypter } from '@libp2p/interface/connection-encrypter'
4
+
5
+ export interface KeyPair {
6
+ publicKey: bytes32
7
+ privateKey: bytes32
8
+ }
9
+
10
+ export interface INoiseConnection extends ConnectionEncrypter<NoiseExtensions> {}
@@ -0,0 +1,4 @@
1
+ export const NOISE_MSG_MAX_LENGTH_BYTES = 65535
2
+ export const NOISE_MSG_MAX_LENGTH_BYTES_WITHOUT_TAG = NOISE_MSG_MAX_LENGTH_BYTES - 16
3
+
4
+ export const DUMP_SESSION_KEYS = Boolean(globalThis.process?.env?.DUMP_SESSION_KEYS)