Compare commits

...

56 Commits

Author SHA1 Message Date
Friedel Ziegelmayer
e18804c31e chore: release version v0.8.0 2017-02-07 21:03:56 +01:00
Friedel Ziegelmayer
133a2c8833 chore: update contributors 2017-02-07 21:03:55 +01:00
Friedel Ziegelmayer
fad0865b2b chore: drop webworker flag 2017-02-07 20:46:58 +01:00
Friedel Ziegelmayer
4edef07182 Merge pull request #67 from libp2p/greenkeeper-aegir-10.0.0
Update aegir to version 10.0.0 🚀
2017-02-07 20:45:13 +01:00
Friedel Ziegelmayer
19c6ce7c06 Merge pull request #65 from dryajov/master
feat: change window to self for webworker support
2017-02-07 20:45:01 +01:00
Friedel Ziegelmayer
3fa76a874f Merge pull request #66 from libp2p/expose-proto
feat: expose protobuf
2017-02-07 20:44:36 +01:00
greenkeeperio-bot
6e0fd6f257 chore(package): update aegir to version 10.0.0
https://greenkeeper.io/
2017-02-07 18:45:52 +01:00
Friedel Ziegelmayer
c91d9b61c8 feat: expose protobuf
this allows other modules to reuse the protobuf definition
2017-02-07 17:51:43 +01:00
Yusef Napora
76eeb5aa18 feat: add support for secp256k1 keys through the libp2p-crypto-secp256k1 module 2017-02-04 10:23:38 +01:00
dryajov
843b5e33d6 WIP: use self instead of window for WebWorker compatibility 2017-01-31 02:09:46 -08:00
Friedel Ziegelmayer
308ac7cd1a chore: release version v0.7.7 2017-01-27 14:07:42 +01:00
Friedel Ziegelmayer
6c8f978ea4 chore: update contributors 2017-01-27 14:07:42 +01:00
Friedel Ziegelmayer
b93b410357 Merge pull request #63 from libp2p/dryajov-master
Dryajov master
2017-01-27 13:53:26 +01:00
Friedel Ziegelmayer
99a5245fa3 update deps 2017-01-27 12:15:19 +01:00
dryajov
34856d58ab removing contributors 2017-01-26 17:20:51 -08:00
dryajov
d59c6af7c0 Merge branch 'master' of https://github.com/libp2p/js-libp2p-crypto 2017-01-23 18:39:51 -08:00
dryajov
1683bf1dc8 reverting version 2017-01-23 18:32:52 -08:00
dryajov
a4edf8b99b chore: release version v0.7.6 2017-01-23 18:30:30 -08:00
dryajov
27524354af chore: update contributors 2017-01-23 18:30:30 -08:00
dryajov
a1f054ca8e adding webworker test task 2017-01-22 19:39:58 -08:00
dryajov
5c61c89391 fixing lint issues with self 2017-01-20 16:20:23 -08:00
David Dias
c138a04d2d chore: release version v0.7.6 2017-01-16 04:21:42 +00:00
David Dias
7c913c0769 chore: update contributors 2017-01-16 04:21:42 +00:00
Friedel Ziegelmayer
1a2d468369 fix: consistent buffer usage (#56)
* fix: consistent buffer usage

Closes #49

* more fixes for node 4
2017-01-16 05:17:50 +01:00
Tom Swindell
98bc0bbc5f Support for WebWorker.
Signed-off-by: Tom Swindell <t.swindell@rubyx.co.uk>
2017-01-14 12:45:52 +00:00
Yusef Napora
c45bdf602e feat(keys): add Ed25519 support for signing & verification
Closes #43
2016-12-23 14:52:40 +01:00
Greenkeeper
e92bab1736 chore(package): update node-webcrypto-ossl to version 1.0.15 (#54)
https://greenkeeper.io/
2016-12-18 11:37:21 +00:00
Friedel Ziegelmayer
c57d1e4d4f chore: release version v0.7.5 2016-12-13 12:56:43 +01:00
Friedel Ziegelmayer
04682acd86 chore: update contributors 2016-12-13 12:56:42 +01:00
Friedel Ziegelmayer
fba4833aef Merge pull request #53 from libp2p/fix/another-buffer-bites-the-dust
fix: use toArrayLike instead of toBuffer for browserify
2016-12-13 12:55:58 +01:00
Friedel Ziegelmayer
2842df7944 fix: use toArrayLike instead of toBuffer for browserify 2016-12-13 12:52:43 +01:00
Greenkeeper
74c0d28f86 chore(package): update aegir to version 9.2.1 (#50)
https://greenkeeper.io/
2016-12-10 11:59:47 -08:00
David Dias
cf7ed6fa49 chore: release version v0.7.4 2016-12-06 00:07:11 +00:00
David Dias
c1ffa41697 chore: update contributors 2016-12-06 00:07:11 +00:00
nikuda
933119445f fix(utils): make util.toBase64 browserify compatible
`bn.toArrayLike` is used instead of `bn.toBuffer`, to ensure compatibility with browserify.
2016-12-03 09:32:07 +01:00
David Dias
a4e6f9dd83 chore: release version v0.7.3 2016-12-01 11:43:46 +00:00
David Dias
e252db300c chore: update contributors 2016-12-01 11:43:46 +00:00
David Dias
98b37d49c4 feat: add randomBytes function (#45)
* feat: add randomBytes function

* fix: apply CR
2016-12-01 11:42:19 +00:00
David Dias
f979fcd3c2 chore: release version v0.7.2 2016-11-30 11:27:17 +00:00
David Dias
0af48bbebc chore: update contributors 2016-11-30 11:27:16 +00:00
David Dias
3f9d8d557c Merge pull request #42 from libp2p/feat/better-compat
Better compatability
2016-11-30 11:23:14 +00:00
Friedel Ziegelmayer
91a3b50ac9 feat(deps): update to multihashing-async@0.3.0 2016-11-29 18:11:58 +01:00
Friedel Ziegelmayer
148d16ab25 feat(rsa): add fallback pure js fallback for webcrypto-ossl 2016-11-29 17:54:41 +01:00
Friedel Ziegelmayer
6d15450438 feat(ecdh): use node core instead of webcrypto-ossl 2016-11-29 16:36:56 +01:00
David Dias
ebe1cecdeb Merge pull request #39 from libp2p/greenkeeper-protocol-buffers-3.2.1
protocol-buffers@3.2.1
2016-11-26 13:21:08 +01:00
greenkeeperio-bot
904cfb27bd chore(package): update protocol-buffers to version 3.2.1
https://greenkeeper.io/
2016-11-26 06:11:28 +01:00
Friedel Ziegelmayer
7790beb207 Merge pull request #37 from libp2p/greenkeeper-node-webcrypto-ossl-1.0.13
node-webcrypto-ossl@1.0.13 breaks build 🚨
2016-11-23 23:26:31 +01:00
greenkeeperio-bot
6308461f0f chore(package): update node-webcrypto-ossl to version 1.0.13
https://greenkeeper.io/
2016-11-23 22:20:49 +01:00
Friedel Ziegelmayer
95a0f1f0c2 Merge pull request #34 from libp2p/greenkeeper-node-webcrypto-ossl-1.0.10
node-webcrypto-ossl@1.0.10 breaks build 🚨
2016-11-16 10:53:36 +01:00
greenkeeperio-bot
0c64122342 chore(package): update node-webcrypto-ossl to version 1.0.10
https://greenkeeper.io/
2016-11-15 07:46:24 +01:00
David Dias
ce5044b4d7 chore: release version v0.7.1 2016-11-11 08:38:28 +00:00
David Dias
1daf429a74 chore: update contributors 2016-11-11 08:38:27 +00:00
David Dias
22e95bc8a4 Merge pull request #29 from libp2p/aes-interop
AES Interop
2016-11-11 08:30:18 +00:00
Friedel Ziegelmayer
9994023490 fix(aes): replace subtle.crypto with browserify-aes
Due to the design of `AES-CTR` in the webcrypto spec, there
is no streaming mode provided. This results in the counter
not being reused between subsequent calls to `encrypt` or
`decrypt`. As both the node.js and the go implementation rely
on this webcrypto had to be replaced.
2016-11-10 17:19:45 +01:00
Friedel Ziegelmayer
393fa17512 test(aes): add failing interop tests 2016-11-10 12:55:49 +01:00
Friedel Ziegelmayer
3cc26d167f chore(benchmarks): lint happy 2016-11-07 11:37:32 +01:00
51 changed files with 3509 additions and 464 deletions

View File

@@ -107,9 +107,21 @@ Depending on the environment this is either an instance of [node-webcrypto-ossl]
### `keys` ### `keys`
#### Supported Key Types
The [`generateKeyPair`](#generatekeypairtype-bits-callback), [`marshalPublicKey`](#marshalpublickeykey-type-callback), and
[`marshalPrivateKey`](#marshalprivatekeykey-type) functions accept a string `type` argument.
Currently the `'RSA'` and `'ed25519'` types are supported, although ed25519 keys support only signing and
verification of messages. For encryption / decryption support, RSA keys should be used.
Installing the [libp2p-crypto-secp256k1](https://github.com/libp2p/js-libp2p-crypto-secp256k1) module adds support for the
`'secp256k1'` type, which supports ECDSA signatures using the secp256k1 elliptic curve popularized by Bitcoin. This module
is not installed by default, and should be explicitly depended on if your project requires secp256k1 support.
### `generateKeyPair(type, bits, callback)` ### `generateKeyPair(type, bits, callback)`
- `type: String`, only `'RSA'` is currently supported - `type: String`, see [Supported Key Types](#supported-key-types) above.
- `bits: Number` Minimum of 1024 - `bits: Number` Minimum of 1024
- `callback: Function` - `callback: Function`
@@ -160,8 +172,8 @@ Calls back with an object of the form
### `marshalPublicKey(key[, type], callback)` ### `marshalPublicKey(key[, type], callback)`
- `key: crypto.rsa.RsaPublicKey` - `key: keys.rsa.RsaPublicKey | keys.ed25519.Ed25519PublicKey | require('libp2p-crypto-secp256k1').Secp256k1PublicKey`
- `type: String`, only `'RSA'` is currently supported - `type: String`, see [Supported Key Types](#supported-key-types) above.
Converts a public key object into a protobuf serialized public key. Converts a public key object into a protobuf serialized public key.
@@ -173,8 +185,8 @@ Converts a protobuf serialized public key into its representative object.
### `marshalPrivateKey(key[, type])` ### `marshalPrivateKey(key[, type])`
- `key: crypto.rsa.RsaPrivateKey` - `key: keys.rsa.RsaPrivateKey | keys.ed25519.Ed25519PrivateKey | require('libp2p-crypto-secp256k1').Secp256k1PrivateKey`
- `type: String`, only `'RSA'` is currently supported - `type: String`, see [Supported Key Types](#supported-key-types) above.
Converts a private key object into a protobuf serialized private key. Converts a private key object into a protobuf serialized private key.
@@ -185,6 +197,11 @@ Converts a private key object into a protobuf serialized private key.
Converts a protobuf serialized private key into its representative object. Converts a protobuf serialized private key into its representative object.
### `randomBytes(number)`
- `number: Number`
Generates a Buffer with length `number` populated by random bytes.
## Contribute ## Contribute

View File

@@ -33,5 +33,5 @@ suite
console.log(String(event.target)) console.log(String(event.target))
}) })
.run({ .run({
'async': true async: true
}) })

View File

@@ -1,6 +1,8 @@
'use strict' 'use strict'
const Benchmark = require('benchmark') const Benchmark = require('benchmark')
const async = require('async')
const crypto = require('../src') const crypto = require('../src')
const suite = new Benchmark.Suite('key-stretcher') const suite = new Benchmark.Suite('key-stretcher')
@@ -10,38 +12,38 @@ const keys = []
const ciphers = ['AES-128', 'AES-256', 'Blowfish'] const ciphers = ['AES-128', 'AES-256', 'Blowfish']
const hashes = ['SHA1', 'SHA256', 'SHA512'] const hashes = ['SHA1', 'SHA256', 'SHA512']
crypto.generateEphemeralKeyPair('P-256', (err, res) => { async.waterfall([
(cb) => crypto.generateEphemeralKeyPair('P-256', cb),
(res, cb) => res.genSharedKey(res.key, cb)
], (err, secret) => {
if (err) { if (err) {
throw err throw err
} }
res.genSharedKey(res.key, (err, secret) => { ciphers.forEach((cipher) => hashes.forEach((hash) => {
if (err) { setup(cipher, hash, secret)
throw err }))
}
ciphers.forEach((cipher) => {
hashes.forEach((hash) => {
suite.add(`keyStretcher ${cipher} ${hash}`, (d) => {
crypto.keyStretcher(cipher, hash, secret, (err, k) => {
if (err) {
throw err
}
keys.push(k) suite
d.resolve() .on('cycle', (event) => {
}) console.log(String(event.target))
}, { })
defer: true .run({
}) async: true
})
}) })
})
}) })
suite function setup (cipher, hash, secret) {
.on('cycle', (event) => { suite.add(`keyStretcher ${cipher} ${hash}`, (d) => {
console.log(String(event.target)) crypto.keyStretcher(cipher, hash, secret, (err, k) => {
}) if (err) {
.run({ throw err
'async': true }
keys.push(k)
d.resolve()
})
}, {
defer: true
}) })
}

View File

@@ -48,5 +48,5 @@ suite
console.log(String(event.target)) console.log(String(event.target))
}) })
.run({ .run({
'async': true async: true
}) })

View File

@@ -1,21 +1,24 @@
{ {
"name": "libp2p-crypto", "name": "libp2p-crypto",
"version": "0.7.0", "version": "0.8.0",
"description": "Crypto primitives for libp2p", "description": "Crypto primitives for libp2p",
"main": "src/index.js", "main": "src/index.js",
"browser": { "browser": {
"node-webcrypto-ossl": false, "node-webcrypto-ossl": false,
"./src/crypto/webcrypto.js": "./src/crypto/webcrypto-browser.js", "./src/crypto/webcrypto.js": "./src/crypto/webcrypto-browser.js",
"./src/crypto/hmac.js": "./src/crypto/hmac-browser.js", "./src/crypto/hmac.js": "./src/crypto/hmac-browser.js",
"./src/crypto/aes.js": "./src/crypto/aes-browser.js" "./src/crypto/ecdh.js": "./src/crypto/ecdh-browser.js",
"./src/crypto/ciphers.js": "./src/crypto/ciphers-browser.js",
"./src/crypto/rsa.js": "./src/crypto/rsa-browser.js"
}, },
"scripts": { "scripts": {
"lint": "aegir-lint", "lint": "aegir-lint",
"build": "aegir-build", "build": "aegir-build",
"test": "aegir-test", "test": "npm run test:node && npm run test:no-webcrypto && npm run test:browser",
"test:node": "aegir-test --env node", "test:node": "aegir-test --env node",
"test:no-webcrypto": "NO_WEBCRYPTO=true aegir-test --env node",
"test:browser": "aegir-test --env browser", "test:browser": "aegir-test --env browser",
"release": "aegir-release", "release": "aegir-release --webworker",
"release-minor": "aegir-release --type minor", "release-minor": "aegir-release --type minor",
"release-major": "aegir-release --type major", "release-major": "aegir-release --type major",
"coverage": "aegir-coverage", "coverage": "aegir-coverage",
@@ -30,19 +33,27 @@
"author": "Friedel Ziegelmayer <dignifiedqurie@gmail.com>", "author": "Friedel Ziegelmayer <dignifiedqurie@gmail.com>",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"asn1.js": "^4.8.1", "asn1.js": "^4.9.1",
"async": "^2.1.2", "async": "^2.1.4",
"multihashing-async": "^0.2.0", "browserify-aes": "^1.0.6",
"node-webcrypto-ossl": "^1.0.7", "keypair": "^1.0.1",
"multihashing-async": "^0.4.0",
"nodeify": "^1.0.0", "nodeify": "^1.0.0",
"protocol-buffers": "^3.1.6", "pem-jwk": "^1.5.1",
"protocol-buffers": "^3.2.1",
"rsa-pem-to-jwk": "^1.1.3",
"safe-buffer": "^5.0.1",
"tweetnacl": "^0.14.5",
"webcrypto-shim": "github:dignifiedquire/webcrypto-shim#master" "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#master"
}, },
"devDependencies": { "devDependencies": {
"aegir": "^9.0.1", "aegir": "^10.0.0",
"benchmark": "^2.1.2", "benchmark": "^2.1.3",
"chai": "^3.5.0", "chai": "^3.5.0",
"pre-commit": "^1.1.3" "pre-commit": "^1.2.2"
},
"optionalDependencies": {
"node-webcrypto-ossl": "^1.0.16"
}, },
"pre-commit": [ "pre-commit": [
"lint", "lint",
@@ -63,6 +74,9 @@
"David Dias <daviddias.p@gmail.com>", "David Dias <daviddias.p@gmail.com>",
"Friedel Ziegelmayer <dignifiedquire@gmail.com>", "Friedel Ziegelmayer <dignifiedquire@gmail.com>",
"Richard Littauer <richard.littauer@gmail.com>", "Richard Littauer <richard.littauer@gmail.com>",
"Tom Swindell <t.swindell@rubyx.co.uk>",
"Yusef Napora <yusef@napora.org>",
"dryajov <dryajov@gmail.com>",
"greenkeeperio-bot <support@greenkeeper.io>", "greenkeeperio-bot <support@greenkeeper.io>",
"nikuda <nikuda@gmail.com>" "nikuda <nikuda@gmail.com>"
] ]

View File

@@ -5,3 +5,4 @@ exports.hmac = require('./crypto/hmac')
exports.ecdh = require('./crypto/ecdh') exports.ecdh = require('./crypto/ecdh')
exports.aes = require('./crypto/aes') exports.aes = require('./crypto/aes')
exports.rsa = require('./crypto/rsa') exports.rsa = require('./crypto/rsa')
exports.ed25519 = require('./crypto/ed25519')

View File

@@ -2,6 +2,8 @@
module.exports = `enum KeyType { module.exports = `enum KeyType {
RSA = 0; RSA = 0;
Ed25519 = 1;
Secp256k1 = 2;
} }
message PublicKey { message PublicKey {

View File

@@ -1,52 +0,0 @@
'use strict'
const nodeify = require('nodeify')
const crypto = require('./webcrypto')()
exports.create = function (key, iv, callback) {
nodeify(crypto.subtle.importKey(
'raw',
key,
{
name: 'AES-CTR'
},
false,
['encrypt', 'decrypt']
).then((key) => {
const counter = copy(iv)
return {
encrypt (data, cb) {
nodeify(crypto.subtle.encrypt(
{
name: 'AES-CTR',
counter: counter,
length: 128
},
key,
data
).then((raw) => Buffer.from(raw)), cb)
},
decrypt (data, cb) {
nodeify(crypto.subtle.decrypt(
{
name: 'AES-CTR',
counter: counter,
length: 128
},
key,
data
).then((raw) => Buffer.from(raw)), cb)
}
}
}), callback)
}
function copy (buf) {
const fresh = new Buffer(buf.length)
buf.copy(fresh)
return fresh
}

View File

@@ -1,20 +1,20 @@
'use strict' 'use strict'
const crypto = require('crypto') const ciphers = require('./ciphers')
const ciphers = { const CIPHER_MODES = {
16: 'aes-128-ctr', 16: 'aes-128-ctr',
32: 'aes-256-ctr' 32: 'aes-256-ctr'
} }
exports.create = function (key, iv, callback) { exports.create = function (key, iv, callback) {
const name = ciphers[key.length] const mode = CIPHER_MODES[key.length]
if (!name) { if (!mode) {
return callback(new Error('Invalid key length')) return callback(new Error('Invalid key length'))
} }
const cipher = crypto.createCipheriv(name, key, iv) const cipher = ciphers.createCipheriv(mode, key, iv)
const decipher = crypto.createDecipheriv(name, key, iv) const decipher = ciphers.createDecipheriv(mode, key, iv)
const res = { const res = {
encrypt (data, cb) { encrypt (data, cb) {

View File

@@ -0,0 +1,8 @@
'use strict'
const crypto = require('browserify-aes')
module.exports = {
createCipheriv: crypto.createCipheriv,
createDecipheriv: crypto.createDecipheriv
}

8
src/crypto/ciphers.js Normal file
View File

@@ -0,0 +1,8 @@
'use strict'
const crypto = require('crypto')
module.exports = {
createCipheriv: crypto.createCipheriv,
createDecipheriv: crypto.createDecipheriv
}

130
src/crypto/ecdh-browser.js Normal file
View File

@@ -0,0 +1,130 @@
'use strict'
const crypto = require('./webcrypto')()
const nodeify = require('nodeify')
const BN = require('asn1.js').bignum
const Buffer = require('safe-buffer').Buffer
const util = require('./util')
const toBase64 = util.toBase64
const toBn = util.toBn
const bits = {
'P-256': 256,
'P-384': 384,
'P-521': 521
}
exports.generateEphmeralKeyPair = function (curve, callback) {
nodeify(crypto.subtle.generateKey(
{
name: 'ECDH',
namedCurve: curve
},
true,
['deriveBits']
).then((pair) => {
// forcePrivate is used for testing only
const genSharedKey = (theirPub, forcePrivate, cb) => {
if (typeof forcePrivate === 'function') {
cb = forcePrivate
forcePrivate = undefined
}
let privateKey
if (forcePrivate) {
privateKey = crypto.subtle.importKey(
'jwk',
unmarshalPrivateKey(curve, forcePrivate),
{
name: 'ECDH',
namedCurve: curve
},
false,
['deriveBits']
)
} else {
privateKey = Promise.resolve(pair.privateKey)
}
const keys = Promise.all([
crypto.subtle.importKey(
'jwk',
unmarshalPublicKey(curve, theirPub),
{
name: 'ECDH',
namedCurve: curve
},
false,
[]
),
privateKey
])
nodeify(keys.then((keys) => crypto.subtle.deriveBits(
{
name: 'ECDH',
namedCurve: curve,
public: keys[0]
},
keys[1],
bits[curve]
)).then((bits) => Buffer.from(bits)), cb)
}
return crypto.subtle.exportKey(
'jwk',
pair.publicKey
).then((publicKey) => {
return {
key: marshalPublicKey(publicKey),
genSharedKey
}
})
}), callback)
}
const curveLengths = {
'P-256': 32,
'P-384': 48,
'P-521': 66
}
// Marshal converts a jwk encodec ECDH public key into the
// form specified in section 4.3.6 of ANSI X9.62. (This is the format
// go-ipfs uses)
function marshalPublicKey (jwk) {
const byteLen = curveLengths[jwk.crv]
return Buffer.concat([
Buffer.from([4]), // uncompressed point
toBn(jwk.x).toArrayLike(Buffer, 'be', byteLen),
toBn(jwk.y).toArrayLike(Buffer, 'be', byteLen)
], 1 + byteLen * 2)
}
// Unmarshal converts a point, serialized by Marshal, into an jwk encoded key
function unmarshalPublicKey (curve, key) {
const byteLen = curveLengths[curve]
if (!key.slice(0, 1).equals(Buffer.from([4]))) {
throw new Error('Invalid key format')
}
const x = new BN(key.slice(1, byteLen + 1))
const y = new BN(key.slice(1 + byteLen))
return {
kty: 'EC',
crv: curve,
x: toBase64(x),
y: toBase64(y),
ext: true
}
}
function unmarshalPrivateKey (curve, key) {
const result = unmarshalPublicKey(curve, key.public)
result.d = toBase64(new BN(key.private))
return result
}

View File

@@ -1,101 +1,41 @@
'use strict' 'use strict'
const crypto = require('./webcrypto')() const crypto = require('crypto')
const nodeify = require('nodeify') const setImmediate = require('async/setImmediate')
const BN = require('asn1.js').bignum
const util = require('./util') const curves = {
const toBase64 = util.toBase64 'P-256': 'prime256v1',
const toBn = util.toBn 'P-384': 'secp384r1',
'P-521': 'secp521r1'
}
exports.generateEphmeralKeyPair = function (curve, callback) { exports.generateEphmeralKeyPair = function (curve, callback) {
nodeify(crypto.subtle.generateKey( if (!curves[curve]) {
{ return callback(new Error(`Unkown curve: ${curve}`))
name: 'ECDH', }
namedCurve: curve const ecdh = crypto.createECDH(curves[curve])
}, ecdh.generateKeys()
true,
['deriveBits'] setImmediate(() => callback(null, {
).then((pair) => { key: ecdh.getPublicKey(),
// forcePrivate is used for testing only genSharedKey (theirPub, forcePrivate, cb) {
const genSharedKey = (theirPub, forcePrivate, cb) => {
if (typeof forcePrivate === 'function') { if (typeof forcePrivate === 'function') {
cb = forcePrivate cb = forcePrivate
forcePrivate = undefined forcePrivate = null
} }
const privateKey = forcePrivate || pair.privateKey if (forcePrivate) {
nodeify(crypto.subtle.importKey( ecdh.setPrivateKey(forcePrivate.private)
'jwk', }
unmarshalPublicKey(curve, theirPub),
{ let secret
name: 'ECDH', try {
namedCurve: curve secret = ecdh.computeSecret(theirPub)
}, } catch (err) {
false, return cb(err)
[] }
).then((publicKey) => {
return crypto.subtle.deriveBits( setImmediate(() => cb(null, secret))
{
name: 'ECDH',
namedCurve: curve,
public: publicKey
},
privateKey,
256
)
}).then((bits) => {
// return p.derive(pub.getPublic()).toBuffer('be')
return Buffer.from(bits)
}), cb)
} }
}))
return crypto.subtle.exportKey(
'jwk',
pair.publicKey
).then((publicKey) => {
return {
key: marshalPublicKey(publicKey),
genSharedKey
}
})
}), callback)
}
const curveLengths = {
'P-256': 32,
'P-384': 48,
'P-521': 66
}
// Marshal converts a jwk encodec ECDH public key into the
// form specified in section 4.3.6 of ANSI X9.62. (This is the format
// go-ipfs uses)
function marshalPublicKey (jwk) {
const byteLen = curveLengths[jwk.crv]
return Buffer.concat([
Buffer([4]), // uncompressed point
toBn(jwk.x).toBuffer('be', byteLen),
toBn(jwk.y).toBuffer('be', byteLen)
], 1 + byteLen * 2)
}
// Unmarshal converts a point, serialized by Marshal, into an jwk encoded key
function unmarshalPublicKey (curve, key) {
const byteLen = curveLengths[curve]
if (!key.slice(0, 1).equals(Buffer([4]))) {
throw new Error('Invalid key format')
}
const x = new BN(key.slice(1, byteLen + 1))
const y = new BN(key.slice(1 + byteLen))
return {
kty: 'EC',
crv: curve,
x: toBase64(x),
y: toBase64(y),
ext: true
}
} }

35
src/crypto/ed25519.js Normal file
View File

@@ -0,0 +1,35 @@
'use strict'
const nacl = require('tweetnacl')
const setImmediate = require('async/setImmediate')
const Buffer = require('safe-buffer').Buffer
exports.publicKeyLength = nacl.sign.publicKeyLength
exports.privateKeyLength = nacl.sign.secretKeyLength
exports.generateKey = function (callback) {
const done = (err, res) => setImmediate(() => {
callback(err, res)
})
let keys
try {
keys = nacl.sign.keyPair()
} catch (err) {
done(err)
return
}
done(null, keys)
}
exports.hashAndSign = function (key, msg, callback) {
setImmediate(() => {
callback(null, Buffer.from(nacl.sign.detached(msg, key)))
})
}
exports.hashAndVerify = function (key, sig, msg, callback) {
setImmediate(() => {
callback(null, nacl.sign.detached.verify(msg, sig, key))
})
}

View File

@@ -1,6 +1,7 @@
'use strict' 'use strict'
const nodeify = require('nodeify') const nodeify = require('nodeify')
const Buffer = require('safe-buffer').Buffer
const crypto = require('./webcrypto')() const crypto = require('./webcrypto')()
const lengths = require('./hmac-lengths') const lengths = require('./hmac-lengths')

120
src/crypto/rsa-browser.js Normal file
View File

@@ -0,0 +1,120 @@
'use strict'
const nodeify = require('nodeify')
const Buffer = require('safe-buffer').Buffer
const crypto = require('./webcrypto')()
exports.utils = require('./rsa-utils')
exports.generateKey = function (bits, callback) {
nodeify(crypto.subtle.generateKey(
{
name: 'RSASSA-PKCS1-v1_5',
modulusLength: bits,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
hash: {name: 'SHA-256'}
},
true,
['sign', 'verify']
)
.then(exportKey)
.then((keys) => ({
privateKey: keys[0],
publicKey: keys[1]
})), callback)
}
// Takes a jwk key
exports.unmarshalPrivateKey = function (key, callback) {
const privateKey = crypto.subtle.importKey(
'jwk',
key,
{
name: 'RSASSA-PKCS1-v1_5',
hash: {name: 'SHA-256'}
},
true,
['sign']
)
nodeify(Promise.all([
privateKey,
derivePublicFromPrivate(key)
]).then((keys) => exportKey({
privateKey: keys[0],
publicKey: keys[1]
})).then((keys) => ({
privateKey: keys[0],
publicKey: keys[1]
})), callback)
}
exports.getRandomValues = function (arr) {
return Buffer.from(crypto.getRandomValues(arr))
}
exports.hashAndSign = function (key, msg, callback) {
nodeify(crypto.subtle.importKey(
'jwk',
key,
{
name: 'RSASSA-PKCS1-v1_5',
hash: {name: 'SHA-256'}
},
false,
['sign']
).then((privateKey) => {
return crypto.subtle.sign(
{name: 'RSASSA-PKCS1-v1_5'},
privateKey,
Uint8Array.from(msg)
)
}).then((sig) => Buffer.from(sig)), callback)
}
exports.hashAndVerify = function (key, sig, msg, callback) {
nodeify(crypto.subtle.importKey(
'jwk',
key,
{
name: 'RSASSA-PKCS1-v1_5',
hash: {name: 'SHA-256'}
},
false,
['verify']
).then((publicKey) => {
return crypto.subtle.verify(
{name: 'RSASSA-PKCS1-v1_5'},
publicKey,
sig,
msg
)
}), callback)
}
function exportKey (pair) {
return Promise.all([
crypto.subtle.exportKey('jwk', pair.privateKey),
crypto.subtle.exportKey('jwk', pair.publicKey)
])
}
function derivePublicFromPrivate (jwKey) {
return crypto.subtle.importKey(
'jwk',
{
kty: jwKey.kty,
n: jwKey.n,
e: jwKey.e,
alg: jwKey.alg,
kid: jwKey.kid
},
{
name: 'RSASSA-PKCS1-v1_5',
hash: {name: 'SHA-256'}
},
true,
['verify']
)
}

114
src/crypto/rsa-utils.js Normal file
View File

@@ -0,0 +1,114 @@
'use strict'
const asn1 = require('asn1.js')
const util = require('./util')
const toBase64 = util.toBase64
const toBn = util.toBn
const RSAPrivateKey = asn1.define('RSAPrivateKey', function () {
this.seq().obj(
this.key('version').int(),
this.key('modulus').int(),
this.key('publicExponent').int(),
this.key('privateExponent').int(),
this.key('prime1').int(),
this.key('prime2').int(),
this.key('exponent1').int(),
this.key('exponent2').int(),
this.key('coefficient').int()
)
})
const AlgorithmIdentifier = asn1.define('AlgorithmIdentifier', function () {
this.seq().obj(
this.key('algorithm').objid({
'1.2.840.113549.1.1.1': 'rsa'
}),
this.key('none').optional().null_(),
this.key('curve').optional().objid(),
this.key('params').optional().seq().obj(
this.key('p').int(),
this.key('q').int(),
this.key('g').int()
)
)
})
const PublicKey = asn1.define('RSAPublicKey', function () {
this.seq().obj(
this.key('algorithm').use(AlgorithmIdentifier),
this.key('subjectPublicKey').bitstr()
)
})
const RSAPublicKey = asn1.define('RSAPublicKey', function () {
this.seq().obj(
this.key('modulus').int(),
this.key('publicExponent').int()
)
})
// Convert a PKCS#1 in ASN1 DER format to a JWK key
exports.pkcs1ToJwk = function (bytes) {
const asn1 = RSAPrivateKey.decode(bytes, 'der')
return {
kty: 'RSA',
n: toBase64(asn1.modulus),
e: toBase64(asn1.publicExponent),
d: toBase64(asn1.privateExponent),
p: toBase64(asn1.prime1),
q: toBase64(asn1.prime2),
dp: toBase64(asn1.exponent1),
dq: toBase64(asn1.exponent2),
qi: toBase64(asn1.coefficient),
alg: 'RS256',
kid: '2011-04-29'
}
}
// Convert a JWK key into PKCS#1 in ASN1 DER format
exports.jwkToPkcs1 = function (jwk) {
return RSAPrivateKey.encode({
version: 0,
modulus: toBn(jwk.n),
publicExponent: toBn(jwk.e),
privateExponent: toBn(jwk.d),
prime1: toBn(jwk.p),
prime2: toBn(jwk.q),
exponent1: toBn(jwk.dp),
exponent2: toBn(jwk.dq),
coefficient: toBn(jwk.qi)
}, 'der')
}
// Convert a PKCIX in ASN1 DER format to a JWK key
exports.pkixToJwk = function (bytes) {
const ndata = PublicKey.decode(bytes, 'der')
const asn1 = RSAPublicKey.decode(ndata.subjectPublicKey.data, 'der')
return {
kty: 'RSA',
n: toBase64(asn1.modulus),
e: toBase64(asn1.publicExponent),
alg: 'RS256',
kid: '2011-04-29'
}
}
// Convert a JWK key to PKCIX in ASN1 DER format
exports.jwkToPkix = function (jwk) {
return PublicKey.encode({
algorithm: {
algorithm: 'rsa',
none: null
},
subjectPublicKey: {
data: RSAPublicKey.encode({
modulus: toBn(jwk.n),
publicExponent: toBn(jwk.e)
}, 'der')
}
}, 'der')
}

View File

@@ -1,228 +1,80 @@
'use strict' 'use strict'
const nodeify = require('nodeify') // Node.js land
const asn1 = require('asn1.js') // First we look if node-webrypto-ossl is available
// otherwise we fall back to using keypair + node core
const util = require('./util') let webcrypto
const toBase64 = util.toBase64 try {
const toBn = util.toBn webcrypto = require('node-webcrypto-ossl')
const crypto = require('./webcrypto')() } catch (err) {
// not available, use the code below
exports.generateKey = function (bits, callback) {
nodeify(crypto.subtle.generateKey(
{
name: 'RSASSA-PKCS1-v1_5',
modulusLength: bits,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
hash: {name: 'SHA-256'}
},
true,
['sign', 'verify']
)
.then(exportKey)
.then((keys) => ({
privateKey: keys[0],
publicKey: keys[1]
})), callback)
} }
// Takes a jwk key if (webcrypto && !process.env.NO_WEBCRYPTO) {
exports.unmarshalPrivateKey = function (key, callback) { module.exports = require('./rsa-browser')
const privateKey = crypto.subtle.importKey( } else {
'jwk', const crypto = require('crypto')
key, const keypair = require('keypair')
{ const setImmediate = require('async/setImmediate')
name: 'RSASSA-PKCS1-v1_5', const pemToJwk = require('pem-jwk').pem2jwk
hash: {name: 'SHA-256'} const jwkToPem = require('pem-jwk').jwk2pem
},
true,
['sign']
)
nodeify(Promise.all([ exports.utils = require('./rsa-utils')
privateKey,
derivePublicFromPrivate(key)
]).then((keys) => exportKey({
privateKey: keys[0],
publicKey: keys[1]
})).then((keys) => ({
privateKey: keys[0],
publicKey: keys[1]
})), callback)
}
exports.getRandomValues = function (arr) { exports.generateKey = function (bits, callback) {
return Buffer.from(crypto.getRandomValues(arr)) const done = (err, res) => setImmediate(() => {
} callback(err, res)
})
exports.hashAndSign = function (key, msg, callback) { let key
nodeify(crypto.subtle.importKey( try {
'jwk', key = keypair({
key, bits: bits
{ })
name: 'RSASSA-PKCS1-v1_5', } catch (err) {
hash: {name: 'SHA-256'} done(err)
}, return
false,
['sign']
).then((privateKey) => {
return crypto.subtle.sign(
{name: 'RSASSA-PKCS1-v1_5'},
privateKey,
Uint8Array.from(msg)
)
}).then((sig) => Buffer.from(sig)), callback)
}
exports.hashAndVerify = function (key, sig, msg, callback) {
nodeify(crypto.subtle.importKey(
'jwk',
key,
{
name: 'RSASSA-PKCS1-v1_5',
hash: {name: 'SHA-256'}
},
false,
['verify']
).then((publicKey) => {
return crypto.subtle.verify(
{name: 'RSASSA-PKCS1-v1_5'},
publicKey,
sig,
msg
)
}), callback)
}
function exportKey (pair) {
return Promise.all([
crypto.subtle.exportKey('jwk', pair.privateKey),
crypto.subtle.exportKey('jwk', pair.publicKey)
])
}
function derivePublicFromPrivate (jwKey) {
return crypto.subtle.importKey(
'jwk',
{
kty: jwKey.kty,
n: jwKey.n,
e: jwKey.e,
alg: jwKey.alg,
kid: jwKey.kid
},
{
name: 'RSASSA-PKCS1-v1_5',
hash: {name: 'SHA-256'}
},
true,
['verify']
)
}
const RSAPrivateKey = asn1.define('RSAPrivateKey', function () {
this.seq().obj(
this.key('version').int(),
this.key('modulus').int(),
this.key('publicExponent').int(),
this.key('privateExponent').int(),
this.key('prime1').int(),
this.key('prime2').int(),
this.key('exponent1').int(),
this.key('exponent2').int(),
this.key('coefficient').int()
)
})
const AlgorithmIdentifier = asn1.define('AlgorithmIdentifier', function () {
this.seq().obj(
this.key('algorithm').objid({
'1.2.840.113549.1.1.1': 'rsa'
}),
this.key('none').optional().null_(),
this.key('curve').optional().objid(),
this.key('params').optional().seq().obj(
this.key('p').int(),
this.key('q').int(),
this.key('g').int()
)
)
})
const PublicKey = asn1.define('RSAPublicKey', function () {
this.seq().obj(
this.key('algorithm').use(AlgorithmIdentifier),
this.key('subjectPublicKey').bitstr()
)
})
const RSAPublicKey = asn1.define('RSAPublicKey', function () {
this.seq().obj(
this.key('modulus').int(),
this.key('publicExponent').int()
)
})
// Convert a PKCS#1 in ASN1 DER format to a JWK key
exports.pkcs1ToJwk = function (bytes) {
const asn1 = RSAPrivateKey.decode(bytes, 'der')
return {
kty: 'RSA',
n: toBase64(asn1.modulus),
e: toBase64(asn1.publicExponent),
d: toBase64(asn1.privateExponent),
p: toBase64(asn1.prime1),
q: toBase64(asn1.prime2),
dp: toBase64(asn1.exponent1),
dq: toBase64(asn1.exponent2),
qi: toBase64(asn1.coefficient),
alg: 'RS256',
kid: '2011-04-29'
}
}
// Convert a JWK key into PKCS#1 in ASN1 DER format
exports.jwkToPkcs1 = function (jwk) {
return RSAPrivateKey.encode({
version: 0,
modulus: toBn(jwk.n),
publicExponent: toBn(jwk.e),
privateExponent: toBn(jwk.d),
prime1: toBn(jwk.p),
prime2: toBn(jwk.q),
exponent1: toBn(jwk.dp),
exponent2: toBn(jwk.dq),
coefficient: toBn(jwk.qi)
}, 'der')
}
// Convert a PKCIX in ASN1 DER format to a JWK key
exports.pkixToJwk = function (bytes) {
const ndata = PublicKey.decode(bytes, 'der')
const asn1 = RSAPublicKey.decode(ndata.subjectPublicKey.data, 'der')
return {
kty: 'RSA',
n: toBase64(asn1.modulus),
e: toBase64(asn1.publicExponent),
alg: 'RS256',
kid: '2011-04-29'
}
}
// Convert a JWK key to PKCIX in ASN1 DER format
exports.jwkToPkix = function (jwk) {
return PublicKey.encode({
algorithm: {
algorithm: 'rsa',
none: null
},
subjectPublicKey: {
data: RSAPublicKey.encode({
modulus: toBn(jwk.n),
publicExponent: toBn(jwk.e)
}, 'der')
} }
}, 'der')
done(null, {
privateKey: pemToJwk(key.private),
publicKey: pemToJwk(key.public)
})
}
// Takes a jwk key
exports.unmarshalPrivateKey = function (key, callback) {
callback(null, {
privateKey: key,
publicKey: {
kty: key.kty,
n: key.n,
e: key.e
}
})
}
exports.getRandomValues = function (arr) {
return crypto.randomBytes(arr.length)
}
exports.hashAndSign = function (key, msg, callback) {
const sign = crypto.createSign('RSA-SHA256')
sign.update(msg)
setImmediate(() => {
callback(null, sign.sign(jwkToPem(key)))
})
}
exports.hashAndVerify = function (key, sig, msg, callback) {
const verify = crypto.createVerify('RSA-SHA256')
verify.update(msg)
setImmediate(() => {
callback(null, verify.verify(jwkToPem(key), sig))
})
}
} }

View File

@@ -1,11 +1,12 @@
'use strict' 'use strict'
const BN = require('asn1.js').bignum const BN = require('asn1.js').bignum
const Buffer = require('safe-buffer').Buffer
// Convert a BN.js instance to a base64 encoded string without padding // Convert a BN.js instance to a base64 encoded string without padding
// Adapted from https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41#appendix-C // Adapted from https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41#appendix-C
exports.toBase64 = function toBase64 (bn) { exports.toBase64 = function toBase64 (bn) {
let s = bn.toBuffer('be').toString('base64') let s = bn.toArrayLike(Buffer, 'be').toString('base64')
return s return s
.replace(/(=*)$/, '') // Remove any trailing '='s .replace(/(=*)$/, '') // Remove any trailing '='s

View File

@@ -1,12 +1,22 @@
/* global self */
'use strict' 'use strict'
module.exports = function getWebCrypto () { module.exports = function getWebCrypto () {
if (typeof window !== 'undefined') { if (typeof self !== 'undefined') {
// This is only a shim for interfaces, not for functionality // This is only a shim for interfaces, not for functionality
require('webcrypto-shim')(window) require('webcrypto-shim')(self)
if (window.crypto) { if (self.crypto) {
return window.crypto return self.crypto
}
}
if (typeof self !== 'undefined') {
require('webcrypto-shim')(self)
if (self.crypto) {
return self.crypto
} }
} }

View File

@@ -1,7 +1,11 @@
'use strict' 'use strict'
module.exports = function getWebCrypto () { module.exports = function getWebCrypto () {
const WebCrypto = require('node-webcrypto-ossl') try {
const webCrypto = new WebCrypto() const WebCrypto = require('node-webcrypto-ossl')
return webCrypto const webCrypto = new WebCrypto()
return webCrypto
} catch (err) {
// fallback to other things
}
} }

View File

@@ -1,14 +1,22 @@
'use strict' 'use strict'
const protobuf = require('protocol-buffers') const protobuf = require('protocol-buffers')
const pbm = protobuf(require('./crypto.proto')) const pbm = protobuf(require('./crypto.proto'))
const c = require('./crypto') const c = require('./crypto')
exports.protobuf = pbm
exports.hmac = c.hmac exports.hmac = c.hmac
exports.aes = c.aes exports.aes = c.aes
exports.webcrypto = c.webcrypto exports.webcrypto = c.webcrypto
const keys = exports.keys = require('./keys') const keys = exports.keys = require('./keys')
function isValidKeyType (keyType) {
const key = keys[keyType.toLowerCase()]
return key !== undefined
}
exports.keyStretcher = require('./key-stretcher') exports.keyStretcher = require('./key-stretcher')
exports.generateEphemeralKeyPair = require('./ephemeral-keys') exports.generateEphemeralKeyPair = require('./ephemeral-keys')
@@ -30,6 +38,14 @@ exports.unmarshalPublicKey = (buf) => {
switch (decoded.Type) { switch (decoded.Type) {
case pbm.KeyType.RSA: case pbm.KeyType.RSA:
return keys.rsa.unmarshalRsaPublicKey(decoded.Data) return keys.rsa.unmarshalRsaPublicKey(decoded.Data)
case pbm.KeyType.Ed25519:
return keys.ed25519.unmarshalEd25519PublicKey(decoded.Data)
case pbm.KeyType.Secp256k1:
if (keys.secp256k1) {
return keys.secp256k1.unmarshalSecp256k1PublicKey(decoded.Data)
} else {
throw new Error('secp256k1 support requires libp2p-crypto-secp256k1 package')
}
default: default:
throw new Error('invalid or unsupported key type') throw new Error('invalid or unsupported key type')
} }
@@ -38,9 +54,7 @@ exports.unmarshalPublicKey = (buf) => {
// Converts a public key object into a protobuf serialized public key // Converts a public key object into a protobuf serialized public key
exports.marshalPublicKey = (key, type) => { exports.marshalPublicKey = (key, type) => {
type = (type || 'rsa').toLowerCase() type = (type || 'rsa').toLowerCase()
if (!isValidKeyType(type)) {
// for now only rsa is supported
if (type !== 'rsa') {
throw new Error('invalid or unsupported key type') throw new Error('invalid or unsupported key type')
} }
@@ -55,6 +69,14 @@ exports.unmarshalPrivateKey = (buf, callback) => {
switch (decoded.Type) { switch (decoded.Type) {
case pbm.KeyType.RSA: case pbm.KeyType.RSA:
return keys.rsa.unmarshalRsaPrivateKey(decoded.Data, callback) return keys.rsa.unmarshalRsaPrivateKey(decoded.Data, callback)
case pbm.KeyType.Ed25519:
return keys.ed25519.unmarshalEd25519PrivateKey(decoded.Data, callback)
case pbm.KeyType.Secp256k1:
if (keys.secp256k1) {
return keys.secp256k1.unmarshalSecp256k1PrivateKey(decoded.Data, callback)
} else {
return callback(new Error('secp256k1 support requires libp2p-crypto-secp256k1 package'))
}
default: default:
callback(new Error('invalid or unsupported key type')) callback(new Error('invalid or unsupported key type'))
} }
@@ -63,11 +85,17 @@ exports.unmarshalPrivateKey = (buf, callback) => {
// Converts a private key object into a protobuf serialized private key // Converts a private key object into a protobuf serialized private key
exports.marshalPrivateKey = (key, type) => { exports.marshalPrivateKey = (key, type) => {
type = (type || 'rsa').toLowerCase() type = (type || 'rsa').toLowerCase()
if (!isValidKeyType(type)) {
// for now only rsa is supported
if (type !== 'rsa') {
throw new Error('invalid or unsupported key type') throw new Error('invalid or unsupported key type')
} }
return key.bytes return key.bytes
} }
exports.randomBytes = (number) => {
if (!number || typeof number !== 'number') {
throw new Error('first argument must be a Number bigger than 0')
}
return c.rsa.getRandomValues(new Uint8Array(number))
}

View File

@@ -2,6 +2,7 @@
const crypto = require('./crypto') const crypto = require('./crypto')
const whilst = require('async/whilst') const whilst = require('async/whilst')
const Buffer = require('safe-buffer').Buffer
const cipherMap = { const cipherMap = {
'AES-128': { 'AES-128': {

142
src/keys/ed25519.js Normal file
View File

@@ -0,0 +1,142 @@
'use strict'
const multihashing = require('multihashing-async')
const protobuf = require('protocol-buffers')
const Buffer = require('safe-buffer').Buffer
const crypto = require('../crypto').ed25519
const pbm = protobuf(require('../crypto.proto'))
class Ed25519PublicKey {
constructor (key) {
this._key = ensureKey(key, crypto.publicKeyLength)
}
verify (data, sig, callback) {
ensure(callback)
crypto.hashAndVerify(this._key, sig, data, callback)
}
marshal () {
return Buffer.from(this._key)
}
get bytes () {
return pbm.PublicKey.encode({
Type: pbm.KeyType.Ed25519,
Data: this.marshal()
})
}
equals (key) {
return this.bytes.equals(key.bytes)
}
hash (callback) {
ensure(callback)
multihashing(this.bytes, 'sha2-256', callback)
}
}
class Ed25519PrivateKey {
// 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)
}
sign (message, callback) {
ensure(callback)
crypto.hashAndSign(this._key, message, callback)
}
get public () {
if (!this._publicKey) {
throw new Error('public key not provided')
}
return new Ed25519PublicKey(this._publicKey)
}
marshal () {
return Buffer.concat([Buffer.from(this._key), Buffer.from(this._publicKey)])
}
get bytes () {
return pbm.PrivateKey.encode({
Type: pbm.KeyType.Ed25519,
Data: this.marshal()
})
}
equals (key) {
return this.bytes.equals(key.bytes)
}
hash (callback) {
ensure(callback)
multihashing(this.bytes, 'sha2-256', callback)
}
}
function unmarshalEd25519PrivateKey (bytes, callback) {
try {
bytes = ensureKey(bytes, crypto.privateKeyLength + crypto.publicKeyLength)
} catch (err) {
return callback(err)
}
const privateKeyBytes = bytes.slice(0, crypto.privateKeyLength)
const publicKeyBytes = bytes.slice(crypto.privateKeyLength, bytes.length)
callback(null, new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes))
}
function unmarshalEd25519PublicKey (bytes) {
bytes = ensureKey(bytes, crypto.publicKeyLength)
return new Ed25519PublicKey(bytes)
}
function generateKeyPair (_bits, cb) {
if (cb === undefined && typeof _bits === 'function') {
cb = _bits
}
crypto.generateKey((err, keys) => {
if (err) {
return cb(err)
}
let privkey
try {
privkey = new Ed25519PrivateKey(keys.secretKey, keys.publicKey)
} catch (err) {
cb(err)
return
}
cb(null, privkey)
})
}
function ensure (cb) {
if (typeof cb !== 'function') {
throw new Error('callback is required')
}
}
function ensureKey (key, length) {
if (Buffer.isBuffer(key)) {
key = new Uint8Array(key)
}
if (!(key instanceof Uint8Array) || key.length !== length) {
throw new Error('Key must be a Uint8Array or Buffer of length ' + length)
}
return key
}
module.exports = {
Ed25519PublicKey,
Ed25519PrivateKey,
unmarshalEd25519PrivateKey,
unmarshalEd25519PublicKey,
generateKeyPair
}

View File

@@ -1,5 +1,11 @@
'use strict' 'use strict'
module.exports = { module.exports = {
rsa: require('./rsa') rsa: require('./rsa'),
ed25519: require('./ed25519')
}
try {
module.exports.secp256k1 = require('libp2p-crypto-secp256k1')
} catch (err) {
} }

View File

@@ -17,7 +17,7 @@ class RsaPublicKey {
} }
marshal () { marshal () {
return crypto.jwkToPkix(this._key) return crypto.utils.jwkToPkix(this._key)
} }
get bytes () { get bytes () {
@@ -71,7 +71,7 @@ class RsaPrivateKey {
} }
marshal () { marshal () {
return crypto.jwkToPkcs1(this._key) return crypto.utils.jwkToPkcs1(this._key)
} }
get bytes () { get bytes () {
@@ -92,7 +92,7 @@ class RsaPrivateKey {
} }
function unmarshalRsaPrivateKey (bytes, callback) { function unmarshalRsaPrivateKey (bytes, callback) {
const jwk = crypto.pkcs1ToJwk(bytes) const jwk = crypto.utils.pkcs1ToJwk(bytes)
crypto.unmarshalPrivateKey(jwk, (err, keys) => { crypto.unmarshalPrivateKey(jwk, (err, keys) => {
if (err) { if (err) {
return callback(err) return callback(err)
@@ -103,7 +103,7 @@ function unmarshalRsaPrivateKey (bytes, callback) {
} }
function unmarshalRsaPublicKey (bytes) { function unmarshalRsaPublicKey (bytes) {
const jwk = crypto.pkixToJwk(bytes) const jwk = crypto.utils.pkixToJwk(bytes)
return new RsaPublicKey(jwk) return new RsaPublicKey(jwk)
} }

View File

@@ -3,7 +3,12 @@
'use strict' 'use strict'
const expect = require('chai').expect const expect = require('chai').expect
const series = require('async/series')
const Buffer = require('safe-buffer').Buffer
const crypto = require('../src') const crypto = require('../src')
const fixtures = require('./fixtures/aes')
const goFixtures = require('./fixtures/go-aes')
const bytes = { const bytes = {
16: 'AES-128', 16: 'AES-128',
@@ -13,25 +18,99 @@ const bytes = {
describe('AES-CTR', () => { describe('AES-CTR', () => {
Object.keys(bytes).forEach((byte) => { Object.keys(bytes).forEach((byte) => {
it(`${bytes[byte]} - encrypt and decrypt`, (done) => { it(`${bytes[byte]} - encrypt and decrypt`, (done) => {
const key = new Buffer(parseInt(byte, 10)) const key = Buffer.alloc(parseInt(byte, 10))
key.fill(5) key.fill(5)
const iv = new Buffer(16) const iv = Buffer.alloc(16)
iv.fill(1) iv.fill(1)
crypto.aes.create(key, iv, (err, cipher) => { crypto.aes.create(key, iv, (err, cipher) => {
expect(err).to.not.exist expect(err).to.not.exist
cipher.encrypt(new Buffer('hello'), (err, res) => { series([
expect(err).to.not.exist encryptAndDecrypt(cipher),
encryptAndDecrypt(cipher),
encryptAndDecrypt(cipher),
encryptAndDecrypt(cipher),
encryptAndDecrypt(cipher)
], done)
})
})
})
Object.keys(bytes).forEach((byte) => {
it(`${bytes[byte]} - fixed - encrypt and decrypt`, (done) => {
const key = Buffer.alloc(parseInt(byte, 10))
key.fill(5)
cipher.decrypt(res, (err, res) => { const iv = Buffer.alloc(16)
iv.fill(1)
crypto.aes.create(key, iv, (err, cipher) => {
expect(err).to.not.exist
series(fixtures[byte].inputs.map((rawIn, i) => (cb) => {
const input = Buffer.from(rawIn)
const output = Buffer.from(fixtures[byte].outputs[i])
cipher.encrypt(input, (err, res) => {
expect(err).to.not.exist expect(err).to.not.exist
expect(res).to.be.eql(new Buffer('hello')) expect(res).to.have.length(output.length)
done() expect(res).to.be.eql(output)
cipher.decrypt(res, (err, res) => {
expect(err).to.not.exist
expect(res).to.be.eql(input)
cb()
})
}) })
}) }), done)
})
})
})
Object.keys(bytes).forEach((byte) => {
if (!goFixtures[byte]) {
return
}
it(`${bytes[byte]} - go interop - encrypt and decrypt`, (done) => {
const key = Buffer.alloc(parseInt(byte, 10))
key.fill(5)
const iv = Buffer.alloc(16)
iv.fill(1)
crypto.aes.create(key, iv, (err, cipher) => {
expect(err).to.not.exist
series(goFixtures[byte].inputs.map((rawIn, i) => (cb) => {
const input = Buffer.from(rawIn)
const output = Buffer.from(goFixtures[byte].outputs[i])
cipher.encrypt(input, (err, res) => {
expect(err).to.not.exist
expect(res).to.have.length(output.length)
expect(res).to.be.eql(output)
cipher.decrypt(res, (err, res) => {
expect(err).to.not.exist
expect(res).to.be.eql(input)
cb()
})
})
}), done)
}) })
}) })
}) })
}) })
function encryptAndDecrypt (cipher) {
const data = Buffer.alloc(100)
data.fill(Math.ceil(Math.random() * 100))
return (cb) => {
cipher.encrypt(data, (err, res) => {
expect(err).to.not.exist
cipher.decrypt(res, (err, res) => {
expect(err).to.not.exist
expect(res).to.be.eql(data)
cb()
})
})
}
}

195
test/ed25519.spec.js Normal file
View File

@@ -0,0 +1,195 @@
/* eslint-env mocha */
'use strict'
const expect = require('chai').expect
const Buffer = require('safe-buffer').Buffer
const crypto = require('../src')
const ed25519 = crypto.keys.ed25519
const fixtures = require('./fixtures/go-key-ed25519')
describe('ed25519', () => {
let key
before((done) => {
crypto.generateKeyPair('Ed25519', 512, (err, _key) => {
if (err) return done(err)
key = _key
done()
})
})
it('generates a valid key', (done) => {
expect(
key
).to.be.an.instanceof(
ed25519.Ed25519PrivateKey
)
key.hash((err, digest) => {
if (err) {
return done(err)
}
expect(digest).to.have.length(34)
done()
})
})
it('signs', (done) => {
const text = crypto.randomBytes(512)
key.sign(text, (err, sig) => {
if (err) {
return done(err)
}
key.public.verify(text, sig, (err, res) => {
if (err) {
return done(err)
}
expect(res).to.be.eql(true)
done()
})
})
})
it('encoding', (done) => {
const keyMarshal = key.marshal()
ed25519.unmarshalEd25519PrivateKey(keyMarshal, (err, key2) => {
if (err) {
return done(err)
}
const keyMarshal2 = key2.marshal()
expect(
keyMarshal
).to.be.eql(
keyMarshal2
)
const pk = key.public
const pkMarshal = pk.marshal()
const pk2 = ed25519.unmarshalEd25519PublicKey(pkMarshal)
const pkMarshal2 = pk2.marshal()
expect(
pkMarshal
).to.be.eql(
pkMarshal2
)
done()
})
})
describe('key equals', () => {
it('equals itself', () => {
expect(
key.equals(key)
).to.be.eql(
true
)
expect(
key.public.equals(key.public)
).to.be.eql(
true
)
})
it('not equals other key', (done) => {
crypto.generateKeyPair('Ed25519', 512, (err, key2) => {
if (err) return done(err)
expect(
key.equals(key2)
).to.be.eql(
false
)
expect(
key2.equals(key)
).to.be.eql(
false
)
expect(
key.public.equals(key2.public)
).to.be.eql(
false
)
expect(
key2.public.equals(key.public)
).to.be.eql(
false
)
done()
})
})
})
it('sign and verify', (done) => {
const data = Buffer.from('hello world')
key.sign(data, (err, sig) => {
if (err) {
return done(err)
}
key.public.verify(data, sig, (err, valid) => {
if (err) {
return done(err)
}
expect(valid).to.be.eql(true)
done()
})
})
})
it('fails to verify for different data', (done) => {
const data = Buffer.from('hello world')
key.sign(data, (err, sig) => {
if (err) {
return done(err)
}
key.public.verify(Buffer.from('hello'), sig, (err, valid) => {
if (err) {
return done(err)
}
expect(valid).to.be.eql(false)
done()
})
})
})
describe('go interop', () => {
let privateKey
before((done) => {
crypto.unmarshalPrivateKey(fixtures.verify.privateKey, (err, key) => {
expect(err).to.not.exist
privateKey = key
done()
})
})
it('verifies with data from go', (done) => {
const key = crypto.unmarshalPublicKey(fixtures.verify.publicKey)
key.verify(fixtures.verify.data, fixtures.verify.signature, (err, ok) => {
if (err) throw err
expect(err).to.not.exist
expect(ok).to.be.eql(true)
done()
})
})
it('generates the same signature as go', (done) => {
privateKey.sign(fixtures.verify.data, (err, sig) => {
expect(err).to.not.exist
expect(sig).to.deep.equal(fixtures.verify.signature)
done()
})
})
})
})

View File

@@ -14,6 +14,11 @@ const lengths = {
'P-384': 97, 'P-384': 97,
'P-521': 133 'P-521': 133
} }
const secretLengths = {
'P-256': 32,
'P-384': 48,
'P-521': 66
}
describe('generateEphemeralKeyPair', () => { describe('generateEphemeralKeyPair', () => {
curves.forEach((curve) => { curves.forEach((curve) => {
@@ -28,7 +33,7 @@ describe('generateEphemeralKeyPair', () => {
keys[0].genSharedKey(keys[1].key, (err, shared) => { keys[0].genSharedKey(keys[1].key, (err, shared) => {
expect(err).to.not.exist expect(err).to.not.exist
expect(shared).to.have.length(32) expect(shared).to.have.length(secretLengths[curve])
done() done()
}) })
}) })
@@ -39,12 +44,29 @@ describe('generateEphemeralKeyPair', () => {
it('generates a shared secret', (done) => { it('generates a shared secret', (done) => {
const curve = fixtures.curve const curve = fixtures.curve
crypto.generateEphemeralKeyPair(curve, (err, alice) => { parallel([
(cb) => crypto.generateEphemeralKeyPair(curve, cb),
(cb) => crypto.generateEphemeralKeyPair(curve, cb)
], (err, res) => {
expect(err).to.not.exist expect(err).to.not.exist
const alice = res[0]
const bob = res[1]
bob.key = fixtures.bob.public
alice.genSharedKey(fixtures.bob.public, (err, s1) => { parallel([
(cb) => alice.genSharedKey(bob.key, cb),
(cb) => bob.genSharedKey(alice.key, fixtures.bob, cb)
], (err, secrets) => {
expect(err).to.not.exist expect(err).to.not.exist
expect(s1).to.have.length(32)
expect(
secrets[0]
).to.be.eql(
secrets[1]
)
expect(secrets[0]).to.have.length(32)
done() done()
}) })
}) })

27
test/fixtures/aes.js vendored Normal file
View File

@@ -0,0 +1,27 @@
'use strict'
const fixes16 = [
require('./fix1.json'),
require('./fix2.json'),
require('./fix3.json'),
require('./fix4.json'),
require('./fix5.json')
]
const fixes32 = [
require('./fix6.json'),
require('./fix7.json'),
require('./fix8.json'),
require('./fix9.json'),
require('./fix10.json')
]
module.exports = {
16: {
inputs: fixes16.map((f) => f.input),
outputs: fixes16.map((f) => f.output)
},
32: {
inputs: fixes32.map((f) => f.input),
outputs: fixes32.map((f) => f.output)
}
}

212
test/fixtures/fix1.json vendored Normal file
View File

@@ -0,0 +1,212 @@
{
"input": {
"type": "Buffer",
"data": [
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47,
47
]
},
"output": {
"type": "Buffer",
"data": [
121,
104,
0,
151,
57,
137,
22,
239,
234,
151,
58,
15,
100,
22,
228,
110,
85,
248,
249,
15,
145,
128,
223,
25,
192,
175,
132,
169,
98,
203,
231,
106,
224,
102,
206,
244,
29,
213,
36,
2,
26,
213,
94,
29,
134,
219,
136,
73,
212,
176,
33,
95,
198,
91,
148,
139,
132,
252,
182,
115,
116,
160,
146,
194,
0,
97,
181,
0,
193,
149,
21,
51,
248,
97,
32,
62,
86,
153,
238,
67,
38,
34,
55,
143,
70,
193,
99,
107,
31,
67,
90,
97,
55,
63,
69,
203,
33,
233,
74,
237
]
}
}

212
test/fixtures/fix10.json vendored Normal file
View File

@@ -0,0 +1,212 @@
{
"input": {
"type": "Buffer",
"data": [
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72,
72
]
},
"output": {
"type": "Buffer",
"data": [
201,
224,
56,
64,
167,
224,
124,
49,
19,
51,
208,
226,
216,
50,
12,
73,
15,
255,
156,
108,
98,
179,
144,
110,
33,
151,
43,
64,
227,
153,
120,
39,
21,
151,
41,
61,
245,
20,
31,
23,
109,
213,
109,
55,
35,
40,
122,
109,
41,
10,
32,
176,
25,
184,
91,
176,
177,
134,
138,
252,
160,
2,
108,
43,
222,
239,
174,
2,
145,
74,
34,
131,
237,
214,
235,
102,
26,
204,
124,
64,
101,
134,
186,
45,
55,
29,
52,
55,
171,
95,
172,
86,
242,
101,
141,
153,
222,
161,
128,
83
]
}
}

212
test/fixtures/fix2.json vendored Normal file
View File

@@ -0,0 +1,212 @@
{
"input": {
"type": "Buffer",
"data": [
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24,
24
]
},
"output": {
"type": "Buffer",
"data": [
109,
172,
127,
179,
110,
222,
79,
219,
87,
76,
70,
204,
166,
110,
184,
229,
90,
49,
160,
252,
78,
58,
73,
51,
152,
218,
3,
200,
10,
124,
152,
117,
137,
40,
23,
127,
56,
57,
203,
31,
101,
227,
31,
198,
223,
86,
98,
120,
100,
86,
116,
144,
142,
127,
68,
175,
249,
232,
22,
83,
22,
68,
60,
230,
146,
22,
153,
193,
67,
5,
51,
253,
239,
210,
80,
31,
254,
103,
185,
145,
123,
99,
205,
175,
156,
144,
191,
67,
31,
236,
43,
98,
197,
235,
31,
50,
69,
228,
100,
64
]
}
}

212
test/fixtures/fix3.json vendored Normal file
View File

@@ -0,0 +1,212 @@
{
"input": {
"type": "Buffer",
"data": [
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7,
7
]
},
"output": {
"type": "Buffer",
"data": [
191,
93,
126,
191,
180,
42,
118,
144,
28,
188,
211,
191,
211,
130,
170,
153,
134,
240,
179,
83,
75,
23,
42,
68,
158,
200,
123,
155,
57,
169,
152,
133,
33,
114,
90,
29,
131,
91,
70,
105,
83,
45,
40,
47,
77,
96,
97,
8,
40,
1,
110,
245,
106,
172,
152,
146,
5,
114,
132,
0,
179,
31,
44,
78,
19,
109,
92,
199,
226,
36,
12,
74,
180,
241,
224,
107,
83,
13,
167,
27,
251,
101,
193,
98,
49,
90,
225,
197,
75,
213,
144,
52,
235,
130,
92,
247,
219,
139,
209,
132
]
}
}

212
test/fixtures/fix4.json vendored Normal file
View File

@@ -0,0 +1,212 @@
{
"input": {
"type": "Buffer",
"data": [
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25,
25
]
},
"output": {
"type": "Buffer",
"data": [
191,
110,
53,
190,
250,
44,
190,
136,
22,
209,
131,
200,
112,
31,
61,
183,
247,
95,
4,
249,
69,
147,
238,
74,
18,
71,
197,
115,
141,
226,
102,
92,
91,
128,
181,
172,
67,
109,
17,
165,
52,
10,
55,
31,
55,
225,
253,
140,
154,
35,
104,
62,
119,
103,
197,
152,
125,
134,
140,
181,
170,
76,
75,
114,
195,
188,
68,
197,
28,
47,
116,
82,
34,
128,
232,
122,
14,
229,
122,
161,
36,
212,
161,
164,
145,
86,
215,
233,
222,
50,
143,
89,
131,
32,
130,
196,
109,
36,
204,
254
]
}
}

212
test/fixtures/fix5.json vendored Normal file
View File

@@ -0,0 +1,212 @@
{
"input": {
"type": "Buffer",
"data": [
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48,
48
]
},
"output": {
"type": "Buffer",
"data": [
97,
142,
8,
37,
69,
173,
124,
180,
97,
70,
45,
91,
196,
126,
184,
135,
213,
104,
171,
89,
231,
63,
43,
42,
7,
245,
75,
165,
205,
182,
24,
50,
170,
217,
128,
112,
114,
215,
209,
145,
135,
235,
179,
212,
5,
81,
142,
199,
53,
221,
39,
239,
167,
21,
237,
168,
145,
249,
250,
108,
2,
247,
89,
73,
228,
227,
255,
155,
121,
157,
205,
96,
43,
32,
112,
209,
173,
96,
143,
43,
220,
140,
26,
205,
34,
34,
53,
157,
41,
167,
125,
235,
243,
85,
13,
14,
93,
109,
233,
186
]
}
}

212
test/fixtures/fix6.json vendored Normal file
View File

@@ -0,0 +1,212 @@
{
"input": {
"type": "Buffer",
"data": [
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68,
68
]
},
"output": {
"type": "Buffer",
"data": [
198,
59,
91,
107,
222,
214,
31,
230,
112,
1,
199,
174,
17,
224,
194,
225,
138,
65,
58,
160,
31,
249,
102,
16,
74,
46,
85,
30,
232,
249,
120,
108,
38,
165,
105,
27,
12,
98,
98,
108,
130,
163,
16,
137,
116,
104,
153,
188,
5,
251,
163,
244,
0,
58,
1,
207,
25,
78,
188,
210,
205,
221,
48,
132,
72,
209,
11,
67,
14,
42,
218,
71,
148,
252,
126,
183,
60,
32,
93,
36,
125,
103,
191,
117,
82,
241,
190,
176,
1,
129,
118,
112,
139,
153,
178,
56,
61,
91,
52,
198
]
}
}

212
test/fixtures/fix7.json vendored Normal file
View File

@@ -0,0 +1,212 @@
{
"input": {
"type": "Buffer",
"data": [
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10,
10
]
},
"output": {
"type": "Buffer",
"data": [
206,
241,
99,
120,
248,
163,
57,
30,
216,
86,
255,
192,
89,
193,
176,
17,
78,
62,
80,
149,
189,
235,
27,
157,
175,
248,
7,
19,
222,
64,
111,
199,
204,
163,
26,
16,
95,
221,
70,
32,
239,
4,
58,
162,
253,
237,
8,
51,
94,
3,
165,
186,
223,
210,
116,
101,
228,
82,
103,
76,
74,
44,
51,
117,
189,
140,
132,
230,
188,
243,
24,
158,
149,
93,
147,
226,
113,
195,
31,
24,
9,
19,
27,
132,
180,
152,
26,
65,
125,
144,
86,
167,
41,
144,
158,
204,
76,
46,
181,
110
]
}
}

212
test/fixtures/fix8.json vendored Normal file
View File

@@ -0,0 +1,212 @@
{
"input": {
"type": "Buffer",
"data": [
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75,
75
]
},
"output": {
"type": "Buffer",
"data": [
153,
161,
201,
66,
87,
46,
242,
87,
136,
238,
151,
198,
129,
122,
62,
205,
142,
252,
109,
187,
238,
183,
63,
95,
240,
97,
220,
209,
37,
144,
237,
84,
251,
149,
152,
222,
89,
200,
208,
119,
213,
38,
65,
19,
2,
252,
193,
125,
94,
76,
182,
198,
243,
121,
253,
16,
45,
254,
82,
47,
146,
206,
41,
105,
254,
237,
236,
141,
118,
214,
197,
228,
59,
125,
45,
200,
61,
24,
110,
26,
235,
92,
175,
255,
85,
119,
57,
160,
145,
107,
206,
28,
62,
10,
166,
89,
7,
20,
246,
243
]
}
}

212
test/fixtures/fix9.json vendored Normal file
View File

@@ -0,0 +1,212 @@
{
"input": {
"type": "Buffer",
"data": [
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35,
35
]
},
"output": {
"type": "Buffer",
"data": [
79,
215,
22,
29,
132,
130,
214,
248,
237,
124,
234,
54,
215,
78,
0,
211,
246,
222,
54,
91,
53,
2,
49,
40,
0,
202,
188,
25,
184,
121,
164,
235,
189,
97,
14,
0,
83,
166,
88,
62,
55,
49,
79,
153,
136,
193,
133,
206,
172,
99,
207,
73,
246,
216,
192,
107,
50,
206,
167,
242,
25,
180,
63,
184,
201,
61,
90,
242,
223,
192,
13,
140,
31,
240,
112,
157,
250,
90,
142,
3,
40,
12,
106,
63,
73,
42,
79,
82,
20,
41,
187,
173,
23,
85,
59,
253,
212,
191,
109,
46
]
}
}

20
test/fixtures/go-aes.js vendored Normal file
View File

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

View File

@@ -1,12 +1,14 @@
'use strict' 'use strict'
const Buffer = require('safe-buffer').Buffer
module.exports = { module.exports = {
curve: 'P-256', curve: 'P-256',
bob: { bob: {
private: [ 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 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: new Buffer([ 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 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
]) ])
} }

30
test/fixtures/go-key-ed25519.js vendored Normal file
View File

@@ -0,0 +1,30 @@
'use strict'
const Buffer = require('safe-buffer').Buffer
module.exports = {
// These were generated in a gore (https://github.com/motemen/gore) repl session:
//
// :import github.com/libp2p/go-libp2p-crypto
// :import crypto/rand
// priv, pub, err := crypto.GenerateEd25519Key(rand.Reader)
// pubkeyBytes, err := pub.Bytes()
// privkeyBytes, err := priv.Bytes()
// data := []byte("hello! and welcome to some awesome crypto primitives")
// sig, err := priv.Sign(data)
//
// :import io/ioutil
// ioutil.WriteFile("/tmp/pubkey_go.bin", pubkeyBytes, 0644)
// // etc..
//
// Then loaded into a node repl and dumped to arrays with:
//
// var pubkey = Array.from(fs.readFileSync('/tmp/pubkey_go.bin'))
// console.log(JSON.stringify(pubkey))
verify: {
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])
}
}

View File

@@ -1,30 +1,32 @@
'use strict' 'use strict'
const Buffer = require('safe-buffer').Buffer
module.exports = { module.exports = {
private: { private: {
hash: new Buffer([ 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 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: new Buffer([ 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 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: { public: {
hash: new Buffer([ 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 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: new Buffer([ 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 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: { verify: {
signature: new Buffer([ 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 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: new Buffer([ 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 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: new Buffer([ 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 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,30 +1,32 @@
'use strict' 'use strict'
const Buffer = require('safe-buffer').Buffer
module.exports = [{ module.exports = [{
cipher: 'AES-256', cipher: 'AES-256',
hash: 'SHA256', hash: 'SHA256',
secret: new Buffer([ 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 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: { k1: {
iv: new Buffer([ iv: Buffer.from([
208, 132, 203, 169, 253, 52, 40, 83, 161, 91, 17, 71, 33, 136, 67, 96 208, 132, 203, 169, 253, 52, 40, 83, 161, 91, 17, 71, 33, 136, 67, 96
]), ]),
cipherKey: new Buffer([ 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 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: new Buffer([ macKey: Buffer.from([
6, 179, 91, 245, 224, 56, 153, 120, 77, 140, 29, 5, 15, 213, 187, 65, 137, 230, 202, 120 6, 179, 91, 245, 224, 56, 153, 120, 77, 140, 29, 5, 15, 213, 187, 65, 137, 230, 202, 120
]) ])
}, },
k2: { k2: {
iv: new Buffer([ iv: Buffer.from([
236, 17, 34, 141, 90, 106, 197, 56, 197, 184, 157, 135, 91, 88, 112, 19 236, 17, 34, 141, 90, 106, 197, 56, 197, 184, 157, 135, 91, 88, 112, 19
]), ]),
cipherKey: new Buffer([ 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 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: new Buffer([ macKey: Buffer.from([
3, 229, 77, 212, 241, 217, 23, 113, 220, 126, 38, 255, 18, 117, 108, 205, 198, 89, 1, 236 3, 229, 77, 212, 241, 217, 23, 113, 220, 126, 38, 255, 18, 117, 108, 205, 198, 89, 1, 236
]) ])
} }

11
test/fixtures/secp256k1.js vendored Normal file
View File

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

View File

@@ -2,7 +2,9 @@
/* eslint-env mocha */ /* eslint-env mocha */
'use strict' 'use strict'
const Buffer = require('safe-buffer').Buffer
const expect = require('chai').expect const expect = require('chai').expect
const crypto = require('../src') const crypto = require('../src')
const hashes = ['SHA1', 'SHA256', 'SHA512'] const hashes = ['SHA1', 'SHA256', 'SHA512']
@@ -10,10 +12,10 @@ const hashes = ['SHA1', 'SHA256', 'SHA512']
describe('HMAC', () => { describe('HMAC', () => {
hashes.forEach((hash) => { hashes.forEach((hash) => {
it(`${hash} - sign and verify`, (done) => { it(`${hash} - sign and verify`, (done) => {
crypto.hmac.create(hash, new Buffer('secret'), (err, hmac) => { crypto.hmac.create(hash, Buffer.from('secret'), (err, hmac) => {
expect(err).to.not.exist expect(err).to.not.exist
hmac.digest(new Buffer('hello world'), (err, sig) => { hmac.digest(Buffer.from('hello world'), (err, sig) => {
expect(err).to.not.exist expect(err).to.not.exist
expect(sig).to.have.length(hmac.length) expect(sig).to.have.length(hmac.length)
done() done()

View File

@@ -23,9 +23,17 @@ describe('libp2p-crypto', () => {
const key2 = crypto.unmarshalPublicKey(crypto.marshalPublicKey(key.public)) const key2 = crypto.unmarshalPublicKey(crypto.marshalPublicKey(key.public))
expect(key2.equals(key.public)).to.be.eql(true) expect(key2.equals(key.public)).to.be.eql(true)
expect(() => {
crypto.marshalPublicKey(key.public, 'invalid-key-type')
}).to.throw()
}) })
it('marshalPrivateKey and unmarshalPrivateKey', (done) => { it('marshalPrivateKey and unmarshalPrivateKey', (done) => {
expect(() => {
crypto.marshalPrivateKey(key, 'invalid-key-type')
}).to.throw()
crypto.unmarshalPrivateKey(crypto.marshalPrivateKey(key), (err, key2) => { crypto.unmarshalPrivateKey(crypto.marshalPrivateKey(key), (err, key2) => {
if (err) { if (err) {
return done(err) return done(err)
@@ -98,4 +106,19 @@ describe('libp2p-crypto', () => {
) )
}) })
}) })
describe('randomBytes', () => {
it('throws with no number passed', () => {
expect(() => {
crypto.randomBytes()
}).to.throw()
})
it('generates different random things', () => {
const buf1 = crypto.randomBytes(10)
expect(buf1.length).to.equal(10)
const buf2 = crypto.randomBytes(10)
expect(buf1).to.not.eql(buf2)
})
})
}) })

View File

@@ -2,6 +2,7 @@
'use strict' 'use strict'
const expect = require('chai').expect const expect = require('chai').expect
const Buffer = require('safe-buffer').Buffer
const crypto = require('../src') const crypto = require('../src')
const rsa = crypto.keys.rsa const rsa = crypto.keys.rsa
@@ -129,7 +130,7 @@ describe('RSA', () => {
}) })
it('sign and verify', (done) => { it('sign and verify', (done) => {
const data = new Buffer('hello world') const data = Buffer.from('hello world')
key.sign(data, (err, sig) => { key.sign(data, (err, sig) => {
if (err) { if (err) {
return done(err) return done(err)
@@ -146,13 +147,13 @@ describe('RSA', () => {
}) })
it('fails to verify for different data', (done) => { it('fails to verify for different data', (done) => {
const data = new Buffer('hello world') const data = Buffer.from('hello world')
key.sign(data, (err, sig) => { key.sign(data, (err, sig) => {
if (err) { if (err) {
return done(err) return done(err)
} }
key.public.verify(new Buffer('hello'), sig, (err, valid) => { key.public.verify(Buffer.from('hello'), sig, (err, valid) => {
if (err) { if (err) {
return done(err) return done(err)
} }

104
test/secp256k1.spec.js Normal file
View File

@@ -0,0 +1,104 @@
/* eslint-env mocha */
'use strict'
const expect = require('chai').expect
const fixtures = require('./fixtures/secp256k1')
const crypto = require('../src')
const mockPublicKey = {
bytes: fixtures.pbmPublicKey
}
const mockPrivateKey = {
bytes: fixtures.pbmPrivateKey,
public: mockPublicKey
}
const mockSecp256k1Module = {
generateKeyPair (bits, callback) {
callback(null, mockPrivateKey)
},
unmarshalSecp256k1PrivateKey (buf, callback) {
callback(null, mockPrivateKey)
},
unmarshalSecp256k1PublicKey (buf) {
return mockPublicKey
}
}
describe('with libp2p-crypto-secp256k1 module present', () => {
let key
before((done) => {
crypto.keys['secp256k1'] = mockSecp256k1Module
crypto.generateKeyPair('secp256k1', 256, (err, _key) => {
if (err) return done(err)
key = _key
done()
})
})
after((done) => {
delete crypto.keys['secp256k1']
done()
})
it('generates a valid key', (done) => {
expect(
key
).to.exist
done()
})
it('protobuf encoding', (done) => {
const keyMarshal = crypto.marshalPrivateKey(key)
crypto.unmarshalPrivateKey(keyMarshal, (err, key2) => {
if (err) return done(err)
const keyMarshal2 = crypto.marshalPrivateKey(key2)
expect(
keyMarshal
).to.be.eql(
keyMarshal2
)
const pk = key.public
const pkMarshal = crypto.marshalPublicKey(pk)
const pk2 = crypto.unmarshalPublicKey(pkMarshal)
const pkMarshal2 = crypto.marshalPublicKey(pk2)
expect(
pkMarshal
).to.be.eql(
pkMarshal2
)
done()
})
})
})
describe('without libp2p-crypto-secp256k1 module present', () => {
it('fails to generate a secp256k1 key', (done) => {
crypto.generateKeyPair('secp256k1', 256, (err, key) => {
expect(err).to.exist
expect(key).to.not.exist
done()
})
})
it('fails to unmarshal a secp256k1 private key', (done) => {
crypto.unmarshalPrivateKey(fixtures.pbmPrivateKey, (err, key) => {
expect(err).to.exist
expect(key).to.not.exist
done()
})
})
it('fails to unmarshal a secp256k1 public key', () => {
expect(() => {
crypto.unmarshalPublicKey(fixtures.pbmPublicKey)
}).to.throw(Error)
})
})

21
test/util.spec.js Normal file
View File

@@ -0,0 +1,21 @@
/* eslint max-nested-callbacks: ["error", 8] */
/* eslint-env mocha */
'use strict'
const expect = require('chai').expect
const util = require('../src/crypto/util')
const BN = require('bn.js')
describe('Util', () => {
let bn
before((done) => {
bn = new BN('dead', 16)
done()
})
it('toBase64', (done) => {
expect(util.toBase64(bn)).to.be.eql('3q0')
done()
})
})