🚀 Socket Launch Week 🚀 Day 4: Introducing Historical Analytics.Learn More
Socket
Sign inDemoInstall
Socket

@libp2p/crypto

Package Overview
Dependencies
Maintainers
6
Versions
679
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@libp2p/crypto - npm Package Compare versions

Comparing version

to
5.1.0-b9e32cc37

dist/src/keys/ecdsa/ecdsa.d.ts

16

dist/src/keys/index.d.ts

@@ -10,3 +10,4 @@ /**

*/
import type { PrivateKey, PublicKey, KeyType, RSAPrivateKey, Secp256k1PrivateKey, Ed25519PrivateKey, Secp256k1PublicKey, Ed25519PublicKey } from '@libp2p/interface';
import type { Curve } from './ecdsa/index.js';
import type { PrivateKey, PublicKey, KeyType, RSAPrivateKey, Secp256k1PrivateKey, Ed25519PrivateKey, Secp256k1PublicKey, Ed25519PublicKey, ECDSAPrivateKey, ECDSAPublicKey } from '@libp2p/interface';
import type { MultihashDigest } from 'multiformats';

@@ -23,2 +24,3 @@ import type { Digest } from 'multiformats/hashes/digest';

export declare function generateKeyPair(type: 'secp256k1'): Promise<Secp256k1PrivateKey>;
export declare function generateKeyPair(type: 'ECDSA', curve?: Curve): Promise<ECDSAPrivateKey>;
export declare function generateKeyPair(type: 'RSA', bits?: number): Promise<RSAPrivateKey>;

@@ -55,3 +57,3 @@ export declare function generateKeyPair(type: KeyType, bits?: number): Promise<PrivateKey>;

*/
export declare function publicKeyFromMultihash(digest: MultihashDigest<0x0>): Ed25519PublicKey | Secp256k1PublicKey;
export declare function publicKeyFromMultihash(digest: MultihashDigest<0x0>): Ed25519PublicKey | Secp256k1PublicKey | ECDSAPublicKey;
/**

@@ -64,3 +66,3 @@ * Converts a public key object into a protobuf serialized public key

*/
export declare function privateKeyFromProtobuf(buf: Uint8Array): Ed25519PrivateKey | Secp256k1PrivateKey | RSAPrivateKey;
export declare function privateKeyFromProtobuf(buf: Uint8Array): Ed25519PrivateKey | Secp256k1PrivateKey | RSAPrivateKey | ECDSAPrivateKey;
/**

@@ -76,2 +78,10 @@ * Creates a private key from the raw key bytes. For Ed25519 keys this requires

export declare function privateKeyToProtobuf(key: PrivateKey): Uint8Array;
/**
* Convert a libp2p RSA or ECDSA private key to a WebCrypto CryptoKeyPair
*/
export declare function privateKeyToCryptoKeyPair(privateKey: PrivateKey): Promise<CryptoKeyPair>;
/**
* Convert a RSA or ECDSA WebCrypto CryptoKeyPair to a libp2p private key
*/
export declare function privateKeyFromCryptoKeyPair(keyPair: CryptoKeyPair): Promise<PrivateKey>;
//# sourceMappingURL=index.d.ts.map

@@ -10,6 +10,13 @@ /**

*/
import { UnsupportedKeyTypeError } from '@libp2p/interface';
import { InvalidParametersError, UnsupportedKeyTypeError } from '@libp2p/interface';
import { ECDSAPrivateKey as ECDSAPrivateKeyClass } from './ecdsa/ecdsa.js';
import { ECDSA_P_256_OID, ECDSA_P_384_OID, ECDSA_P_521_OID } from './ecdsa/index.js';
import { generateECDSAKeyPair, pkiMessageToECDSAPrivateKey, pkiMessageToECDSAPublicKey, unmarshalECDSAPrivateKey, unmarshalECDSAPublicKey } from './ecdsa/utils.js';
import { privateKeyLength as ed25519PrivateKeyLength, publicKeyLength as ed25519PublicKeyLength } from './ed25519/index.js';
import { generateEd25519KeyPair, generateEd25519KeyPairFromSeed, unmarshalEd25519PrivateKey, unmarshalEd25519PublicKey } from './ed25519/utils.js';
import * as pb from './keys.js';
import { pkcs1ToRSAPrivateKey, pkixToRSAPublicKey, generateRSAKeyPair } from './rsa/utils.js';
import { decodeDer } from './rsa/der.js';
import { RSAES_PKCS1_V1_5_OID } from './rsa/index.js';
import { pkcs1ToRSAPrivateKey, pkixToRSAPublicKey, generateRSAKeyPair, pkcs1MessageToRSAPrivateKey, pkixMessageToRSAPublicKey, jwkToRSAPrivateKey } from './rsa/utils.js';
import { privateKeyLength as secp256k1PrivateKeyLength, publicKeyLength as secp256k1PublicKeyLength } from './secp256k1/index.js';
import { generateSecp256k1KeyPair, unmarshalSecp256k1PrivateKey, unmarshalSecp256k1PublicKey } from './secp256k1/utils.js';

@@ -26,4 +33,7 @@ export { generateEphemeralKeyPair } from './ecdh/index.js';

if (type === 'RSA') {
return generateRSAKeyPair(bits ?? 2048);
return generateRSAKeyPair(toBits(bits));
}
if (type === 'ECDSA') {
return generateECDSAKeyPair(toCurve(bits));
}
throw new UnsupportedKeyTypeError();

@@ -56,2 +66,4 @@ }

return unmarshalSecp256k1PublicKey(data);
case pb.KeyType.ECDSA:
return unmarshalECDSAPublicKey(data);
default:

@@ -65,11 +77,17 @@ throw new UnsupportedKeyTypeError();

