Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ incrby
microtask
nothrow
peerStore
prehash
reprovide
reprovided
reprovider
Expand Down
2 changes: 1 addition & 1 deletion interop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"@multiformats/multiaddr": "^13.0.1",
"aegir": "^47.0.22",
"libp2p": "^3.0.0",
"p-event": "^6.0.1",
"p-event": "^7.0.0",
"redis": "^4.7.1"
}
}
6 changes: 3 additions & 3 deletions packages/connection-encrypter-noise/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@
"@libp2p/interface": "^3.0.0",
"@libp2p/peer-id": "^6.0.0",
"@libp2p/utils": "^7.0.0",
"@noble/ciphers": "^1.3.0",
"@noble/curves": "^1.9.7",
"@noble/hashes": "^1.8.0",
"@noble/ciphers": "^2.0.1",
"@noble/curves": "^2.0.1",
"@noble/hashes": "^2.0.1",
"protons-runtime": "^5.6.0",
"uint8arraylist": "^2.4.8",
"uint8arrays": "^5.1.0",
Expand Down
8 changes: 4 additions & 4 deletions packages/connection-encrypter-noise/src/crypto/js.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { chacha20poly1305 } from '@noble/ciphers/chacha'
import { x25519 } from '@noble/curves/ed25519'
import { extract, expand } from '@noble/hashes/hkdf'
import { sha256 } from '@noble/hashes/sha2'
import { chacha20poly1305 } from '@noble/ciphers/chacha.js'
import { x25519 } from '@noble/curves/ed25519.js'
import { extract, expand } from '@noble/hashes/hkdf.js'
import { sha256 } from '@noble/hashes/sha2.js'
import type { ICryptoInterface } from '../crypto.js'
import type { KeyPair } from '../types.js'
import type { Uint8ArrayList } from 'uint8arraylist'
Expand Down
2 changes: 1 addition & 1 deletion packages/connection-encrypter-tls/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"@peculiar/webcrypto": "^1.5.0",
"@peculiar/x509": "^1.13.0",
"asn1js": "^3.0.6",
"p-event": "^6.0.1",
"p-event": "^7.0.0",
"protons-runtime": "^5.6.0",
"uint8arraylist": "^2.4.8",
"uint8arrays": "^5.1.0"
Expand Down
4 changes: 2 additions & 2 deletions packages/crypto/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@
},
"dependencies": {
"@libp2p/interface": "^3.0.0",
"@noble/curves": "^1.9.7",
"@noble/hashes": "^1.8.0",
"@noble/curves": "^2.0.1",
"@noble/hashes": "^2.0.1",
"multiformats": "^13.4.0",
"protons-runtime": "^5.6.0",
"uint8arraylist": "^2.4.8",
Expand Down
8 changes: 4 additions & 4 deletions packages/crypto/src/keys/ed25519/index.browser.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ed25519 as ed } from '@noble/curves/ed25519'
import { ed25519 as ed } from '@noble/curves/ed25519.js'
import { toString as uint8arrayToString } from 'uint8arrays/to-string'
import crypto from '../../webcrypto/index.js'
import type { Uint8ArrayKeyPair } from '../interface.js'
Expand All @@ -24,7 +24,7 @@ const webCryptoEd25519SupportedPromise = (async () => {

export function generateKey (): Uint8ArrayKeyPair {
// the actual private key (32 bytes)
const privateKeyRaw = ed.utils.randomPrivateKey()
const privateKeyRaw = ed.utils.randomSecretKey()
const publicKey = ed.getPublicKey(privateKeyRaw)

// concatenated the public key to the private key
Expand Down Expand Up @@ -78,7 +78,7 @@ async function hashAndSignWebCrypto (privateKey: Uint8Array, msg: Uint8Array | U
return new Uint8Array(sig, 0, sig.byteLength)
}

function hashAndSignNoble (privateKey: Uint8Array, msg: Uint8Array | Uint8ArrayList): Uint8Array {
export function hashAndSignNoble (privateKey: Uint8Array, msg: Uint8Array | Uint8ArrayList): Uint8Array {
const privateKeyRaw = privateKey.subarray(0, KEYS_BYTE_LENGTH)

return ed.sign(msg instanceof Uint8Array ? msg : msg.subarray(), privateKeyRaw)
Expand Down Expand Up @@ -106,7 +106,7 @@ async function hashAndVerifyWebCrypto (publicKey: Uint8Array, sig: Uint8Array, m
throw new TypeError('WebCrypto does not support SharedArrayBuffer for Ed25519 keys')
}

function hashAndVerifyNoble (publicKey: Uint8Array, sig: Uint8Array, msg: Uint8Array | Uint8ArrayList): boolean {
export function hashAndVerifyNoble (publicKey: Uint8Array, sig: Uint8Array, msg: Uint8Array | Uint8ArrayList): boolean {
return ed.verify(sig, msg instanceof Uint8Array ? msg : msg.subarray(), publicKey)
}

Expand Down
2 changes: 1 addition & 1 deletion packages/crypto/src/keys/rsa/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { InvalidParametersError, InvalidPublicKeyError } from '@libp2p/interface'
import { sha256 } from '@noble/hashes/sha256'
import { sha256 } from '@noble/hashes/sha2.js'
import { create } from 'multiformats/hashes/digest'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
Expand Down
22 changes: 17 additions & 5 deletions packages/crypto/src/keys/secp256k1/index.browser.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { secp256k1 as secp } from '@noble/curves/secp256k1'
import { secp256k1 as secp } from '@noble/curves/secp256k1.js'
import { sha256 } from 'multiformats/hashes/sha2'
import { SigningError, VerificationError } from '../../errors.js'
import { isPromise } from '../../util.js'
Expand All @@ -21,7 +21,10 @@ export function hashAndSign (key: Uint8Array, msg: Uint8Array | Uint8ArrayList,
return p
.then(({ digest }) => {
options?.signal?.throwIfAborted()
return secp.sign(digest, key).toDERRawBytes()
return secp.sign(digest, key, {
prehash: false,
format: 'der'
})
})
.catch(err => {
if (err.name === 'AbortError') {
Expand All @@ -33,7 +36,10 @@ export function hashAndSign (key: Uint8Array, msg: Uint8Array | Uint8ArrayList,
}

try {
return secp.sign(p.digest, key).toDERRawBytes()
return secp.sign(p.digest, key, {
prehash: false,
format: 'der'
})
} catch (err) {
throw new SigningError(String(err))
}
Expand All @@ -49,7 +55,10 @@ export function hashAndVerify (key: Uint8Array, sig: Uint8Array, msg: Uint8Array
return p
.then(({ digest }) => {
options?.signal?.throwIfAborted()
return secp.verify(sig, digest, key)
return secp.verify(sig, digest, key, {
prehash: false,
format: 'der'
})
})
.catch(err => {
if (err.name === 'AbortError') {
Expand All @@ -62,7 +71,10 @@ export function hashAndVerify (key: Uint8Array, sig: Uint8Array, msg: Uint8Array

try {
options?.signal?.throwIfAborted()
return secp.verify(sig, p.digest, key)
return secp.verify(sig, p.digest, key, {
prehash: false,
format: 'der'
})
} catch (err) {
throw new VerificationError(String(err))
}
Expand Down
13 changes: 9 additions & 4 deletions packages/crypto/src/keys/secp256k1/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import crypto from 'node:crypto'
import { secp256k1 as secp } from '@noble/curves/secp256k1'
import { secp256k1 as secp } from '@noble/curves/secp256k1.js'
import { SigningError, VerificationError } from '../../errors.js'
import type { AbortOptions } from '@libp2p/interface'
import type { Uint8ArrayList } from 'uint8arraylist'
Expand Down Expand Up @@ -29,8 +29,10 @@ export function hashAndSign (key: Uint8Array, msg: Uint8Array | Uint8ArrayList,
const digest = hash.digest()

try {
const signature = secp.sign(digest, key)
return signature.toDERRawBytes()
return secp.sign(digest, key, {
prehash: false,
format: 'der'
})
} catch (err) {
throw new SigningError(String(err))
}
Expand All @@ -54,7 +56,10 @@ export function hashAndVerify (key: Uint8Array, sig: Uint8Array, msg: Uint8Array
const digest = hash.digest()

try {
return secp.verify(sig, digest, key)
return secp.verify(sig, digest, key, {
prehash: false,
format: 'der'
})
} catch (err) {
throw new VerificationError(String(err))
}
Expand Down
12 changes: 5 additions & 7 deletions packages/crypto/src/keys/secp256k1/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { InvalidPrivateKeyError, InvalidPublicKeyError } from '@libp2p/interface'
import { secp256k1 as secp } from '@noble/curves/secp256k1'
import { secp256k1 as secp } from '@noble/curves/secp256k1.js'
import { Secp256k1PublicKey as Secp256k1PublicKeyClass, Secp256k1PrivateKey as Secp256k1PrivateKeyClass } from './secp256k1.js'
import type { Secp256k1PublicKey, Secp256k1PrivateKey } from '@libp2p/interface'

Expand All @@ -21,13 +21,11 @@ export async function generateSecp256k1KeyPair (): Promise<Secp256k1PrivateKey>
}

export function compressSecp256k1PublicKey (key: Uint8Array): Uint8Array {
const point = secp.ProjectivePoint.fromHex(key).toRawBytes(true)
return point
return secp.Point.fromBytes(key).toBytes()
}

export function decompressSecp256k1PublicKey (key: Uint8Array): Uint8Array {
const point = secp.ProjectivePoint.fromHex(key).toRawBytes(false)
return point
return secp.Point.fromBytes(key).toBytes(false)
}

export function validateSecp256k1PrivateKey (key: Uint8Array): Uint8Array {
Expand All @@ -42,7 +40,7 @@ export function validateSecp256k1PrivateKey (key: Uint8Array): Uint8Array {

export function validateSecp256k1PublicKey (key: Uint8Array): Uint8Array {
try {
secp.ProjectivePoint.fromHex(key)
secp.Point.fromBytes(key)

return key
} catch (err) {
Expand All @@ -59,5 +57,5 @@ export function computeSecp256k1PublicKey (privateKey: Uint8Array): Uint8Array {
}

export function generateSecp256k1PrivateKey (): Uint8Array {
return secp.utils.randomPrivateKey()
return secp.utils.randomSecretKey()
}
7 changes: 3 additions & 4 deletions packages/crypto/src/pbkdf2.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { InvalidParametersError } from '@libp2p/interface'
import { pbkdf2 as pbkdf2Sync } from '@noble/hashes/pbkdf2'
import { sha1 } from '@noble/hashes/sha1'
import { sha256 } from '@noble/hashes/sha256'
import { sha512 } from '@noble/hashes/sha512'
import { sha1 } from '@noble/hashes/legacy.js'
import { pbkdf2 as pbkdf2Sync } from '@noble/hashes/pbkdf2.js'
import { sha256, sha512 } from '@noble/hashes/sha2.js'
import { base64 } from 'multiformats/bases/base64'

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/crypto/src/random-bytes.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { InvalidParametersError } from '@libp2p/interface'
import { randomBytes as randB } from '@noble/hashes/utils'
import { randomBytes as randB } from '@noble/hashes/utils.js'

/**
* Generates a Uint8Array with length `number` populated by random bytes
Expand Down
28 changes: 27 additions & 1 deletion packages/crypto/test/keys/ed25519.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { expect } from 'aegir/chai'
import { Uint8ArrayList } from 'uint8arraylist'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import { randomBytes } from '../../src/index.js'
import { hashAndSignNoble, hashAndVerifyNoble } from '../../src/keys/ed25519/index.browser.ts'
import { unmarshalEd25519PrivateKey, unmarshalEd25519PublicKey } from '../../src/keys/ed25519/utils.js'
import { generateKeyPair, generateKeyPairFromSeed, privateKeyFromProtobuf, privateKeyFromRaw, publicKeyFromProtobuf, publicKeyFromRaw, privateKeyToCryptoKeyPair } from '../../src/keys/index.js'
import fixtures from '../fixtures/go-key-ed25519.js'
Expand Down Expand Up @@ -61,6 +62,20 @@ describe('ed25519', function () {
expect(res).to.be.be.true()
})

it('signs using noble', async () => {
const text = randomBytes(512)
const sig = await key.sign(text)
const res = hashAndVerifyNoble(key.publicKey.raw, sig, text)
expect(res).to.be.be.true()
})

it('verifies using noble', async () => {
const text = randomBytes(512)
const sig = hashAndSignNoble(key.raw, text)
const res = await key.publicKey.verify(text, sig)
expect(res).to.be.be.true()
})

it('signs a list', async () => {
const text = new Uint8ArrayList(
randomBytes(512),
Expand Down Expand Up @@ -205,13 +220,18 @@ describe('ed25519', function () {
})

describe('go interop', () => {
// @ts-check
it('verifies with data from go', async () => {
const key = publicKeyFromProtobuf(fixtures.verify.publicKey)
const ok = await key.verify(fixtures.verify.data, fixtures.verify.signature)
expect(ok).to.be.true()
})

it('verifies with data from go using noble', async () => {
const key = publicKeyFromProtobuf(fixtures.verify.publicKey)
const ok = hashAndVerifyNoble(key.raw, fixtures.verify.signature, fixtures.verify.data)
expect(ok).to.be.true()
})

it('does not include the redundant public key when marshalling privatekey', async () => {
const key = privateKeyFromProtobuf(fixtures.redundantPubKey.privateKey)
const bytes = key.raw
Expand All @@ -231,6 +251,12 @@ describe('ed25519', function () {
expect(sig).to.eql(fixtures.verify.signature)
})

it('generates the same signature as go using nobel', async () => {
const key = privateKeyFromProtobuf(fixtures.verify.privateKey)
const sig = hashAndSignNoble(key.raw, fixtures.verify.data)
expect(sig).to.eql(fixtures.verify.signature)
})

it('generates the same signature as go with redundant public key', async () => {
const key = privateKeyFromProtobuf(fixtures.redundantPubKey.privateKey)
const sig = await key.sign(fixtures.redundantPubKey.data)
Expand Down
2 changes: 1 addition & 1 deletion packages/crypto/test/keys/rsa.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint max-nested-callbacks: ["error", 8] */
/* eslint-env mocha */
import { isPrivateKey, isPublicKey } from '@libp2p/interface'
import { sha256 } from '@noble/hashes/sha256'
import { sha256 } from '@noble/hashes/sha2.js'
import { expect } from 'aegir/chai'
import * as asn1js from 'asn1js'
import { create } from 'multiformats/hashes/digest'
Expand Down
2 changes: 1 addition & 1 deletion packages/floodsub/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
"aegir": "^47.0.22",
"delay": "^6.0.0",
"it-all": "^3.0.9",
"p-wait-for": "^5.0.2",
"p-wait-for": "^6.0.0",
"protons": "^7.7.0",
"sinon": "^21.0.0",
"sinon-ts": "^2.0.0"
Expand Down
4 changes: 2 additions & 2 deletions packages/gossipsub/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@
"it-all": "^3.0.6",
"mkdirp": "^3.0.1",
"p-defer": "^4.0.0",
"p-event": "^6.0.0",
"p-event": "^7.0.0",
"p-retry": "^7.0.0",
"p-wait-for": "^5.0.2",
"p-wait-for": "^6.0.0",
"protons": "^7.5.0",
"sinon": "^21.0.0",
"sinon-ts": "^2.0.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@
"main-event": "^1.0.1",
"multiformats": "^13.4.0",
"p-defer": "^4.0.1",
"p-event": "^6.0.1",
"p-event": "^7.0.0",
"p-retry": "^7.0.0",
"p-wait-for": "^5.0.2",
"p-wait-for": "^6.0.0",
"sinon": "^21.0.0",
"sinon-ts": "^2.0.0",
"uint8arraylist": "^2.4.8",
Expand Down
4 changes: 2 additions & 2 deletions packages/interface-compliance-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@
"it-to-buffer": "^4.0.10",
"libp2p": "^3.0.0",
"p-defer": "^4.0.1",
"p-event": "^6.0.1",
"p-event": "^7.0.0",
"p-retry": "^7.0.0",
"p-wait-for": "^5.0.2",
"p-wait-for": "^6.0.0",
"protons-runtime": "^5.6.0",
"race-signal": "^2.0.0",
"sinon": "^21.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/interop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"it-first": "^3.0.9",
"multiformats": "^13.4.0",
"p-retry": "^7.0.0",
"p-wait-for": "^5.0.2",
"p-wait-for": "^6.0.0",
"protons-runtime": "^5.6.0",
"uint8arraylist": "^2.4.8",
"uint8arrays": "^5.1.0"
Expand Down
2 changes: 1 addition & 1 deletion packages/kad-dht/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
"main-event": "^1.0.1",
"multiformats": "^13.4.0",
"p-defer": "^4.0.1",
"p-event": "^6.0.1",
"p-event": "^7.0.0",
"progress-events": "^1.0.1",
"protons-runtime": "^5.6.0",
"race-signal": "^2.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/keychain/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"dependencies": {
"@libp2p/crypto": "^5.1.9",
"@libp2p/interface": "^3.0.0",
"@noble/hashes": "^1.8.0",
"@noble/hashes": "^2.0.1",
"asn1js": "^3.0.6",
"interface-datastore": "^8.3.2",
"multiformats": "^13.4.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/keychain/src/utils/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { AES_GCM } from '@libp2p/crypto/ciphers'
import { privateKeyToProtobuf } from '@libp2p/crypto/keys'
import webcrypto from '@libp2p/crypto/webcrypto'
import { InvalidParametersError, UnsupportedKeyTypeError } from '@libp2p/interface'
import { pbkdf2Async } from '@noble/hashes/pbkdf2'
import { sha512 } from '@noble/hashes/sha512'
import { pbkdf2Async } from '@noble/hashes/pbkdf2.js'
import { sha512 } from '@noble/hashes/sha2.js'
import * as asn1js from 'asn1js'
import { base64 } from 'multiformats/bases/base64'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
Expand Down
Loading
Loading