Skip to content
This repository has been archived by the owner on Jul 21, 2023. It is now read-only.

Async Crypto Endeavour #12

Merged
merged 4 commits into from
Nov 3, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions .aegir.js

This file was deleted.

1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,4 @@ build
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules

lib
dist
18 changes: 11 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
sudo: false
language: node_js
node_js:
- 4
- 5
- stable

matrix:
include:
- node_js: 4
env: CXX=g++-4.8
- node_js: 6
env:
- SAUCE=true
- CXX=g++-4.8
- node_js: stable
env: CXX=g++-4.8

# Make sure we have new NPM.
before_install:
Expand All @@ -22,9 +29,6 @@ before_script:
after_success:
- npm run coverage-publish

env:
- CXX=g++-4.8

addons:
firefox: 'latest'
apt:
Expand Down
95 changes: 80 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
[![Circle CI](https://circleci.com/gh/libp2p/js-libp2p-crypto.svg?style=svg)](https://circleci.com/gh/libp2p/js-libp2p-crypto)
[![Dependency Status](https://david-dm.org/libp2p/js-libp2p-crypto.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-crypto)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard)
![](https://img.shields.io/badge/npm-%3E%3D3.0.0-orange.svg?style=flat-square)
![](https://img.shields.io/badge/Node.js-%3E%3D4.0.0-orange.svg?style=flat-square)

[![Sauce Test Status](https://saucelabs.com/browser-matrix/ipfs-js-libp2p-crypto.svg)](https://saucelabs.com/u/ipfs-js-
libp2p-crypto)

> Crypto primitives for libp2p in JavaScript

Expand All @@ -21,13 +26,22 @@ needed for libp2p. This is based on this [go implementation](https://github.com/
- [Usage](#usage)
- [Example](#example)
- [API](#api)
- [`generateKeyPair(type, bits)`](#generatekeypairtype-bits)
- [`generateEphemeralKeyPair(curve)`](#generateephemeralkeypaircurve)
- [`keyStretcher(cipherType, hashType, secret)`](#keystretcherciphertype-hashtype-secret)
- [`marshalPublicKey(key[, type])`](#marshalpublickeykey-type)
- [`hmac`](#hmac)
- [`create(hash, secret, callback)`](#createhash-secret-callback)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why stop linking to things?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's continue linking the methods.

- [`digest(data, callback)`](#digestdata-callback)
- [`aes`](#aes)
- [`create(key, iv, callback)`](#createkey-iv-callback)
- [`encrypt(data, callback)`](#encryptdata-callback)
- [`encrypt(data, callback)`](#encryptdata-callback)
- [`webcrypto`](#webcrypto)
- [`keys`](#keys)
- [`generateKeyPair(type, bits, callback)`](#generatekeypairtype-bits-callback)
- [`generateEphemeralKeyPair(curve, callback)`](#generateephemeralkeypaircurve-callback)
- [`keyStretcher(cipherType, hashType, secret, callback)`](#keystretcherciphertype-hashtype-secret-callback)
- [`marshalPublicKey(key[, type], callback)`](#marshalpublickeykey-type-callback)
- [`unmarshalPublicKey(buf)`](#unmarshalpublickeybuf)
- [`marshalPrivateKey(key[, type])`](#marshalprivatekeykey-type)
- [`unmarshalPrivateKey(buf)`](#unmarshalprivatekeybuf)
- [`unmarshalPrivateKey(buf, callback)`](#unmarshalprivatekeybuf-callback)
- [Contribute](#contribute)
- [License](#license)

Expand All @@ -44,43 +58,91 @@ npm install --save libp2p-crypto
```js
const crypto = require('libp2p-crypto')

var keyPair = crypto.generateKeyPair('RSA', 2048)
crypto.generateKeyPair('RSA', 2048, (err, key) => {
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it key or keyPair? Wanna show an example of logging out each?

```

## API

### `generateKeyPair(type, bits)`
### `hmac`

Exposes an interface to the Keyed-Hash Message Authentication Code (HMAC) as defined in U.S. Federal Information Processing Standards Publication 198. An HMAC is a cryptographic hash that uses a key to sign a message. The receiver verifies the hash by recomputing it using the same key.

#### `create(hash, secret, callback)`

- `hash: String`
- `secret: Buffer`
- `callback: Function`

##### `digest(data, callback)`

- `data: Buffer`
- `callback: Function`

### `aes`
Expoes an interface to AES encryption (formerly Rijndael), as defined in U.S. Federal Information Processing Standards Publication 197.

This uses `CTR` mode.

#### `create(key, iv, callback)`

- `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`.
- `callback: Function`

##### `encrypt(data, callback)`

- `data: Buffer`
- `callback: Function`

##### `encrypt(data, callback)`

- `data: Buffer`
- `callback: Function`


### `webcrypto`

Depending on the environment this is either an instance of [node-webcrypto-ossl](https://github.com/PeculiarVentures/node-webcrypto-ossl) or the result of `window.crypto`.

### `keys`

### `generateKeyPair(type, bits, callback)`

- `type: String`, only `'RSA'` is currently supported
- `bits: Number`
- `bits: Number` Minimum of 1024
- `callback: Function`

Generates a keypair of the given type and bitsize.

### `generateEphemeralKeyPair(curve)`
### `generateEphemeralKeyPair(curve, callback)`

- `curve: String`, one of `'P-256'`, `'P-384'`, `'P-521'` is currently supported
- `callback: Function`

Generates an ephemeral public key and returns a function that will compute the shared secret key.

Focuses only on ECDH now, but can be made more general in the future.

Returns an object of the form
Calls back with an object of the form

```js
{
key: Buffer,
genSharedKey: Function
}
```

### `keyStretcher(cipherType, hashType, secret)`
### `keyStretcher(cipherType, hashType, secret, callback)`

- `cipherType: String`, one of `'AES-128'`, `'AES-256'`, `'Blowfish'`
- `hashType: String`, one of `'SHA1'`, `SHA256`, `SHA512`
- `secret: Buffer`
- `callback: Function`

Generates a set of keys for each party by stretching the shared key.

Returns an object of the form
Calls back with an object of the form
```js
{
k1: {
Expand All @@ -95,7 +157,8 @@ Returns an object of the form
}
}
```
### `marshalPublicKey(key[, type])`

### `marshalPublicKey(key[, type], callback)`

- `key: crypto.rsa.RsaPublicKey`
- `type: String`, only `'RSA'` is currently supported
Expand All @@ -115,11 +178,13 @@ Converts a protobuf serialized public key into its representative object.

Converts a private key object into a protobuf serialized private key.

### `unmarshalPrivateKey(buf)`
### `unmarshalPrivateKey(buf, callback)`

- `buf: Buffer`
- `callback: Function`

Converts a protobuf serialized private key into its representative object.

Converts a protobuf serialized private key into its representative object.

## Contribute

Expand Down
37 changes: 37 additions & 0 deletions benchmarks/ephemeral-keys.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use strict'

const Benchmark = require('benchmark')
const crypto = require('../src')

const suite = new Benchmark.Suite('ephemeral-keys')

const secrets = []
const curves = ['P-256', 'P-384', 'P-521']

curves.forEach((curve) => {
suite.add(`ephemeral key with secrect ${curve}`, (d) => {
crypto.generateEphemeralKeyPair('P-256', (err, res) => {
if (err) {
throw err
}
res.genSharedKey(res.key, (err, secret) => {
if (err) {
throw err
}
secrets.push(secret)

d.resolve()
})
})
}, {
defer: true
})
})

suite
.on('cycle', (event) => {
console.log(String(event.target))
})
.run({
'async': true
})
47 changes: 47 additions & 0 deletions benchmarks/key-stretcher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use strict'

const Benchmark = require('benchmark')
const crypto = require('../src')

const suite = new Benchmark.Suite('key-stretcher')

const keys = []

const ciphers = ['AES-128', 'AES-256', 'Blowfish']
const hashes = ['SHA1', 'SHA256', 'SHA512']

crypto.generateEphemeralKeyPair('P-256', (err, res) => {
if (err) {
throw err
}

res.genSharedKey(res.key, (err, secret) => {
if (err) {
throw err
}
ciphers.forEach((cipher) => {
hashes.forEach((hash) => {
suite.add(`keyStretcher ${cipher} ${hash}`, (d) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this d?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we all want to know ;)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is an object provided from benchmark that has one method .resolve to indicate that the benchmark is done.

crypto.keyStretcher(cipher, hash, secret, (err, k) => {
if (err) {
throw err
}

keys.push(k)
d.resolve()
})
}, {
defer: true
})
})
})
})
})

suite
.on('cycle', (event) => {
console.log(String(event.target))
})
.run({
'async': true
})
52 changes: 52 additions & 0 deletions benchmarks/rsa.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'use strict'

const Benchmark = require('benchmark')
const crypto = require('../src')

const suite = new Benchmark.Suite('rsa')

const keys = []
const bits = [1024, 2048, 4096]

bits.forEach((bit) => {
suite.add(`generateKeyPair ${bit}bits`, (d) => {
crypto.generateKeyPair('RSA', bit, (err, key) => {
if (err) throw err
keys.push(key)
d.resolve()
})
}, {
defer: true
})
})

suite.add('sign and verify', (d) => {
const key = keys[0]
const text = key.genSecret()

key.sign(text, (err, sig) => {
if (err) {
throw err
}

key.public.verify(text, sig, (err, res) => {
if (err) {
throw err
}
if (res !== true) {
throw new Error('failed to verify')
}
d.resolve()
})
})
}, {
defer: true
})

suite
.on('cycle', (event) => {
console.log(String(event.target))
})
.run({
'async': true
})
Loading