@libp2p/crypto
Advanced tools
Comparing version 4.1.9 to 5.0.0-7cd984569
import { concat } from 'uint8arrays/concat'; | ||
import { fromString } from 'uint8arrays/from-string'; | ||
import webcrypto from '../webcrypto.js'; | ||
import webcrypto from '../webcrypto/index.js'; | ||
// WebKit on Linux does not support deriving a key from an empty PBKDF2 key. | ||
@@ -5,0 +5,0 @@ // So, as a workaround, we provide the generated key as a constant. We test that |
@@ -1,2 +0,2 @@ | ||
import { generateEphmeralKeyPair } from './ecdh.js'; | ||
import { generateEphemeralKeyPair } from './ecdh/index.js'; | ||
/** | ||
@@ -8,3 +8,3 @@ * Generates an ephemeral public key and returns a function that will compute | ||
*/ | ||
export default generateEphmeralKeyPair; | ||
export default generateEphemeralKeyPair; | ||
//# sourceMappingURL=ephemeral-keys.d.ts.map |
@@ -1,2 +0,2 @@ | ||
import { generateEphmeralKeyPair } from './ecdh.js'; | ||
import { generateEphemeralKeyPair } from './ecdh/index.js'; | ||
/** | ||
@@ -8,3 +8,3 @@ * Generates an ephemeral public key and returns a function that will compute | ||
*/ | ||
export default generateEphmeralKeyPair; | ||
export default generateEphemeralKeyPair; | ||
//# sourceMappingURL=ephemeral-keys.js.map |
@@ -12,58 +12,55 @@ /** | ||
*/ | ||
import * as Ed25519 from './ed25519-class.js'; | ||
import generateEphemeralKeyPair from './ephemeral-keys.js'; | ||
import { keyStretcher } from './key-stretcher.js'; | ||
import * as keysPBM from './keys.js'; | ||
import * as RSA from './rsa-class.js'; | ||
import * as Secp256k1 from './secp256k1-class.js'; | ||
import type { PrivateKey, PublicKey, KeyType as KeyTypes } from '@libp2p/interface'; | ||
export { keyStretcher }; | ||
export { generateEphemeralKeyPair }; | ||
export { keysPBM }; | ||
export type { KeyTypes }; | ||
export { RsaPrivateKey, RsaPublicKey, MAX_RSA_KEY_SIZE } from './rsa-class.js'; | ||
export { Ed25519PrivateKey, Ed25519PublicKey } from './ed25519-class.js'; | ||
export { Secp256k1PrivateKey, Secp256k1PublicKey } from './secp256k1-class.js'; | ||
export type { JWKKeyPair } from './interface.js'; | ||
export declare const supportedKeys: { | ||
rsa: typeof RSA; | ||
ed25519: typeof Ed25519; | ||
secp256k1: typeof Secp256k1; | ||
}; | ||
import type { PrivateKey, PublicKey, KeyType, RSAPrivateKey, Secp256k1PrivateKey, Ed25519PrivateKey, Secp256k1PublicKey, Ed25519PublicKey } from '@libp2p/interface'; | ||
import type { MultihashDigest } from 'multiformats'; | ||
export { generateEphemeralKeyPair } from './ecdh/index.js'; | ||
export { keyStretcher } from './key-stretcher.js'; | ||
/** | ||
* Generates a keypair of the given type and bitsize | ||
*/ | ||
export declare function generateKeyPair<T extends KeyTypes>(type: T, bits?: number): Promise<PrivateKey<T>>; | ||
export declare function generateKeyPair(type: 'Ed25519'): Promise<Ed25519PrivateKey>; | ||
export declare function generateKeyPair(type: 'secp256k1'): Promise<Secp256k1PrivateKey>; | ||
export declare function generateKeyPair(type: 'RSA', bits?: number): Promise<RSAPrivateKey>; | ||
export declare function generateKeyPair(type: KeyType, bits?: number): Promise<PrivateKey>; | ||
/** | ||
* Generates a keypair of the given type and bitsize. | ||
* Generates a keypair of the given type from the passed seed. Currently only | ||
* supports Ed25519 keys. | ||
* | ||
* Seed is a 32 byte uint8array | ||
*/ | ||
export declare function generateKeyPairFromSeed<T extends KeyTypes>(type: T, seed: Uint8Array, bits?: number): Promise<PrivateKey<T>>; | ||
export declare function generateKeyPairFromSeed(type: 'Ed25519', seed: Uint8Array): Promise<Ed25519PrivateKey>; | ||
export declare function generateKeyPairFromSeed<T extends KeyType>(type: T, seed: Uint8Array, bits?: number): Promise<never>; | ||
/** | ||
* Converts a protobuf serialized public key into its representative object | ||
*/ | ||
export declare function unmarshalPublicKey<T extends KeyTypes>(buf: Uint8Array): PublicKey<T>; | ||
export declare function publicKeyFromProtobuf(buf: Uint8Array): PublicKey; | ||
/** | ||
* Creates a public key from the raw key bytes | ||
*/ | ||
export declare function publicKeyFromRaw(buf: Uint8Array): PublicKey; | ||
/** | ||
* Creates a public key from an identity multihash which contains a protobuf | ||
* encoded Ed25519 or secp256k1 public key. | ||
* | ||
* RSA keys are not supported as in practice we they are not stored in identity | ||
* multihashes since the hash would be very large. | ||
*/ | ||
export declare function publicKeyFromMultihash(digest: MultihashDigest<0x0>): Ed25519PublicKey | Secp256k1PublicKey; | ||
/** | ||
* Converts a public key object into a protobuf serialized public key | ||
*/ | ||
export declare function marshalPublicKey(key: { | ||
bytes: Uint8Array; | ||
}, type?: string): Uint8Array; | ||
export declare function publicKeyToProtobuf(key: PublicKey): Uint8Array; | ||
/** | ||
* Converts a protobuf serialized private key into its representative object | ||
*/ | ||
export declare function unmarshalPrivateKey<T extends KeyTypes>(buf: Uint8Array): Promise<PrivateKey<T>>; | ||
export declare function privateKeyFromProtobuf(buf: Uint8Array): Ed25519PrivateKey | Secp256k1PrivateKey | RSAPrivateKey; | ||
/** | ||
* Converts a private key object into a protobuf serialized private key | ||
* Creates a private key from the raw key bytes. For Ed25519 keys this requires | ||
* the public key to be appended to the private key otherwise we can't | ||
* differentiate between Ed25519 and secp256k1 keys as they are the same length. | ||
*/ | ||
export declare function marshalPrivateKey(key: { | ||
bytes: Uint8Array; | ||
}, type?: string): Uint8Array; | ||
export declare function privateKeyFromRaw(buf: Uint8Array): PrivateKey; | ||
/** | ||
* Converts an exported private key into its representative object. | ||
* | ||
* Supported formats are 'pem' (RSA only) and 'libp2p-key'. | ||
* Converts a private key object into a protobuf serialized private key | ||
*/ | ||
export declare function importKey<T extends KeyTypes>(encryptedKey: string, password: string): Promise<PrivateKey<T>>; | ||
export declare function privateKeyToProtobuf(key: PrivateKey): Uint8Array; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -12,65 +12,75 @@ /** | ||
*/ | ||
import { CodeError } from '@libp2p/interface'; | ||
import * as Ed25519 from './ed25519-class.js'; | ||
import generateEphemeralKeyPair from './ephemeral-keys.js'; | ||
import { importer } from './importer.js'; | ||
import { keyStretcher } from './key-stretcher.js'; | ||
import * as keysPBM from './keys.js'; | ||
import * as RSA from './rsa-class.js'; | ||
import { importFromPem } from './rsa-utils.js'; | ||
import * as Secp256k1 from './secp256k1-class.js'; | ||
export { keyStretcher }; | ||
export { generateEphemeralKeyPair }; | ||
export { keysPBM }; | ||
export { RsaPrivateKey, RsaPublicKey, MAX_RSA_KEY_SIZE } from './rsa-class.js'; | ||
export { Ed25519PrivateKey, Ed25519PublicKey } from './ed25519-class.js'; | ||
export { Secp256k1PrivateKey, Secp256k1PublicKey } from './secp256k1-class.js'; | ||
export const supportedKeys = { | ||
rsa: RSA, | ||
ed25519: Ed25519, | ||
secp256k1: Secp256k1 | ||
}; | ||
function unsupportedKey(type) { | ||
const supported = Object.keys(supportedKeys).join(' / '); | ||
return new CodeError(`invalid or unsupported key type ${type}. Must be ${supported}`, 'ERR_UNSUPPORTED_KEY_TYPE'); | ||
import { UnsupportedKeyTypeError } from '@libp2p/interface'; | ||
import { generateEd25519KeyPair, generateEd25519KeyPairFromSeed, unmarshalEd25519PrivateKey, unmarshalEd25519PublicKey } from './ed25519/utils.js'; | ||
import * as pb from './keys.js'; | ||
import { pkcs1ToRSAPrivateKey, pkixToRSAPublicKey, generateRSAKeyPair } from './rsa/utils.js'; | ||
import { generateSecp256k1KeyPair, unmarshalSecp256k1PrivateKey, unmarshalSecp256k1PublicKey } from './secp256k1/utils.js'; | ||
export { generateEphemeralKeyPair } from './ecdh/index.js'; | ||
export { keyStretcher } from './key-stretcher.js'; | ||
export async function generateKeyPair(type, bits) { | ||
if (type === 'Ed25519') { | ||
return generateEd25519KeyPair(); | ||
} | ||
if (type === 'secp256k1') { | ||
return generateSecp256k1KeyPair(); | ||
} | ||
if (type === 'RSA') { | ||
return generateRSAKeyPair(bits ?? 2048); | ||
} | ||
throw new UnsupportedKeyTypeError(); | ||
} | ||
function typeToKey(type) { | ||
type = type.toLowerCase(); | ||
if (type === 'rsa' || type === 'ed25519' || type === 'secp256k1') { | ||
return supportedKeys[type]; | ||
export async function generateKeyPairFromSeed(type, seed) { | ||
if (type !== 'Ed25519') { | ||
throw new UnsupportedKeyTypeError('Seed key derivation only supported for Ed25519 keys'); | ||
} | ||
throw unsupportedKey(type); | ||
return generateEd25519KeyPairFromSeed(seed); | ||
} | ||
/** | ||
* Generates a keypair of the given type and bitsize | ||
* Converts a protobuf serialized public key into its representative object | ||
*/ | ||
export async function generateKeyPair(type, bits) { | ||
return typeToKey(type).generateKeyPair(bits ?? 2048); | ||
export function publicKeyFromProtobuf(buf) { | ||
const { Type, Data } = pb.PublicKey.decode(buf); | ||
const data = Data ?? new Uint8Array(); | ||
switch (Type) { | ||
case pb.KeyType.RSA: | ||
return pkixToRSAPublicKey(data); | ||
case pb.KeyType.Ed25519: | ||
return unmarshalEd25519PublicKey(data); | ||
case pb.KeyType.secp256k1: | ||
return unmarshalSecp256k1PublicKey(data); | ||
default: | ||
throw new UnsupportedKeyTypeError(); | ||
} | ||
} | ||
/** | ||
* Generates a keypair of the given type and bitsize. | ||
* | ||
* Seed is a 32 byte uint8array | ||
* Creates a public key from the raw key bytes | ||
*/ | ||
export async function generateKeyPairFromSeed(type, seed, bits) { | ||
if (type.toLowerCase() !== 'ed25519') { | ||
throw new CodeError('Seed key derivation is unimplemented for RSA or secp256k1', 'ERR_UNSUPPORTED_KEY_DERIVATION_TYPE'); | ||
export function publicKeyFromRaw(buf) { | ||
if (buf.byteLength === 32) { | ||
return unmarshalEd25519PublicKey(buf); | ||
} | ||
return Ed25519.generateKeyPairFromSeed(seed); | ||
else if (buf.byteLength === 34) { | ||
return unmarshalSecp256k1PublicKey(buf); | ||
} | ||
else { | ||
return pkixToRSAPublicKey(buf); | ||
} | ||
} | ||
/** | ||
* Converts a protobuf serialized public key into its representative object | ||
* Creates a public key from an identity multihash which contains a protobuf | ||
* encoded Ed25519 or secp256k1 public key. | ||
* | ||
* RSA keys are not supported as in practice we they are not stored in identity | ||
* multihashes since the hash would be very large. | ||
*/ | ||
export function unmarshalPublicKey(buf) { | ||
const decoded = keysPBM.PublicKey.decode(buf); | ||
const data = decoded.Data ?? new Uint8Array(); | ||
switch (decoded.Type) { | ||
case keysPBM.KeyType.RSA: | ||
return supportedKeys.rsa.unmarshalRsaPublicKey(data); | ||
case keysPBM.KeyType.Ed25519: | ||
return supportedKeys.ed25519.unmarshalEd25519PublicKey(data); | ||
case keysPBM.KeyType.Secp256k1: | ||
return supportedKeys.secp256k1.unmarshalSecp256k1PublicKey(data); | ||
export function publicKeyFromMultihash(digest) { | ||
const { Type, Data } = pb.PublicKey.decode(digest.digest); | ||
const data = Data ?? new Uint8Array(); | ||
switch (Type) { | ||
case pb.KeyType.Ed25519: | ||
return unmarshalEd25519PublicKey(data); | ||
case pb.KeyType.secp256k1: | ||
return unmarshalSecp256k1PublicKey(data); | ||
default: | ||
throw unsupportedKey(decoded.Type ?? 'unknown'); | ||
throw new UnsupportedKeyTypeError(); | ||
} | ||
@@ -81,6 +91,7 @@ } | ||
*/ | ||
export function marshalPublicKey(key, type) { | ||
type = (type ?? 'rsa').toLowerCase(); | ||
typeToKey(type); // check type | ||
return key.bytes; | ||
export function publicKeyToProtobuf(key) { | ||
return pb.PublicKey.encode({ | ||
Type: pb.KeyType[key.type], | ||
Data: key.raw | ||
}); | ||
} | ||
@@ -90,42 +101,41 @@ /** | ||
*/ | ||
export async function unmarshalPrivateKey(buf) { | ||
const decoded = keysPBM.PrivateKey.decode(buf); | ||
export function privateKeyFromProtobuf(buf) { | ||
const decoded = pb.PrivateKey.decode(buf); | ||
const data = decoded.Data ?? new Uint8Array(); | ||
switch (decoded.Type) { | ||
case keysPBM.KeyType.RSA: | ||
return supportedKeys.rsa.unmarshalRsaPrivateKey(data); | ||
case keysPBM.KeyType.Ed25519: | ||
return supportedKeys.ed25519.unmarshalEd25519PrivateKey(data); | ||
case keysPBM.KeyType.Secp256k1: | ||
return supportedKeys.secp256k1.unmarshalSecp256k1PrivateKey(data); | ||
case pb.KeyType.RSA: | ||
return pkcs1ToRSAPrivateKey(data); | ||
case pb.KeyType.Ed25519: | ||
return unmarshalEd25519PrivateKey(data); | ||
case pb.KeyType.secp256k1: | ||
return unmarshalSecp256k1PrivateKey(data); | ||
default: | ||
throw unsupportedKey(decoded.Type ?? 'RSA'); | ||
throw new UnsupportedKeyTypeError(); | ||
} | ||
} | ||
/** | ||
* Converts a private key object into a protobuf serialized private key | ||
* Creates a private key from the raw key bytes. For Ed25519 keys this requires | ||
* the public key to be appended to the private key otherwise we can't | ||
* differentiate between Ed25519 and secp256k1 keys as they are the same length. | ||
*/ | ||
export function marshalPrivateKey(key, type) { | ||
type = (type ?? 'rsa').toLowerCase(); | ||
typeToKey(type); // check type | ||
return key.bytes; | ||
} | ||
/** | ||
* Converts an exported private key into its representative object. | ||
* | ||
* Supported formats are 'pem' (RSA only) and 'libp2p-key'. | ||
*/ | ||
export async function importKey(encryptedKey, password) { | ||
try { | ||
const key = await importer(encryptedKey, password); | ||
return await unmarshalPrivateKey(key); | ||
export function privateKeyFromRaw(buf) { | ||
if (buf.byteLength === 64) { | ||
return unmarshalEd25519PrivateKey(buf); | ||
} | ||
catch (_) { | ||
// Ignore and try the old pem decrypt | ||
else if (buf.byteLength === 32) { | ||
return unmarshalSecp256k1PrivateKey(buf); | ||
} | ||
if (!encryptedKey.includes('BEGIN')) { | ||
throw new CodeError('Encrypted key was not a libp2p-key or a PEM file', 'ERR_INVALID_IMPORT_FORMAT'); | ||
else { | ||
return pkcs1ToRSAPrivateKey(buf); | ||
} | ||
return importFromPem(encryptedKey, password); | ||
} | ||
/** | ||
* Converts a private key object into a protobuf serialized private key | ||
*/ | ||
export function privateKeyToProtobuf(key) { | ||
return pb.PrivateKey.encode({ | ||
Type: pb.KeyType[key.type], | ||
Data: key.raw | ||
}); | ||
} | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,2 @@ | ||
import { CodeError } from '@libp2p/interface'; | ||
import { InvalidParametersError } from '@libp2p/interface'; | ||
import { concat as uint8ArrayConcat } from 'uint8arrays/concat'; | ||
@@ -24,10 +24,12 @@ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'; | ||
export async function keyStretcher(cipherType, hash, secret) { | ||
const cipher = cipherMap[cipherType]; | ||
if (cipher == null) { | ||
const allowed = Object.keys(cipherMap).join(' / '); | ||
throw new CodeError(`unknown cipher type '${cipherType}'. Must be ${allowed}`, 'ERR_INVALID_CIPHER_TYPE'); | ||
if (cipherType !== 'AES-128' && cipherType !== 'AES-256' && cipherType !== 'Blowfish') { | ||
throw new InvalidParametersError('Cipher type was missing or unsupported'); | ||
} | ||
if (hash == null) { | ||
throw new CodeError('missing hash type', 'ERR_MISSING_HASH_TYPE'); | ||
if (hash !== 'SHA1' && hash !== 'SHA256' && hash !== 'SHA512') { | ||
throw new InvalidParametersError('Hash type was missing or unsupported'); | ||
} | ||
if (secret == null || !(secret instanceof Uint8Array)) { | ||
throw new InvalidParametersError('Secret was missing or an incorrect type'); | ||
} | ||
const cipher = cipherMap[cipherType]; | ||
const cipherKeySize = cipher.keySize; | ||
@@ -34,0 +36,0 @@ const ivSize = cipher.ivSize; |
@@ -1,2 +0,2 @@ | ||
import type { Codec } from 'protons-runtime'; | ||
import { type Codec, type DecodeOptions } from 'protons-runtime'; | ||
import type { Uint8ArrayList } from 'uint8arraylist'; | ||
@@ -6,3 +6,3 @@ export declare enum KeyType { | ||
Ed25519 = "Ed25519", | ||
Secp256k1 = "Secp256k1" | ||
secp256k1 = "secp256k1" | ||
} | ||
@@ -19,3 +19,3 @@ export declare namespace KeyType { | ||
const encode: (obj: Partial<PublicKey>) => Uint8Array; | ||
const decode: (buf: Uint8Array | Uint8ArrayList) => PublicKey; | ||
const decode: (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions<PublicKey>) => PublicKey; | ||
} | ||
@@ -29,4 +29,4 @@ export interface PrivateKey { | ||
const encode: (obj: Partial<PrivateKey>) => Uint8Array; | ||
const decode: (buf: Uint8Array | Uint8ArrayList) => PrivateKey; | ||
const decode: (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions<PrivateKey>) => PrivateKey; | ||
} | ||
//# sourceMappingURL=keys.d.ts.map |
@@ -6,3 +6,3 @@ /* eslint-disable import/export */ | ||
/* eslint-disable @typescript-eslint/no-empty-interface */ | ||
import { enumeration, encodeMessage, decodeMessage, message } from 'protons-runtime'; | ||
import { decodeMessage, encodeMessage, enumeration, message } from 'protons-runtime'; | ||
export var KeyType; | ||
@@ -12,3 +12,3 @@ (function (KeyType) { | ||
KeyType["Ed25519"] = "Ed25519"; | ||
KeyType["Secp256k1"] = "Secp256k1"; | ||
KeyType["secp256k1"] = "secp256k1"; | ||
})(KeyType || (KeyType = {})); | ||
@@ -19,3 +19,3 @@ var __KeyTypeValues; | ||
__KeyTypeValues[__KeyTypeValues["Ed25519"] = 1] = "Ed25519"; | ||
__KeyTypeValues[__KeyTypeValues["Secp256k1"] = 2] = "Secp256k1"; | ||
__KeyTypeValues[__KeyTypeValues["secp256k1"] = 2] = "secp256k1"; | ||
})(__KeyTypeValues || (__KeyTypeValues = {})); | ||
@@ -47,3 +47,3 @@ (function (KeyType) { | ||
} | ||
}, (reader, length) => { | ||
}, (reader, length, opts = {}) => { | ||
const obj = {}; | ||
@@ -54,11 +54,14 @@ const end = length == null ? reader.len : reader.pos + length; | ||
switch (tag >>> 3) { | ||
case 1: | ||
case 1: { | ||
obj.Type = KeyType.codec().decode(reader); | ||
break; | ||
case 2: | ||
} | ||
case 2: { | ||
obj.Data = reader.bytes(); | ||
break; | ||
default: | ||
} | ||
default: { | ||
reader.skipType(tag & 7); | ||
break; | ||
} | ||
} | ||
@@ -74,4 +77,4 @@ } | ||
}; | ||
PublicKey.decode = (buf) => { | ||
return decodeMessage(buf, PublicKey.codec()); | ||
PublicKey.decode = (buf, opts) => { | ||
return decodeMessage(buf, PublicKey.codec(), opts); | ||
}; | ||
@@ -99,3 +102,3 @@ })(PublicKey || (PublicKey = {})); | ||
} | ||
}, (reader, length) => { | ||
}, (reader, length, opts = {}) => { | ||
const obj = {}; | ||
@@ -106,11 +109,14 @@ const end = length == null ? reader.len : reader.pos + length; | ||
switch (tag >>> 3) { | ||
case 1: | ||
case 1: { | ||
obj.Type = KeyType.codec().decode(reader); | ||
break; | ||
case 2: | ||
} | ||
case 2: { | ||
obj.Data = reader.bytes(); | ||
break; | ||
default: | ||
} | ||
default: { | ||
reader.skipType(tag & 7); | ||
break; | ||
} | ||
} | ||
@@ -126,6 +132,6 @@ } | ||
}; | ||
PrivateKey.decode = (buf) => { | ||
return decodeMessage(buf, PrivateKey.codec()); | ||
PrivateKey.decode = (buf, opts) => { | ||
return decodeMessage(buf, PrivateKey.codec(), opts); | ||
}; | ||
})(PrivateKey || (PrivateKey = {})); | ||
//# sourceMappingURL=keys.js.map |
@@ -1,2 +0,2 @@ | ||
import { CodeError } from '@libp2p/interface'; | ||
import { InvalidParametersError } from '@libp2p/interface'; | ||
import { pbkdf2 as pbkdf2Sync } from '@noble/hashes/pbkdf2'; | ||
@@ -25,3 +25,3 @@ import { sha1 } from '@noble/hashes/sha1'; | ||
const types = Object.keys(hashName).join(' / '); | ||
throw new CodeError(`Hash '${hash}' is unknown or not supported. Must be ${types}`, 'ERR_UNSUPPORTED_HASH_TYPE'); | ||
throw new InvalidParametersError(`Hash '${hash}' is unknown or not supported. Must be ${types}`); | ||
} | ||
@@ -28,0 +28,0 @@ const hasher = hashName[hash]; |
@@ -1,2 +0,2 @@ | ||
import { CodeError } from '@libp2p/interface'; | ||
import { InvalidParametersError } from '@libp2p/interface'; | ||
import { randomBytes as randB } from '@noble/hashes/utils'; | ||
@@ -8,3 +8,3 @@ /** | ||
if (isNaN(length) || length <= 0) { | ||
throw new CodeError('random bytes length must be a Number bigger than 0', 'ERR_INVALID_LENGTH'); | ||
throw new InvalidParametersError('random bytes length must be a Number bigger than 0'); | ||
} | ||
@@ -11,0 +11,0 @@ return randB(length); |
{ | ||
"name": "@libp2p/crypto", | ||
"version": "4.1.9", | ||
"version": "5.0.0-7cd984569", | ||
"description": "Crypto primitives for libp2p", | ||
@@ -54,2 +54,6 @@ "license": "Apache-2.0 OR MIT", | ||
}, | ||
"./ciphers": { | ||
"types": "./dist/src/ciphers/index.d.ts", | ||
"import": "./dist/src/ciphers/index.js" | ||
}, | ||
"./hmac": { | ||
@@ -62,2 +66,6 @@ "types": "./dist/src/hmac/index.d.ts", | ||
"import": "./dist/src/keys/index.js" | ||
}, | ||
"./webcrypto": { | ||
"types": "./dist/src/webcrypto/index.d.ts", | ||
"import": "./dist/src/webcrypto/index.js" | ||
} | ||
@@ -89,3 +97,3 @@ }, | ||
"dependencies": { | ||
"@libp2p/interface": "^1.7.0", | ||
"@libp2p/interface": "2.0.0-7cd984569", | ||
"@noble/curves": "^1.4.0", | ||
@@ -107,10 +115,10 @@ "@noble/hashes": "^1.4.0", | ||
"./dist/src/ciphers/aes-gcm.js": "./dist/src/ciphers/aes-gcm.browser.js", | ||
"./dist/src/hmac/index.js": "./dist/src/hmac/index-browser.js", | ||
"./dist/src/keys/ecdh.js": "./dist/src/keys/ecdh-browser.js", | ||
"./dist/src/keys/ed25519.js": "./dist/src/keys/ed25519-browser.js", | ||
"./dist/src/keys/rsa.js": "./dist/src/keys/rsa-browser.js", | ||
"./dist/src/keys/secp256k1.js": "./dist/src/keys/secp256k1-browser.js", | ||
"./dist/src/webcrypto.js": "./dist/src/webcrypto-browser.js" | ||
"./dist/src/hmac/index.js": "./dist/src/hmac/index.browser.js", | ||
"./dist/src/keys/ecdh/index.js": "./dist/src/keys/ecdh/index.browser.js", | ||
"./dist/src/keys/ed25519/index.js": "./dist/src/keys/ed25519/index.browser.js", | ||
"./dist/src/keys/rsa/index.js": "./dist/src/keys/rsa/index.browser.js", | ||
"./dist/src/keys/secp256k1/index.js": "./dist/src/keys/secp256k1/index.browser.js", | ||
"./dist/src/webcrypto/webcrypto.js": "./dist/src/webcrypto/webcrypto.browser.js" | ||
}, | ||
"sideEffects": false | ||
} |
import { concat } from 'uint8arrays/concat' | ||
import { fromString } from 'uint8arrays/from-string' | ||
import webcrypto from '../webcrypto.js' | ||
import webcrypto from '../webcrypto/index.js' | ||
import type { CreateOptions, AESCipher } from './interface.js' | ||
@@ -5,0 +5,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { generateEphmeralKeyPair } from './ecdh.js' | ||
import { generateEphemeralKeyPair } from './ecdh/index.js' | ||
@@ -9,2 +9,2 @@ /** | ||
*/ | ||
export default generateEphmeralKeyPair | ||
export default generateEphemeralKeyPair |
@@ -13,81 +13,102 @@ /** | ||
import { CodeError } from '@libp2p/interface' | ||
import * as Ed25519 from './ed25519-class.js' | ||
import generateEphemeralKeyPair from './ephemeral-keys.js' | ||
import { importer } from './importer.js' | ||
import { keyStretcher } from './key-stretcher.js' | ||
import * as keysPBM from './keys.js' | ||
import * as RSA from './rsa-class.js' | ||
import { importFromPem } from './rsa-utils.js' | ||
import * as Secp256k1 from './secp256k1-class.js' | ||
import type { PrivateKey, PublicKey, KeyType as KeyTypes } from '@libp2p/interface' | ||
import { UnsupportedKeyTypeError } from '@libp2p/interface' | ||
import { generateEd25519KeyPair, generateEd25519KeyPairFromSeed, unmarshalEd25519PrivateKey, unmarshalEd25519PublicKey } from './ed25519/utils.js' | ||
import * as pb from './keys.js' | ||
import { pkcs1ToRSAPrivateKey, pkixToRSAPublicKey, generateRSAKeyPair } from './rsa/utils.js' | ||
import { generateSecp256k1KeyPair, unmarshalSecp256k1PrivateKey, unmarshalSecp256k1PublicKey } from './secp256k1/utils.js' | ||
import type { PrivateKey, PublicKey, KeyType, RSAPrivateKey, Secp256k1PrivateKey, Ed25519PrivateKey, Secp256k1PublicKey, Ed25519PublicKey } from '@libp2p/interface' | ||
import type { MultihashDigest } from 'multiformats' | ||
export { keyStretcher } | ||
export { generateEphemeralKeyPair } | ||
export { keysPBM } | ||
export { generateEphemeralKeyPair } from './ecdh/index.js' | ||
export { keyStretcher } from './key-stretcher.js' | ||
export type { KeyTypes } | ||
/** | ||
* Generates a keypair of the given type and bitsize | ||
*/ | ||
export async function generateKeyPair (type: 'Ed25519'): Promise<Ed25519PrivateKey> | ||
export async function generateKeyPair (type: 'secp256k1'): Promise<Secp256k1PrivateKey> | ||
export async function generateKeyPair (type: 'RSA', bits?: number): Promise<RSAPrivateKey> | ||
export async function generateKeyPair (type: KeyType, bits?: number): Promise<PrivateKey> | ||
export async function generateKeyPair (type: KeyType, bits?: number): Promise<unknown> { | ||
if (type === 'Ed25519') { | ||
return generateEd25519KeyPair() | ||
} | ||
export { RsaPrivateKey, RsaPublicKey, MAX_RSA_KEY_SIZE } from './rsa-class.js' | ||
export { Ed25519PrivateKey, Ed25519PublicKey } from './ed25519-class.js' | ||
export { Secp256k1PrivateKey, Secp256k1PublicKey } from './secp256k1-class.js' | ||
export type { JWKKeyPair } from './interface.js' | ||
if (type === 'secp256k1') { | ||
return generateSecp256k1KeyPair() | ||
} | ||
export const supportedKeys = { | ||
rsa: RSA, | ||
ed25519: Ed25519, | ||
secp256k1: Secp256k1 | ||
} | ||
if (type === 'RSA') { | ||
return generateRSAKeyPair(bits ?? 2048) | ||
} | ||
function unsupportedKey (type: string): CodeError<Record<string, never>> { | ||
const supported = Object.keys(supportedKeys).join(' / ') | ||
return new CodeError(`invalid or unsupported key type ${type}. Must be ${supported}`, 'ERR_UNSUPPORTED_KEY_TYPE') | ||
throw new UnsupportedKeyTypeError() | ||
} | ||
function typeToKey (type: string): typeof RSA | typeof Ed25519 | typeof Secp256k1 { | ||
type = type.toLowerCase() | ||
if (type === 'rsa' || type === 'ed25519' || type === 'secp256k1') { | ||
return supportedKeys[type] | ||
/** | ||
* Generates a keypair of the given type from the passed seed. Currently only | ||
* supports Ed25519 keys. | ||
* | ||
* Seed is a 32 byte uint8array | ||
*/ | ||
export async function generateKeyPairFromSeed (type: 'Ed25519', seed: Uint8Array): Promise<Ed25519PrivateKey> | ||
export async function generateKeyPairFromSeed <T extends KeyType> (type: T, seed: Uint8Array, bits?: number): Promise<never> | ||
export async function generateKeyPairFromSeed (type: string, seed: Uint8Array): Promise<unknown> { | ||
if (type !== 'Ed25519') { | ||
throw new UnsupportedKeyTypeError('Seed key derivation only supported for Ed25519 keys') | ||
} | ||
throw unsupportedKey(type) | ||
return generateEd25519KeyPairFromSeed(seed) | ||
} | ||
/** | ||
* Generates a keypair of the given type and bitsize | ||
* Converts a protobuf serialized public key into its representative object | ||
*/ | ||
export async function generateKeyPair <T extends KeyTypes> (type: T, bits?: number): Promise<PrivateKey<T>> { | ||
return typeToKey(type).generateKeyPair(bits ?? 2048) | ||
export function publicKeyFromProtobuf (buf: Uint8Array): PublicKey { | ||
const { Type, Data } = pb.PublicKey.decode(buf) | ||
const data = Data ?? new Uint8Array() | ||
switch (Type) { | ||
case pb.KeyType.RSA: | ||
return pkixToRSAPublicKey(data) | ||
case pb.KeyType.Ed25519: | ||
return unmarshalEd25519PublicKey(data) | ||
case pb.KeyType.secp256k1: | ||
return unmarshalSecp256k1PublicKey(data) | ||
default: | ||
throw new UnsupportedKeyTypeError() | ||
} | ||
} | ||
/** | ||
* Generates a keypair of the given type and bitsize. | ||
* | ||
* Seed is a 32 byte uint8array | ||
* Creates a public key from the raw key bytes | ||
*/ | ||
export async function generateKeyPairFromSeed <T extends KeyTypes> (type: T, seed: Uint8Array, bits?: number): Promise<PrivateKey<T>> { | ||
if (type.toLowerCase() !== 'ed25519') { | ||
throw new CodeError('Seed key derivation is unimplemented for RSA or secp256k1', 'ERR_UNSUPPORTED_KEY_DERIVATION_TYPE') | ||
export function publicKeyFromRaw (buf: Uint8Array): PublicKey { | ||
if (buf.byteLength === 32) { | ||
return unmarshalEd25519PublicKey(buf) | ||
} else if (buf.byteLength === 34) { | ||
return unmarshalSecp256k1PublicKey(buf) | ||
} else { | ||
return pkixToRSAPublicKey(buf) | ||
} | ||
return Ed25519.generateKeyPairFromSeed(seed) | ||
} | ||
/** | ||
* Converts a protobuf serialized public key into its representative object | ||
* Creates a public key from an identity multihash which contains a protobuf | ||
* encoded Ed25519 or secp256k1 public key. | ||
* | ||
* RSA keys are not supported as in practice we they are not stored in identity | ||
* multihashes since the hash would be very large. | ||
*/ | ||
export function unmarshalPublicKey <T extends KeyTypes> (buf: Uint8Array): PublicKey<T> { | ||
const decoded = keysPBM.PublicKey.decode(buf) | ||
const data = decoded.Data ?? new Uint8Array() | ||
export function publicKeyFromMultihash (digest: MultihashDigest<0x0>): Ed25519PublicKey | Secp256k1PublicKey { | ||
const { Type, Data } = pb.PublicKey.decode(digest.digest) | ||
const data = Data ?? new Uint8Array() | ||
switch (decoded.Type) { | ||
case keysPBM.KeyType.RSA: | ||
return supportedKeys.rsa.unmarshalRsaPublicKey(data) | ||
case keysPBM.KeyType.Ed25519: | ||
return supportedKeys.ed25519.unmarshalEd25519PublicKey(data) | ||
case keysPBM.KeyType.Secp256k1: | ||
return supportedKeys.secp256k1.unmarshalSecp256k1PublicKey(data) | ||
switch (Type) { | ||
case pb.KeyType.Ed25519: | ||
return unmarshalEd25519PublicKey(data) | ||
case pb.KeyType.secp256k1: | ||
return unmarshalSecp256k1PublicKey(data) | ||
default: | ||
throw unsupportedKey(decoded.Type ?? 'unknown') | ||
throw new UnsupportedKeyTypeError() | ||
} | ||
@@ -99,6 +120,7 @@ } | ||
*/ | ||
export function marshalPublicKey (key: { bytes: Uint8Array }, type?: string): Uint8Array { | ||
type = (type ?? 'rsa').toLowerCase() | ||
typeToKey(type) // check type | ||
return key.bytes | ||
export function publicKeyToProtobuf (key: PublicKey): Uint8Array { | ||
return pb.PublicKey.encode({ | ||
Type: pb.KeyType[key.type], | ||
Data: key.raw | ||
}) | ||
} | ||
@@ -109,15 +131,15 @@ | ||
*/ | ||
export async function unmarshalPrivateKey <T extends KeyTypes> (buf: Uint8Array): Promise<PrivateKey<T>> { | ||
const decoded = keysPBM.PrivateKey.decode(buf) | ||
export function privateKeyFromProtobuf (buf: Uint8Array): Ed25519PrivateKey | Secp256k1PrivateKey | RSAPrivateKey { | ||
const decoded = pb.PrivateKey.decode(buf) | ||
const data = decoded.Data ?? new Uint8Array() | ||
switch (decoded.Type) { | ||
case keysPBM.KeyType.RSA: | ||
return supportedKeys.rsa.unmarshalRsaPrivateKey(data) | ||
case keysPBM.KeyType.Ed25519: | ||
return supportedKeys.ed25519.unmarshalEd25519PrivateKey(data) | ||
case keysPBM.KeyType.Secp256k1: | ||
return supportedKeys.secp256k1.unmarshalSecp256k1PrivateKey(data) | ||
case pb.KeyType.RSA: | ||
return pkcs1ToRSAPrivateKey(data) | ||
case pb.KeyType.Ed25519: | ||
return unmarshalEd25519PrivateKey(data) | ||
case pb.KeyType.secp256k1: | ||
return unmarshalSecp256k1PrivateKey(data) | ||
default: | ||
throw unsupportedKey(decoded.Type ?? 'RSA') | ||
throw new UnsupportedKeyTypeError() | ||
} | ||
@@ -127,28 +149,24 @@ } | ||
/** | ||
* Converts a private key object into a protobuf serialized private key | ||
* Creates a private key from the raw key bytes. For Ed25519 keys this requires | ||
* the public key to be appended to the private key otherwise we can't | ||
* differentiate between Ed25519 and secp256k1 keys as they are the same length. | ||
*/ | ||
export function marshalPrivateKey (key: { bytes: Uint8Array }, type?: string): Uint8Array { | ||
type = (type ?? 'rsa').toLowerCase() | ||
typeToKey(type) // check type | ||
return key.bytes | ||
export function privateKeyFromRaw (buf: Uint8Array): PrivateKey { | ||
if (buf.byteLength === 64) { | ||
return unmarshalEd25519PrivateKey(buf) | ||
} else if (buf.byteLength === 32) { | ||
return unmarshalSecp256k1PrivateKey(buf) | ||
} else { | ||
return pkcs1ToRSAPrivateKey(buf) | ||
} | ||
} | ||
/** | ||
* Converts an exported private key into its representative object. | ||
* | ||
* Supported formats are 'pem' (RSA only) and 'libp2p-key'. | ||
* Converts a private key object into a protobuf serialized private key | ||
*/ | ||
export async function importKey <T extends KeyTypes> (encryptedKey: string, password: string): Promise<PrivateKey<T>> { | ||
try { | ||
const key = await importer(encryptedKey, password) | ||
return await unmarshalPrivateKey(key) | ||
} catch (_) { | ||
// Ignore and try the old pem decrypt | ||
} | ||
if (!encryptedKey.includes('BEGIN')) { | ||
throw new CodeError('Encrypted key was not a libp2p-key or a PEM file', 'ERR_INVALID_IMPORT_FORMAT') | ||
} | ||
return importFromPem(encryptedKey, password) | ||
export function privateKeyToProtobuf (key: PrivateKey): Uint8Array { | ||
return pb.PrivateKey.encode({ | ||
Type: pb.KeyType[key.type], | ||
Data: key.raw | ||
}) | ||
} |
@@ -1,2 +0,2 @@ | ||
import { CodeError } from '@libp2p/interface' | ||
import { InvalidParametersError } from '@libp2p/interface' | ||
import { concat as uint8ArrayConcat } from 'uint8arrays/concat' | ||
@@ -7,3 +7,8 @@ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' | ||
const cipherMap = { | ||
interface Cipher { | ||
ivSize: number | ||
keySize: number | ||
} | ||
const cipherMap: Record<string, Cipher> = { | ||
'AES-128': { | ||
@@ -28,13 +33,15 @@ ivSize: 16, | ||
export async function keyStretcher (cipherType: 'AES-128' | 'AES-256' | 'Blowfish', hash: 'SHA1' | 'SHA256' | 'SHA512', secret: Uint8Array): Promise<EnhancedKeyPair> { | ||
const cipher = cipherMap[cipherType] | ||
if (cipherType !== 'AES-128' && cipherType !== 'AES-256' && cipherType !== 'Blowfish') { | ||
throw new InvalidParametersError('Cipher type was missing or unsupported') | ||
} | ||
if (cipher == null) { | ||
const allowed = Object.keys(cipherMap).join(' / ') | ||
throw new CodeError(`unknown cipher type '${cipherType}'. Must be ${allowed}`, 'ERR_INVALID_CIPHER_TYPE') | ||
if (hash !== 'SHA1' && hash !== 'SHA256' && hash !== 'SHA512') { | ||
throw new InvalidParametersError('Hash type was missing or unsupported') | ||
} | ||
if (hash == null) { | ||
throw new CodeError('missing hash type', 'ERR_MISSING_HASH_TYPE') | ||
if (secret == null || !(secret instanceof Uint8Array)) { | ||
throw new InvalidParametersError('Secret was missing or an incorrect type') | ||
} | ||
const cipher = cipherMap[cipherType] | ||
const cipherKeySize = cipher.keySize | ||
@@ -41,0 +48,0 @@ const ivSize = cipher.ivSize |
@@ -7,4 +7,3 @@ /* eslint-disable import/export */ | ||
import { enumeration, encodeMessage, decodeMessage, message } from 'protons-runtime' | ||
import type { Codec } from 'protons-runtime' | ||
import { type Codec, decodeMessage, type DecodeOptions, encodeMessage, enumeration, message } from 'protons-runtime' | ||
import type { Uint8ArrayList } from 'uint8arraylist' | ||
@@ -15,3 +14,3 @@ | ||
Ed25519 = 'Ed25519', | ||
Secp256k1 = 'Secp256k1' | ||
secp256k1 = 'secp256k1' | ||
} | ||
@@ -22,3 +21,3 @@ | ||
Ed25519 = 1, | ||
Secp256k1 = 2 | ||
secp256k1 = 2 | ||
} | ||
@@ -59,3 +58,3 @@ | ||
} | ||
}, (reader, length) => { | ||
}, (reader, length, opts = {}) => { | ||
const obj: any = {} | ||
@@ -69,11 +68,14 @@ | ||
switch (tag >>> 3) { | ||
case 1: | ||
case 1: { | ||
obj.Type = KeyType.codec().decode(reader) | ||
break | ||
case 2: | ||
} | ||
case 2: { | ||
obj.Data = reader.bytes() | ||
break | ||
default: | ||
} | ||
default: { | ||
reader.skipType(tag & 7) | ||
break | ||
} | ||
} | ||
@@ -93,4 +95,4 @@ } | ||
export const decode = (buf: Uint8Array | Uint8ArrayList): PublicKey => { | ||
return decodeMessage(buf, PublicKey.codec()) | ||
export const decode = (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions<PublicKey>): PublicKey => { | ||
return decodeMessage(buf, PublicKey.codec(), opts) | ||
} | ||
@@ -127,3 +129,3 @@ } | ||
} | ||
}, (reader, length) => { | ||
}, (reader, length, opts = {}) => { | ||
const obj: any = {} | ||
@@ -137,11 +139,14 @@ | ||
switch (tag >>> 3) { | ||
case 1: | ||
case 1: { | ||
obj.Type = KeyType.codec().decode(reader) | ||
break | ||
case 2: | ||
} | ||
case 2: { | ||
obj.Data = reader.bytes() | ||
break | ||
default: | ||
} | ||
default: { | ||
reader.skipType(tag & 7) | ||
break | ||
} | ||
} | ||
@@ -161,5 +166,5 @@ } | ||
export const decode = (buf: Uint8Array | Uint8ArrayList): PrivateKey => { | ||
return decodeMessage(buf, PrivateKey.codec()) | ||
export const decode = (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions<PrivateKey>): PrivateKey => { | ||
return decodeMessage(buf, PrivateKey.codec(), opts) | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
import { CodeError } from '@libp2p/interface' | ||
import { InvalidParametersError } from '@libp2p/interface' | ||
import { pbkdf2 as pbkdf2Sync } from '@noble/hashes/pbkdf2' | ||
@@ -27,3 +27,3 @@ import { sha1 } from '@noble/hashes/sha1' | ||
const types = Object.keys(hashName).join(' / ') | ||
throw new CodeError(`Hash '${hash}' is unknown or not supported. Must be ${types}`, 'ERR_UNSUPPORTED_HASH_TYPE') | ||
throw new InvalidParametersError(`Hash '${hash}' is unknown or not supported. Must be ${types}`) | ||
} | ||
@@ -30,0 +30,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { CodeError } from '@libp2p/interface' | ||
import { InvalidParametersError } from '@libp2p/interface' | ||
import { randomBytes as randB } from '@noble/hashes/utils' | ||
@@ -9,5 +9,5 @@ | ||
if (isNaN(length) || length <= 0) { | ||
throw new CodeError('random bytes length must be a Number bigger than 0', 'ERR_INVALID_LENGTH') | ||
throw new InvalidParametersError('random bytes length must be a Number bigger than 0') | ||
} | ||
return randB(length) | ||
} |
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
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
175
377163
4501
1
1
+ Added@libp2p/interface@2.0.0-7cd984569(transitive)
- Removed@libp2p/interface@1.7.0(transitive)