export function publicKeyFromRaw(buf) {
if (buf.byteLength === 32) {
if (buf.byteLength === ed25519PublicKeyLength) {
return unmarshalEd25519PublicKey(buf);
}
else if (buf.byteLength === 33) {
else if (buf.byteLength === secp256k1PublicKeyLength) {
return unmarshalSecp256k1PublicKey(buf);
}
else {
return pkixToRSAPublicKey(buf);
const message = decodeDer(buf);
const ecdsaOid = message[1]?.[0];
if (ecdsaOid === ECDSA_P_256_OID || ecdsaOid === ECDSA_P_384_OID || ecdsaOid === ECDSA_P_521_OID) {
return pkiMessageToECDSAPublicKey(message);
}
if (message[0]?.[0] === RSAES_PKCS1_V1_5_OID) {
return pkixMessageToRSAPublicKey(message, buf);
}
throw new InvalidParametersError('Could not extract public key from raw bytes');
}

@@ -91,2 +109,4 @@ /**

return unmarshalSecp256k1PublicKey(data);
case pb.KeyType.ECDSA:
return unmarshalECDSAPublicKey(data);
default:

@@ -118,2 +138,4 @@ throw new UnsupportedKeyTypeError();

return unmarshalSecp256k1PrivateKey(data);
case pb.KeyType.ECDSA:
return unmarshalECDSAPrivateKey(data);
default:

@@ -129,11 +151,17 @@ throw new UnsupportedKeyTypeError();

export function privateKeyFromRaw(buf) {
if (buf.byteLength === 64) {
if (buf.byteLength === ed25519PrivateKeyLength) {
return unmarshalEd25519PrivateKey(buf);
}
else if (buf.byteLength === 32) {
else if (buf.byteLength === secp256k1PrivateKeyLength) {
return unmarshalSecp256k1PrivateKey(buf);
}
else {
return pkcs1ToRSAPrivateKey(buf);
const message = decodeDer(buf);
const ecdsaOid = message[2]?.[0];
if (ecdsaOid === ECDSA_P_256_OID || ecdsaOid === ECDSA_P_384_OID || ecdsaOid === ECDSA_P_521_OID) {
return pkiMessageToECDSAPrivateKey(message);
}
if (message.length > 8) {
return pkcs1MessageToRSAPrivateKey(message);
}
throw new InvalidParametersError('Could not extract private key from raw bytes');
}

@@ -149,2 +177,64 @@ /**

}
function toBits(bits) {
if (bits == null) {
return 2048;
}
return parseInt(bits, 10);
}
function toCurve(curve) {
if (curve === 'P-256' || curve == null) {
return 'P-256';
}
if (curve === 'P-384') {
return 'P-384';
}
if (curve === 'P-521') {
return 'P-521';
}
throw new InvalidParametersError('Unsupported curve, should be P-256, P-384 or P-521');
}
/**
* Convert a libp2p RSA or ECDSA private key to a WebCrypto CryptoKeyPair
*/
export async function privateKeyToCryptoKeyPair(privateKey) {
if (privateKey.type === 'RSA') {
return {
privateKey: await crypto.subtle.importKey('jwk', privateKey.jwk, {
name: 'RSASSA-PKCS1-v1_5',
hash: { name: 'SHA-256' }
}, true, ['sign']),
publicKey: await crypto.subtle.importKey('jwk', privateKey.publicKey.jwk, {
name: 'RSASSA-PKCS1-v1_5',
hash: { name: 'SHA-256' }
}, true, ['verify'])
};
}
if (privateKey.type === 'ECDSA') {
return {
privateKey: await crypto.subtle.importKey('jwk', privateKey.jwk, {
name: 'ECDSA',
namedCurve: privateKey.jwk.crv ?? 'P-256'
}, true, ['sign']),
publicKey: await crypto.subtle.importKey('jwk', privateKey.publicKey.jwk, {
name: 'ECDSA',
namedCurve: privateKey.publicKey.jwk.crv ?? 'P-256'
}, true, ['verify'])
};
}
throw new InvalidParametersError('Only RSA and ECDSA keys are supported');
}
/**
* Convert a RSA or ECDSA WebCrypto CryptoKeyPair to a libp2p private key
*/
export async function privateKeyFromCryptoKeyPair(keyPair) {
if (keyPair.privateKey.algorithm.name === 'RSASSA-PKCS1-v1_5') {
const jwk = await crypto.subtle.exportKey('jwk', keyPair.privateKey);
return jwkToRSAPrivateKey(jwk);
}
if (keyPair.privateKey.algorithm.name === 'ECDSA') {
const jwk = await crypto.subtle.exportKey('jwk', keyPair.privateKey);
return new ECDSAPrivateKeyClass(jwk);
}
throw new InvalidParametersError('Only RSA and ECDSA keys are supported');
}
//# sourceMappingURL=index.js.map

3

dist/src/keys/keys.d.ts

@@ -6,3 +6,4 @@ import { type Codec, type DecodeOptions } from 'protons-runtime';

Ed25519 = "Ed25519",
secp256k1 = "secp256k1"
secp256k1 = "secp256k1",
ECDSA = "ECDSA"
}

@@ -9,0 +10,0 @@ export declare namespace KeyType {

@@ -12,2 +12,3 @@ /* eslint-disable import/export */

KeyType["secp256k1"] = "secp256k1";
KeyType["ECDSA"] = "ECDSA";
})(KeyType || (KeyType = {}));

@@ -19,2 +20,3 @@ var __KeyTypeValues;

__KeyTypeValues[__KeyTypeValues["secp256k1"] = 2] = "secp256k1";
__KeyTypeValues[__KeyTypeValues["ECDSA"] = 3] = "ECDSA";
})(__KeyTypeValues || (__KeyTypeValues = {}));

