mirror of
https://github.com/fluencelabs/js-libp2p-crypto
synced 2025-03-15 09:41:03 +00:00
feat: add typescript types + linting/tests (#161)
* feat: adds typescript types + linting/tests Signed-off-by: Carson Farmer <carson.farmer@gmail.com> * feat: much better types testing Signed-off-by: Carson Farmer <carson.farmer@gmail.com> * chore: revert eslintignore Signed-off-by: Carson Farmer <carson.farmer@gmail.com> * feat: update types entry Signed-off-by: Carson Farmer <carson.farmer@gmail.com> * chore: exclude has no effect here Signed-off-by: Carson Farmer <carson.farmer@gmail.com> * feat: more nuanced return types on keypair Signed-off-by: Carson Farmer <carson.farmer@gmail.com>
This commit is contained in:
parent
b5d94ecae7
commit
e01977c5a3
10
package.json
10
package.json
@ -3,6 +3,7 @@
|
|||||||
"version": "0.17.1",
|
"version": "0.17.1",
|
||||||
"description": "Crypto primitives for libp2p",
|
"description": "Crypto primitives for libp2p",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
|
"types": "src/index.d.ts",
|
||||||
"leadMaintainer": "Jacob Heun <jacobheun@gmail.com>",
|
"leadMaintainer": "Jacob Heun <jacobheun@gmail.com>",
|
||||||
"browser": {
|
"browser": {
|
||||||
"./src/hmac/index.js": "./src/hmac/index-browser.js",
|
"./src/hmac/index.js": "./src/hmac/index-browser.js",
|
||||||
@ -25,7 +26,8 @@
|
|||||||
"release-minor": "aegir release --type minor",
|
"release-minor": "aegir release --type minor",
|
||||||
"release-major": "aegir release --type major",
|
"release-major": "aegir release --type major",
|
||||||
"coverage": "aegir coverage --ignore src/keys/keys.proto.js",
|
"coverage": "aegir coverage --ignore src/keys/keys.proto.js",
|
||||||
"size": "aegir build --bundlesize"
|
"size": "aegir build --bundlesize",
|
||||||
|
"test:types": "npx tsc"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"IPFS",
|
"IPFS",
|
||||||
@ -53,6 +55,12 @@
|
|||||||
"ursa-optional": "~0.10.1"
|
"ursa-optional": "~0.10.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/bn.js": "^4.11.6",
|
||||||
|
"@types/chai": "^4.2.7",
|
||||||
|
"@types/chai-string": "^1.4.2",
|
||||||
|
"@types/dirty-chai": "^2.0.2",
|
||||||
|
"@types/mocha": "^5.2.7",
|
||||||
|
"@types/sinon": "^7.5.1",
|
||||||
"aegir": "^20.4.1",
|
"aegir": "^20.4.1",
|
||||||
"benchmark": "^2.1.4",
|
"benchmark": "^2.1.4",
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
|
345
src/index.d.ts
vendored
Normal file
345
src/index.d.ts
vendored
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
/// <reference types="node" />
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supported key types.
|
||||||
|
*/
|
||||||
|
export type KeyType = "Ed25519" | "RSA" | "secp256k1";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps an IPFS hash name to its node-forge equivalent.
|
||||||
|
* See https://github.com/multiformats/multihash/blob/master/hashtable.csv
|
||||||
|
*/
|
||||||
|
export type HashType = "SHA1" | "SHA256" | "SHA512";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supported curve types.
|
||||||
|
*/
|
||||||
|
export type CurveType = "P-256" | "P-384" | "P-521";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supported cipher types.
|
||||||
|
*/
|
||||||
|
export type CipherType = "AES-128" | "AES-256" | "Blowfish";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exposes an interface to AES encryption (formerly Rijndael),
|
||||||
|
* as defined in U.S. Federal Information Processing Standards Publication 197.
|
||||||
|
* This uses CTR mode.
|
||||||
|
*/
|
||||||
|
export namespace aes {
|
||||||
|
/**
|
||||||
|
* AES Cipher in CTR mode.
|
||||||
|
*/
|
||||||
|
interface Cipher {
|
||||||
|
encrypt(data: Buffer): Promise<Buffer>;
|
||||||
|
decrypt(data: Buffer): Promise<Buffer>;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Create a new AES Cipher.
|
||||||
|
* @param key The key, if length 16 then AES 128 is used. For length 32, AES 256 is used.
|
||||||
|
* @param iv Must have length 16.
|
||||||
|
*/
|
||||||
|
function create(key: Buffer, iv: Buffer): Promise<Cipher>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exposes an interface to the Keyed-Hash Message Authentication Code (HMAC)
|
||||||
|
* as defined in U.S. Federal Information Processing Standards Publication 198.
|
||||||
|
* An HMAC is a cryptographic hash that uses a key to sign a message.
|
||||||
|
* The receiver verifies the hash by recomputing it using the same key.
|
||||||
|
*/
|
||||||
|
export namespace hmac {
|
||||||
|
/**
|
||||||
|
* HMAC Digest.
|
||||||
|
*/
|
||||||
|
interface Digest {
|
||||||
|
digest(data: Buffer): Promise<Buffer>;
|
||||||
|
length: 20 | 32 | 64 | number;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Create a new HMAC Digest.
|
||||||
|
*/
|
||||||
|
function create(
|
||||||
|
hash: "SHA1" | "SHA256" | "SHA512" | string,
|
||||||
|
secret: Buffer
|
||||||
|
): Promise<Digest>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic public key interface.
|
||||||
|
*/
|
||||||
|
export interface PublicKey {
|
||||||
|
readonly bytes: Buffer;
|
||||||
|
verify(data: Buffer, sig: Buffer): Promise<boolean>;
|
||||||
|
marshal(): Buffer;
|
||||||
|
equals(key: PublicKey): boolean;
|
||||||
|
hash(): Promise<Buffer>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic private key interface.
|
||||||
|
*/
|
||||||
|
export interface PrivateKey {
|
||||||
|
readonly public: PublicKey;
|
||||||
|
readonly bytes: Buffer;
|
||||||
|
sign(data: Buffer): Promise<Buffer>;
|
||||||
|
marshal(): Buffer;
|
||||||
|
equals(key: PrivateKey): boolean;
|
||||||
|
hash(): Promise<Buffer>;
|
||||||
|
/**
|
||||||
|
* Gets the ID of the key.
|
||||||
|
*
|
||||||
|
* The key id is the base58 encoding of the SHA-256 multihash of its public key.
|
||||||
|
* The public key is a protobuf encoding containing a type and the DER encoding
|
||||||
|
* of the PKCS SubjectPublicKeyInfo.
|
||||||
|
*/
|
||||||
|
id(): Promise<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Keystretcher {
|
||||||
|
(res: Buffer): Keystretcher;
|
||||||
|
iv: Buffer;
|
||||||
|
cipherKey: Buffer;
|
||||||
|
macKey: Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StretchPair {
|
||||||
|
k1: Keystretcher;
|
||||||
|
k2: Keystretcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exposes an interface to various cryptographic key generation routines.
|
||||||
|
* Currently the 'RSA' and 'ed25519' types are supported, although ed25519 keys
|
||||||
|
* support only signing and verification of messages. For encryption / decryption
|
||||||
|
* support, RSA keys should be used.
|
||||||
|
* Installing the libp2p-crypto-secp256k1 module adds support for the 'secp256k1'
|
||||||
|
* type, which supports ECDSA signatures using the secp256k1 elliptic curve
|
||||||
|
* popularized by Bitcoin. This module is not installed by default, and should be
|
||||||
|
* explicitly depended on if your project requires secp256k1 support.
|
||||||
|
*/
|
||||||
|
export namespace keys {
|
||||||
|
export {};
|
||||||
|
export namespace supportedKeys {
|
||||||
|
namespace rsa {
|
||||||
|
class RsaPublicKey implements PublicKey {
|
||||||
|
constructor(key: Buffer);
|
||||||
|
readonly bytes: Buffer;
|
||||||
|
verify(data: Buffer, sig: Buffer): Promise<boolean>;
|
||||||
|
marshal(): Buffer;
|
||||||
|
encrypt(bytes: Buffer): Buffer;
|
||||||
|
equals(key: PublicKey): boolean;
|
||||||
|
hash(): Promise<Buffer>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type alias for export method
|
||||||
|
export type KeyInfo = any;
|
||||||
|
|
||||||
|
class RsaPrivateKey implements PrivateKey {
|
||||||
|
constructor(key: any, publicKey: Buffer);
|
||||||
|
readonly public: RsaPublicKey;
|
||||||
|
readonly bytes: Buffer;
|
||||||
|
genSecret(): Buffer;
|
||||||
|
sign(data: Buffer): Promise<Buffer>;
|
||||||
|
decrypt(bytes: Buffer): Buffer;
|
||||||
|
marshal(): Buffer;
|
||||||
|
equals(key: PrivateKey): boolean;
|
||||||
|
hash(): Promise<Buffer>;
|
||||||
|
id(): Promise<string>;
|
||||||
|
/**
|
||||||
|
* Exports the key into a password protected PEM format
|
||||||
|
*
|
||||||
|
* @param password The password to read the encrypted PEM
|
||||||
|
* @param format Defaults to 'pkcs-8'.
|
||||||
|
*/
|
||||||
|
export(password: string, format?: "pkcs-8" | string): KeyInfo;
|
||||||
|
}
|
||||||
|
function unmarshalRsaPublicKey(buf: Buffer): RsaPublicKey;
|
||||||
|
function unmarshalRsaPrivateKey(buf: Buffer): Promise<RsaPrivateKey>;
|
||||||
|
function generateKeyPair(bits: number): Promise<RsaPrivateKey>;
|
||||||
|
function fromJwk(jwk: Buffer): Promise<RsaPrivateKey>;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace ed25519 {
|
||||||
|
class Ed25519PublicKey implements PublicKey {
|
||||||
|
constructor(key: Buffer);
|
||||||
|
readonly bytes: Buffer;
|
||||||
|
verify(data: Buffer, sig: Buffer): Promise<boolean>;
|
||||||
|
marshal(): Buffer;
|
||||||
|
encrypt(bytes: Buffer): Buffer;
|
||||||
|
equals(key: PublicKey): boolean;
|
||||||
|
hash(): Promise<Buffer>;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Ed25519PrivateKey implements PrivateKey {
|
||||||
|
constructor(key: Buffer, publicKey: Buffer);
|
||||||
|
readonly public: Ed25519PublicKey;
|
||||||
|
readonly bytes: Buffer;
|
||||||
|
sign(data: Buffer): Promise<Buffer>;
|
||||||
|
marshal(): Buffer;
|
||||||
|
equals(key: PrivateKey): boolean;
|
||||||
|
hash(): Promise<Buffer>;
|
||||||
|
id(): Promise<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
function unmarshalEd25519PrivateKey(
|
||||||
|
buf: Buffer
|
||||||
|
): Promise<Ed25519PrivateKey>;
|
||||||
|
function unmarshalEd25519PublicKey(buf: Buffer): Ed25519PublicKey;
|
||||||
|
function generateKeyPair(): Promise<Ed25519PrivateKey>;
|
||||||
|
function generateKeyPairFromSeed(
|
||||||
|
seed: Buffer
|
||||||
|
): Promise<Ed25519PrivateKey>;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace secp256k1 {
|
||||||
|
class Secp256k1PublicKey implements PublicKey {
|
||||||
|
constructor(key: Buffer);
|
||||||
|
readonly bytes: Buffer;
|
||||||
|
verify(data: Buffer, sig: Buffer): Promise<boolean>;
|
||||||
|
marshal(): Buffer;
|
||||||
|
encrypt(bytes: Buffer): Buffer;
|
||||||
|
equals(key: PublicKey): boolean;
|
||||||
|
hash(): Promise<Buffer>;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Secp256k1PrivateKey implements PrivateKey {
|
||||||
|
constructor(key: Uint8Array | Buffer, publicKey: Uint8Array | Buffer);
|
||||||
|
readonly public: Secp256k1PublicKey;
|
||||||
|
readonly bytes: Buffer;
|
||||||
|
sign(data: Buffer): Promise<Buffer>;
|
||||||
|
marshal(): Buffer;
|
||||||
|
equals(key: PrivateKey): boolean;
|
||||||
|
hash(): Promise<Buffer>;
|
||||||
|
id(): Promise<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
function unmarshalSecp256k1PrivateKey(
|
||||||
|
bytes: Buffer
|
||||||
|
): Promise<Secp256k1PrivateKey>;
|
||||||
|
function unmarshalSecp256k1PublicKey(bytes: Buffer): Secp256k1PublicKey;
|
||||||
|
function generateKeyPair(): Promise<Secp256k1PrivateKey>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const keysPBM: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a keypair of the given type and bitsize.
|
||||||
|
* @param type One of the supported key types.
|
||||||
|
* @param bits Number of bits. Minimum of 1024.
|
||||||
|
*/
|
||||||
|
export function generateKeyPair(
|
||||||
|
type: KeyType | string,
|
||||||
|
bits: number
|
||||||
|
): Promise<PrivateKey>;
|
||||||
|
export function generateKeyPair(
|
||||||
|
type: "Ed25519",
|
||||||
|
bits: number
|
||||||
|
): Promise<keys.supportedKeys.ed25519.Ed25519PrivateKey>;
|
||||||
|
export function generateKeyPair(
|
||||||
|
type: "RSA",
|
||||||
|
bits: number
|
||||||
|
): Promise<keys.supportedKeys.rsa.RsaPrivateKey>;
|
||||||
|
export function generateKeyPair(
|
||||||
|
type: "secp256k1",
|
||||||
|
bits: number
|
||||||
|
): Promise<keys.supportedKeys.secp256k1.Secp256k1PrivateKey>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a keypair of the given type and bitsize.
|
||||||
|
* @param type One of the supported key types. Currently only 'Ed25519' is supported.
|
||||||
|
* @param seed A 32 byte uint8array.
|
||||||
|
* @param bits Number of bits. Minimum of 1024.
|
||||||
|
*/
|
||||||
|
export function generateKeyPairFromSeed(
|
||||||
|
type: KeyType | string,
|
||||||
|
seed: Uint8Array,
|
||||||
|
bits: number
|
||||||
|
): Promise<PrivateKey>;
|
||||||
|
export function generateKeyPairFromSeed(
|
||||||
|
type: "Ed25519",
|
||||||
|
seed: Uint8Array,
|
||||||
|
bits: number
|
||||||
|
): Promise<keys.supportedKeys.ed25519.Ed25519PrivateKey>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates an ephemeral public key and returns a function that will compute the shared secret key.
|
||||||
|
* Focuses only on ECDH now, but can be made more general in the future.
|
||||||
|
* @param curve The curve to use. One of 'P-256', 'P-384', 'P-521' is currently supported.
|
||||||
|
*/
|
||||||
|
export function generateEphemeralKeyPair(
|
||||||
|
curve: CurveType | string
|
||||||
|
): Promise<{
|
||||||
|
key: Buffer;
|
||||||
|
genSharedKey: (theirPub: Buffer, forcePrivate?: any) => Promise<Buffer>;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a set of keys for each party by stretching the shared key.
|
||||||
|
* @param cipherType The cipher type to use. One of 'AES-128', 'AES-256', or 'Blowfish'
|
||||||
|
* @param hashType The hash type to use. One of 'SHA1', 'SHA2256', or 'SHA2512'.
|
||||||
|
* @param secret The shared key secret.
|
||||||
|
*/
|
||||||
|
export function keyStretcher(
|
||||||
|
cipherType: CipherType | string,
|
||||||
|
hashType: HashType | string,
|
||||||
|
secret: Buffer | string
|
||||||
|
): Promise<StretchPair>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a protobuf serialized public key into its representative object.
|
||||||
|
* @param buf The protobuf serialized public key.
|
||||||
|
*/
|
||||||
|
export function unmarshalPublicKey(buf: Buffer): PublicKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a public key object into a protobuf serialized public key.
|
||||||
|
* @param key An RSA, Ed25519, or Secp256k1 public key object.
|
||||||
|
* @param type One of the supported key types.
|
||||||
|
*/
|
||||||
|
export function marshalPublicKey(key: PublicKey, type?: KeyType | string): Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a protobuf serialized private key into its representative object.
|
||||||
|
* @param buf The protobuf serialized private key.
|
||||||
|
*/
|
||||||
|
export function unmarshalPrivateKey(buf: Buffer): Promise<PrivateKey>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a private key object into a protobuf serialized private key.
|
||||||
|
* @param key An RSA, Ed25519, or Secp256k1 private key object.
|
||||||
|
* @param type One of the supported key types.
|
||||||
|
*/
|
||||||
|
export function marshalPrivateKey(key: PrivateKey, type?: KeyType | string): Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a PEM password protected private key into its representative object.
|
||||||
|
* @param pem Password protected private key in PEM format.
|
||||||
|
* @param password The password used to protect the key.
|
||||||
|
*/
|
||||||
|
function _import(pem: string, password: string): Promise<supportedKeys.rsa.RsaPrivateKey>;
|
||||||
|
export { _import as import };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a Buffer populated by random bytes.
|
||||||
|
* @param The size of the random bytes Buffer.
|
||||||
|
*/
|
||||||
|
export function randomBytes(number: number): Buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the Password-Based Key Derivation Function 2.
|
||||||
|
* @param password The password.
|
||||||
|
* @param salt The salt.
|
||||||
|
* @param iterations Number of iterations to use.
|
||||||
|
* @param keySize The size of the output key in bytes.
|
||||||
|
* @param hash The hash name ('sha1', 'sha2-512, ...)
|
||||||
|
*/
|
||||||
|
export function pbkdf2(
|
||||||
|
password: string | Buffer,
|
||||||
|
salt: string | Buffer,
|
||||||
|
iterations: number,
|
||||||
|
keySize: number,
|
||||||
|
hash: string
|
||||||
|
): Buffer;
|
@ -110,7 +110,6 @@ class RsaPrivateKey {
|
|||||||
*
|
*
|
||||||
* @param {string} password - The password to read the encrypted PEM
|
* @param {string} password - The password to read the encrypted PEM
|
||||||
* @param {string} [format] - Defaults to 'pkcs-8'.
|
* @param {string} [format] - Defaults to 'pkcs-8'.
|
||||||
* @returns {KeyInfo}
|
|
||||||
*/
|
*/
|
||||||
async export (password, format = 'pkcs-8') { // eslint-disable-line require-await
|
async export (password, format = 'pkcs-8') { // eslint-disable-line require-await
|
||||||
let pem = null
|
let pem = null
|
||||||
|
@ -3,7 +3,10 @@
|
|||||||
const crypto = require('crypto')
|
const crypto = require('crypto')
|
||||||
const errcode = require('err-code')
|
const errcode = require('err-code')
|
||||||
const randomBytes = require('../random-bytes')
|
const randomBytes = require('../random-bytes')
|
||||||
|
// @ts-check
|
||||||
|
/**
|
||||||
|
* @type {PrivateKey}
|
||||||
|
*/
|
||||||
let keypair
|
let keypair
|
||||||
try {
|
try {
|
||||||
if (process.env.LP2P_FORCE_CRYPTO_LIB === 'keypair') {
|
if (process.env.LP2P_FORCE_CRYPTO_LIB === 'keypair') {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/* eslint max-nested-callbacks: ["error", 8] */
|
/* eslint max-nested-callbacks: ["error", 8] */
|
||||||
|
/* eslint-disable valid-jsdoc */
|
||||||
/* eslint-env mocha */
|
/* eslint-env mocha */
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
@ -17,6 +18,8 @@ const bytes = {
|
|||||||
32: 'AES-256'
|
32: 'AES-256'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @typedef {import("libp2p-crypto").aes.Cipher} Cipher */
|
||||||
|
|
||||||
describe('AES-CTR', () => {
|
describe('AES-CTR', () => {
|
||||||
Object.keys(bytes).forEach((byte) => {
|
Object.keys(bytes).forEach((byte) => {
|
||||||
it(`${bytes[byte]} - encrypt and decrypt`, async () => {
|
it(`${bytes[byte]} - encrypt and decrypt`, async () => {
|
||||||
@ -93,6 +96,10 @@ describe('AES-CTR', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// @ts-check
|
||||||
|
/**
|
||||||
|
* @type {function(Cipher): void}
|
||||||
|
*/
|
||||||
async function encryptAndDecrypt (cipher) {
|
async function encryptAndDecrypt (cipher) {
|
||||||
const data = Buffer.alloc(100)
|
const data = Buffer.alloc(100)
|
||||||
data.fill(Math.ceil(Math.random() * 100))
|
data.fill(Math.ceil(Math.random() * 100))
|
||||||
|
@ -10,8 +10,14 @@ const crypto = require('../src')
|
|||||||
const fixtures = require('./fixtures/go-key-rsa')
|
const fixtures = require('./fixtures/go-key-rsa')
|
||||||
const { expectErrCode } = require('./util')
|
const { expectErrCode } = require('./util')
|
||||||
|
|
||||||
|
/** @typedef {import("libp2p-crypto").PrivateKey} PrivateKey */
|
||||||
|
|
||||||
describe('libp2p-crypto', function () {
|
describe('libp2p-crypto', function () {
|
||||||
this.timeout(20 * 1000)
|
this.timeout(20 * 1000)
|
||||||
|
// @ts-check
|
||||||
|
/**
|
||||||
|
* @type {PrivateKey}
|
||||||
|
*/
|
||||||
let key
|
let key
|
||||||
before(async () => {
|
before(async () => {
|
||||||
key = await crypto.keys.generateKeyPair('RSA', 512)
|
key = await crypto.keys.generateKeyPair('RSA', 512)
|
||||||
@ -109,9 +115,9 @@ describe('libp2p-crypto', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('randomBytes', () => {
|
describe('randomBytes', () => {
|
||||||
it('throws with no number passed', () => {
|
it('throws with invalid number passed', () => {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
crypto.randomBytes()
|
crypto.randomBytes(-1)
|
||||||
}).to.throw()
|
}).to.throw()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -12,8 +12,14 @@ const fixtures = require('../fixtures/go-key-ed25519')
|
|||||||
|
|
||||||
const testGarbage = require('../helpers/test-garbage-error-handling')
|
const testGarbage = require('../helpers/test-garbage-error-handling')
|
||||||
|
|
||||||
|
/** @typedef {import("libp2p-crypto").PrivateKey} PrivateKey */
|
||||||
|
|
||||||
describe('ed25519', function () {
|
describe('ed25519', function () {
|
||||||
this.timeout(20 * 1000)
|
this.timeout(20 * 1000)
|
||||||
|
// @ts-check
|
||||||
|
/**
|
||||||
|
* @type {PrivateKey}
|
||||||
|
*/
|
||||||
let key
|
let key
|
||||||
before(async () => {
|
before(async () => {
|
||||||
key = await crypto.keys.generateKeyPair('Ed25519', 512)
|
key = await crypto.keys.generateKeyPair('Ed25519', 512)
|
||||||
@ -118,11 +124,15 @@ describe('ed25519', function () {
|
|||||||
|
|
||||||
describe('throws error instead of crashing', () => {
|
describe('throws error instead of crashing', () => {
|
||||||
const key = crypto.keys.unmarshalPublicKey(fixtures.verify.publicKey)
|
const key = crypto.keys.unmarshalPublicKey(fixtures.verify.publicKey)
|
||||||
testGarbage.doTests('key.verify', key.verify.bind(key), 2)
|
testGarbage.doTests('key.verify', key.verify.bind(key), 2, null)
|
||||||
testGarbage.doTests('crypto.keys.unmarshalPrivateKey', crypto.keys.unmarshalPrivateKey.bind(crypto.keys))
|
testGarbage.doTests('crypto.keys.unmarshalPrivateKey', crypto.keys.unmarshalPrivateKey.bind(crypto.keys), null, null)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('go interop', () => {
|
describe('go interop', () => {
|
||||||
|
// @ts-check
|
||||||
|
/**
|
||||||
|
* @type {PrivateKey}
|
||||||
|
*/
|
||||||
let privateKey
|
let privateKey
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
|
@ -11,6 +11,10 @@ const fixtures = require('../fixtures/go-elliptic-key')
|
|||||||
const crypto = require('../../src')
|
const crypto = require('../../src')
|
||||||
|
|
||||||
const curves = ['P-256', 'P-384'] // 'P-521' fails in tests :( no clue why
|
const curves = ['P-256', 'P-384'] // 'P-521' fails in tests :( no clue why
|
||||||
|
// @ts-check
|
||||||
|
/**
|
||||||
|
* @type {Record<string, number>}
|
||||||
|
*/
|
||||||
const lengths = {
|
const lengths = {
|
||||||
'P-256': 65,
|
'P-256': 65,
|
||||||
'P-384': 97,
|
'P-384': 97,
|
||||||
|
@ -15,6 +15,10 @@ describe('keyStretcher', () => {
|
|||||||
const ciphers = ['AES-128', 'AES-256', 'Blowfish']
|
const ciphers = ['AES-128', 'AES-256', 'Blowfish']
|
||||||
const hashes = ['SHA1', 'SHA256', 'SHA512']
|
const hashes = ['SHA1', 'SHA256', 'SHA512']
|
||||||
let res
|
let res
|
||||||
|
// @ts-check
|
||||||
|
/**
|
||||||
|
* @type {Buffer}
|
||||||
|
*/
|
||||||
let secret
|
let secret
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
|
@ -15,12 +15,18 @@ const fixtures = require('../fixtures/go-key-rsa')
|
|||||||
|
|
||||||
const testGarbage = require('../helpers/test-garbage-error-handling')
|
const testGarbage = require('../helpers/test-garbage-error-handling')
|
||||||
|
|
||||||
|
/** @typedef {import('libp2p-crypto').keys.supportedKeys.rsa.RsaPrivateKey} RsaPrivateKey */
|
||||||
|
|
||||||
describe('RSA', function () {
|
describe('RSA', function () {
|
||||||
this.timeout(20 * 1000)
|
this.timeout(20 * 1000)
|
||||||
|
// @ts-check
|
||||||
|
/**
|
||||||
|
* @type {RsaPrivateKey}
|
||||||
|
*/
|
||||||
let key
|
let key
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
key = await crypto.keys.generateKeyPair('RSA', 512)
|
key = await rsa.generateKeyPair(512)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('generates a valid key', async () => {
|
it('generates a valid key', async () => {
|
||||||
@ -88,15 +94,19 @@ describe('RSA', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('encrypt decrypt browser/node interop', async () => {
|
it('encrypt decrypt browser/node interop', async () => {
|
||||||
|
// @ts-check
|
||||||
|
/**
|
||||||
|
* @type {any}
|
||||||
|
*/
|
||||||
const id = await crypto.keys.unmarshalPrivateKey(Buffer.from('CAASqAkwggSkAgEAAoIBAQCk0O+6oNRxhcdZe2GxEDrFBkDV4TZFZnp2ly/dL1cGMBql/8oXPZgei6h7+P5zzfDq2YCfwbjbf0IVY1AshRl6B5VGE1WS+9p1y1OZxJf5os6V1ENnTi6FTcyuBl4BN8dmIKOif0hqgqflaT5OhfYZDXfbJyVQj4vb2+Stu2Xpph3nwqAnTw/7GC/7jrt2Cq6Tu1PoZi36wSwEPYW3eQ1HAYxZjTYYDXl2iyHygnTcbkGRwAQ7vjk+mW7u60zyoolCm9f6Y7c/orJ33DDUocbaGJLlHcfd8bioBwaZy/2m7q43X8pQs0Q1/iwUt0HHZj1YARmHKbh0zR31ciFiV37dAgMBAAECggEADtJBNKnA4QKURj47r0YT2uLwkqtBi6UnDyISalQXAdXyl4n0nPlrhBewC5H9I+HZr+zmTbeIjaiYgz7el1pSy7AB4v7bG7AtWZlyx6mvtwHGjR+8/f3AXjl8Vgv5iSeAdXUq8fJ7SyS7v3wi38HZOzCEXj9bci6ud5ODMYJgLE4gZD0+i1+/V9cpuYfGpS/gLTLEMQLiw/9o8NSZ7sAnxg0UlYhotqaQY23hvXPBOe+0oa95zl2n6XTxCafa3dQl/B6CD1tUq9dhbQew4bxqMq/mhRO9pREEqZ083Uh+u4PTc1BeHgIQaS864pHPb+AY1F7KDvPtHhdojnghp8d70QKBgQDeRYFxo6sd04ohY86Z/i9icVYIyCvfXAKnaMKeGUjK7ou6sDJwFX8W97+CzXpZ/vffsk/l5GGhC50KqrITxHAy/h5IjyDODfps7NMIp0Dm9sO4PWibbw3OOVBRc8w3b3i7I8MrUUA1nLHE1T1HA1rKOTz5jYhE0fi9XKiT1ciKOQKBgQC903w+n9y7M7eaMW7Z5/13kZ7PS3HlM681eaPrk8J4J+c6miFF40/8HOsmarS38v0fgTeKkriPz5A7aLzRHhSiOnp350JNM6c3sLwPEs2qx/CRuWWx1rMERatfDdUH6mvlK6QHu0QgSfQR27EO6a6XvVSJXbvFmimjmtIaz/IpxQKBgQDWJ9HYVAGC81abZTaiWK3/A4QJYhQjWNuVwPICsgnYvI4Uib+PDqcs0ffLZ38DRw48kek5bxpBuJbOuDhro1EXUJCNCJpq7jzixituovd9kTRyR3iKii2bDM2+LPwOTXDdnk9lZRugjCEbrPkleq33Ob7uEtfAty4aBTTHe6uEwQKBgQCB+2q8RyMSXNuADhFlzOFXGrOwJm0bEUUMTPrduRQUyt4e1qOqA3klnXe3mqGcxBpnlEe/76/JacvNom6Ikxx16a0qpYRU8OWz0KU1fR6vrrEgV98241k5t6sdL4+MGA1Bo5xyXtzLb1hdUh3vpDwVU2OrnC+To3iXus/b5EBiMQKBgEI1OaBcFiyjgLGEyFKoZbtzH1mdatTExfrAQqCjOVjQByoMpGhHTXwEaosvyYu63Pa8AJPT7juSGaiKYEJFcXO9BiNyVfmQiqSHJcYeuh+fmO9IlHRHgy5xaIIC00AHS2vC/gXwmXAdPis6BZqDJeiCuOLWJ94QXn8JBT8IgGAI', 'base64'))
|
const id = await crypto.keys.unmarshalPrivateKey(Buffer.from('CAASqAkwggSkAgEAAoIBAQCk0O+6oNRxhcdZe2GxEDrFBkDV4TZFZnp2ly/dL1cGMBql/8oXPZgei6h7+P5zzfDq2YCfwbjbf0IVY1AshRl6B5VGE1WS+9p1y1OZxJf5os6V1ENnTi6FTcyuBl4BN8dmIKOif0hqgqflaT5OhfYZDXfbJyVQj4vb2+Stu2Xpph3nwqAnTw/7GC/7jrt2Cq6Tu1PoZi36wSwEPYW3eQ1HAYxZjTYYDXl2iyHygnTcbkGRwAQ7vjk+mW7u60zyoolCm9f6Y7c/orJ33DDUocbaGJLlHcfd8bioBwaZy/2m7q43X8pQs0Q1/iwUt0HHZj1YARmHKbh0zR31ciFiV37dAgMBAAECggEADtJBNKnA4QKURj47r0YT2uLwkqtBi6UnDyISalQXAdXyl4n0nPlrhBewC5H9I+HZr+zmTbeIjaiYgz7el1pSy7AB4v7bG7AtWZlyx6mvtwHGjR+8/f3AXjl8Vgv5iSeAdXUq8fJ7SyS7v3wi38HZOzCEXj9bci6ud5ODMYJgLE4gZD0+i1+/V9cpuYfGpS/gLTLEMQLiw/9o8NSZ7sAnxg0UlYhotqaQY23hvXPBOe+0oa95zl2n6XTxCafa3dQl/B6CD1tUq9dhbQew4bxqMq/mhRO9pREEqZ083Uh+u4PTc1BeHgIQaS864pHPb+AY1F7KDvPtHhdojnghp8d70QKBgQDeRYFxo6sd04ohY86Z/i9icVYIyCvfXAKnaMKeGUjK7ou6sDJwFX8W97+CzXpZ/vffsk/l5GGhC50KqrITxHAy/h5IjyDODfps7NMIp0Dm9sO4PWibbw3OOVBRc8w3b3i7I8MrUUA1nLHE1T1HA1rKOTz5jYhE0fi9XKiT1ciKOQKBgQC903w+n9y7M7eaMW7Z5/13kZ7PS3HlM681eaPrk8J4J+c6miFF40/8HOsmarS38v0fgTeKkriPz5A7aLzRHhSiOnp350JNM6c3sLwPEs2qx/CRuWWx1rMERatfDdUH6mvlK6QHu0QgSfQR27EO6a6XvVSJXbvFmimjmtIaz/IpxQKBgQDWJ9HYVAGC81abZTaiWK3/A4QJYhQjWNuVwPICsgnYvI4Uib+PDqcs0ffLZ38DRw48kek5bxpBuJbOuDhro1EXUJCNCJpq7jzixituovd9kTRyR3iKii2bDM2+LPwOTXDdnk9lZRugjCEbrPkleq33Ob7uEtfAty4aBTTHe6uEwQKBgQCB+2q8RyMSXNuADhFlzOFXGrOwJm0bEUUMTPrduRQUyt4e1qOqA3klnXe3mqGcxBpnlEe/76/JacvNom6Ikxx16a0qpYRU8OWz0KU1fR6vrrEgV98241k5t6sdL4+MGA1Bo5xyXtzLb1hdUh3vpDwVU2OrnC+To3iXus/b5EBiMQKBgEI1OaBcFiyjgLGEyFKoZbtzH1mdatTExfrAQqCjOVjQByoMpGhHTXwEaosvyYu63Pa8AJPT7juSGaiKYEJFcXO9BiNyVfmQiqSHJcYeuh+fmO9IlHRHgy5xaIIC00AHS2vC/gXwmXAdPis6BZqDJeiCuOLWJ94QXn8JBT8IgGAI', 'base64'))
|
||||||
|
|
||||||
const msg = Buffer.from('hello')
|
const msg = Buffer.from('hello')
|
||||||
|
|
||||||
// browser
|
// browser
|
||||||
const dec1 = await id.decrypt(Buffer.from('YRFUDx8UjbWSfDS84cDA4WowaaOmd1qFNAv5QutodCKYb9uPtU/tDiAvJzOGu5DCJRo2J0l/35P2weiB4/C2Cb1aZgXKMx/QQC+2jSJiymhqcZaYerjTvkCFwkjCaqthoVo/YXxsaFZ1q7bdTZUDH1TaJR7hWfSyzyPcA8c0w43MIsw16pY8ZaPSclvnCwhoTg1JGjMk6te3we7+wR8QU7VrPhs54mZWxrpu3NQ8xZ6xQqIedsEiNhBUccrCSzYghgsP0Ae/8iKyGyl3U6IegsJNn8jcocvzOJrmU03rgIFPjvuBdaqB38xDSTjbA123KadB28jNoSZh18q/yH3ZIg==', 'base64'))
|
const dec1 = id.decrypt(Buffer.from('YRFUDx8UjbWSfDS84cDA4WowaaOmd1qFNAv5QutodCKYb9uPtU/tDiAvJzOGu5DCJRo2J0l/35P2weiB4/C2Cb1aZgXKMx/QQC+2jSJiymhqcZaYerjTvkCFwkjCaqthoVo/YXxsaFZ1q7bdTZUDH1TaJR7hWfSyzyPcA8c0w43MIsw16pY8ZaPSclvnCwhoTg1JGjMk6te3we7+wR8QU7VrPhs54mZWxrpu3NQ8xZ6xQqIedsEiNhBUccrCSzYghgsP0Ae/8iKyGyl3U6IegsJNn8jcocvzOJrmU03rgIFPjvuBdaqB38xDSTjbA123KadB28jNoSZh18q/yH3ZIg==', 'base64'))
|
||||||
expect(dec1).to.be.eql(msg)
|
expect(dec1).to.be.eql(msg)
|
||||||
// node
|
// node
|
||||||
const dec2 = await id.decrypt(Buffer.from('e6yxssqXsWc27ozDy0PGKtMkCS28KwFyES2Ijz89yiz+w6bSFkNOhHPKplpPzgQEuNoUGdbseKlJFyRYHjIT8FQFBHZM8UgSkgoimbY5on4xSxXs7E5/+twjqKdB7oNveTaTf7JCwaeUYnKSjbiYFEawtMiQE91F8sTT7TmSzOZ48tUhnddAAZ3Ac/O3Z9MSAKOCDipi+JdZtXRT8KimGt36/7hjjosYmPuHR1Xy/yMTL6SMbXtBM3yAuEgbQgP+q/7kHMHji3/JvTpYdIUU+LVtkMusXNasRA+UWG2zAht18vqjFMsm9JTiihZw9jRHD4vxAhf75M992tnC+0ZuQg==', 'base64'))
|
const dec2 = id.decrypt(Buffer.from('e6yxssqXsWc27ozDy0PGKtMkCS28KwFyES2Ijz89yiz+w6bSFkNOhHPKplpPzgQEuNoUGdbseKlJFyRYHjIT8FQFBHZM8UgSkgoimbY5on4xSxXs7E5/+twjqKdB7oNveTaTf7JCwaeUYnKSjbiYFEawtMiQE91F8sTT7TmSzOZ48tUhnddAAZ3Ac/O3Z9MSAKOCDipi+JdZtXRT8KimGt36/7hjjosYmPuHR1Xy/yMTL6SMbXtBM3yAuEgbQgP+q/7kHMHji3/JvTpYdIUU+LVtkMusXNasRA+UWG2zAht18vqjFMsm9JTiihZw9jRHD4vxAhf75M992tnC+0ZuQg==', 'base64'))
|
||||||
expect(dec2).to.be.eql(msg)
|
expect(dec2).to.be.eql(msg)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -142,7 +152,12 @@ describe('RSA', function () {
|
|||||||
describe('throws error instead of crashing', () => {
|
describe('throws error instead of crashing', () => {
|
||||||
const key = crypto.keys.unmarshalPublicKey(fixtures.verify.publicKey)
|
const key = crypto.keys.unmarshalPublicKey(fixtures.verify.publicKey)
|
||||||
testGarbage.doTests('key.verify', key.verify.bind(key), 2, true)
|
testGarbage.doTests('key.verify', key.verify.bind(key), 2, true)
|
||||||
testGarbage.doTests('crypto.keys.unmarshalPrivateKey', crypto.keys.unmarshalPrivateKey.bind(crypto.keys))
|
testGarbage.doTests(
|
||||||
|
'crypto.keys.unmarshalPrivateKey',
|
||||||
|
crypto.keys.unmarshalPrivateKey.bind(crypto.keys),
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('go interop', () => {
|
describe('go interop', () => {
|
||||||
|
@ -12,7 +12,8 @@ const crypto = require('../../src')
|
|||||||
|
|
||||||
describe('without libp2p-crypto-secp256k1 module present', () => {
|
describe('without libp2p-crypto-secp256k1 module present', () => {
|
||||||
before(() => {
|
before(() => {
|
||||||
sinon.replace(crypto.keys.supportedKeys, 'secp256k1', null)
|
const empty = null
|
||||||
|
sinon.replace(crypto.keys.supportedKeys, 'secp256k1', empty)
|
||||||
})
|
})
|
||||||
|
|
||||||
after(() => {
|
after(() => {
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
|
/* eslint-disable valid-jsdoc */
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const chai = require('chai')
|
const chai = require('chai')
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
|
|
||||||
|
// @ts-check
|
||||||
|
/**
|
||||||
|
* @type {function(any, string): void}
|
||||||
|
*/
|
||||||
const expectErrCode = async (p, code) => {
|
const expectErrCode = async (p, code) => {
|
||||||
try {
|
try {
|
||||||
await p
|
await p
|
||||||
|
30
tsconfig.json
Normal file
30
tsconfig.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"lib": [
|
||||||
|
"es6"
|
||||||
|
],
|
||||||
|
"target": "ES5",
|
||||||
|
"noImplicitAny": false,
|
||||||
|
"noImplicitThis": true,
|
||||||
|
"strictFunctionTypes": true,
|
||||||
|
"strictNullChecks": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"allowJs": true,
|
||||||
|
"checkJs": true,
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"libp2p-crypto": [
|
||||||
|
"./src",
|
||||||
|
"../../src",
|
||||||
|
"../src"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"types": ["node", "mocha", "chai"],
|
||||||
|
"noEmit": true,
|
||||||
|
"forceConsistentCasingInFileNames": true
|
||||||
|
},
|
||||||
|
"files": ["./src/index.d.ts",],
|
||||||
|
"include": ["./test/**/*.spec.js"]
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user