Skip to content

Commit 3732fda

Browse files
authored
fix!: update hashing libs to @noble (#323)
* fix: update hashing libs Signed-off-by: Marin Petrunic <marin.petrunic@gmail.com> * chore: remove @noble/curve package Signed-off-by: Marin Petrunic <marin.petrunic@gmail.com> * fix!: rename stablelib crypto backend into pureJsCrypto Signed-off-by: Marin Petrunic <marin.petrunic@gmail.com> * fix lint Signed-off-by: Marin Petrunic <marin.petrunic@gmail.com> --------- Signed-off-by: Marin Petrunic <marin.petrunic@gmail.com>
1 parent 8426920 commit 3732fda

File tree

8 files changed

+45
-48
lines changed

8 files changed

+45
-48
lines changed

benchmarks/benchmark.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
/* eslint-disable */
22

3-
import { Noise } from '../dist/src/index.js'
3+
import { noise } from '../dist/src/index.js'
44
import benchmark from 'benchmark'
55
import { duplexPair } from 'it-pair/duplex'
66
import { createFromJSON } from '@libp2p/peer-id-factory'
77

88
const bench = async function () {
99
console.log('Initializing handshake benchmark')
10-
const initiator = new Noise()
10+
const initiator = noise()()
1111
const initiatorPeer = await createFromJSON({
1212
id: '12D3KooWH45PiqBjfnEfDfCD6TqJrpqTBJvQDwGHvjGpaWwms46D',
1313
privKey: 'CAESYBtKXrMwawAARmLScynQUuSwi/gGSkwqDPxi15N3dqDHa4T4iWupkMe5oYGwGH3Hyfvd/QcgSTqg71oYZJadJ6prhPiJa6mQx7mhgbAYfcfJ+939ByBJOqDvWhhklp0nqg==',
1414
pubKey: 'CAESIGuE+IlrqZDHuaGBsBh9x8n73f0HIEk6oO9aGGSWnSeq'
1515
})
16-
const responder = new Noise()
16+
const responder = noise()()
1717
const responderPeer = await createFromJSON({
1818
id: '12D3KooWP63uzL78BRMpkQ7augMdNi1h3VBrVWZucKjyhzGVaSi1',
1919
privKey: 'CAESYPxO3SHyfc2578hDmfkGGBY255JjiLuVavJWy+9ivlpsxSyVKf36ipyRGL6szGzHuFs5ceEuuGVrPMg/rW2Ch1bFLJUp/fqKnJEYvqzMbMe4Wzlx4S64ZWs8yD+tbYKHVg==',

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@
7676
"@libp2p/logger": "^2.0.5",
7777
"@libp2p/peer-id": "^2.0.0",
7878
"@stablelib/chacha20poly1305": "^1.0.1",
79-
"@stablelib/hkdf": "^1.0.1",
80-
"@stablelib/sha256": "^1.0.1",
79+
"@noble/hashes": "^1.3.0",
8180
"@stablelib/x25519": "^1.0.3",
8281
"it-length-prefixed": "^9.0.1",
8382
"it-pair": "^2.0.2",

src/crypto/stablelib.ts renamed to src/crypto/js.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
1-
import { HKDF } from '@stablelib/hkdf'
21
import * as x25519 from '@stablelib/x25519'
3-
import { SHA256, hash } from '@stablelib/sha256'
2+
import { sha256 } from '@noble/hashes/sha256'
3+
import { hkdf } from '@noble/hashes/hkdf'
44
import { ChaCha20Poly1305 } from '@stablelib/chacha20poly1305'
55
import type { bytes32, bytes } from '../@types/basic.js'
66
import type { Hkdf } from '../@types/handshake.js'
77
import type { KeyPair } from '../@types/libp2p.js'
88
import type { ICryptoInterface } from '../crypto.js'
99

10-
export const stablelib: ICryptoInterface = {
10+
export const pureJsCrypto: ICryptoInterface = {
1111
hashSHA256 (data: Uint8Array): Uint8Array {
12-
return hash(data)
12+
return sha256(data)
1313
},
1414

1515
getHKDF (ck: bytes32, ikm: Uint8Array): Hkdf {
16-
const hkdf = new HKDF(SHA256, ikm, ck)
17-
const okmU8Array = hkdf.expand(96)
18-
const okm = okmU8Array
16+
const okm = hkdf(sha256, ikm, ck, undefined, 96)
1917

2018
const k1 = okm.subarray(0, 32)
2119
const k2 = okm.subarray(32, 64)

src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import type { ConnectionEncrypter } from '@libp2p/interface-connection-encrypter
22
import { Noise } from './noise.js'
33
import type { NoiseInit } from './noise.js'
44
import type { NoiseExtensions } from './proto/payload.js'
5-
export * from './crypto.js'
6-
export * from './crypto/stablelib.js'
5+
export type { ICryptoInterface } from './crypto.js'
6+
export { pureJsCrypto } from './crypto/js.js'
77

88
export function noise (init: NoiseInit = {}): () => ConnectionEncrypter<NoiseExtensions> {
99
return () => new Noise(init)

src/noise.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import type { IHandshake } from './@types/handshake-interface.js'
1010
import type { INoiseConnection, KeyPair } from './@types/libp2p.js'
1111
import { NOISE_MSG_MAX_LENGTH_BYTES } from './constants.js'
1212
import type { ICryptoInterface } from './crypto.js'
13-
import { stablelib } from './crypto/stablelib.js'
13+
import { pureJsCrypto } from './crypto/js.js'
1414
import { decryptStream, encryptStream } from './crypto/streaming.js'
1515
import { uint16BEDecode, uint16BEEncode } from './encoder.js'
1616
import { XXHandshake } from './handshake-xx.js'
@@ -49,7 +49,7 @@ export class Noise implements INoiseConnection {
4949
constructor (init: NoiseInit = {}) {
5050
const { staticNoiseKey, extensions, crypto, prologueBytes, metrics } = init
5151

52-
this.crypto = crypto ?? stablelib
52+
this.crypto = crypto ?? pureJsCrypto
5353
this.extensions = extensions
5454
this.metrics = metrics ? registerMetrics(metrics) : undefined
5555

test/handshakes/xx.spec.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
44
import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
55
import type { KeyPair } from '../../src/@types/libp2p.js'
66
import type { NoiseSession } from '../../src/@types/handshake.js'
7-
import { stablelib } from '../../src/crypto/stablelib.js'
7+
import { pureJsCrypto } from '../../src/crypto/js.js'
88
import { XX } from '../../src/handshakes/xx.js'
99
import { createHandshakePayload, getHandshakePayload } from '../../src/utils.js'
1010
import { generateEd25519Keys } from '../utils.js'
@@ -14,9 +14,9 @@ describe('XX Handshake', () => {
1414

1515
it('Test creating new XX session', async () => {
1616
try {
17-
const xx = new XX(stablelib)
17+
const xx = new XX(pureJsCrypto)
1818

19-
const kpInitiator: KeyPair = stablelib.generateX25519KeyPair()
19+
const kpInitiator: KeyPair = pureJsCrypto.generateX25519KeyPair()
2020

2121
xx.initSession(true, prologue, kpInitiator)
2222
} catch (e) {
@@ -31,15 +31,15 @@ describe('XX Handshake', () => {
3131
const ck = Buffer.alloc(32)
3232
ckBytes.copy(ck)
3333

34-
const [k1, k2, k3] = stablelib.getHKDF(ck, ikm)
34+
const [k1, k2, k3] = pureJsCrypto.getHKDF(ck, ikm)
3535
expect(uint8ArrayToString(k1, 'hex')).to.equal('cc5659adff12714982f806e2477a8d5ddd071def4c29bb38777b7e37046f6914')
3636
expect(uint8ArrayToString(k2, 'hex')).to.equal('a16ada915e551ab623f38be674bb4ef15d428ae9d80688899c9ef9b62ef208fa')
3737
expect(uint8ArrayToString(k3, 'hex')).to.equal('ff67bf9727e31b06efc203907e6786667d2c7a74ac412b4d31a80ba3fd766f68')
3838
})
3939

4040
async function doHandshake (xx: XX): Promise<{ nsInit: NoiseSession, nsResp: NoiseSession }> {
41-
const kpInit = stablelib.generateX25519KeyPair()
42-
const kpResp = stablelib.generateX25519KeyPair()
41+
const kpInit = pureJsCrypto.generateX25519KeyPair()
42+
const kpResp = pureJsCrypto.generateX25519KeyPair()
4343

4444
// initiator setup
4545
const libp2pInitKeys = await generateEd25519Keys()
@@ -107,7 +107,7 @@ describe('XX Handshake', () => {
107107

108108
it('Test handshake', async () => {
109109
try {
110-
const xx = new XX(stablelib)
110+
const xx = new XX(pureJsCrypto)
111111
await doHandshake(xx)
112112
} catch (e) {
113113
const err = e as Error
@@ -117,7 +117,7 @@ describe('XX Handshake', () => {
117117

118118
it('Test symmetric encrypt and decrypt', async () => {
119119
try {
120-
const xx = new XX(stablelib)
120+
const xx = new XX(pureJsCrypto)
121121
const { nsInit, nsResp } = await doHandshake(xx)
122122
const ad = Buffer.from('authenticated')
123123
const message = Buffer.from('HelloCrypto')
@@ -139,7 +139,7 @@ describe('XX Handshake', () => {
139139
})
140140

141141
it('Test multiple messages encryption and decryption', async () => {
142-
const xx = new XX(stablelib)
142+
const xx = new XX(pureJsCrypto)
143143
const { nsInit, nsResp } = await doHandshake(xx)
144144
const ad = Buffer.from('authenticated')
145145
const message = Buffer.from('ethereum1')

test/noise.spec.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
99
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
1010
import sinon from 'sinon'
1111
import { NOISE_MSG_MAX_LENGTH_BYTES } from '../src/constants.js'
12-
import { stablelib } from '../src/crypto/stablelib.js'
12+
import { pureJsCrypto } from '../src/crypto/js.js'
1313
import { decode0, decode2, encode1, uint16BEDecode, uint16BEEncode } from '../src/encoder.js'
1414
import { XX } from '../src/handshakes/xx.js'
1515
import { XXHandshake } from '../src/handshake-xx.js'
@@ -68,11 +68,11 @@ describe('Noise', () => {
6868
}
6969
)
7070
const prologue = Buffer.alloc(0)
71-
const staticKeys = stablelib.generateX25519KeyPair()
72-
const xx = new XX(stablelib)
71+
const staticKeys = pureJsCrypto.generateX25519KeyPair()
72+
const xx = new XX(pureJsCrypto)
7373

7474
const payload = await getPayload(remotePeer, staticKeys.publicKey)
75-
const handshake = new XXHandshake(false, payload, prologue, stablelib, staticKeys, wrapped, localPeer, xx)
75+
const handshake = new XXHandshake(false, payload, prologue, pureJsCrypto, staticKeys, wrapped, localPeer, xx)
7676

7777
let receivedMessageBuffer = decode0((await wrapped.readLP()).slice())
7878
// The first handshake message contains the initiator's ephemeral public key
@@ -132,9 +132,9 @@ describe('Noise', () => {
132132

133133
it('should working without remote peer provided in incoming connection', async () => {
134134
try {
135-
const staticKeysInitiator = stablelib.generateX25519KeyPair()
135+
const staticKeysInitiator = pureJsCrypto.generateX25519KeyPair()
136136
const noiseInit = new Noise({ staticNoiseKey: staticKeysInitiator.privateKey })
137-
const staticKeysResponder = stablelib.generateX25519KeyPair()
137+
const staticKeysResponder = pureJsCrypto.generateX25519KeyPair()
138138
const noiseResp = new Noise({ staticNoiseKey: staticKeysResponder.privateKey })
139139

140140
const [inboundConnection, outboundConnection] = duplexPair<Uint8Array>()
@@ -165,9 +165,9 @@ describe('Noise', () => {
165165
it('should accept and return Noise extension from remote peer', async () => {
166166
try {
167167
const certhashInit = Buffer.from('certhash data from init')
168-
const staticKeysInitiator = stablelib.generateX25519KeyPair()
168+
const staticKeysInitiator = pureJsCrypto.generateX25519KeyPair()
169169
const noiseInit = new Noise({ staticNoiseKey: staticKeysInitiator.privateKey, extensions: { webtransportCerthashes: [certhashInit] } })
170-
const staticKeysResponder = stablelib.generateX25519KeyPair()
170+
const staticKeysResponder = pureJsCrypto.generateX25519KeyPair()
171171
const certhashResp = Buffer.from('certhash data from respon')
172172
const noiseResp = new Noise({ staticNoiseKey: staticKeysResponder.privateKey, extensions: { webtransportCerthashes: [certhashResp] } })
173173

@@ -187,8 +187,8 @@ describe('Noise', () => {
187187

188188
it('should accept a prologue', async () => {
189189
try {
190-
const noiseInit = new Noise({ staticNoiseKey: undefined, crypto: stablelib, prologueBytes: Buffer.from('Some prologue') })
191-
const noiseResp = new Noise({ staticNoiseKey: undefined, crypto: stablelib, prologueBytes: Buffer.from('Some prologue') })
190+
const noiseInit = new Noise({ staticNoiseKey: undefined, crypto: pureJsCrypto, prologueBytes: Buffer.from('Some prologue') })
191+
const noiseResp = new Noise({ staticNoiseKey: undefined, crypto: pureJsCrypto, prologueBytes: Buffer.from('Some prologue') })
192192

193193
const [inboundConnection, outboundConnection] = duplexPair<Uint8Array>()
194194
const [outbound, inbound] = await Promise.all([

test/xx-handshake.spec.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { assert, expect } from 'aegir/chai'
44
import { duplexPair } from 'it-pair/duplex'
55
import { pbStream } from 'it-pb-stream'
66
import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
7-
import { stablelib } from '../src/crypto/stablelib.js'
7+
import { pureJsCrypto } from '../src/crypto/js.js'
88
import { XXHandshake } from '../src/handshake-xx.js'
99
import { getPayload } from '../src/utils.js'
1010
import { createPeerIdsFromFixtures } from './fixtures/peer.js'
@@ -23,14 +23,14 @@ describe('XX Handshake', () => {
2323
const connectionTo = pbStream(duplex[1])
2424

2525
const prologue = Buffer.alloc(0)
26-
const staticKeysInitiator = stablelib.generateX25519KeyPair()
27-
const staticKeysResponder = stablelib.generateX25519KeyPair()
26+
const staticKeysInitiator = pureJsCrypto.generateX25519KeyPair()
27+
const staticKeysResponder = pureJsCrypto.generateX25519KeyPair()
2828

2929
const initPayload = await getPayload(peerA, staticKeysInitiator.publicKey)
30-
const handshakeInitator = new XXHandshake(true, initPayload, prologue, stablelib, staticKeysInitiator, connectionFrom, peerB)
30+
const handshakeInitator = new XXHandshake(true, initPayload, prologue, pureJsCrypto, staticKeysInitiator, connectionFrom, peerB)
3131

3232
const respPayload = await getPayload(peerB, staticKeysResponder.publicKey)
33-
const handshakeResponder = new XXHandshake(false, respPayload, prologue, stablelib, staticKeysResponder, connectionTo, peerA)
33+
const handshakeResponder = new XXHandshake(false, respPayload, prologue, pureJsCrypto, staticKeysResponder, connectionTo, peerA)
3434

3535
await handshakeInitator.propose()
3636
await handshakeResponder.propose()
@@ -70,14 +70,14 @@ describe('XX Handshake', () => {
7070
const connectionTo = pbStream(duplex[1])
7171

7272
const prologue = Buffer.alloc(0)
73-
const staticKeysInitiator = stablelib.generateX25519KeyPair()
74-
const staticKeysResponder = stablelib.generateX25519KeyPair()
73+
const staticKeysInitiator = pureJsCrypto.generateX25519KeyPair()
74+
const staticKeysResponder = pureJsCrypto.generateX25519KeyPair()
7575

7676
const initPayload = await getPayload(peerA, staticKeysInitiator.publicKey)
77-
const handshakeInitator = new XXHandshake(true, initPayload, prologue, stablelib, staticKeysInitiator, connectionFrom, fakePeer)
77+
const handshakeInitator = new XXHandshake(true, initPayload, prologue, pureJsCrypto, staticKeysInitiator, connectionFrom, fakePeer)
7878

7979
const respPayload = await getPayload(peerB, staticKeysResponder.publicKey)
80-
const handshakeResponder = new XXHandshake(false, respPayload, prologue, stablelib, staticKeysResponder, connectionTo, peerA)
80+
const handshakeResponder = new XXHandshake(false, respPayload, prologue, pureJsCrypto, staticKeysResponder, connectionTo, peerA)
8181

8282
await handshakeInitator.propose()
8383
await handshakeResponder.propose()
@@ -99,14 +99,14 @@ describe('XX Handshake', () => {
9999
const connectionTo = pbStream(duplex[1])
100100

101101
const prologue = Buffer.alloc(0)
102-
const staticKeysInitiator = stablelib.generateX25519KeyPair()
103-
const staticKeysResponder = stablelib.generateX25519KeyPair()
102+
const staticKeysInitiator = pureJsCrypto.generateX25519KeyPair()
103+
const staticKeysResponder = pureJsCrypto.generateX25519KeyPair()
104104

105105
const initPayload = await getPayload(peerA, staticKeysInitiator.publicKey)
106-
const handshakeInitator = new XXHandshake(true, initPayload, prologue, stablelib, staticKeysInitiator, connectionFrom, peerB)
106+
const handshakeInitator = new XXHandshake(true, initPayload, prologue, pureJsCrypto, staticKeysInitiator, connectionFrom, peerB)
107107

108108
const respPayload = await getPayload(peerB, staticKeysResponder.publicKey)
109-
const handshakeResponder = new XXHandshake(false, respPayload, prologue, stablelib, staticKeysResponder, connectionTo, fakePeer)
109+
const handshakeResponder = new XXHandshake(false, respPayload, prologue, pureJsCrypto, staticKeysResponder, connectionTo, fakePeer)
110110

111111
await handshakeInitator.propose()
112112
await handshakeResponder.propose()

0 commit comments

Comments
 (0)