Compare commits

..

No commits in common. "master" and "v0.17.8" have entirely different histories.

37 changed files with 389 additions and 814 deletions

View File

@ -1,59 +1,3 @@
<a name="0.19.2"></a>
## [0.19.2](https://github.com/libp2p/js-libp2p-crypto/compare/v0.19.1...v0.19.2) (2021-03-17)
### Bug Fixes
* ed25519 PeerID generation ([#186](https://github.com/libp2p/js-libp2p-crypto/issues/186)) ([1c16dd3](https://github.com/libp2p/js-libp2p-crypto/commit/1c16dd3)), closes [ipfs/js-ipfs#3591](https://github.com/ipfs/js-ipfs/issues/3591) [libp2p/js-libp2p-crypto#185](https://github.com/libp2p/js-libp2p-crypto/issues/185)
<a name="0.19.1"></a>
## [0.19.1](https://github.com/libp2p/js-libp2p-crypto/compare/v0.19.0...v0.19.1) (2021-03-15)
### Bug Fixes
* ed25519 key ID generation ([bc33769](https://github.com/libp2p/js-libp2p-crypto/commit/bc33769))
<a name="0.19.0"></a>
# [0.19.0](https://github.com/libp2p/js-libp2p-crypto/compare/v0.18.0...v0.19.0) (2021-01-15)
<a name="0.18.0"></a>
# [0.18.0](https://github.com/libp2p/js-libp2p-crypto/compare/v0.17.9...v0.18.0) (2020-08-07)
### Bug Fixes
* remove rendundant public key ([#181](https://github.com/libp2p/js-libp2p-crypto/issues/181)) ([afcffc8](https://github.com/libp2p/js-libp2p-crypto/commit/afcffc8))
* replace node buffers with uint8arrays ([#180](https://github.com/libp2p/js-libp2p-crypto/issues/180)) ([a0f387a](https://github.com/libp2p/js-libp2p-crypto/commit/a0f387a))
### BREAKING CHANGES
* The private ed25519 key will no longer include the redundant public key
* chore: fix lint
* - Where node Buffers were returned, now Uint8Arrays are
* chore: remove commented code
<a name="0.17.9"></a>
## [0.17.9](https://github.com/libp2p/js-libp2p-crypto/compare/v0.17.8...v0.17.9) (2020-08-05)
### Features
* add exporting/importing of non rsa keys in libp2p-key format ([#179](https://github.com/libp2p/js-libp2p-crypto/issues/179)) ([7273739](https://github.com/libp2p/js-libp2p-crypto/commit/7273739))
<a name="0.17.8"></a>
## [0.17.8](https://github.com/libp2p/js-libp2p-crypto/compare/v0.17.7...v0.17.8) (2020-07-20)

114
README.md
View File

@ -20,12 +20,10 @@ This repo contains the JavaScript implementation of the crypto primitives needed
## Table of Contents
- [js-libp2p-crypto](#js-libp2p-crypto)
- [Lead Maintainer](#lead-maintainer)
- [Table of Contents](#table-of-contents)
- [Install](#install)
- [Usage](#usage)
- [Web Crypto API](#web-crypto-api)
- [API](#api)
- [Lead Maintainer](#Lead-Maintainer)
- [Table of Contents](#Table-of-Contents)
- [Install](#Install)
- [API](#API)
- [`crypto.aes`](#cryptoaes)
- [`crypto.aes.create(key, iv)`](#cryptoaescreatekey-iv)
- [`decrypt(data)`](#decryptdata)
@ -34,19 +32,18 @@ This repo contains the JavaScript implementation of the crypto primitives needed
- [`crypto.hmac.create(hash, secret)`](#cryptohmaccreatehash-secret)
- [`digest(data)`](#digestdata)
- [`crypto.keys`](#cryptokeys)
- [`crypto.keys.generateKeyPair(type, bits)`](#cryptokeysgeneratekeypairtype-bits)
- [`crypto.keys.generateEphemeralKeyPair(curve)`](#cryptokeysgenerateephemeralkeypaircurve)
- [`crypto.keys.keyStretcher(cipherType, hashType, secret)`](#cryptokeyskeystretcherciphertype-hashtype-secret)
- [`crypto.keys.marshalPublicKey(key, [type])`](#cryptokeysmarshalpublickeykey-type)
- [`crypto.keys.unmarshalPublicKey(buf)`](#cryptokeysunmarshalpublickeybuf)
- [`crypto.keys.marshalPrivateKey(key, [type])`](#cryptokeysmarshalprivatekeykey-type)
- [`crypto.keys.unmarshalPrivateKey(buf)`](#cryptokeysunmarshalprivatekeybuf)
- [`crypto.keys.import(encryptedKey, password)`](#cryptokeysimportencryptedkey-password)
- [`privateKey.export(password, format)`](#privatekeyexportpassword-format)
- [`crypto.randomBytes(number)`](#cryptorandombytesnumber)
- [`crypto.pbkdf2(password, salt, iterations, keySize, hash)`](#cryptopbkdf2password-salt-iterations-keysize-hash)
- [Contribute](#contribute)
- [License](#license)
- [`crypto.keys.generateKeyPair(type, bits)`](#cryptokeysgenerateKeyPairtype-bits)
- [`crypto.keys.generateEphemeralKeyPair(curve)`](#cryptokeysgenerateEphemeralKeyPaircurve)
- [`crypto.keys.keyStretcher(cipherType, hashType, secret)`](#cryptokeyskeyStretchercipherType-hashType-secret)
- [`crypto.keys.marshalPublicKey(key, [type])`](#cryptokeysmarshalPublicKeykey-type)
- [`crypto.keys.unmarshalPublicKey(buf)`](#cryptokeysunmarshalPublicKeybuf)
- [`crypto.keys.marshalPrivateKey(key, [type])`](#cryptokeysmarshalPrivateKeykey-type)
- [`crypto.keys.unmarshalPrivateKey(buf)`](#cryptokeysunmarshalPrivateKeybuf)
- [`crypto.keys.import(pem, password)`](#cryptokeysimportpem-password)
- [`crypto.randomBytes(number)`](#cryptorandomBytesnumber)
- [`crypto.pbkdf2(password, salt, iterations, keySize, hash)`](#cryptopbkdf2password-salt-iterations-keySize-hash)
- [Contribute](#Contribute)
- [License](#License)
## Install
@ -85,22 +82,22 @@ This uses `CTR` mode.
#### `crypto.aes.create(key, iv)`
- `key: Uint8Array` The key, if length `16` then `AES 128` is used. For length `32`, `AES 256` is used.
- `iv: Uint8Array` Must have length `16`.
- `key: Buffer` The key, if length `16` then `AES 128` is used. For length `32`, `AES 256` is used.
- `iv: Buffer` Must have length `16`.
Returns `Promise<{decrypt<Function>, encrypt<Function>}>`
##### `decrypt(data)`
- `data: Uint8Array`
- `data: Buffer`
Returns `Promise<Uint8Array>`
Returns `Promise<Buffer>`
##### `encrypt(data)`
- `data: Uint8Array`
- `data: Buffer`
Returns `Promise<Uint8Array>`
Returns `Promise<Buffer>`
```js
const crypto = require('libp2p-crypto')
@ -108,26 +105,26 @@ const crypto = require('libp2p-crypto')
// Setting up Key and IV
// A 16 bytes array, 128 Bits, AES-128 is chosen
const key128 = Uint8Array.from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
const key128 = Buffer.from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
// A 16 bytes array, 128 Bits,
const IV = Uint8Array.from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
const IV = Buffer.from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
async function main () {
const decryptedMessage = 'Hello, world!'
// Encrypting
const cipher = await crypto.aes.create(key128, IV)
const encryptedBuffer = await cipher.encrypt(Uint8Array.from(decryptedMessage))
const encryptedBuffer = await cipher.encrypt(Buffer.from(decryptedMessage))
console.log(encryptedBuffer)
// prints: <Uint8Array 42 f1 67 d9 2e 42 d0 32 9e b1 f8 3c>
// prints: <Buffer 42 f1 67 d9 2e 42 d0 32 9e b1 f8 3c>
// Decrypting
const decipher = await crypto.aes.create(key128, IV)
const decryptedBuffer = await cipher.decrypt(encryptedBuffer)
console.log(decryptedBuffer)
// prints: <Uint8Array 42 f1 67 d9 2e 42 d0 32 9e b1 f8 3c>
// prints: <Buffer 42 f1 67 d9 2e 42 d0 32 9e b1 f8 3c>
console.log(decryptedBuffer.toString('utf-8'))
// prints: Hello, world!
@ -143,15 +140,15 @@ Exposes an interface to the Keyed-Hash Message Authentication Code (HMAC) as def
#### `crypto.hmac.create(hash, secret)`
- `hash: String`
- `secret: Uint8Array`
- `secret: Buffer`
Returns `Promise<{digest<Function>}>`
##### `digest(data)`
- `data: Uint8Array`
- `data: Buffer`
Returns `Promise<Uint8Array>`
Returns `Promise<Buffer>`
Example:
@ -160,8 +157,8 @@ const crypto = require('libp2p-crypto')
async function main () {
const hash = 'SHA1' // 'SHA256' || 'SHA512'
const hmac = await crypto.hmac.create(hash, uint8ArrayFromString('secret'))
const sig = await hmac.digest(uint8ArrayFromString('hello world'))
const hmac = await crypto.hmac.create(hash, Buffer.from('secret'))
const sig = await hmac.digest(Buffer.from('hello world'))
console.log(sig)
}
@ -181,7 +178,7 @@ Currently the `'RSA'`, `'ed25519'`, and `secp256k1` types are supported, althoug
- `type: String`, see [Supported Key Types](#supported-key-types) above.
- `bits: Number` Minimum of 1024
Returns `Promise<{privateKey<Uint8Array>, publicKey<Uint8Array>}>`
Returns `Promise<{privateKey<Buffer>, publicKey<Buffer>}>`
Generates a keypair of the given type and bitsize.
@ -199,7 +196,7 @@ Resolves to an object of the form:
```js
{
key: Uint8Array,
key: Buffer,
genSharedKey: Function
}
```
@ -208,7 +205,7 @@ Resolves to an object of the form:
- `cipherType: String`, one of `'AES-128'`, `'AES-256'`, `'Blowfish'`
- `hashType: String`, one of `'SHA1'`, `SHA256`, `SHA512`
- `secret: Uint8Array`
- `secret: Buffer`
Returns `Promise`
@ -219,14 +216,14 @@ Resolves to an object of the form:
```js
{
k1: {
iv: Uint8Array,
cipherKey: Uint8Array,
macKey: Uint8Array
iv: Buffer,
cipherKey: Buffer,
macKey: Buffer
},
k2: {
iv: Uint8Array,
cipherKey: Uint8Array,
macKey: Uint8Array
iv: Buffer,
cipherKey: Buffer,
macKey: Buffer
}
}
```
@ -236,13 +233,13 @@ Resolves to an object of the form:
- `key: keys.rsa.RsaPublicKey | keys.ed25519.Ed25519PublicKey | keys.secp256k1.Secp256k1PublicKey`
- `type: String`, see [Supported Key Types](#supported-key-types) above. Defaults to 'rsa'.
Returns `Uint8Array`
Returns `Buffer`
Converts a public key object into a protobuf serialized public key.
### `crypto.keys.unmarshalPublicKey(buf)`
- `buf: Uint8Array`
- `buf: Buffer`
Returns `RsaPublicKey|Ed25519PublicKey|Secp256k1PublicKey`
@ -253,43 +250,34 @@ Converts a protobuf serialized public key into its representative object.
- `key: keys.rsa.RsaPrivateKey | keys.ed25519.Ed25519PrivateKey | keys.secp256k1.Secp256k1PrivateKey`
- `type: String`, see [Supported Key Types](#supported-key-types) above.
Returns `Uint8Array`
Returns `Buffer`
Converts a private key object into a protobuf serialized private key.
### `crypto.keys.unmarshalPrivateKey(buf)`
- `buf: Uint8Array`
- `buf: Buffer`
Returns `Promise<RsaPrivateKey|Ed25519PrivateKey|Secp256k1PrivateKey>`
Converts a protobuf serialized private key into its representative object.
### `crypto.keys.import(encryptedKey, password)`
### `crypto.keys.import(pem, password)`
- `encryptedKey: string`
- `pem: string`
- `password: string`
Returns `Promise<PrivateKey>`
Returns `Promise<RsaPrivateKey>`
Converts an exported private key into its representative object. Supported formats are 'pem' (RSA only) and 'libp2p-key'.
### `privateKey.export(password, format)`
- `password: string`
- `format: string` the format to export to: 'pem' (rsa only), 'libp2p-key'
Returns `string`
Exports the password protected `PrivateKey`. RSA keys will be exported as password protected PEM by default. Ed25519 and Secp256k1 keys will be exported as password protected AES-GCM base64 encoded strings ('libp2p-key' format).
Converts a PEM password protected private key into its representative object.
### `crypto.randomBytes(number)`
- `number: Number`
Returns `Uint8Array`
Returns `Buffer`
Generates a Uint8Array with length `number` populated by random bytes.
Generates a Buffer with length `number` populated by random bytes.
### `crypto.pbkdf2(password, salt, iterations, keySize, hash)`

View File

@ -1,15 +1,14 @@
{
"name": "libp2p-crypto",
"version": "0.19.2",
"version": "0.17.8",
"description": "Crypto primitives for libp2p",
"main": "src/index.js",
"types": "src/index.d.ts",
"leadMaintainer": "Jacob Heun <jacobheun@gmail.com>",
"browser": {
"./src/aes/ciphers.js": "./src/aes/ciphers-browser.js",
"./src/ciphers/aes-gcm.js": "./src/ciphers/aes-gcm.browser.js",
"./src/hmac/index.js": "./src/hmac/index-browser.js",
"./src/keys/ecdh.js": "./src/keys/ecdh-browser.js",
"./src/aes/ciphers.js": "./src/aes/ciphers-browser.js",
"./src/keys/rsa.js": "./src/keys/rsa-browser.js"
},
"files": [
@ -39,27 +38,26 @@
],
"license": "MIT",
"dependencies": {
"buffer": "^5.5.0",
"err-code": "^2.0.0",
"is-typedarray": "^1.0.0",
"iso-random-stream": "^1.1.0",
"keypair": "^1.0.1",
"multibase": "^4.0.3",
"multicodec": "^3.0.1",
"multihashes": "^4.0.2",
"multihashing-async": "^2.0.1",
"node-forge": "^0.10.0",
"multibase": "^0.7.0",
"multihashing-async": "^0.8.1",
"node-forge": "^0.9.1",
"pem-jwk": "^2.0.0",
"protons": "^2.0.0",
"protons": "^1.0.1",
"secp256k1": "^4.0.0",
"uint8arrays": "^2.1.4",
"ursa-optional": "^0.10.1"
"ursa-optional": "~0.10.1"
},
"devDependencies": {
"@types/chai": "^4.2.12",
"@types/chai": "^4.2.11",
"@types/chai-string": "^1.4.2",
"@types/dirty-chai": "^2.0.2",
"@types/mocha": "^8.0.1",
"aegir": "^25.0.0",
"@types/mocha": "^7.0.1",
"@types/sinon": "^9.0.0",
"aegir": "^22.0.0",
"benchmark": "^2.1.4",
"chai": "^4.2.0",
"chai-string": "^1.5.0",
@ -86,21 +84,20 @@
"dryajov <dryajov@gmail.com>",
"Alan Shaw <alan.shaw@protocol.ai>",
"Hugo Dias <hugomrdias@gmail.com>",
"Cayman <caymannava@gmail.com>",
"Yusef Napora <yusef@napora.org>",
"ᴠɪᴄᴛᴏʀ ʙᴊᴇʟᴋʜᴏʟᴍ <victorbjelkholm@gmail.com>",
"Cayman <caymannava@gmail.com>",
"Victor Bjelkholm <victorbjelkholm@gmail.com>",
"Arve Knudsen <arve.knudsen@gmail.com>",
"Alex Potsides <alex@achingbrain.net>",
"Vasco Santos <vasco.santos@ua.pt>",
"Alberto Elias <hi@albertoelias.me>",
"Jack Kleeman <jackkleeman@gmail.com>",
"Nadim Kobeissi <nadim@symbolic.software>",
"Richard Littauer <richard.littauer@gmail.com>",
"Richard Schneider <makaretu@gmail.com>",
"Alex Potsides <alex@achingbrain.net>",
"dirkmc <dirkmdev@gmail.com>",
"Alberto Elias <hi@albertoelias.me>",
"nikuda <nikuda@gmail.com>",
"Joao Santos <jrmsantos15@gmail.com>",
"Tom Swindell <t.swindell@rubyx.co.uk>",
"Carson Farmer <carson.farmer@gmail.com>",
"Tom Swindell <t.swindell@rubyx.co.uk>"
"Joao Santos <jrmsantos15@gmail.com>"
]
}

View File

@ -1,28 +1,26 @@
'use strict'
const { Buffer } = require('buffer')
require('node-forge/lib/aes')
const forge = require('node-forge/lib/forge')
const uint8ArrayToString = require('uint8arrays/to-string')
const uint8ArrayFromString = require('uint8arrays/from-string')
module.exports = {
createCipheriv: (mode, key, iv) => {
const cipher2 = forge.cipher.createCipher('AES-CTR', uint8ArrayToString(key, 'ascii'))
cipher2.start({ iv: uint8ArrayToString(iv, 'ascii') })
const cipher2 = forge.cipher.createCipher('AES-CTR', key.toString('binary'))
cipher2.start({ iv: iv.toString('binary') })
return {
update: (data) => {
cipher2.update(forge.util.createBuffer(uint8ArrayToString(data, 'ascii')))
return uint8ArrayFromString(cipher2.output.getBytes(), 'ascii')
cipher2.update(forge.util.createBuffer(data.toString('binary')))
return Buffer.from(cipher2.output.getBytes(), 'binary')
}
}
},
createDecipheriv: (mode, key, iv) => {
const cipher2 = forge.cipher.createDecipher('AES-CTR', uint8ArrayToString(key, 'ascii'))
cipher2.start({ iv: uint8ArrayToString(iv, 'ascii') })
const cipher2 = forge.cipher.createDecipher('AES-CTR', key.toString('binary'))
cipher2.start({ iv: iv.toString('binary') })
return {
update: (data) => {
cipher2.update(forge.util.createBuffer(uint8ArrayToString(data, 'ascii')))
return uint8ArrayFromString(cipher2.output.getBytes(), 'ascii')
cipher2.update(forge.util.createBuffer(data.toString('binary')))
return Buffer.from(cipher2.output.getBytes(), 'binary')
}
}
}

View File

@ -1,89 +0,0 @@
'use strict'
const concat = require('uint8arrays/concat')
const fromString = require('uint8arrays/from-string')
const webcrypto = require('../webcrypto')
// Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples
/**
*
* @param {object} [options]
* @param {string} [options.algorithm=AES-GCM]
* @param {Number} [options.nonceLength=12]
* @param {Number} [options.keyLength=16]
* @param {string} [options.digest=sha256]
* @param {Number} [options.saltLength=16]
* @param {Number} [options.iterations=32767]
* @returns {*}
*/
function create ({
algorithm = 'AES-GCM',
nonceLength = 12,
keyLength = 16,
digest = 'SHA-256',
saltLength = 16,
iterations = 32767
} = {}) {
const crypto = webcrypto.get()
keyLength *= 8 // Browser crypto uses bits instead of bytes
/**
* Uses the provided password to derive a pbkdf2 key. The key
* will then be used to encrypt the data.
*
* @param {Uint8Array} data The data to decrypt
* @param {string} password A plain password
* @returns {Promise<Uint8Array>}
*/
async function encrypt (data, password) { // eslint-disable-line require-await
const salt = crypto.getRandomValues(new Uint8Array(saltLength))
const nonce = crypto.getRandomValues(new Uint8Array(nonceLength))
const aesGcm = { name: algorithm, iv: nonce }
// Derive a key using PBKDF2.
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } }
const rawKey = await crypto.subtle.importKey('raw', fromString(password), { name: 'PBKDF2' }, false, ['deriveKey', 'deriveBits'])
const cryptoKey = await crypto.subtle.deriveKey(deriveParams, rawKey, { name: algorithm, length: keyLength }, true, ['encrypt'])
// Encrypt the string.
const ciphertext = await crypto.subtle.encrypt(aesGcm, cryptoKey, data)
return concat([salt, aesGcm.iv, new Uint8Array(ciphertext)])
}
/**
* Uses the provided password to derive a pbkdf2 key. The key
* will then be used to decrypt the data. The options used to create
* this decryption cipher must be the same as those used to create
* the encryption cipher.
*
* @param {Uint8Array} data The data to decrypt
* @param {string} password A plain password
* @returns {Promise<Uint8Array>}
*/
async function decrypt (data, password) {
const salt = data.slice(0, saltLength)
const nonce = data.slice(saltLength, saltLength + nonceLength)
const ciphertext = data.slice(saltLength + nonceLength)
const aesGcm = { name: algorithm, iv: nonce }
// Derive the key using PBKDF2.
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } }
const rawKey = await crypto.subtle.importKey('raw', fromString(password), { name: 'PBKDF2' }, false, ['deriveKey', 'deriveBits'])
const cryptoKey = await crypto.subtle.deriveKey(deriveParams, rawKey, { name: algorithm, length: keyLength }, true, ['decrypt'])
// Decrypt the string.
const plaintext = await crypto.subtle.decrypt(aesGcm, cryptoKey, ciphertext)
return new Uint8Array(plaintext)
}
return {
encrypt,
decrypt
}
}
module.exports = {
create
}

View File

@ -1,130 +0,0 @@
'use strict'
const crypto = require('crypto')
const uint8ArrayConcat = require('uint8arrays/concat')
const uint8ArrayFromString = require('uint8arrays/from-string')
// Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples
/**
*
* @param {object} [options]
* @param {Number} [options.algorithmTagLength=16]
* @param {Number} [options.nonceLength=12]
* @param {Number} [options.keyLength=16]
* @param {string} [options.digest=sha256]
* @param {Number} [options.saltLength=16]
* @param {Number} [options.iterations=32767]
* @returns {*}
*/
function create ({
algorithmTagLength = 16,
nonceLength = 12,
keyLength = 16,
digest = 'sha256',
saltLength = 16,
iterations = 32767
} = {}) {
const algorithm = 'aes-128-gcm'
/**
*
* @private
* @param {Uint8Array} data
* @param {Uint8Array} key
* @returns {Promise<Uint8Array>}
*/
async function encryptWithKey (data, key) { // eslint-disable-line require-await
const nonce = crypto.randomBytes(nonceLength)
// Create the cipher instance.
const cipher = crypto.createCipheriv(algorithm, key, nonce)
// Encrypt and prepend nonce.
const ciphertext = uint8ArrayConcat([cipher.update(data), cipher.final()])
return uint8ArrayConcat([nonce, ciphertext, cipher.getAuthTag()])
}
/**
* Uses the provided password to derive a pbkdf2 key. The key
* will then be used to encrypt the data.
*
* @param {Uint8Array} data The data to decrypt
* @param {string|Uint8Array} password A plain password
* @returns {Promise<Uint8Array>}
*/
async function encrypt (data, password) { // eslint-disable-line require-await
// Generate a 128-bit salt using a CSPRNG.
const salt = crypto.randomBytes(saltLength)
if (typeof password === 'string' || password instanceof String) {
password = uint8ArrayFromString(password)
}
// Derive a key using PBKDF2.
const key = crypto.pbkdf2Sync(password, salt, iterations, keyLength, digest)
// Encrypt and prepend salt.
return uint8ArrayConcat([salt, await encryptWithKey(Uint8Array.from(data), key)])
}
/**
* Decrypts the given cipher text with the provided key. The `key` should
* be a cryptographically safe key and not a plaintext password. To use
* a plaintext password, use `decrypt`. The options used to create
* this decryption cipher must be the same as those used to create
* the encryption cipher.
*
* @private
* @param {Uint8Array} ciphertextAndNonce The data to decrypt
* @param {Uint8Array} key
* @returns {Promise<Uint8Array>}
*/
async function decryptWithKey (ciphertextAndNonce, key) { // eslint-disable-line require-await
// Create Uint8Arrays of nonce, ciphertext and tag.
const nonce = ciphertextAndNonce.slice(0, nonceLength)
const ciphertext = ciphertextAndNonce.slice(nonceLength, ciphertextAndNonce.length - algorithmTagLength)
const tag = ciphertextAndNonce.slice(ciphertext.length + nonceLength)
// Create the cipher instance.
const cipher = crypto.createDecipheriv(algorithm, key, nonce)
// Decrypt and return result.
cipher.setAuthTag(tag)
return uint8ArrayConcat([cipher.update(ciphertext), cipher.final()])
}
/**
* Uses the provided password to derive a pbkdf2 key. The key
* will then be used to decrypt the data. The options used to create
* this decryption cipher must be the same as those used to create
* the encryption cipher.
*
* @param {Uint8Array} data The data to decrypt
* @param {string|Uint8Array} password A plain password
*/
async function decrypt (data, password) { // eslint-disable-line require-await
// Create Uint8Arrays of salt and ciphertextAndNonce.
const salt = data.slice(0, saltLength)
const ciphertextAndNonce = data.slice(saltLength)
if (typeof password === 'string' || password instanceof String) {
password = uint8ArrayFromString(password)
}
// Derive the key using PBKDF2.
const key = crypto.pbkdf2Sync(password, salt, iterations, keyLength, digest)
// Decrypt and return result.
return decryptWithKey(ciphertextAndNonce, key)
}
return {
encrypt,
decrypt
}
}
module.exports = {
create
}

View File

@ -1,5 +1,5 @@
'use strict'
const { Buffer } = require('buffer')
const webcrypto = require('../webcrypto')
const lengths = require('./lengths')
@ -10,8 +10,7 @@ const hashTypes = {
}
const sign = async (key, data) => {
const buf = await webcrypto.get().subtle.sign({ name: 'HMAC' }, key, data)
return new Uint8Array(buf, buf.byteOffset, buf.byteLength)
return Buffer.from(await webcrypto.get().subtle.sign({ name: 'HMAC' }, key, data))
}
exports.create = async function (hashType, secret) {

177
src/index.d.ts vendored
View File

@ -1,3 +1,5 @@
/// <reference types="node" />
/**
* Supported key types.
*/
@ -29,15 +31,15 @@ export namespace aes {
* AES Cipher in CTR mode.
*/
interface Cipher {
encrypt(data: Uint8Array): Promise<Uint8Array>;
decrypt(data: Uint8Array): Promise<Uint8Array>;
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: Uint8Array, iv: Uint8Array): Promise<Cipher>;
function create(key: Buffer, iv: Buffer): Promise<Cipher>;
}
/**
@ -51,7 +53,7 @@ export namespace hmac {
* HMAC Digest.
*/
interface Digest {
digest(data: Uint8Array): Promise<Uint8Array>;
digest(data: Buffer): Promise<Buffer>;
length: 20 | 32 | 64 | number;
}
/**
@ -59,7 +61,7 @@ export namespace hmac {
*/
function create(
hash: "SHA1" | "SHA256" | "SHA512" | string,
secret: Uint8Array
secret: Buffer
): Promise<Digest>;
}
@ -67,11 +69,11 @@ export namespace hmac {
* Generic public key interface.
*/
export interface PublicKey {
readonly bytes: Uint8Array;
verify(data: Uint8Array, sig: Uint8Array): Promise<boolean>;
marshal(): Uint8Array;
readonly bytes: Buffer;
verify(data: Buffer, sig: Buffer): Promise<boolean>;
marshal(): Buffer;
equals(key: PublicKey): boolean;
hash(): Promise<Uint8Array>;
hash(): Promise<Buffer>;
}
/**
@ -79,11 +81,11 @@ export interface PublicKey {
*/
export interface PrivateKey {
readonly public: PublicKey;
readonly bytes: Uint8Array;
sign(data: Uint8Array): Promise<Uint8Array>;
marshal(): Uint8Array;
readonly bytes: Buffer;
sign(data: Buffer): Promise<Buffer>;
marshal(): Buffer;
equals(key: PrivateKey): boolean;
hash(): Promise<Uint8Array>;
hash(): Promise<Buffer>;
/**
* Gets the ID of the key.
*
@ -92,17 +94,13 @@ export interface PrivateKey {
* of the PKCS SubjectPublicKeyInfo.
*/
id(): Promise<string>;
/**
* Exports the password protected key in the format specified.
*/
export(password: string, format?: "pkcs-8" | string): Promise<string>;
}
export interface Keystretcher {
(res: Uint8Array): Keystretcher;
iv: Uint8Array;
cipherKey: Uint8Array;
macKey: Uint8Array;
(res: Buffer): Keystretcher;
iv: Buffer;
cipherKey: Buffer;
macKey: Buffer;
}
export interface StretchPair {
@ -125,94 +123,101 @@ export namespace keys {
export namespace supportedKeys {
namespace rsa {
class RsaPublicKey implements PublicKey {
constructor(key: Uint8Array);
readonly bytes: Uint8Array;
verify(data: Uint8Array, sig: Uint8Array): Promise<boolean>;
marshal(): Uint8Array;
encrypt(bytes: Uint8Array): Uint8Array;
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<Uint8Array>;
hash(): Promise<Buffer>;
}
// Type alias for export method
export type KeyInfo = any;
class RsaPrivateKey implements PrivateKey {
constructor(key: any, publicKey: Uint8Array);
constructor(key: any, publicKey: Buffer);
readonly public: RsaPublicKey;
readonly bytes: Uint8Array;
genSecret(): Uint8Array;
sign(data: Uint8Array): Promise<Uint8Array>;
decrypt(bytes: Uint8Array): Uint8Array;
marshal(): Uint8Array;
readonly bytes: Buffer;
genSecret(): Buffer;
sign(data: Buffer): Promise<Buffer>;
decrypt(bytes: Buffer): Buffer;
marshal(): Buffer;
equals(key: PrivateKey): boolean;
hash(): Promise<Uint8Array>;
hash(): Promise<Buffer>;
id(): Promise<string>;
export(password: string, format?: string): 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: Uint8Array): RsaPublicKey;
function unmarshalRsaPrivateKey(buf: Uint8Array): Promise<RsaPrivateKey>;
function unmarshalRsaPublicKey(buf: Buffer): RsaPublicKey;
function unmarshalRsaPrivateKey(buf: Buffer): Promise<RsaPrivateKey>;
function generateKeyPair(bits: number): Promise<RsaPrivateKey>;
function fromJwk(jwk: Uint8Array): Promise<RsaPrivateKey>;
function fromJwk(jwk: Buffer): Promise<RsaPrivateKey>;
}
namespace ed25519 {
class Ed25519PublicKey implements PublicKey {
constructor(key: Uint8Array);
readonly bytes: Uint8Array;
verify(data: Uint8Array, sig: Uint8Array): Promise<boolean>;
marshal(): Uint8Array;
encrypt(bytes: Uint8Array): Uint8Array;
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<Uint8Array>;
hash(): Promise<Buffer>;
}
class Ed25519PrivateKey implements PrivateKey {
constructor(key: Uint8Array, publicKey: Uint8Array);
constructor(key: Buffer, publicKey: Buffer);
readonly public: Ed25519PublicKey;
readonly bytes: Uint8Array;
sign(data: Uint8Array): Promise<Uint8Array>;
marshal(): Uint8Array;
readonly bytes: Buffer;
sign(data: Buffer): Promise<Buffer>;
marshal(): Buffer;
equals(key: PrivateKey): boolean;
hash(): Promise<Uint8Array>;
hash(): Promise<Buffer>;
id(): Promise<string>;
export(password: string, format?: string): Promise<string>;
}
function unmarshalEd25519PrivateKey(
buf: Uint8Array
buf: Buffer
): Promise<Ed25519PrivateKey>;
function unmarshalEd25519PublicKey(buf: Uint8Array): Ed25519PublicKey;
function unmarshalEd25519PublicKey(buf: Buffer): Ed25519PublicKey;
function generateKeyPair(): Promise<Ed25519PrivateKey>;
function generateKeyPairFromSeed(
seed: Uint8Array
seed: Buffer
): Promise<Ed25519PrivateKey>;
}
namespace secp256k1 {
class Secp256k1PublicKey implements PublicKey {
constructor(key: Uint8Array);
readonly bytes: Uint8Array;
verify(data: Uint8Array, sig: Uint8Array): Promise<boolean>;
marshal(): Uint8Array;
encrypt(bytes: Uint8Array): Uint8Array;
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<Uint8Array>;
hash(): Promise<Buffer>;
}
class Secp256k1PrivateKey implements PrivateKey {
constructor(key: Uint8Array, publicKey: Uint8Array);
constructor(key: Uint8Array | Buffer, publicKey: Uint8Array | Buffer);
readonly public: Secp256k1PublicKey;
readonly bytes: Uint8Array;
sign(data: Uint8Array): Promise<Uint8Array>;
marshal(): Uint8Array;
readonly bytes: Buffer;
sign(data: Buffer): Promise<Buffer>;
marshal(): Buffer;
equals(key: PrivateKey): boolean;
hash(): Promise<Uint8Array>;
hash(): Promise<Buffer>;
id(): Promise<string>;
export(password: string, format?: string): Promise<string>;
}
function unmarshalSecp256k1PrivateKey(
bytes: Uint8Array
bytes: Buffer
): Promise<Secp256k1PrivateKey>;
function unmarshalSecp256k1PublicKey(bytes: Uint8Array): Secp256k1PublicKey;
function unmarshalSecp256k1PublicKey(bytes: Buffer): Secp256k1PublicKey;
function generateKeyPair(): Promise<Secp256k1PrivateKey>;
}
}
@ -229,14 +234,16 @@ export namespace keys {
bits: number
): Promise<PrivateKey>;
export function generateKeyPair(
type: "Ed25519"
type: "Ed25519",
bits: number
): Promise<keys.supportedKeys.ed25519.Ed25519PrivateKey>;
export function generateKeyPair(
export function generateKeyPair(
type: "RSA",
bits: number
): Promise<keys.supportedKeys.rsa.RsaPrivateKey>;
export function generateKeyPair(
type: "secp256k1"
export function generateKeyPair(
type: "secp256k1",
bits: number
): Promise<keys.supportedKeys.secp256k1.Secp256k1PrivateKey>;
/**
@ -264,8 +271,8 @@ export namespace keys {
export function generateEphemeralKeyPair(
curve: CurveType | string
): Promise<{
key: Uint8Array;
genSharedKey: (theirPub: Uint8Array, forcePrivate?: any) => Promise<Uint8Array>;
key: Buffer;
genSharedKey: (theirPub: Buffer, forcePrivate?: any) => Promise<Buffer>;
}>;
/**
@ -277,49 +284,49 @@ export namespace keys {
export function keyStretcher(
cipherType: CipherType | string,
hashType: HashType | string,
secret: Uint8Array | 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: Uint8Array): PublicKey;
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): Uint8Array;
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: Uint8Array): Promise<PrivateKey>;
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): Uint8Array;
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, format?: string): Promise<supportedKeys.rsa.RsaPrivateKey>;
function _import(pem: string, password: string): Promise<supportedKeys.rsa.RsaPrivateKey>;
export { _import as import };
}
/**
* Generates a Uint8Array populated by random bytes.
* @param The size of the random bytes Uint8Array.
* Generates a Buffer populated by random bytes.
* @param The size of the random bytes Buffer.
*/
export function randomBytes(number: number): Uint8Array;
export function randomBytes(number: number): Buffer;
/**
* Computes the Password-Based Key Derivation Function 2.
@ -330,9 +337,9 @@ export function randomBytes(number: number): Uint8Array;
* @param hash The hash name ('sha1', 'sha2-512, ...)
*/
export function pbkdf2(
password: string | Uint8Array,
salt: string | Uint8Array,
password: string | Buffer,
salt: string | Buffer,
iterations: number,
keySize: number,
hash: string
): Uint8Array;
): Buffer;

View File

@ -1,12 +1,10 @@
'use strict'
const errcode = require('err-code')
const { Buffer } = require('buffer')
const webcrypto = require('../webcrypto')
const { base64urlToBuffer } = require('../util')
const { bufferToBase64url, base64urlToBuffer } = require('../util')
const validateCurveType = require('./validate-curve-type')
const uint8ArrayToString = require('uint8arrays/to-string')
const uint8ArrayConcat = require('uint8arrays/concat')
const uint8ArrayEquals = require('uint8arrays/equals')
const bits = {
'P-256': 256,
@ -58,7 +56,7 @@ exports.generateEphmeralKeyPair = async function (curve) {
privateKey
]
const buffer = await webcrypto.get().subtle.deriveBits(
return Buffer.from(await webcrypto.get().subtle.deriveBits(
{
name: 'ECDH',
namedCurve: curve,
@ -66,9 +64,7 @@ exports.generateEphmeralKeyPair = async function (curve) {
},
keys[1],
bits[curve]
)
return new Uint8Array(buffer, buffer.byteOffset, buffer.byteLength)
))
}
const publicKey = await webcrypto.get().subtle.exportKey('jwk', pair.publicKey)
@ -91,8 +87,8 @@ const curveLengths = {
function marshalPublicKey (jwk) {
const byteLen = curveLengths[jwk.crv]
return uint8ArrayConcat([
Uint8Array.from([4]), // uncompressed point
return Buffer.concat([
Buffer.from([4]), // uncompressed point
base64urlToBuffer(jwk.x, byteLen),
base64urlToBuffer(jwk.y, byteLen)
], 1 + byteLen * 2)
@ -102,20 +98,20 @@ function marshalPublicKey (jwk) {
function unmarshalPublicKey (curve, key) {
const byteLen = curveLengths[curve]
if (uint8ArrayEquals(!key.slice(0, 1), Uint8Array.from([4]))) {
if (!key.slice(0, 1).equals(Buffer.from([4]))) {
throw errcode(new Error('Cannot unmarshal public key - invalid key format'), 'ERR_INVALID_KEY_FORMAT')
}
return {
kty: 'EC',
crv: curve,
x: uint8ArrayToString(key.slice(1, byteLen + 1), 'base64url'),
y: uint8ArrayToString(key.slice(1 + byteLen), 'base64url'),
x: bufferToBase64url(key.slice(1, byteLen + 1), byteLen),
y: bufferToBase64url(key.slice(1 + byteLen), byteLen),
ext: true
}
}
const unmarshalPrivateKey = (curve, key) => ({
...unmarshalPublicKey(curve, key.public),
d: uint8ArrayToString(key.private, 'base64url')
d: bufferToBase64url(key.private)
})

View File

@ -1,13 +1,13 @@
'use strict'
const { Buffer } = require('buffer')
const sha = require('multihashing-async/src/sha')
const protobuf = require('protons')
const multibase = require('multibase')
const errcode = require('err-code')
const uint8ArrayEquals = require('uint8arrays/equals')
const mh = require('multihashes')
const crypto = require('./ed25519')
const pbm = protobuf(require('./keys.proto'))
const exporter = require('./exporter')
class Ed25519PublicKey {
constructor (key) {
@ -19,7 +19,7 @@ class Ed25519PublicKey {
}
marshal () {
return this._key
return Buffer.from(this._key)
}
get bytes () {
@ -30,7 +30,7 @@ class Ed25519PublicKey {
}
equals (key) {
return uint8ArrayEquals(this.bytes, key.bytes)
return this.bytes.equals(key.bytes)
}
async hash () { // eslint-disable-line require-await
@ -39,8 +39,8 @@ class Ed25519PublicKey {
}
class Ed25519PrivateKey {
// key - 64 byte Uint8Array containing private key
// publicKey - 32 byte Uint8Array containing public key
// key - 64 byte Uint8Array or Buffer containing private key
// publicKey - 32 byte Uint8Array or Buffer containing public key
constructor (key, publicKey) {
this._key = ensureKey(key, crypto.privateKeyLength)
this._publicKey = ensureKey(publicKey, crypto.publicKeyLength)
@ -55,7 +55,7 @@ class Ed25519PrivateKey {
}
marshal () {
return this._key
return Buffer.concat([Buffer.from(this._key), Buffer.from(this._publicKey)])
}
get bytes () {
@ -66,7 +66,7 @@ class Ed25519PrivateKey {
}
equals (key) {
return uint8ArrayEquals(this.bytes, key.bytes)
return this.bytes.equals(key.bytes)
}
async hash () { // eslint-disable-line require-await
@ -83,23 +83,8 @@ class Ed25519PrivateKey {
* @returns {Promise<String>}
*/
async id () {
const encoding = mh.encode(this.public.bytes, 'identity')
return await mh.toB58String(encoding)
}
/**
* Exports the key into a password protected `format`
*
* @param {string} password - The password to encrypt the key
* @param {string} [format=libp2p-key] - The format in which to export as
* @returns {Promise<Uint8Array>} The encrypted private key
*/
async export (password, format = 'libp2p-key') { // eslint-disable-line require-await
if (format === 'libp2p-key') {
return exporter.export(this.bytes, password)
} else {
throw errcode(new Error(`export format '${format}' is not supported`), 'ERR_INVALID_EXPORT_FORMAT')
}
const hash = await this.public.hash()
return multibase.encode('base58btc', hash).toString().slice(1)
}
}
@ -136,7 +121,7 @@ async function generateKeyPairFromSeed (seed) {
function ensureKey (key, length) {
key = Uint8Array.from(key || [])
if (key.length !== length) {
throw errcode(new Error(`Key must be a Uint8Array of length ${length}, got ${key.length}`), 'ERR_INVALID_KEY_TYPE')
throw errcode(new Error(`Key must be a Uint8Array or Buffer of length ${length}, got ${key.length}`), 'ERR_INVALID_KEY_TYPE')
}
return key
}

View File

@ -16,7 +16,7 @@ exports.generateKeyFromSeed = async function (seed) { // eslint-disable-line req
exports.hashAndSign = async function (key, msg) { // eslint-disable-line require-await
return forge.pki.ed25519.sign({ message: msg, privateKey: key })
// return Uint8Array.from(nacl.sign.detached(msg, key))
// return Buffer.from(nacl.sign.detached(msg, key))
}
exports.hashAndVerify = async function (key, sig, msg) { // eslint-disable-line require-await

View File

@ -1,22 +0,0 @@
'use strict'
const multibase = require('multibase')
const ciphers = require('../ciphers/aes-gcm')
module.exports = {
/**
* Exports the given PrivateKey as a base64 encoded string.
* The PrivateKey is encrypted via a password derived PBKDF2 key
* leveraging the aes-gcm cipher algorithm.
*
* @param {Uint8Array} privateKey The PrivateKey protobuf
* @param {string} password
* @returns {Promise<string>} A base64 encoded string
*/
export: async function (privateKey, password) {
const cipher = ciphers.create()
const encryptedKey = await cipher.encrypt(privateKey, password)
const base64 = multibase.names.base64
return base64.encode(encryptedKey)
}
}

View File

@ -1,22 +0,0 @@
'use strict'
const multibase = require('multibase')
const ciphers = require('../ciphers/aes-gcm')
module.exports = {
/**
* Attempts to decrypt a base64 encoded PrivateKey string
* with the given password. The privateKey must have been exported
* using the same password and underlying cipher (aes-gcm)
*
* @param {string} privateKey A base64 encoded encrypted key
* @param {string} password
* @returns {Promise<Uint8Array>} The private key protobuf
*/
import: async function (privateKey, password) {
const base64 = multibase.names.base64
const encryptedKey = base64.decode(privateKey)
const cipher = ciphers.create()
return await cipher.decrypt(encryptedKey, password)
}
}

View File

@ -1,14 +1,12 @@
'use strict'
const { Buffer } = require('buffer')
const protobuf = require('protons')
const keysPBM = protobuf(require('./keys.proto'))
require('node-forge/lib/asn1')
require('node-forge/lib/pbe')
const forge = require('node-forge/lib/forge')
const errcode = require('err-code')
const uint8ArrayFromString = require('uint8arrays/from-string')
const importer = require('./importer')
exports = module.exports
@ -111,25 +109,12 @@ exports.marshalPrivateKey = (key, type) => {
return key.bytes
}
/**
*
* @param {string} encryptedKey
* @param {string} password
*/
exports.import = async (encryptedKey, password) => { // eslint-disable-line require-await
try {
const key = await importer.import(encryptedKey, password)
return exports.unmarshalPrivateKey(key)
} catch (_) {
// Ignore and try the old pem decrypt
}
// Only rsa supports pem right now
const key = forge.pki.decryptRsaPrivateKey(encryptedKey, password)
exports.import = async (pem, password) => { // eslint-disable-line require-await
const key = forge.pki.decryptRsaPrivateKey(pem, password)
if (key === null) {
throw errcode(new Error('Cannot read the key, most likely the password is wrong or not a RSA key'), 'ERR_CANNOT_DECRYPT_PEM')
}
let der = forge.asn1.toDer(forge.pki.privateKeyToAsn1(key))
der = uint8ArrayFromString(der.getBytes(), 'ascii')
der = Buffer.from(der.getBytes(), 'binary')
return supportedKeys.rsa.unmarshalRsaPrivateKey(der)
}

View File

@ -1,8 +1,6 @@
'use strict'
const { Buffer } = require('buffer')
const errcode = require('err-code')
const uint8ArrayConcat = require('uint8arrays/concat')
const uint8ArrayFromString = require('uint8arrays/from-string')
const hmac = require('../hmac')
const cipherMap = {
@ -37,7 +35,7 @@ module.exports = async (cipherType, hash, secret) => {
const cipherKeySize = cipher.keySize
const ivSize = cipher.ivSize
const hmacKeySize = 20
const seed = uint8ArrayFromString('key expansion')
const seed = Buffer.from('key expansion')
const resultLength = 2 * (ivSize + cipherKeySize + hmacKeySize)
const m = await hmac.create(hash, secret)
@ -47,7 +45,7 @@ module.exports = async (cipherType, hash, secret) => {
let j = 0
while (j < resultLength) {
const b = await m.digest(uint8ArrayConcat([a, seed]))
const b = await m.digest(Buffer.concat([a, seed]))
let todo = b.length
if (j + todo > resultLength) {
@ -60,7 +58,7 @@ module.exports = async (cipherType, hash, secret) => {
}
const half = resultLength / 2
const resultBuffer = uint8ArrayConcat(result)
const resultBuffer = Buffer.concat(result)
const r1 = resultBuffer.slice(0, half)
const r2 = resultBuffer.slice(half, resultLength)

View File

@ -1,9 +1,8 @@
'use strict'
const { Buffer } = require('buffer')
const webcrypto = require('../webcrypto')
const randomBytes = require('../random-bytes')
const uint8ArrayToString = require('uint8arrays/to-string')
const uint8ArrayFromString = require('uint8arrays/from-string')
exports.utils = require('./rsa-utils')
@ -76,7 +75,7 @@ exports.hashAndSign = async function (key, msg) {
Uint8Array.from(msg)
)
return new Uint8Array(sig, sig.byteOffset, sig.byteLength)
return Buffer.from(sig)
}
exports.hashAndVerify = async function (key, sig, msg) {
@ -130,8 +129,8 @@ RSA encryption/decryption for the browser with webcrypto workarround
Explanation:
- Convert JWK to nodeForge
- Convert msg Uint8Array to nodeForge buffer: ByteBuffer is a "binary-string backed buffer", so let's make our Uint8Array a binary string
- Convert resulting nodeForge buffer to Uint8Array: it returns a binary string, turn that into a Uint8Array
- Convert msg buffer to nodeForge buffer: ByteBuffer is a "binary-string backed buffer", so let's make our buffer a binary string
- Convert resulting nodeForge buffer to buffer: it returns a binary string, turn that into a uint8array(buffer)
*/
@ -139,9 +138,9 @@ const { jwk2pub, jwk2priv } = require('./jwk2pem')
function convertKey (key, pub, msg, handle) {
const fkey = pub ? jwk2pub(key) : jwk2priv(key)
const fmsg = uint8ArrayToString(Uint8Array.from(msg), 'ascii')
const fmsg = Buffer.from(msg).toString('binary')
const fomsg = handle(fmsg, fkey)
return uint8ArrayFromString(fomsg, 'ascii')
return Buffer.from(fomsg, 'binary')
}
exports.encrypt = function (key, msg) {

View File

@ -2,17 +2,14 @@
const sha = require('multihashing-async/src/sha')
const protobuf = require('protons')
const multibase = require('multibase')
const errcode = require('err-code')
const uint8ArrayEquals = require('uint8arrays/equals')
const uint8ArrayToString = require('uint8arrays/to-string')
require('node-forge/lib/sha512')
require('node-forge/lib/ed25519')
const forge = require('node-forge/lib/forge')
const crypto = require('./rsa')
const pbm = protobuf(require('./keys.proto'))
const exporter = require('./exporter')
require('node-forge/lib/sha512')
require('node-forge/lib/ed25519')
const forge = require('node-forge/lib/forge')
class RsaPublicKey {
constructor (key) {
@ -39,7 +36,7 @@ class RsaPublicKey {
}
equals (key) {
return uint8ArrayEquals(this.bytes, key.bytes)
return this.bytes.equals(key.bytes)
}
async hash () { // eslint-disable-line require-await
@ -49,7 +46,7 @@ class RsaPublicKey {
class RsaPrivateKey {
// key - Object of the jwk format
// publicKey - Uint8Array of the spki format
// publicKey - Buffer of the spki format
constructor (key, publicKey) {
this._key = key
this._publicKey = publicKey
@ -87,7 +84,7 @@ class RsaPrivateKey {
}
equals (key) {
return uint8ArrayEquals(this.bytes, key.bytes)
return this.bytes.equals(key.bytes)
}
async hash () { // eslint-disable-line require-await
@ -105,33 +102,35 @@ class RsaPrivateKey {
*/
async id () {
const hash = await this.public.hash()
return uint8ArrayToString(hash, 'base58btc')
return multibase.encode('base58btc', hash).toString().slice(1)
}
/**
* Exports the key into a password protected PEM format
*
* @param {string} password - The password to read the encrypted PEM
* @param {string} [format=pkcs-8] - The format in which to export as
* @param {string} [format] - Defaults to 'pkcs-8'.
*/
async export (password, format = 'pkcs-8') { // eslint-disable-line require-await
if (format === 'pkcs-8') {
const buffer = new forge.util.ByteBuffer(this.marshal())
const asn1 = forge.asn1.fromDer(buffer)
const privateKey = forge.pki.privateKeyFromAsn1(asn1)
let pem = null
const buffer = new forge.util.ByteBuffer(this.marshal())
const asn1 = forge.asn1.fromDer(buffer)
const privateKey = forge.pki.privateKeyFromAsn1(asn1)
if (format === 'pkcs-8') {
const options = {
algorithm: 'aes256',
count: 10000,
saltSize: 128 / 8,
prfAlgorithm: 'sha512'
}
return forge.pki.encryptRsaPrivateKey(privateKey, password, options)
} else if (format === 'libp2p-key') {
return exporter.export(this.bytes, password)
pem = forge.pki.encryptRsaPrivateKey(privateKey, password, options)
} else {
throw errcode(new Error(`export format '${format}' is not supported`), 'ERR_INVALID_EXPORT_FORMAT')
throw errcode(new Error(`Unknown export format '${format}'. Must be pkcs-8`), 'ERR_INVALID_EXPORT_FORMAT')
}
return pem
}
}

View File

@ -1,15 +1,14 @@
'use strict'
const { Buffer } = require('buffer')
require('node-forge/lib/asn1')
require('node-forge/lib/rsa')
const forge = require('node-forge/lib/forge')
const { bigIntegerToUintBase64url, base64urlToBigInteger } = require('./../util')
const uint8ArrayFromString = require('uint8arrays/from-string')
const uint8ArrayToString = require('uint8arrays/to-string')
// Convert a PKCS#1 in ASN1 DER format to a JWK key
exports.pkcs1ToJwk = function (bytes) {
const asn1 = forge.asn1.fromDer(uint8ArrayToString(bytes, 'ascii'))
const asn1 = forge.asn1.fromDer(bytes.toString('binary'))
const privateKey = forge.pki.privateKeyFromAsn1(asn1)
// https://tools.ietf.org/html/rfc7518#section-6.3.1
@ -41,12 +40,12 @@ exports.jwkToPkcs1 = function (jwk) {
qInv: base64urlToBigInteger(jwk.qi)
})
return uint8ArrayFromString(forge.asn1.toDer(asn1).getBytes(), 'ascii')
return Buffer.from(forge.asn1.toDer(asn1).getBytes(), 'binary')
}
// Convert a PKCIX in ASN1 DER format to a JWK key
exports.pkixToJwk = function (bytes) {
const asn1 = forge.asn1.fromDer(uint8ArrayToString(bytes, 'ascii'))
const asn1 = forge.asn1.fromDer(bytes.toString('binary'))
const publicKey = forge.pki.publicKeyFromAsn1(asn1)
return {
@ -65,5 +64,5 @@ exports.jwkToPkix = function (jwk) {
e: base64urlToBigInteger(jwk.e)
})
return uint8ArrayFromString(forge.asn1.toDer(asn1).getBytes(), 'ascii')
return Buffer.from(forge.asn1.toDer(asn1).getBytes(), 'binary')
}

View File

@ -1,11 +1,7 @@
'use strict'
const multibase = require('multibase')
const sha = require('multihashing-async/src/sha')
const errcode = require('err-code')
const uint8ArrayEquals = require('uint8arrays/equals')
const uint8ArrayToString = require('uint8arrays/to-string')
const exporter = require('./exporter')
module.exports = (keysProtobuf, randomBytes, crypto) => {
crypto = crypto || require('./secp256k1')(randomBytes)
@ -32,7 +28,7 @@ module.exports = (keysProtobuf, randomBytes, crypto) => {
}
equals (key) {
return uint8ArrayEquals(this.bytes, key.bytes)
return this.bytes.equals(key.bytes)
}
hash () {
@ -68,7 +64,7 @@ module.exports = (keysProtobuf, randomBytes, crypto) => {
}
equals (key) {
return uint8ArrayEquals(this.bytes, key.bytes)
return this.bytes.equals(key.bytes)
}
hash () {
@ -86,22 +82,7 @@ module.exports = (keysProtobuf, randomBytes, crypto) => {
*/
async id () {
const hash = await this.public.hash()
return uint8ArrayToString(hash, 'base58btc')
}
/**
* Exports the key into a password protected `format`
*
* @param {string} password - The password to encrypt the key
* @param {string} [format=libp2p-key] - The format in which to export as
* @returns {Promise<string>} The encrypted private key
*/
async export (password, format = 'libp2p-key') { // eslint-disable-line require-await
if (format === 'libp2p-key') {
return exporter.export(this.bytes, password)
} else {
throw errcode(new Error(`export format '${format}' is not supported`), 'ERR_INVALID_EXPORT_FORMAT')
}
return multibase.encode('base58btc', hash).toString().slice(1)
}
}

View File

@ -1,9 +1,26 @@
'use strict'
const { Buffer } = require('buffer')
var isTypedArray = require('is-typedarray').strict
const secp256k1 = require('secp256k1')
const sha = require('multihashing-async/src/sha')
const HASH_ALGORITHM = 'sha2-256'
function typedArrayTobuffer (arr) {
if (isTypedArray(arr)) {
// To avoid a copy, use the typed array's underlying ArrayBuffer to back new Buffer
var buf = Buffer.from(arr.buffer)
if (arr.byteLength !== arr.buffer.byteLength) {
// Respect the "view", i.e. byteOffset and byteLength, without doing a copy
buf = buf.slice(arr.byteOffset, arr.byteOffset + arr.byteLength)
}
return buf
} else {
// Pass through all other types to `Buffer.from`
return Buffer.from(arr)
}
}
module.exports = (randomBytes) => {
const privateKeyLength = 32
@ -18,12 +35,12 @@ module.exports = (randomBytes) => {
async function hashAndSign (key, msg) {
const digest = await sha.digest(msg, HASH_ALGORITHM)
const sig = secp256k1.ecdsaSign(digest, key)
return secp256k1.signatureExport(sig.signature)
return typedArrayTobuffer(secp256k1.signatureExport(sig.signature))
}
async function hashAndVerify (key, sig, msg) {
const digest = await sha.digest(msg, HASH_ALGORITHM)
sig = secp256k1.signatureImport(sig)
sig = typedArrayTobuffer(secp256k1.signatureImport(sig))
return secp256k1.ecdsaVerify(sig, digest, key)
}
@ -31,11 +48,11 @@ module.exports = (randomBytes) => {
if (!secp256k1.publicKeyVerify(key)) {
throw new Error('Invalid public key')
}
return secp256k1.publicKeyConvert(key, true)
return typedArrayTobuffer(secp256k1.publicKeyConvert(key, true))
}
function decompressPublicKey (key) {
return secp256k1.publicKeyConvert(key, false)
return typedArrayTobuffer(secp256k1.publicKeyConvert(key, false))
}
function validatePrivateKey (key) {
@ -52,7 +69,7 @@ module.exports = (randomBytes) => {
function computePublicKey (privateKey) {
validatePrivateKey(privateKey)
return secp256k1.publicKeyCreate(privateKey)
return typedArrayTobuffer(secp256k1.publicKeyCreate(privateKey))
}
return {

View File

@ -1,15 +1,13 @@
'use strict'
const { Buffer } = require('buffer')
require('node-forge/lib/util')
require('node-forge/lib/jsbn')
const forge = require('node-forge/lib/forge')
const uint8ArrayFromString = require('uint8arrays/from-string')
const uint8ArrayToString = require('uint8arrays/to-string')
const uint8ArrayConcat = require('uint8arrays/concat')
exports.bigIntegerToUintBase64url = (num, len) => {
// Call `.abs()` to convert to unsigned
let buf = Uint8Array.from(num.abs().toByteArray()) // toByteArray converts to big endian
let buf = Buffer.from(num.abs().toByteArray()) // toByteArray converts to big endian
// toByteArray() gives us back a signed array, which will include a leading 0
// byte if the most significant bit of the number is 1:
@ -19,24 +17,38 @@ exports.bigIntegerToUintBase64url = (num, len) => {
if (len != null) {
if (buf.length > len) throw new Error('byte array longer than desired length')
buf = uint8ArrayConcat([new Uint8Array(len - buf.length), buf])
buf = Buffer.concat([Buffer.alloc(len - buf.length), buf])
}
return uint8ArrayToString(buf, 'base64url')
return exports.bufferToBase64url(buf)
}
// Convert a Buffer to a base64 encoded string without padding
// Adapted from https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41#appendix-C
exports.bufferToBase64url = buf => {
return buf
.toString('base64')
.split('=')[0] // Remove any trailing '='s
.replace(/\+/g, '-') // 62nd char of encoding
.replace(/\//g, '_') // 63rd char of encoding
}
// Convert a base64url encoded string to a BigInteger
exports.base64urlToBigInteger = str => {
const buf = exports.base64urlToBuffer(str)
return new forge.jsbn.BigInteger(uint8ArrayToString(buf, 'base16'), 16)
return new forge.jsbn.BigInteger(buf.toString('hex'), 16)
}
exports.base64urlToBuffer = (str, len) => {
let buf = uint8ArrayFromString(str, 'base64urlpad')
str = (str + '==='.slice((str.length + 3) % 4))
.replace(/-/g, '+')
.replace(/_/g, '/')
let buf = Buffer.from(str, 'base64')
if (len != null) {
if (buf.length > len) throw new Error('byte array longer than desired length')
buf = uint8ArrayConcat([new Uint8Array(len - buf.length), buf])
buf = Buffer.concat([Buffer.alloc(len - buf.length), buf])
}
return buf

View File

@ -2,7 +2,7 @@
/* eslint-disable valid-jsdoc */
/* eslint-env mocha */
'use strict'
const { Buffer } = require('buffer')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
@ -23,10 +23,10 @@ const bytes = {
describe('AES-CTR', () => {
Object.keys(bytes).forEach((byte) => {
it(`${bytes[byte]} - encrypt and decrypt`, async () => {
const key = new Uint8Array(parseInt(byte, 10))
const key = Buffer.alloc(parseInt(byte, 10))
key.fill(5)
const iv = new Uint8Array(16)
const iv = Buffer.alloc(16)
iv.fill(1)
const cipher = await crypto.aes.create(key, iv)
@ -41,18 +41,18 @@ describe('AES-CTR', () => {
Object.keys(bytes).forEach((byte) => {
it(`${bytes[byte]} - fixed - encrypt and decrypt`, async () => {
const key = new Uint8Array(parseInt(byte, 10))
const key = Buffer.alloc(parseInt(byte, 10))
key.fill(5)
const iv = new Uint8Array(16)
const iv = Buffer.alloc(16)
iv.fill(1)
const cipher = await crypto.aes.create(key, iv)
for (let i = 0; i < fixtures[byte].inputs.length; i++) {
const rawIn = fixtures[byte].inputs[i]
const input = Uint8Array.from(rawIn.data)
const output = Uint8Array.from(fixtures[byte].outputs[i].data)
const input = Buffer.from(rawIn)
const output = Buffer.from(fixtures[byte].outputs[i])
const encrypted = await cipher.encrypt(input)
expect(encrypted).to.have.length(output.length)
expect(encrypted).to.eql(output)
@ -68,18 +68,18 @@ describe('AES-CTR', () => {
}
it(`${bytes[byte]} - go interop - encrypt and decrypt`, async () => {
const key = new Uint8Array(parseInt(byte, 10))
const key = Buffer.alloc(parseInt(byte, 10))
key.fill(5)
const iv = new Uint8Array(16)
const iv = Buffer.alloc(16)
iv.fill(1)
const cipher = await crypto.aes.create(key, iv)
for (let i = 0; i < goFixtures[byte].inputs.length; i++) {
const rawIn = goFixtures[byte].inputs[i]
const input = Uint8Array.from(rawIn)
const output = Uint8Array.from(goFixtures[byte].outputs[i])
const input = Buffer.from(rawIn)
const output = Buffer.from(goFixtures[byte].outputs[i])
const encrypted = await cipher.encrypt(input)
expect(encrypted).to.have.length(output.length)
expect(encrypted).to.eql(output)
@ -90,8 +90,8 @@ describe('AES-CTR', () => {
})
it('checks key length', () => {
const key = new Uint8Array(5)
const iv = new Uint8Array(16)
const key = Buffer.alloc(5)
const iv = Buffer.alloc(16)
return expectErrCode(crypto.aes.create(key, iv), 'ERR_INVALID_KEY_LENGTH')
})
})
@ -101,7 +101,7 @@ describe('AES-CTR', () => {
* @type {function(Cipher): Promise<void>}
*/
async function encryptAndDecrypt (cipher) {
const data = new Uint8Array(100)
const data = Buffer.alloc(100)
data.fill(Math.ceil(Math.random() * 100))
const encrypted = await cipher.encrypt(data)

View File

@ -2,10 +2,9 @@
'use strict'
const chai = require('chai')
chai.use(require('dirty-chai'))
const dirtyChai = require('dirty-chai')
const expect = chai.expect
const uint8ArrayFromString = require('uint8arrays/from-string')
chai.use(dirtyChai)
const crypto = require('../')
const webcrypto = require('../src/webcrypto')
@ -37,7 +36,7 @@ describe('Missing web crypto', () => {
})
it('should error for hmac create when web crypto is missing', () => {
return expectMissingWebCrypto(() => crypto.hmac.create('SHA256', uint8ArrayFromString('secret')))
return expectMissingWebCrypto(() => crypto.hmac.create('SHA256', Buffer.from('secret')))
})
it('should error for generate ephemeral key pair when web crypto is missing', () => {
@ -53,10 +52,10 @@ describe('Missing web crypto', () => {
})
it('should error for sign RSA private key when web crypto is missing', () => {
return expectMissingWebCrypto(() => rsaPrivateKey.sign(uint8ArrayFromString('test')))
return expectMissingWebCrypto(() => rsaPrivateKey.sign(Buffer.from('test')))
})
it('should error for verify RSA public key when web crypto is missing', () => {
return expectMissingWebCrypto(() => rsaPrivateKey.public.verify(uint8ArrayFromString('test'), uint8ArrayFromString('test')))
return expectMissingWebCrypto(() => rsaPrivateKey.public.verify(Buffer.from('test'), Buffer.from('test')))
})
})

View File

@ -9,7 +9,6 @@ chai.use(dirtyChai)
const crypto = require('../src')
const fixtures = require('./fixtures/go-key-rsa')
const { expectErrCode } = require('./util')
const uint8ArrayEquals = require('uint8arrays/equals')
/** @typedef {import("libp2p-crypto").PrivateKey} PrivateKey */
@ -84,7 +83,7 @@ describe('libp2p-crypto', function () {
it('unmarshal -> marshal, public key', () => {
const key = crypto.keys.unmarshalPublicKey(fixtures.public.key)
const marshalled = crypto.keys.marshalPublicKey(key)
expect(uint8ArrayEquals(fixtures.public.key, marshalled)).to.eql(true)
expect(fixtures.public.key.equals(marshalled)).to.eql(true)
})
})

View File

@ -1,12 +1,13 @@
'use strict'
const { Buffer } = require('buffer')
module.exports = {
curve: 'P-256',
bob: {
private: Uint8Array.from([
private: Buffer.from([
181, 217, 162, 151, 225, 36, 53, 253, 107, 66, 27, 27, 232, 72, 0, 0, 103, 167, 84, 62, 203, 91, 97, 137, 131, 193, 230, 126, 98, 242, 216, 170
]),
public: Uint8Array.from([
public: Buffer.from([
4, 53, 59, 128, 56, 162, 250, 72, 141, 206, 117, 232, 57, 96, 39, 39, 247, 7, 27, 57, 251, 232, 120, 186, 21, 239, 176, 139, 195, 129, 125, 85, 11, 188, 191, 32, 227, 0, 6, 163, 101, 68, 208, 1, 43, 131, 124, 112, 102, 91, 104, 79, 16, 119, 152, 208, 4, 147, 155, 83, 20, 146, 104, 55, 90
])
}

View File

@ -1,4 +1,5 @@
'use strict'
const { Buffer } = require('buffer')
module.exports = {
// Generation code from https://github.com/libp2p/js-libp2p-crypto/issues/175#issuecomment-634467463
@ -19,24 +20,24 @@ module.exports = {
// privkeyBytes, _ := priv.Bytes()
// data := []byte("hello! and welcome to some awesome crypto primitives")
// sig, _ := priv.Sign(data)
// fmt.Println("{\n publicKey: Uint8Array.from(", strings.Replace(fmt.Sprint(pubkeyBytes), " ", ",", -1), "),")
// fmt.Println(" privateKey: Uint8Array.from(", strings.Replace(fmt.Sprint(privkeyBytes), " ", ",", -1), "),")
// fmt.Println(" data: Uint8Array.from(", strings.Replace(fmt.Sprint(data), " ", ",", -1), "),")
// fmt.Println(" signature: Uint8Array.from(", strings.Replace(fmt.Sprint(sig), " ", ",", -1), ")\n}")
// fmt.Println("{\n publicKey: Buffer.from(", strings.Replace(fmt.Sprint(pubkeyBytes), " ", ",", -1), "),")
// fmt.Println(" privateKey: Buffer.from(", strings.Replace(fmt.Sprint(privkeyBytes), " ", ",", -1), "),")
// fmt.Println(" data: Buffer.from(", strings.Replace(fmt.Sprint(data), " ", ",", -1), "),")
// fmt.Println(" signature: Buffer.from(", strings.Replace(fmt.Sprint(sig), " ", ",", -1), ")\n}")
// }
//
// The legacy key unnecessarily appends the publickey. (It's already included) See https://github.com/libp2p/js-libp2p-crypto/issues/175
redundantPubKey: {
privateKey: Uint8Array.from([8, 1, 18, 96, 201, 208, 1, 110, 176, 16, 230, 37, 66, 184, 149, 252, 78, 56, 206, 136, 2, 38, 118, 152, 226, 197, 117, 200, 54, 189, 156, 218, 184, 7, 118, 57, 233, 49, 221, 97, 164, 158, 241, 129, 73, 166, 225, 255, 193, 118, 22, 84, 55, 15, 249, 168, 225, 180, 198, 191, 14, 75, 187, 243, 150, 91, 232, 37, 233, 49, 221, 97, 164, 158, 241, 129, 73, 166, 225, 255, 193, 118, 22, 84, 55, 15, 249, 168, 225, 180, 198, 191, 14, 75, 187, 243, 150, 91, 232, 37]),
publicKey: Uint8Array.from([8, 1, 18, 32, 233, 49, 221, 97, 164, 158, 241, 129, 73, 166, 225, 255, 193, 118, 22, 84, 55, 15, 249, 168, 225, 180, 198, 191, 14, 75, 187, 243, 150, 91, 232, 37]),
data: Uint8Array.from([104, 101, 108, 108, 111, 33, 32, 97, 110, 100, 32, 119, 101, 108, 99, 111, 109, 101, 32, 116, 111, 32, 115, 111, 109, 101, 32, 97, 119, 101, 115, 111, 109, 101, 32, 99, 114, 121, 112, 116, 111, 32, 112, 114, 105, 109, 105, 116, 105, 118, 101, 115]),
signature: Uint8Array.from([7, 230, 175, 164, 228, 58, 78, 208, 62, 243, 73, 142, 83, 195, 176, 217, 166, 62, 41, 165, 168, 164, 75, 179, 163, 86, 102, 32, 18, 84, 150, 237, 39, 207, 213, 20, 134, 237, 50, 41, 176, 183, 229, 133, 38, 255, 42, 228, 68, 186, 100, 14, 175, 156, 243, 118, 125, 125, 120, 212, 124, 103, 252, 12])
privateKey: Buffer.from([8, 1, 18, 96, 201, 208, 1, 110, 176, 16, 230, 37, 66, 184, 149, 252, 78, 56, 206, 136, 2, 38, 118, 152, 226, 197, 117, 200, 54, 189, 156, 218, 184, 7, 118, 57, 233, 49, 221, 97, 164, 158, 241, 129, 73, 166, 225, 255, 193, 118, 22, 84, 55, 15, 249, 168, 225, 180, 198, 191, 14, 75, 187, 243, 150, 91, 232, 37, 233, 49, 221, 97, 164, 158, 241, 129, 73, 166, 225, 255, 193, 118, 22, 84, 55, 15, 249, 168, 225, 180, 198, 191, 14, 75, 187, 243, 150, 91, 232, 37]),
publicKey: Buffer.from([8, 1, 18, 32, 233, 49, 221, 97, 164, 158, 241, 129, 73, 166, 225, 255, 193, 118, 22, 84, 55, 15, 249, 168, 225, 180, 198, 191, 14, 75, 187, 243, 150, 91, 232, 37]),
data: Buffer.from([104, 101, 108, 108, 111, 33, 32, 97, 110, 100, 32, 119, 101, 108, 99, 111, 109, 101, 32, 116, 111, 32, 115, 111, 109, 101, 32, 97, 119, 101, 115, 111, 109, 101, 32, 99, 114, 121, 112, 116, 111, 32, 112, 114, 105, 109, 105, 116, 105, 118, 101, 115]),
signature: Buffer.from([7, 230, 175, 164, 228, 58, 78, 208, 62, 243, 73, 142, 83, 195, 176, 217, 166, 62, 41, 165, 168, 164, 75, 179, 163, 86, 102, 32, 18, 84, 150, 237, 39, 207, 213, 20, 134, 237, 50, 41, 176, 183, 229, 133, 38, 255, 42, 228, 68, 186, 100, 14, 175, 156, 243, 118, 125, 125, 120, 212, 124, 103, 252, 12])
},
verify: {
publicKey: Uint8Array.from([8, 1, 18, 32, 163, 176, 195, 47, 254, 208, 49, 5, 192, 102, 32, 63, 58, 202, 171, 153, 146, 164, 25, 212, 25, 91, 146, 26, 117, 165, 148, 6, 207, 90, 217, 126]),
privateKey: Uint8Array.from([8, 1, 18, 64, 232, 56, 175, 20, 240, 160, 19, 47, 92, 88, 115, 221, 164, 13, 36, 162, 158, 136, 247, 31, 29, 231, 76, 143, 12, 91, 193, 4, 88, 33, 67, 23, 163, 176, 195, 47, 254, 208, 49, 5, 192, 102, 32, 63, 58, 202, 171, 153, 146, 164, 25, 212, 25, 91, 146, 26, 117, 165, 148, 6, 207, 90, 217, 126]),
data: Uint8Array.from([104, 101, 108, 108, 111, 33, 32, 97, 110, 100, 32, 119, 101, 108, 99, 111, 109, 101, 32, 116, 111, 32, 115, 111, 109, 101, 32, 97, 119, 101, 115, 111, 109, 101, 32, 99, 114, 121, 112, 116, 111, 32, 112, 114, 105, 109, 105, 116, 105, 118, 101, 115]),
signature: Uint8Array.from([160, 125, 30, 62, 213, 189, 239, 92, 87, 76, 205, 169, 251, 149, 187, 57, 96, 85, 175, 213, 22, 132, 229, 60, 196, 18, 117, 194, 12, 174, 135, 31, 39, 168, 174, 103, 78, 55, 37, 222, 37, 172, 222, 239, 153, 63, 197, 152, 67, 167, 191, 215, 161, 212, 216, 163, 81, 77, 45, 228, 151, 79, 101, 1])
publicKey: Buffer.from([8, 1, 18, 32, 163, 176, 195, 47, 254, 208, 49, 5, 192, 102, 32, 63, 58, 202, 171, 153, 146, 164, 25, 212, 25, 91, 146, 26, 117, 165, 148, 6, 207, 90, 217, 126]),
privateKey: Buffer.from([8, 1, 18, 64, 232, 56, 175, 20, 240, 160, 19, 47, 92, 88, 115, 221, 164, 13, 36, 162, 158, 136, 247, 31, 29, 231, 76, 143, 12, 91, 193, 4, 88, 33, 67, 23, 163, 176, 195, 47, 254, 208, 49, 5, 192, 102, 32, 63, 58, 202, 171, 153, 146, 164, 25, 212, 25, 91, 146, 26, 117, 165, 148, 6, 207, 90, 217, 126]),
data: Buffer.from([104, 101, 108, 108, 111, 33, 32, 97, 110, 100, 32, 119, 101, 108, 99, 111, 109, 101, 32, 116, 111, 32, 115, 111, 109, 101, 32, 97, 119, 101, 115, 111, 109, 101, 32, 99, 114, 121, 112, 116, 111, 32, 112, 114, 105, 109, 105, 116, 105, 118, 101, 115]),
signature: Buffer.from([160, 125, 30, 62, 213, 189, 239, 92, 87, 76, 205, 169, 251, 149, 187, 57, 96, 85, 175, 213, 22, 132, 229, 60, 196, 18, 117, 194, 12, 174, 135, 31, 39, 168, 174, 103, 78, 55, 37, 222, 37, 172, 222, 239, 153, 63, 197, 152, 67, 167, 191, 215, 161, 212, 216, 163, 81, 77, 45, 228, 151, 79, 101, 1])
}
}

View File

@ -1,30 +1,30 @@
'use strict'
const { Buffer } = require('buffer')
module.exports = {
private: {
hash: Uint8Array.from([
hash: Buffer.from([
18, 32, 168, 125, 165, 65, 34, 157, 209, 4, 24, 158, 80, 196, 125, 86, 103, 0, 228, 145, 109, 252, 153, 7, 189, 9, 16, 37, 239, 36, 48, 78, 214, 212
]),
key: Uint8Array.from([
key: Buffer.from([
8, 0, 18, 192, 2, 48, 130, 1, 60, 2, 1, 0, 2, 65, 0, 230, 157, 160, 242, 74, 222, 87, 0, 77, 180, 91, 175, 217, 166, 2, 95, 193, 239, 195, 140, 224, 57, 84, 207, 46, 172, 113, 196, 20, 133, 117, 205, 45, 7, 224, 41, 40, 195, 254, 124, 14, 84, 223, 147, 67, 198, 48, 36, 53, 161, 112, 46, 153, 90, 19, 123, 94, 247, 5, 116, 1, 238, 32, 15, 2, 3, 1, 0, 1, 2, 65, 0, 191, 59, 140, 255, 254, 23, 123, 91, 148, 19, 240, 71, 213, 26, 181, 51, 68, 181, 150, 153, 214, 65, 148, 83, 45, 103, 239, 250, 225, 237, 125, 173, 111, 244, 37, 124, 87, 178, 86, 10, 14, 207, 63, 105, 213, 37, 81, 23, 230, 4, 222, 179, 144, 40, 252, 163, 190, 7, 241, 221, 28, 54, 225, 209, 2, 33, 0, 235, 132, 229, 150, 99, 182, 176, 194, 198, 65, 210, 160, 184, 70, 82, 49, 235, 199, 14, 11, 92, 66, 237, 45, 220, 72, 235, 1, 244, 145, 205, 57, 2, 33, 0, 250, 171, 146, 180, 188, 194, 14, 152, 52, 64, 38, 52, 158, 86, 46, 109, 66, 100, 122, 43, 88, 167, 143, 98, 104, 143, 160, 60, 171, 185, 31, 135, 2, 33, 0, 206, 47, 255, 203, 100, 170, 137, 31, 75, 240, 78, 84, 212, 95, 4, 16, 158, 73, 27, 27, 136, 255, 50, 163, 166, 169, 211, 204, 87, 111, 217, 201, 2, 33, 0, 177, 51, 194, 213, 3, 175, 7, 84, 47, 115, 189, 206, 106, 180, 47, 195, 203, 48, 110, 112, 224, 14, 43, 189, 124, 127, 51, 222, 79, 226, 225, 87, 2, 32, 67, 23, 190, 222, 106, 22, 115, 139, 217, 244, 178, 53, 153, 99, 5, 176, 72, 77, 193, 61, 67, 134, 37, 238, 69, 66, 159, 28, 39, 5, 238, 125
])
},
public: {
hash: Uint8Array.from([
hash: Buffer.from([
18, 32, 112, 151, 163, 167, 204, 243, 175, 123, 208, 162, 90, 84, 199, 174, 202, 110, 0, 119, 27, 202, 7, 149, 161, 251, 215, 168, 163, 54, 93, 54, 195, 20
]),
key: Uint8Array.from([
key: Buffer.from([
8, 0, 18, 94, 48, 92, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 75, 0, 48, 72, 2, 65, 0, 230, 157, 160, 242, 74, 222, 87, 0, 77, 180, 91, 175, 217, 166, 2, 95, 193, 239, 195, 140, 224, 57, 84, 207, 46, 172, 113, 196, 20, 133, 117, 205, 45, 7, 224, 41, 40, 195, 254, 124, 14, 84, 223, 147, 67, 198, 48, 36, 53, 161, 112, 46, 153, 90, 19, 123, 94, 247, 5, 116, 1, 238, 32, 15, 2, 3, 1, 0, 1
])
},
verify: {
signature: Uint8Array.from([
signature: Buffer.from([
3, 116, 81, 57, 91, 194, 7, 1, 230, 236, 229, 142, 36, 209, 208, 107, 47, 52, 164, 236, 139, 35, 155, 97, 43, 64, 145, 91, 19, 218, 149, 63, 99, 164, 191, 110, 145, 37, 18, 7, 98, 112, 144, 35, 29, 186, 169, 150, 165, 88, 145, 170, 197, 110, 42, 163, 188, 10, 42, 63, 34, 93, 91, 94, 199, 110, 10, 82, 238, 80, 93, 93, 77, 130, 22, 216, 229, 172, 36, 229, 82, 162, 20, 78, 19, 46, 82, 243, 43, 80, 115, 125, 145, 231, 194, 224, 30, 187, 55, 228, 74, 52, 203, 191, 254, 148, 136, 218, 62, 147, 171, 130, 251, 181, 105, 29, 238, 207, 197, 249, 61, 105, 202, 172, 160, 174, 43, 124, 115, 130, 169, 30, 76, 41, 52, 200, 2, 26, 53, 190, 43, 20, 203, 10, 217, 250, 47, 102, 92, 103, 197, 22, 108, 184, 74, 218, 82, 202, 180, 98, 13, 114, 12, 92, 1, 139, 150, 170, 8, 92, 32, 116, 168, 219, 157, 162, 28, 77, 29, 29, 74, 136, 144, 49, 173, 245, 253, 76, 167, 200, 169, 163, 7, 49, 133, 120, 99, 191, 53, 10, 66, 26, 234, 240, 139, 235, 134, 30, 55, 248, 150, 100, 242, 150, 159, 198, 44, 78, 150, 7, 133, 139, 59, 76, 3, 225, 94, 13, 89, 122, 34, 95, 95, 107, 74, 169, 171, 169, 222, 25, 191, 182, 148, 116, 66, 67, 102, 12, 193, 217, 247, 243, 148, 233, 161, 157
]),
data: Uint8Array.from([
data: Buffer.from([
10, 16, 27, 128, 228, 220, 147, 176, 53, 105, 175, 171, 32, 213, 35, 236, 203, 60, 18, 171, 2, 8, 0, 18, 166, 2, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 181, 113, 138, 108, 208, 103, 166, 102, 37, 36, 204, 250, 228, 165, 44, 64, 176, 210, 205, 141, 241, 55, 200, 110, 98, 68, 85, 199, 254, 19, 86, 204, 63, 250, 167, 38, 59, 249, 146, 228, 73, 171, 63, 18, 96, 104, 191, 137, 186, 244, 255, 90, 16, 119, 195, 52, 177, 213, 254, 187, 174, 84, 174, 173, 12, 236, 53, 234, 3, 209, 82, 37, 78, 111, 214, 135, 76, 195, 9, 242, 134, 188, 153, 84, 139, 231, 51, 146, 177, 60, 12, 25, 158, 91, 215, 152, 7, 0, 84, 35, 36, 230, 227, 67, 198, 72, 50, 110, 37, 209, 98, 193, 65, 93, 173, 199, 4, 198, 102, 99, 148, 144, 224, 217, 114, 53, 144, 245, 251, 114, 211, 20, 82, 163, 123, 75, 16, 192, 106, 213, 128, 2, 11, 200, 203, 84, 41, 199, 224, 155, 171, 217, 64, 109, 116, 188, 151, 183, 173, 52, 205, 164, 93, 13, 251, 65, 182, 160, 154, 185, 239, 33, 184, 84, 159, 105, 101, 173, 194, 251, 123, 84, 92, 66, 61, 180, 45, 104, 162, 224, 214, 233, 64, 220, 165, 2, 104, 116, 150, 2, 234, 203, 112, 21, 124, 23, 48, 66, 30, 63, 30, 36, 246, 135, 203, 218, 115, 22, 189, 39, 39, 125, 205, 65, 222, 220, 77, 18, 84, 121, 161, 153, 125, 25, 139, 137, 170, 239, 150, 106, 119, 168, 216, 140, 113, 121, 26, 53, 118, 110, 53, 192, 244, 252, 145, 85, 2, 3, 1, 0, 1, 26, 17, 80, 45, 50, 53, 54, 44, 80, 45, 51, 56, 52, 44, 80, 45, 53, 50, 49, 34, 24, 65, 69, 83, 45, 50, 53, 54, 44, 65, 69, 83, 45, 49, 50, 56, 44, 66, 108, 111, 119, 102, 105, 115, 104, 42, 13, 83, 72, 65, 50, 53, 54, 44, 83, 72, 65, 53, 49, 50, 10, 16, 220, 83, 240, 105, 6, 203, 78, 83, 210, 115, 6, 106, 98, 82, 1, 161, 18, 171, 2, 8, 0, 18, 166, 2, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 185, 234, 19, 191, 164, 33, 65, 94, 87, 42, 74, 83, 224, 25, 142, 44, 26, 7, 92, 242, 189, 42, 170, 197, 178, 92, 45, 240, 107, 141, 128, 59, 122, 252, 48, 140, 4, 85, 85, 203, 3, 197, 8, 127, 120, 98, 44, 169, 135, 196, 70, 137, 117, 180, 177, 134, 170, 35, 165, 88, 105, 30, 114, 138, 11, 96, 68, 99, 18, 149, 223, 166, 105, 12, 176, 77, 48, 214, 22, 236, 17, 154, 213, 209, 158, 169, 202, 5, 100, 210, 83, 90, 201, 38, 205, 246, 231, 106, 63, 86, 222, 143, 157, 173, 62, 4, 85, 232, 20, 188, 6, 209, 186, 132, 192, 117, 146, 181, 233, 26, 0, 240, 138, 206, 91, 170, 114, 137, 217, 132, 139, 242, 144, 213, 103, 101, 190, 146, 188, 250, 188, 134, 255, 70, 125, 78, 65, 136, 239, 190, 206, 139, 155, 140, 163, 233, 170, 247, 205, 87, 209, 19, 29, 173, 10, 147, 43, 28, 90, 46, 6, 197, 217, 186, 66, 68, 126, 76, 64, 184, 8, 170, 23, 79, 243, 223, 119, 133, 118, 50, 226, 44, 246, 176, 10, 161, 219, 83, 54, 68, 248, 5, 14, 177, 114, 54, 63, 11, 71, 136, 142, 56, 151, 123, 230, 61, 80, 15, 180, 42, 49, 220, 148, 99, 231, 20, 230, 220, 85, 207, 187, 37, 210, 137, 171, 125, 71, 14, 53, 100, 91, 83, 209, 50, 132, 165, 253, 25, 161, 5, 97, 164, 163, 83, 95, 53, 2, 3, 1, 0, 1, 26, 17, 80, 45, 50, 53, 54, 44, 80, 45, 51, 56, 52, 44, 80, 45, 53, 50, 49, 34, 15, 65, 69, 83, 45, 50, 53, 54, 44, 65, 69, 83, 45, 49, 50, 56, 42, 13, 83, 72, 65, 50, 53, 54, 44, 83, 72, 65, 53, 49, 50, 4, 97, 54, 203, 112, 136, 34, 231, 162, 19, 154, 131, 27, 105, 26, 121, 238, 120, 25, 203, 66, 232, 53, 198, 20, 19, 96, 119, 218, 90, 64, 170, 3, 132, 116, 1, 87, 116, 232, 165, 161, 198, 117, 167, 60, 145, 1, 253, 108, 50, 150, 117, 8, 140, 133, 48, 30, 236, 36, 84, 186, 22, 144, 87, 101
]),
publicKey: Uint8Array.from([
publicKey: Buffer.from([
8, 0, 18, 166, 2, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 181, 113, 138, 108, 208, 103, 166, 102, 37, 36, 204, 250, 228, 165, 44, 64, 176, 210, 205, 141, 241, 55, 200, 110, 98, 68, 85, 199, 254, 19, 86, 204, 63, 250, 167, 38, 59, 249, 146, 228, 73, 171, 63, 18, 96, 104, 191, 137, 186, 244, 255, 90, 16, 119, 195, 52, 177, 213, 254, 187, 174, 84, 174, 173, 12, 236, 53, 234, 3, 209, 82, 37, 78, 111, 214, 135, 76, 195, 9, 242, 134, 188, 153, 84, 139, 231, 51, 146, 177, 60, 12, 25, 158, 91, 215, 152, 7, 0, 84, 35, 36, 230, 227, 67, 198, 72, 50, 110, 37, 209, 98, 193, 65, 93, 173, 199, 4, 198, 102, 99, 148, 144, 224, 217, 114, 53, 144, 245, 251, 114, 211, 20, 82, 163, 123, 75, 16, 192, 106, 213, 128, 2, 11, 200, 203, 84, 41, 199, 224, 155, 171, 217, 64, 109, 116, 188, 151, 183, 173, 52, 205, 164, 93, 13, 251, 65, 182, 160, 154, 185, 239, 33, 184, 84, 159, 105, 101, 173, 194, 251, 123, 84, 92, 66, 61, 180, 45, 104, 162, 224, 214, 233, 64, 220, 165, 2, 104, 116, 150, 2, 234, 203, 112, 21, 124, 23, 48, 66, 30, 63, 30, 36, 246, 135, 203, 218, 115, 22, 189, 39, 39, 125, 205, 65, 222, 220, 77, 18, 84, 121, 161, 153, 125, 25, 139, 137, 170, 239, 150, 106, 119, 168, 216, 140, 113, 121, 26, 53, 118, 110, 53, 192, 244, 252, 145, 85, 2, 3, 1, 0, 1
])
}

View File

@ -1,6 +1,6 @@
'use strict'
const uint8ArrayFromString = require('uint8arrays/from-string')
const { Buffer } = require('buffer')
// The keypair and signature below were generated in a gore repl session (https://github.com/motemen/gore)
// using the secp256k1 fork of go-libp2p-crypto by github user @vyzo
@ -24,8 +24,8 @@ const uint8ArrayFromString = require('uint8arrays/from-string')
// and the results copy/pasted in here
module.exports = {
privateKey: uint8ArrayFromString('08021220358f15db8c2014d570e8e3a622454e2273975a3cca443ec0c45375b13d381d18', 'base16'),
publicKey: uint8ArrayFromString('08021221029c0ce5d53646ed47112560297a3e59b78b8cbd4bae37c7a0c236eeb91d0fbeaf', 'base16'),
message: uint8ArrayFromString('hello! and welcome to some awesome crypto primitives'),
signature: uint8ArrayFromString('304402200e4c629e9f5d99439115e60989cd40087f6978c36078b0b50cf3d30af5c38d4102204110342c8e7f0809897c1c7a66e49e1c6b7cb0a6ed6993640ec2fe742c1899a9', 'base16')
privateKey: Buffer.from('08021220358f15db8c2014d570e8e3a622454e2273975a3cca443ec0c45375b13d381d18', 'hex'),
publicKey: Buffer.from('08021221029c0ce5d53646ed47112560297a3e59b78b8cbd4bae37c7a0c236eeb91d0fbeaf', 'hex'),
message: Buffer.from('hello! and welcome to some awesome crypto primitives', 'utf-8'),
signature: Buffer.from('304402200e4c629e9f5d99439115e60989cd40087f6978c36078b0b50cf3d30af5c38d4102204110342c8e7f0809897c1c7a66e49e1c6b7cb0a6ed6993640ec2fe742c1899a9', 'hex')
}

View File

@ -1,30 +1,30 @@
'use strict'
const { Buffer } = require('buffer')
module.exports = [{
cipher: 'AES-256',
hash: 'SHA256',
secret: Uint8Array.from([
secret: Buffer.from([
195, 191, 209, 165, 209, 201, 127, 122, 136, 111, 31, 66, 111, 68, 38, 155, 216, 204, 46, 181, 200, 188, 170, 204, 104, 74, 239, 251, 173, 114, 222, 234
]),
k1: {
iv: Uint8Array.from([
iv: Buffer.from([
208, 132, 203, 169, 253, 52, 40, 83, 161, 91, 17, 71, 33, 136, 67, 96
]),
cipherKey: Uint8Array.from([
cipherKey: Buffer.from([
156, 48, 241, 157, 92, 248, 153, 186, 114, 127, 195, 114, 106, 104, 215, 133, 35, 11, 131, 137, 123, 70, 74, 26, 15, 60, 189, 32, 67, 221, 115, 137
]),
macKey: Uint8Array.from([
macKey: Buffer.from([
6, 179, 91, 245, 224, 56, 153, 120, 77, 140, 29, 5, 15, 213, 187, 65, 137, 230, 202, 120
])
},
k2: {
iv: Uint8Array.from([
iv: Buffer.from([
236, 17, 34, 141, 90, 106, 197, 56, 197, 184, 157, 135, 91, 88, 112, 19
]),
cipherKey: Uint8Array.from([
cipherKey: Buffer.from([
151, 145, 195, 219, 76, 195, 102, 109, 187, 231, 100, 150, 132, 245, 251, 130, 254, 37, 178, 55, 227, 34, 114, 39, 238, 34, 2, 193, 107, 130, 32, 87
]),
macKey: Uint8Array.from([
macKey: Buffer.from([
3, 229, 77, 212, 241, 217, 23, 113, 220, 126, 38, 255, 18, 117, 108, 205, 198, 89, 1, 236
])
}

View File

@ -1,10 +1,9 @@
'use strict'
const uint8ArrayFromString = require('uint8arrays/from-string')
const { Buffer } = require('buffer')
module.exports = {
// protobuf marshaled key pair generated with libp2p-crypto-secp256k1
// and marshaled with libp2p-crypto.marshalPublicKey / marshalPrivateKey
pbmPrivateKey: uint8ArrayFromString('08021220e0600103010000000100000000000000be1dc82c2e000000e8d6030301000000', 'base16'),
pbmPublicKey: uint8ArrayFromString('0802122103a9a7272a726fa083abf31ba44037f8347fbc5e5d3113d62a7c6bc26752fd8ee1', 'base16')
pbmPrivateKey: Buffer.from('08021220e0600103010000000100000000000000be1dc82c2e000000e8d6030301000000', 'hex'),
pbmPublicKey: Buffer.from('0802122103a9a7272a726fa083abf31ba44037f8347fbc5e5d3113d62a7c6bc26752fd8ee1', 'hex')
}

View File

@ -1,9 +1,9 @@
/* eslint-env mocha */
'use strict'
const uint8ArrayFromString = require('uint8arrays/from-string')
const { Buffer } = require('buffer')
const util = require('util')
const garbage = [uint8ArrayFromString('00010203040506070809', 'base16'), {}, null, false, undefined, true, 1, 0, uint8ArrayFromString(''), 'aGVsbG93b3JsZA==', 'helloworld', '']
const garbage = [Buffer.from('00010203040506070809', 'hex'), {}, null, false, undefined, true, 1, 0, Buffer.from(''), 'aGVsbG93b3JsZA==', 'helloworld', '']
function doTests (fncName, fnc, num, skipBuffersAndStrings) {
if (!num) {
@ -11,8 +11,8 @@ function doTests (fncName, fnc, num, skipBuffersAndStrings) {
}
garbage.forEach((garbage) => {
if (skipBuffersAndStrings && (garbage instanceof Uint8Array || (typeof garbage) === 'string')) {
// skip this garbage because it's a Uint8Array or a String and we were told do do that
if (skipBuffersAndStrings && (Buffer.isBuffer(garbage) || (typeof garbage) === 'string')) {
// skip this garbage because it's a buffer or a string and we were told do do that
return
}
const args = []

View File

@ -1,12 +1,11 @@
/* eslint max-nested-callbacks: ["error", 8] */
/* eslint-env mocha */
'use strict'
const { Buffer } = require('buffer')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
const uint8ArrayFromString = require('uint8arrays/from-string')
const crypto = require('../../src')
@ -15,8 +14,8 @@ const hashes = ['SHA1', 'SHA256', 'SHA512']
describe('HMAC', () => {
hashes.forEach((hash) => {
it(`${hash} - sign and verify`, async () => {
const hmac = await crypto.hmac.create(hash, uint8ArrayFromString('secret'))
const sig = await hmac.digest(uint8ArrayFromString('hello world'))
const hmac = await crypto.hmac.create(hash, Buffer.from('secret'))
const sig = await hmac.digest(Buffer.from('hello world'))
expect(sig).to.have.length(hmac.length)
})
})

View File

@ -1,11 +1,11 @@
/* eslint-env mocha */
'use strict'
const { Buffer } = require('buffer')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
const uint8ArrayFromString = require('uint8arrays/from-string')
const crypto = require('../../src')
const ed25519 = crypto.keys.supportedKeys.ed25519
@ -80,29 +80,9 @@ describe('ed25519', function () {
})
it('key id', async () => {
const key = await crypto.keys.unmarshalPrivateKey(fixtures.verify.privateKey)
const id = await key.id()
expect(id).to.eql('12D3KooWLqLxEfJ9nDdEe8Kh8PFvNPQRYDQBwyL7CMM7HhVd5LsX')
})
it('should export a password encrypted libp2p-key', async () => {
const key = await crypto.keys.generateKeyPair('Ed25519')
const encryptedKey = await key.export('my secret')
// Import the key
const importedKey = await crypto.keys.import(encryptedKey, 'my secret')
expect(key.equals(importedKey)).to.equal(true)
})
it('should fail to import libp2p-key with wrong password', async () => {
const key = await crypto.keys.generateKeyPair('Ed25519')
const encryptedKey = await key.export('my secret', 'libp2p-key')
try {
await crypto.keys.import(encryptedKey, 'not my secret')
} catch (err) {
expect(err).to.exist()
return
}
expect.fail('should have thrown')
expect(id).to.exist()
expect(id).to.be.a('string')
})
describe('key equals', () => {
@ -130,16 +110,16 @@ describe('ed25519', function () {
})
it('sign and verify', async () => {
const data = uint8ArrayFromString('hello world')
const data = Buffer.from('hello world')
const sig = await key.sign(data)
const valid = await key.public.verify(data, sig)
expect(valid).to.eql(true)
})
it('fails to verify for different data', async () => {
const data = uint8ArrayFromString('hello world')
const data = Buffer.from('hello world')
const sig = await key.sign(data)
const valid = await key.public.verify(uint8ArrayFromString('hello'), sig)
const valid = await key.public.verify(Buffer.from('hello'), sig)
expect(valid).to.be.eql(false)
})
@ -157,13 +137,6 @@ describe('ed25519', function () {
expect(ok).to.eql(true)
})
it('does not include the redundant public key when marshalling privatekey', async () => {
const key = await crypto.keys.unmarshalPrivateKey(fixtures.redundantPubKey.privateKey)
const bytes = key.marshal()
expect(bytes.length).to.equal(64)
expect(bytes.slice(32)).to.eql(key.public.marshal())
})
it('verifies with data from go with redundant public key', async () => {
const key = crypto.keys.unmarshalPublicKey(fixtures.redundantPubKey.publicKey)
const ok = await key.verify(fixtures.redundantPubKey.data, fixtures.redundantPubKey.signature)

View File

@ -17,7 +17,7 @@ describe('keyStretcher', () => {
let res
// @ts-check
/**
* @type {Uint8Array}
* @type {Buffer}
*/
let secret

View File

@ -2,13 +2,13 @@
/* eslint-env mocha */
'use strict'
const { Buffer } = require('buffer')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
chai.use(require('chai-string'))
const { expectErrCode } = require('../util')
const uint8ArrayFromString = require('uint8arrays/from-string')
const crypto = require('../../src')
const rsa = crypto.keys.supportedKeys.rsa
@ -59,9 +59,9 @@ describe('RSA', function () {
})
it('key id', async () => {
const key = await crypto.keys.unmarshalPrivateKey(uint8ArrayFromString('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', 'base64pad'))
const id = await key.id()
expect(id).to.eql('QmQgsppVMDUpe83wcAqaemKbYvHeF127gnSFQ1xFnBodVw')
expect(id).to.exist()
expect(id).to.be.a('string')
})
describe('key equals', () => {
@ -81,14 +81,14 @@ describe('RSA', function () {
})
it('sign and verify', async () => {
const data = uint8ArrayFromString('hello world')
const data = Buffer.from('hello world')
const sig = await key.sign(data)
const valid = await key.public.verify(data, sig)
expect(valid).to.be.eql(true)
})
it('encrypt and decrypt', async () => {
const data = uint8ArrayFromString('hello world')
const data = Buffer.from('hello world')
const enc = await key.public.encrypt(data)
const dec = await key.decrypt(enc)
expect(dec).to.be.eql(data)
@ -99,22 +99,22 @@ describe('RSA', function () {
/**
* @type {any}
*/
const id = await crypto.keys.unmarshalPrivateKey(uint8ArrayFromString('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', 'base64pad'))
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 = uint8ArrayFromString('hello')
const msg = Buffer.from('hello')
// browser
const dec1 = id.decrypt(uint8ArrayFromString('YRFUDx8UjbWSfDS84cDA4WowaaOmd1qFNAv5QutodCKYb9uPtU/tDiAvJzOGu5DCJRo2J0l/35P2weiB4/C2Cb1aZgXKMx/QQC+2jSJiymhqcZaYerjTvkCFwkjCaqthoVo/YXxsaFZ1q7bdTZUDH1TaJR7hWfSyzyPcA8c0w43MIsw16pY8ZaPSclvnCwhoTg1JGjMk6te3we7+wR8QU7VrPhs54mZWxrpu3NQ8xZ6xQqIedsEiNhBUccrCSzYghgsP0Ae/8iKyGyl3U6IegsJNn8jcocvzOJrmU03rgIFPjvuBdaqB38xDSTjbA123KadB28jNoSZh18q/yH3ZIg==', 'base64pad'))
const dec1 = id.decrypt(Buffer.from('YRFUDx8UjbWSfDS84cDA4WowaaOmd1qFNAv5QutodCKYb9uPtU/tDiAvJzOGu5DCJRo2J0l/35P2weiB4/C2Cb1aZgXKMx/QQC+2jSJiymhqcZaYerjTvkCFwkjCaqthoVo/YXxsaFZ1q7bdTZUDH1TaJR7hWfSyzyPcA8c0w43MIsw16pY8ZaPSclvnCwhoTg1JGjMk6te3we7+wR8QU7VrPhs54mZWxrpu3NQ8xZ6xQqIedsEiNhBUccrCSzYghgsP0Ae/8iKyGyl3U6IegsJNn8jcocvzOJrmU03rgIFPjvuBdaqB38xDSTjbA123KadB28jNoSZh18q/yH3ZIg==', 'base64'))
expect(dec1).to.be.eql(msg)
// node
const dec2 = id.decrypt(uint8ArrayFromString('e6yxssqXsWc27ozDy0PGKtMkCS28KwFyES2Ijz89yiz+w6bSFkNOhHPKplpPzgQEuNoUGdbseKlJFyRYHjIT8FQFBHZM8UgSkgoimbY5on4xSxXs7E5/+twjqKdB7oNveTaTf7JCwaeUYnKSjbiYFEawtMiQE91F8sTT7TmSzOZ48tUhnddAAZ3Ac/O3Z9MSAKOCDipi+JdZtXRT8KimGt36/7hjjosYmPuHR1Xy/yMTL6SMbXtBM3yAuEgbQgP+q/7kHMHji3/JvTpYdIUU+LVtkMusXNasRA+UWG2zAht18vqjFMsm9JTiihZw9jRHD4vxAhf75M992tnC+0ZuQg==', 'base64pad'))
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)
})
it('fails to verify for different data', async () => {
const data = uint8ArrayFromString('hello world')
const data = Buffer.from('hello world')
const sig = await key.sign(data)
const valid = await key.public.verify(uint8ArrayFromString('hello'), sig)
const valid = await key.public.verify(Buffer.from('hello'), sig)
expect(valid).to.be.eql(false)
})
@ -135,24 +135,6 @@ describe('RSA', function () {
expect(key.equals(clone)).to.eql(true)
})
it('should export a password encrypted libp2p-key', async () => {
const encryptedKey = await key.export('my secret', 'libp2p-key')
// Import the key
const importedKey = await crypto.keys.import(encryptedKey, 'my secret')
expect(key.equals(importedKey)).to.equal(true)
})
it('should fail to import libp2p-key with wrong password', async () => {
const encryptedKey = await key.export('my secret', 'libp2p-key')
try {
await crypto.keys.import(encryptedKey, 'not my secret')
} catch (err) {
expect(err).to.exist()
return
}
expect.fail('should have thrown')
})
it('needs correct password', async () => {
const pem = await key.export('another secret')
try {

View File

@ -1,6 +1,7 @@
/* eslint-env mocha */
'use strict'
const { Buffer } = require('buffer')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
@ -10,8 +11,6 @@ const secp256k1 = crypto.keys.supportedKeys.secp256k1
const keysPBM = crypto.keys.keysPBM
const randomBytes = crypto.randomBytes
const secp256k1Crypto = require('../../src/keys/secp256k1')(randomBytes)
const uint8ArrayFromString = require('uint8arrays/from-string')
const fixtures = require('../fixtures/go-key-secp256k1')
describe('secp256k1 keys', () => {
let key
@ -59,30 +58,9 @@ describe('secp256k1 keys', () => {
})
it('key id', async () => {
const decoded = keysPBM.PrivateKey.decode(fixtures.privateKey)
const key = await secp256k1.unmarshalSecp256k1PrivateKey(decoded.Data)
const id = await key.id()
expect(id).to.eql('QmPCyMBGEyifPtx5aa6k6wkY9N1eBf9vHK1eKfNc35q9uq')
})
it('should export a password encrypted libp2p-key', async () => {
const key = await crypto.keys.generateKeyPair('secp256k1')
const encryptedKey = await key.export('my secret')
// Import the key
const importedKey = await crypto.keys.import(encryptedKey, 'my secret')
expect(key.equals(importedKey)).to.equal(true)
})
it('should fail to import libp2p-key with wrong password', async () => {
const key = await crypto.keys.generateKeyPair('secp256k1')
const encryptedKey = await key.export('my secret', 'libp2p-key')
try {
await crypto.keys.import(encryptedKey, 'not my secret')
} catch (err) {
expect(err).to.exist()
return
}
expect.fail('should have thrown')
expect(id).to.exist()
expect(id).to.be.a('string')
})
describe('key equals', () => {
@ -102,16 +80,16 @@ describe('secp256k1 keys', () => {
})
it('sign and verify', async () => {
const data = uint8ArrayFromString('hello world')
const data = Buffer.from('hello world')
const sig = await key.sign(data)
const valid = await key.public.verify(data, sig)
expect(valid).to.eql(true)
})
it('fails to verify for different data', async () => {
const data = uint8ArrayFromString('hello world')
const data = Buffer.from('hello world')
const sig = await key.sign(data)
const valid = await key.public.verify(uint8ArrayFromString('hello'), sig)
const valid = await key.public.verify(Buffer.from('hello'), sig)
expect(valid).to.eql(false)
})
})
@ -147,7 +125,7 @@ describe('handles generation of invalid key', () => {
before(() => {
generateKey = secp256k1Crypto.generateKey
secp256k1 = require('../../src/keys/secp256k1-class')(keysPBM, randomBytes, secp256k1Crypto)
secp256k1Crypto.generateKey = () => uint8ArrayFromString('not a real key')
secp256k1Crypto.generateKey = () => Buffer.from('not a real key')
})
after(() => {
@ -181,17 +159,17 @@ describe('crypto functions', () => {
})
it('does not validate an invalid key', () => {
expect(() => secp256k1Crypto.validatePublicKey(uint8ArrayFromString('42'))).to.throw()
expect(() => secp256k1Crypto.validatePrivateKey(uint8ArrayFromString('42'))).to.throw()
expect(() => secp256k1Crypto.validatePublicKey(Buffer.from('42'))).to.throw()
expect(() => secp256k1Crypto.validatePrivateKey(Buffer.from('42'))).to.throw()
})
it('validates a correct signature', async () => {
const sig = await secp256k1Crypto.hashAndSign(privKey, uint8ArrayFromString('hello'))
const valid = await secp256k1Crypto.hashAndVerify(pubKey, sig, uint8ArrayFromString('hello'))
const sig = await secp256k1Crypto.hashAndSign(privKey, Buffer.from('hello'))
const valid = await secp256k1Crypto.hashAndVerify(pubKey, sig, Buffer.from('hello'))
expect(valid).to.equal(true)
})
it('errors if given a null Uint8Array to sign', async () => {
it('errors if given a null buffer to sign', async () => {
try {
await secp256k1Crypto.hashAndSign(privKey, null)
} catch (err) {
@ -202,15 +180,15 @@ describe('crypto functions', () => {
it('errors when signing with an invalid key', async () => {
try {
await secp256k1Crypto.hashAndSign(uint8ArrayFromString('42'), uint8ArrayFromString('Hello'))
await secp256k1Crypto.hashAndSign(Buffer.from('42'), Buffer.from('Hello'))
} catch (err) {
return expect(err.message).to.equal('Expected private key to be an Uint8Array with length 32')
}
throw new Error('Expected error to be thrown')
})
it('errors if given a null Uint8Array to validate', async () => {
const sig = await secp256k1Crypto.hashAndSign(privKey, uint8ArrayFromString('hello'))
it('errors if given a null buffer to validate', async () => {
const sig = await secp256k1Crypto.hashAndSign(privKey, Buffer.from('hello'))
try {
await secp256k1Crypto.hashAndVerify(privKey, sig, null)
@ -222,7 +200,7 @@ describe('crypto functions', () => {
it('errors when validating a message with an invalid signature', async () => {
try {
await secp256k1Crypto.hashAndVerify(pubKey, uint8ArrayFromString('invalid-sig'), uint8ArrayFromString('hello'))
await secp256k1Crypto.hashAndVerify(pubKey, Buffer.from('invalid-sig'), Buffer.from('hello'))
} catch (err) {
return expect(err.message).to.equal('Signature could not be parsed')
}
@ -231,7 +209,7 @@ describe('crypto functions', () => {
it('errors when signing with an invalid key', async () => {
try {
await secp256k1Crypto.hashAndSign(uint8ArrayFromString('42'), uint8ArrayFromString('Hello'))
await secp256k1Crypto.hashAndSign(Buffer.from('42'), Buffer.from('Hello'))
} catch (err) {
return expect(err.message).to.equal('Expected private key to be an Uint8Array with length 32')
}
@ -239,11 +217,11 @@ describe('crypto functions', () => {
})
it('throws when compressing an invalid public key', () => {
expect(() => secp256k1Crypto.compressPublicKey(uint8ArrayFromString('42'))).to.throw()
expect(() => secp256k1Crypto.compressPublicKey(Buffer.from('42'))).to.throw()
})
it('throws when decompressing an invalid public key', () => {
expect(() => secp256k1Crypto.decompressPublicKey(uint8ArrayFromString('42'))).to.throw()
expect(() => secp256k1Crypto.decompressPublicKey(Buffer.from('42'))).to.throw()
})
it('compresses/decompresses a valid public key', () => {
@ -256,6 +234,8 @@ describe('crypto functions', () => {
})
describe('go interop', () => {
const fixtures = require('../fixtures/go-key-secp256k1')
it('loads a private key marshaled by go-libp2p-crypto', async () => {
// we need to first extract the key data from the protobuf, which is
// normally handled by js-libp2p-crypto

View File

@ -3,6 +3,7 @@
'use strict'
const chai = require('chai')
const { Buffer } = require('buffer')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
@ -31,8 +32,8 @@ describe('Util', () => {
expect(num.equals(bn)).to.be.true()
})
it('should convert base64url encoded string to Uint8Array with padding', () => {
it('should convert base64url encoded string to Buffer with padding', () => {
const buf = util.base64urlToBuffer('AP8', 2)
expect(Uint8Array.from([0, 255])).to.eql(buf)
expect(Buffer.from([0, 255])).to.eql(buf)
})
})