@@ -21,0 +23,0 @@ (function (KeyType) {

@@ -8,4 +8,5 @@ import { Uint8ArrayList } from 'uint8arraylist';

export declare function encodeBitString(value: Uint8Array | Uint8ArrayList): Uint8ArrayList;
export declare function encodeSequence(values: Array<Uint8Array | Uint8ArrayList>): Uint8ArrayList;
export declare function encodeOctetString(value: Uint8Array | Uint8ArrayList): Uint8ArrayList;
export declare function encodeSequence(values: Array<Uint8Array | Uint8ArrayList>, tag?: number): Uint8ArrayList;
export {};
//# sourceMappingURL=der.d.ts.map

@@ -6,4 +6,7 @@ import { Uint8ArrayList } from 'uint8arraylist';

const decoders = {
0x0: readSequence,
0x1: readSequence,
0x2: readInteger,
0x3: readBitString,
0x4: readOctetString,
0x5: readNull,

@@ -72,5 +75,38 @@ 0x6: readObjectIdentifier,

const count = readLength(buf, context);
// skip OID
context.offset += count;
return ['oid-unimplemented'];
const finalOffset = context.offset + count;
const byte = buf[context.offset];
context.offset++;
let val1 = 0;
let val2 = 0;
if (byte < 40) {
val1 = 0;
val2 = byte;
}
else if (byte < 80) {
val1 = 1;
val2 = byte - 40;
}
else {
val1 = 2;
val2 = byte - 80;
}
let oid = `${val1}.${val2}`;
let num = [];
while (context.offset < finalOffset) {
const byte = buf[context.offset];
context.offset++;
// remove msb
num.push(byte & 0b01111111);
if (byte < 128) {
num.reverse();
// reached the end of the encoding
let val = 0;
for (let i = 0; i < num.length; i++) {
val += num[i] << (i * 7);
}
oid += `.${val}`;
num = [];
}
}
return oid;
}

@@ -85,3 +121,3 @@ function readNull(buf, context) {

context.offset++;
const bytes = buf.subarray(context.offset, context.offset + length);
const bytes = buf.subarray(context.offset, context.offset + length - 1);
context.offset += length;

@@ -92,6 +128,10 @@ if (unusedBits !== 0) {

}
return decodeDer(bytes, {
offset: 0
});
return bytes;
}
function readOctetString(buf, context) {
const length = readLength(buf, context);
const bytes = buf.subarray(context.offset, context.offset + length);
context.offset += length;
return bytes;
}
function encodeNumber(value) {

@@ -120,3 +160,3 @@ let number = value.toString(16);

const contents = new Uint8ArrayList();
const mask = parseInt('10000000', 2);
const mask = 0b10000000;
const positive = (value.subarray()[0] & mask) === mask;

@@ -135,3 +175,6 @@ if (positive) {

}
export function encodeSequence(values) {
export function encodeOctetString(value) {
return new Uint8ArrayList(Uint8Array.from([0x04]), encodeLength(value), value);
}
export function encodeSequence(values, tag = 0x30) {
const output = new Uint8ArrayList();

@@ -141,4 +184,4 @@ for (const buf of values) {

}
return new Uint8ArrayList(Uint8Array.from([0x30]), encodeLength(output), output);
return new Uint8ArrayList(Uint8Array.from([tag]), encodeLength(output), output);
}
//# sourceMappingURL=der.js.map

@@ -5,2 +5,3 @@ import randomBytes from '../../random-bytes.js';

import type { Uint8ArrayList } from 'uint8arraylist';
export declare const RSAES_PKCS1_V1_5_OID = "1.2.840.113549.1.1.1";
export { utils };

@@ -7,0 +8,0 @@ export declare function generateRSAKey(bits: number): Promise<JWKKeyPair>;

@@ -6,2 +6,3 @@ import { InvalidParametersError } from '@libp2p/interface';

import * as utils from './utils.js';
export const RSAES_PKCS1_V1_5_OID = '1.2.840.113549.1.1.1';
export { utils };

@@ -8,0 +9,0 @@ export async function generateRSAKey(bits) {

@@ -5,2 +5,3 @@ import randomBytes from '../../random-bytes.js';

import type { Uint8ArrayList } from 'uint8arraylist';
export declare const RSAES_PKCS1_V1_5_OID = "1.2.840.113549.1.1.1";
export { utils };

@@ -7,0 +8,0 @@ export declare function generateRSAKey(bits: number): Promise<JWKKeyPair>;

@@ -8,2 +8,3 @@ import crypto from 'crypto';

const keypair = promisify(crypto.generateKeyPair);
export const RSAES_PKCS1_V1_5_OID = '1.2.840.113549.1.1.1';
export { utils };

@@ -10,0 +11,0 @@ export async function generateRSAKey(bits) {

@@ -7,6 +7,6 @@ import { CID } from 'multiformats/cid';

readonly type = "RSA";
private readonly _key;
readonly jwk: JsonWebKey;
private _raw?;
private readonly _multihash;
constructor(key: JsonWebKey, digest: Digest<18, number>);
constructor(jwk: JsonWebKey, digest: Digest<18, number>);
get raw(): Uint8Array;

@@ -21,6 +21,6 @@ toMultihash(): Digest<18, number>;

readonly type = "RSA";
private readonly _key;
readonly jwk: JsonWebKey;
private _raw?;
readonly publicKey: RSAPublicKey;
constructor(key: JsonWebKey, publicKey: RSAPublicKey);
constructor(jwk: JsonWebKey, publicKey: RSAPublicKey);
get raw(): Uint8Array;

@@ -27,0 +27,0 @@ equals(key: any): boolean;

@@ -8,7 +8,7 @@ import { base58btc } from 'multiformats/bases/base58';

type = 'RSA';
_key;
jwk;
_raw;
_multihash;
constructor(key, digest) {
this._key = key;
constructor(jwk, digest) {
this.jwk = jwk;
this._multihash = digest;

@@ -18,3 +18,3 @@ }

if (this._raw == null) {
this._raw = utils.jwkToPkix(this._key);
this._raw = utils.jwkToPkix(this.jwk);
}

@@ -39,3 +39,3 @@ return this._raw;

verify(data, sig) {
return hashAndVerify(this._key, sig, data);
return hashAndVerify(this.jwk, sig, data);
}

@@ -45,7 +45,7 @@ }

type = 'RSA';
_key;
jwk;
_raw;
publicKey;
constructor(key, publicKey) {
this._key = key;
constructor(jwk, publicKey) {
this.jwk = jwk;
this.publicKey = publicKey;

@@ -55,3 +55,3 @@ }

if (this._raw == null) {
this._raw = utils.jwkToPkcs1(this._key);
this._raw = utils.jwkToPkcs1(this.jwk);
}

@@ -67,5 +67,5 @@ return this._raw;

sign(message) {
return hashAndSign(this._key, message);
return hashAndSign(this.jwk, message);
}
}
//# sourceMappingURL=rsa.js.map

@@ -10,2 +10,6 @@ import type { JWKKeyPair } from '../interface.js';

/**
* Convert a PKCS#1 in ASN1 DER format to a JWK private key
*/
export declare function pkcs1MessageToJwk(message: any): JsonWebKey;
/**
* Convert a JWK private key into PKCS#1 in ASN1 DER format

@@ -18,2 +22,3 @@ */

export declare function pkixToJwk(bytes: Uint8Array): JsonWebKey;
export declare function pkixMessageToJwk(message: any): JsonWebKey;
/**

@@ -24,9 +29,14 @@ * Convert a JWK public key to PKIX in ASN1 DER format

/**
* Turn PKCS#1 DER bytes to a PrivateKey
* Turn PKCS#1 DER bytes into a PrivateKey
*/
export declare function pkcs1ToRSAPrivateKey(bytes: Uint8Array): RSAPrivateKey;
/**
* Turn PKIX bytes to a PublicKey
* Turn PKCS#1 DER bytes into a PrivateKey
*/
export declare function pkcs1MessageToRSAPrivateKey(message: any): RSAPrivateKey;
/**
* Turn a PKIX message into a PublicKey
*/
export declare function pkixToRSAPublicKey(bytes: Uint8Array, digest?: Digest<18, number>): RSAPublicKey;
export declare function pkixMessageToRSAPublicKey(message: any, bytes: Uint8Array, digest?: Digest<18, number>): RSAPublicKey;
export declare function jwkToRSAPrivateKey(jwk: JsonWebKey): RSAPrivateKey;

@@ -33,0 +43,0 @@ export declare function generateRSAKeyPair(bits: number): Promise<RSAPrivateKey>;

@@ -20,12 +20,18 @@ import { InvalidParametersError, InvalidPublicKeyError } from '@libp2p/interface';

export function pkcs1ToJwk(bytes) {
const values = decodeDer(bytes);
const message = decodeDer(bytes);
return pkcs1MessageToJwk(message);
}
/**
* Convert a PKCS#1 in ASN1 DER format to a JWK private key
*/
export function pkcs1MessageToJwk(message) {
return {
n: uint8ArrayToString(values[1], 'base64url'),
e: uint8ArrayToString(values[2], 'base64url'),
d: uint8ArrayToString(values[3], 'base64url'),
p: uint8ArrayToString(values[4], 'base64url'),
q: uint8ArrayToString(values[5], 'base64url'),
dp: uint8ArrayToString(values[6], 'base64url'),
dq: uint8ArrayToString(values[7], 'base64url'),
qi: uint8ArrayToString(values[8], 'base64url'),
n: uint8ArrayToString(message[1], 'base64url'),
e: uint8ArrayToString(message[2], 'base64url'),
d: uint8ArrayToString(message[3], 'base64url'),
p: uint8ArrayToString(message[4], 'base64url'),
q: uint8ArrayToString(message[5], 'base64url'),
dp: uint8ArrayToString(message[6], 'base64url'),
dq: uint8ArrayToString(message[7], 'base64url'),
qi: uint8ArrayToString(message[8], 'base64url'),
kty: 'RSA'

@@ -57,5 +63,11 @@ };

export function pkixToJwk(bytes) {
const decoded = decodeDer(bytes, {
const message = decodeDer(bytes, {
offset: 0
});
return pkixMessageToJwk(message);
}
export function pkixMessageToJwk(message) {
const keys = decodeDer(message[1], {
offset: 0
});
// this looks fragile but DER is a canonical format so we are safe to have

@@ -65,4 +77,4 @@ // deeply property chains like this

kty: 'RSA',
n: uint8ArrayToString(decoded[1][0], 'base64url'),
e: uint8ArrayToString(decoded[1][1], 'base64url')
n: uint8ArrayToString(keys[0], 'base64url'),
e: uint8ArrayToString(keys[1], 'base64url')
};

@@ -87,10 +99,17 @@ }

/**
* Turn PKCS#1 DER bytes to a PrivateKey
* Turn PKCS#1 DER bytes into a PrivateKey
*/
export function pkcs1ToRSAPrivateKey(bytes) {
const jwk = pkcs1ToJwk(bytes);
const message = decodeDer(bytes);
return pkcs1MessageToRSAPrivateKey(message);
}
/**
* Turn PKCS#1 DER bytes into a PrivateKey
*/
export function pkcs1MessageToRSAPrivateKey(message) {
const jwk = pkcs1MessageToJwk(message);
return jwkToRSAPrivateKey(jwk);
}
/**
* Turn PKIX bytes to a PublicKey
* Turn a PKIX message into a PublicKey
*/

@@ -101,3 +120,9 @@ export function pkixToRSAPublicKey(bytes, digest) {

}
const jwk = pkixToJwk(bytes);
const message = decodeDer(bytes, {
offset: 0
});
return pkixMessageToRSAPublicKey(message, bytes, digest);
}
export function pkixMessageToRSAPublicKey(message, bytes, digest) {
const jwk = pkixMessageToJwk(message);
if (digest == null) {

@@ -104,0 +129,0 @@ const hash = sha256(pb.PublicKey.encode({

import type { Uint8ArrayList } from 'uint8arraylist';
declare const PUBLIC_KEY_BYTE_LENGTH = 33;
declare const PRIVATE_KEY_BYTE_LENGTH = 32;
export { PUBLIC_KEY_BYTE_LENGTH as publicKeyLength };
export { PRIVATE_KEY_BYTE_LENGTH as privateKeyLength };
/**

@@ -3,0 +7,0 @@ * Hash and sign message with private key

@@ -5,2 +5,6 @@ import { secp256k1 as secp } from '@noble/curves/secp256k1';

import { isPromise } from '../../util.js';
const PUBLIC_KEY_BYTE_LENGTH = 33;
const PRIVATE_KEY_BYTE_LENGTH = 32;
export { PUBLIC_KEY_BYTE_LENGTH as publicKeyLength };
export { PRIVATE_KEY_BYTE_LENGTH as privateKeyLength };
/**

@@ -7,0 +11,0 @@ * Hash and sign message with private key

import type { Uint8ArrayList } from 'uint8arraylist';
declare const PUBLIC_KEY_BYTE_LENGTH = 33;
declare const PRIVATE_KEY_BYTE_LENGTH = 32;
export { PUBLIC_KEY_BYTE_LENGTH as publicKeyLength };
export { PRIVATE_KEY_BYTE_LENGTH as privateKeyLength };
/**

@@ -3,0 +7,0 @@ * Hash and sign message with private key

import crypto from 'node:crypto';
import { secp256k1 as secp } from '@noble/curves/secp256k1';
import { SigningError, VerificationError } from '../../errors.js';
const PUBLIC_KEY_BYTE_LENGTH = 33;
const PRIVATE_KEY_BYTE_LENGTH = 32;
export { PUBLIC_KEY_BYTE_LENGTH as publicKeyLength };
export { PRIVATE_KEY_BYTE_LENGTH as privateKeyLength };
/**

@@ -5,0 +9,0 @@ * Hash and sign message with private key

{
"name": "@libp2p/crypto",
"version": "5.0.15",
"version": "5.1.0-b9e32cc37",
"description": "Crypto primitives for libp2p",

@@ -95,3 +95,3 @@ "license": "Apache-2.0 OR MIT",

"dependencies": {
"@libp2p/interface": "^2.7.0",
"@libp2p/interface": "2.8.0-b9e32cc37",
"@noble/curves": "^1.7.0",

@@ -98,0 +98,0 @@ "@noble/hashes": "^1.6.1",

@@ -11,8 +11,16 @@ /**

import { UnsupportedKeyTypeError } from '@libp2p/interface'
import { InvalidParametersError, UnsupportedKeyTypeError } from '@libp2p/interface'
import { ECDSAPrivateKey as ECDSAPrivateKeyClass } from './ecdsa/ecdsa.js'
import { ECDSA_P_256_OID, ECDSA_P_384_OID, ECDSA_P_521_OID } from './ecdsa/index.js'
import { generateECDSAKeyPair, pkiMessageToECDSAPrivateKey, pkiMessageToECDSAPublicKey, unmarshalECDSAPrivateKey, unmarshalECDSAPublicKey } from './ecdsa/utils.js'
import { privateKeyLength as ed25519PrivateKeyLength, publicKeyLength as ed25519PublicKeyLength } from './ed25519/index.js'
import { generateEd25519KeyPair, generateEd25519KeyPairFromSeed, unmarshalEd25519PrivateKey, unmarshalEd25519PublicKey } from './ed25519/utils.js'
import * as pb from './keys.js'
import { pkcs1ToRSAPrivateKey, pkixToRSAPublicKey, generateRSAKeyPair } from './rsa/utils.js'
import { decodeDer } from './rsa/der.js'
import { RSAES_PKCS1_V1_5_OID } from './rsa/index.js'
import { pkcs1ToRSAPrivateKey, pkixToRSAPublicKey, generateRSAKeyPair, pkcs1MessageToRSAPrivateKey, pkixMessageToRSAPublicKey, jwkToRSAPrivateKey } from './rsa/utils.js'
import { privateKeyLength as secp256k1PrivateKeyLength, publicKeyLength as secp256k1PublicKeyLength } from './secp256k1/index.js'
import { generateSecp256k1KeyPair, unmarshalSecp256k1PrivateKey, unmarshalSecp256k1PublicKey } from './secp256k1/utils.js'
import type { PrivateKey, PublicKey, KeyType, RSAPrivateKey, Secp256k1PrivateKey, Ed25519PrivateKey, Secp256k1PublicKey, Ed25519PublicKey } from '@libp2p/interface'
import type { Curve } from './ecdsa/index.js'
import type { PrivateKey, PublicKey, KeyType, RSAPrivateKey, Secp256k1PrivateKey, Ed25519PrivateKey, Secp256k1PublicKey, Ed25519PublicKey, ECDSAPrivateKey, ECDSAPublicKey } from '@libp2p/interface'
import type { MultihashDigest } from 'multiformats'

@@ -31,5 +39,6 @@ import type { Digest } from 'multiformats/hashes/digest'

export async function generateKeyPair (type: 'secp256k1'): Promise<Secp256k1PrivateKey>
export async function generateKeyPair (type: 'ECDSA', curve?: Curve): Promise<ECDSAPrivateKey>
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> {
export async function generateKeyPair (type: KeyType, bits?: number | string): Promise<unknown> {
if (type === 'Ed25519') {

@@ -44,5 +53,9 @@ return generateEd25519KeyPair()

if (type === 'RSA') {
return generateRSAKeyPair(bits ?? 2048)
return generateRSAKeyPair(toBits(bits))
}
if (type === 'ECDSA') {
return generateECDSAKeyPair(toCurve(bits))
}
throw new UnsupportedKeyTypeError()

@@ -87,2 +100,4 @@ }

return unmarshalSecp256k1PublicKey(data)
case pb.KeyType.ECDSA:
return unmarshalECDSAPublicKey(data)
default:

@@ -97,9 +112,20 @@ throw new UnsupportedKeyTypeError()

export function publicKeyFromRaw (buf: Uint8Array): PublicKey {
if (buf.byteLength === 32) {
if (buf.byteLength === ed25519PublicKeyLength) {
return unmarshalEd25519PublicKey(buf)
} else if (buf.byteLength === 33) {
} else if (buf.byteLength === secp256k1PublicKeyLength) {
return unmarshalSecp256k1PublicKey(buf)
} else {
return pkixToRSAPublicKey(buf)
}
const message = decodeDer(buf)
const ecdsaOid = message[1]?.[0]
if (ecdsaOid === ECDSA_P_256_OID || ecdsaOid === ECDSA_P_384_OID || ecdsaOid === ECDSA_P_521_OID) {
return pkiMessageToECDSAPublicKey(message)
}
if (message[0]?.[0] === RSAES_PKCS1_V1_5_OID) {
return pkixMessageToRSAPublicKey(message, buf)
}
throw new InvalidParametersError('Could not extract public key from raw bytes')
}

@@ -114,3 +140,3 @@

*/
export function publicKeyFromMultihash (digest: MultihashDigest<0x0>): Ed25519PublicKey | Secp256k1PublicKey {
export function publicKeyFromMultihash (digest: MultihashDigest<0x0>): Ed25519PublicKey | Secp256k1PublicKey | ECDSAPublicKey {
const { Type, Data } = pb.PublicKey.decode(digest.digest)

@@ -124,2 +150,4 @@ const data = Data ?? new Uint8Array()

return unmarshalSecp256k1PublicKey(data)
case pb.KeyType.ECDSA:
return unmarshalECDSAPublicKey(data)
default:

@@ -143,3 +171,3 @@ throw new UnsupportedKeyTypeError()

*/
export function privateKeyFromProtobuf (buf: Uint8Array): Ed25519PrivateKey | Secp256k1PrivateKey | RSAPrivateKey {
export function privateKeyFromProtobuf (buf: Uint8Array): Ed25519PrivateKey | Secp256k1PrivateKey | RSAPrivateKey | ECDSAPrivateKey {
const decoded = pb.PrivateKey.decode(buf)

@@ -155,2 +183,4 @@ const data = decoded.Data ?? new Uint8Array()

return unmarshalSecp256k1PrivateKey(data)
case pb.KeyType.ECDSA:
return unmarshalECDSAPrivateKey(data)
default:

@@ -167,9 +197,20 @@ throw new UnsupportedKeyTypeError()

export function privateKeyFromRaw (buf: Uint8Array): PrivateKey {
if (buf.byteLength === 64) {
if (buf.byteLength === ed25519PrivateKeyLength) {
return unmarshalEd25519PrivateKey(buf)
} else if (buf.byteLength === 32) {
} else if (buf.byteLength === secp256k1PrivateKeyLength) {
return unmarshalSecp256k1PrivateKey(buf)
} else {
return pkcs1ToRSAPrivateKey(buf)
}
const message = decodeDer(buf)
const ecdsaOid = message[2]?.[0]
if (ecdsaOid === ECDSA_P_256_OID || ecdsaOid === ECDSA_P_384_OID || ecdsaOid === ECDSA_P_521_OID) {
return pkiMessageToECDSAPrivateKey(message)
}
if (message.length > 8) {
return pkcs1MessageToRSAPrivateKey(message)
}
throw new InvalidParametersError('Could not extract private key from raw bytes')
}

@@ -186,1 +227,77 @@

}
function toBits (bits: any): number {
if (bits == null) {
return 2048
}
return parseInt(bits, 10)
}
function toCurve (curve: any): Curve {
if (curve === 'P-256' || curve == null) {
return 'P-256'
}
if (curve === 'P-384') {
return 'P-384'
}
if (curve === 'P-521') {
return 'P-521'
}
throw new InvalidParametersError('Unsupported curve, should be P-256, P-384 or P-521')
}
/**
* Convert a libp2p RSA or ECDSA private key to a WebCrypto CryptoKeyPair
*/
export async function privateKeyToCryptoKeyPair (privateKey: PrivateKey): Promise<CryptoKeyPair> {
if (privateKey.type === 'RSA') {
return {
privateKey: await crypto.subtle.importKey('jwk', privateKey.jwk, {
name: 'RSASSA-PKCS1-v1_5',
hash: { name: 'SHA-256' }
}, true, ['sign']),
publicKey: await crypto.subtle.importKey('jwk', privateKey.publicKey.jwk, {
name: 'RSASSA-PKCS1-v1_5',
hash: { name: 'SHA-256' }
}, true, ['verify'])
}
}
if (privateKey.type === 'ECDSA') {
return {
privateKey: await crypto.subtle.importKey('jwk', privateKey.jwk, {
name: 'ECDSA',
namedCurve: privateKey.jwk.crv ?? 'P-256'
}, true, ['sign']),
publicKey: await crypto.subtle.importKey('jwk', privateKey.publicKey.jwk, {
name: 'ECDSA',
namedCurve: privateKey.publicKey.jwk.crv ?? 'P-256'
}, true, ['verify'])
}
}
throw new InvalidParametersError('Only RSA and ECDSA keys are supported')
}
/**
* Convert a RSA or ECDSA WebCrypto CryptoKeyPair to a libp2p private key
*/
export async function privateKeyFromCryptoKeyPair (keyPair: CryptoKeyPair): Promise<PrivateKey> {
if (keyPair.privateKey.algorithm.name === 'RSASSA-PKCS1-v1_5') {
const jwk = await crypto.subtle.exportKey('jwk', keyPair.privateKey)
return jwkToRSAPrivateKey(jwk)
}
if (keyPair.privateKey.algorithm.name === 'ECDSA') {
const jwk = await crypto.subtle.exportKey('jwk', keyPair.privateKey)
return new ECDSAPrivateKeyClass(jwk)
}
throw new InvalidParametersError('Only RSA and ECDSA keys are supported')
}

@@ -13,3 +13,4 @@ /* eslint-disable import/export */

Ed25519 = 'Ed25519',
secp256k1 = 'secp256k1'
secp256k1 = 'secp256k1',
ECDSA = 'ECDSA'
}

@@ -20,3 +21,4 @@

Ed25519 = 1,
secp256k1 = 2
secp256k1 = 2,
ECDSA = 3
}

@@ -23,0 +25,0 @@

@@ -16,4 +16,7 @@ import { Uint8ArrayList } from 'uint8arraylist'

const decoders: Record<number, Decoder> = {
0x0: readSequence,
0x1: readSequence,
0x2: readInteger,
0x3: readBitString,
0x4: readOctetString,
0x5: readNull,

@@ -100,9 +103,49 @@ 0x6: readObjectIdentifier,

function readObjectIdentifier (buf: Uint8Array, context: Context): string[] {
function readObjectIdentifier (buf: Uint8Array, context: Context): string {
const count = readLength(buf, context)
const finalOffset = context.offset + count
// skip OID
context.offset += count
const byte = buf[context.offset]
context.offset++
return ['oid-unimplemented']
let val1 = 0
let val2 = 0
if (byte < 40) {
val1 = 0
val2 = byte
} else if (byte < 80) {
val1 = 1
val2 = byte - 40
} else {
val1 = 2
val2 = byte - 80
}
let oid = `${val1}.${val2}`
let num: number[] = []
while (context.offset < finalOffset) {
const byte = buf[context.offset]
context.offset++
// remove msb
num.push(byte & 0b01111111)
if (byte < 128) {
num.reverse()
// reached the end of the encoding
let val = 0
for (let i = 0; i < num.length; i++) {
val += num[i] << (i * 7)
}
oid += `.${val}`
num = []
}
}
return oid
}

@@ -120,3 +163,3 @@

context.offset++
const bytes = buf.subarray(context.offset, context.offset + length)
const bytes = buf.subarray(context.offset, context.offset + length - 1)
context.offset += length

@@ -129,7 +172,13 @@

return decodeDer(bytes, {
offset: 0
})
return bytes
}
function readOctetString (buf: Uint8Array, context: Context): any {
const length = readLength(buf, context)
const bytes = buf.subarray(context.offset, context.offset + length)
context.offset += length
return bytes
}
function encodeNumber (value: number): Uint8ArrayList {

@@ -170,3 +219,3 @@ let number = value.toString(16)

const mask = parseInt('10000000', 2)
const mask = 0b10000000
const positive = (value.subarray()[0] & mask) === mask

@@ -203,3 +252,11 @@

export function encodeSequence (values: Array<Uint8Array | Uint8ArrayList>): Uint8ArrayList {
export function encodeOctetString (value: Uint8Array | Uint8ArrayList): Uint8ArrayList {
return new Uint8ArrayList(
Uint8Array.from([0x04]),
encodeLength(value),
value
)
}
export function encodeSequence (values: Array<Uint8Array | Uint8ArrayList>, tag = 0x30): Uint8ArrayList {
const output = new Uint8ArrayList()

@@ -214,3 +271,3 @@

return new Uint8ArrayList(
Uint8Array.from([0x30]),
Uint8Array.from([tag]),
encodeLength(output),

@@ -217,0 +274,0 @@ output

@@ -9,2 +9,3 @@ import { InvalidParametersError } from '@libp2p/interface'

export const RSAES_PKCS1_V1_5_OID = '1.2.840.113549.1.1.1'
export { utils }

@@ -11,0 +12,0 @@

@@ -12,2 +12,4 @@ import crypto from 'crypto'

export const RSAES_PKCS1_V1_5_OID = '1.2.840.113549.1.1.1'
export { utils }

@@ -14,0 +16,0 @@

@@ -11,8 +11,8 @@ import { base58btc } from 'multiformats/bases/base58'

public readonly type = 'RSA'
private readonly _key: JsonWebKey
public readonly jwk: JsonWebKey
private _raw?: Uint8Array
private readonly _multihash: Digest<18, number>
constructor (key: JsonWebKey, digest: Digest<18, number>) {
this._key = key
constructor (jwk: JsonWebKey, digest: Digest<18, number>) {
this.jwk = jwk
this._multihash = digest

@@ -23,3 +23,3 @@ }

if (this._raw == null) {
this._raw = utils.jwkToPkix(this._key)
this._raw = utils.jwkToPkix(this.jwk)
}

@@ -51,3 +51,3 @@

verify (data: Uint8Array | Uint8ArrayList, sig: Uint8Array): boolean | Promise<boolean> {
return hashAndVerify(this._key, sig, data)
return hashAndVerify(this.jwk, sig, data)
}

@@ -58,8 +58,8 @@ }

public readonly type = 'RSA'
private readonly _key: JsonWebKey
public readonly jwk: JsonWebKey
private _raw?: Uint8Array
public readonly publicKey: RSAPublicKey
constructor (key: JsonWebKey, publicKey: RSAPublicKey) {
this._key = key
constructor (jwk: JsonWebKey, publicKey: RSAPublicKey) {
this.jwk = jwk
this.publicKey = publicKey

@@ -70,3 +70,3 @@ }

if (this._raw == null) {
this._raw = utils.jwkToPkcs1(this._key)
this._raw = utils.jwkToPkcs1(this.jwk)
}

@@ -86,4 +86,4 @@

sign (message: Uint8Array | Uint8ArrayList): Uint8Array | Promise<Uint8Array> {
return hashAndSign(this._key, message)
return hashAndSign(this.jwk, message)
}
}

@@ -26,13 +26,20 @@ import { InvalidParametersError, InvalidPublicKeyError } from '@libp2p/interface'

export function pkcs1ToJwk (bytes: Uint8Array): JsonWebKey {
const values = decodeDer(bytes)
const message = decodeDer(bytes)
return pkcs1MessageToJwk(message)
}
/**
* Convert a PKCS#1 in ASN1 DER format to a JWK private key
*/
export function pkcs1MessageToJwk (message: any): JsonWebKey {
return {
n: uint8ArrayToString(values[1], 'base64url'),
e: uint8ArrayToString(values[2], 'base64url'),
d: uint8ArrayToString(values[3], 'base64url'),
p: uint8ArrayToString(values[4], 'base64url'),
q: uint8ArrayToString(values[5], 'base64url'),
dp: uint8ArrayToString(values[6], 'base64url'),
dq: uint8ArrayToString(values[7], 'base64url'),
qi: uint8ArrayToString(values[8], 'base64url'),
n: uint8ArrayToString(message[1], 'base64url'),
e: uint8ArrayToString(message[2], 'base64url'),
d: uint8ArrayToString(message[3], 'base64url'),
p: uint8ArrayToString(message[4], 'base64url'),
q: uint8ArrayToString(message[5], 'base64url'),
dp: uint8ArrayToString(message[6], 'base64url'),
dq: uint8ArrayToString(message[7], 'base64url'),
qi: uint8ArrayToString(message[8], 'base64url'),
kty: 'RSA'

@@ -67,6 +74,14 @@ }

export function pkixToJwk (bytes: Uint8Array): JsonWebKey {
const decoded = decodeDer(bytes, {
const message = decodeDer(bytes, {
offset: 0
})
return pkixMessageToJwk(message)
}
export function pkixMessageToJwk (message: any): JsonWebKey {
const keys = decodeDer(message[1], {
offset: 0
})
// this looks fragile but DER is a canonical format so we are safe to have

@@ -77,7 +92,7 @@ // deeply property chains like this

n: uint8ArrayToString(
decoded[1][0],
keys[0],
'base64url'
),
e: uint8ArrayToString(
decoded[1][1],
keys[1],
'base64url'

@@ -110,7 +125,16 @@ )

/**
* Turn PKCS#1 DER bytes to a PrivateKey
* Turn PKCS#1 DER bytes into a PrivateKey
*/
export function pkcs1ToRSAPrivateKey (bytes: Uint8Array): RSAPrivateKey {
const jwk = pkcs1ToJwk(bytes)
const message = decodeDer(bytes)
return pkcs1MessageToRSAPrivateKey(message)
}
/**
* Turn PKCS#1 DER bytes into a PrivateKey
*/
export function pkcs1MessageToRSAPrivateKey (message: any): RSAPrivateKey {
const jwk = pkcs1MessageToJwk(message)
return jwkToRSAPrivateKey(jwk)

@@ -120,3 +144,3 @@ }

/**
* Turn PKIX bytes to a PublicKey
* Turn a PKIX message into a PublicKey
*/

@@ -128,4 +152,12 @@ export function pkixToRSAPublicKey (bytes: Uint8Array, digest?: Digest<18, number>): RSAPublicKey {

const jwk = pkixToJwk(bytes)
const message = decodeDer(bytes, {
offset: 0
})
return pkixMessageToRSAPublicKey(message, bytes, digest)
}
export function pkixMessageToRSAPublicKey (message: any, bytes: Uint8Array, digest?: Digest<18, number>): RSAPublicKey {
const jwk = pkixMessageToJwk(message)
if (digest == null) {

@@ -132,0 +164,0 @@ const hash = sha256(pb.PublicKey.encode({

@@ -7,2 +7,8 @@ import { secp256k1 as secp } from '@noble/curves/secp256k1'

const PUBLIC_KEY_BYTE_LENGTH = 33
const PRIVATE_KEY_BYTE_LENGTH = 32
export { PUBLIC_KEY_BYTE_LENGTH as publicKeyLength }
export { PRIVATE_KEY_BYTE_LENGTH as privateKeyLength }
/**

@@ -9,0 +15,0 @@ * Hash and sign message with private key

@@ -6,2 +6,8 @@ import crypto from 'node:crypto'

const PUBLIC_KEY_BYTE_LENGTH = 33
const PRIVATE_KEY_BYTE_LENGTH = 32
export { PUBLIC_KEY_BYTE_LENGTH as publicKeyLength }
export { PRIVATE_KEY_BYTE_LENGTH as privateKeyLength }
/**

@@ -8,0 +14,0 @@ * Hash and sign message with private key

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

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