Compare commits

...

24 Commits

Author SHA1 Message Date
564489b0ea chore: release version v0.8.0 2016-11-03 07:52:10 +00:00
65c2ac8dca chore: update contributors 2016-11-03 07:52:10 +00:00
31701e236d Async Crypto Endeavour (#33)
* refactor: make import and creation async - This allows the use of native key generation in the browser

BREAKING CHANGE:

This changes the interface of .create, .createFromPrivKey,
.createFromPubKey, .createFromJSON
2016-11-03 07:51:29 +00:00
e08907ff94 Merge pull request #34 from RichardLitt/master
Update README URLs based on HTTP redirects
2016-10-02 15:06:15 +01:00
f6a42fef76 Update README URLs based on HTTP redirects 2016-10-02 10:03:56 -04:00
ba8aa3ff34 Merge pull request #32 from libp2p/greenkeeper-libp2p-crypto-0.6.1
Update libp2p-crypto to version 0.6.1 🚀
2016-09-13 17:23:40 +02:00
ae81e95927 chore(package): update libp2p-crypto to version 0.6.1
https://greenkeeper.io/
2016-09-13 12:35:32 +02:00
d24500a042 Update README.md 2016-09-11 16:40:26 -04:00
5fec44833e Update README.md 2016-09-11 16:40:09 -04:00
2432c56ad5 Merge pull request #30 from npmcdn-to-unpkg-bot/npmcdn-to-unpkg
Replace npmcdn.com with unpkg.com
2016-09-11 13:03:07 -04:00
f0e380af58 Replace npmcdn.com with unpkg.com 2016-09-11 12:29:33 +01:00
24cd31b2d1 Merge pull request #29 from libp2p/greenkeeper-aegir-8.0.0
Update aegir to version 8.0.0 🚀
2016-09-06 21:15:05 +02:00
5f9136b3ca chore(package): update aegir to version 8.0.0
https://greenkeeper.io/
2016-09-06 15:11:37 +02:00
4fe3e12b3c Merge pull request #26 from libp2p/greenkeeper-update-all
Update all dependencies 🌴
2016-08-04 20:43:19 +02:00
49d454da7d chore(package): update dependencies
https://greenkeeper.io/
2016-08-04 19:11:03 +02:00
7336b6ad80 chore: release version v0.7.0 2016-05-26 19:23:08 +01:00
461d2ea287 chore: update contributors 2016-05-26 19:23:08 +01:00
7c100f845a update aegir 2016-05-26 19:20:59 +01:00
c3f50a2dfd Merge pull request #25 from diasdavid/crypto
refactor: use libp2p and standardized rsa keys
2016-05-24 13:24:54 +01:00
907ed1571d chore: add more release tasks 2016-05-24 14:15:00 +02:00
2aad1dce7b test: fix node-forge for the browser setup 2016-05-24 14:14:11 +02:00
58f1933980 fix: code review and docs and go interop 2016-05-24 14:03:31 +02:00
ab5504686a fix: use new version of libp2p-crypto 2016-05-24 12:39:36 +02:00
4beb1f8888 refactor: use libp2p and standardized rsa keys 2016-05-23 22:06:25 +02:00
11 changed files with 491 additions and 29835 deletions

3
.gitignore vendored
View File

@ -26,5 +26,4 @@ build/Release
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules node_modules
lib dist
dist

View File

@ -1,8 +1,16 @@
sudo: false sudo: false
language: node_js language: node_js
node_js:
- 4 matrix:
- 5 include:
- node_js: 4
env: CXX=g++-4.8
- node_js: 6
env:
- SAUCE=true
- CXX=g++-4.8
- node_js: stable
env: CXX=g++-4.8
# Make sure we have new NPM. # Make sure we have new NPM.
before_install: before_install:
@ -13,12 +21,17 @@ script:
- npm test - npm test
- npm run coverage - npm run coverage
addons:
firefox: 'latest'
before_script: before_script:
- export DISPLAY=:99.0 - export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start - sh -e /etc/init.d/xvfb start
after_success: after_success:
- npm run coverage-publish - npm run coverage-publish
addons:
firefox: latest
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8

135
README.md
View File

@ -2,18 +2,49 @@
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) [![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io)
[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) [![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs)
[![Build Status](https://travis-ci.org/diasdavid/js-peer-id.svg?style=flat-square)](https://travis-ci.org/diasdavid/js-peer-id) [![Build Status](https://travis-ci.org/libp2p/js-peer-id.svg?style=flat-square)](https://travis-ci.org/libp2p/js-peer-id)
[![Coverage Status](https://coveralls.io/repos/github/diasdavid/js-peer-id/badge.svg?branch=master)](https://coveralls.io/github/diasdavid/js-peer-id?branch=master) [![Coverage Status](https://coveralls.io/repos/github/libp2p/js-peer-id/badge.svg?branch=master)](https://coveralls.io/github/libp2p/js-peer-id?branch=master)
[![Dependency Status](https://david-dm.org/diasdavid/js-peer-id.svg?style=flat-square)](https://david-dm.org/diasdavid/js-peer-id) [![Dependency Status](https://david-dm.org/libp2p/js-peer-id.svg?style=flat-square)](https://david-dm.org/libp2p/js-peer-id)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard)
![](https://img.shields.io/badge/npm-%3E%3D3.0.0-orange.svg?style=flat-square)
![](https://img.shields.io/badge/Node.js-%3E%3D4.0.0-orange.svg?style=flat-square)
[![Sauce Test Status](https://saucelabs.com/browser-matrix/ipfs-js-peer-id.svg)](https://saucelabs.com/u/ipfs-js-peer-id)
> [IPFS](https://github.com/ipfs/ipfs) Peer ID implementation in JavaScript. > [IPFS](https://github.com/ipfs/ipfs) Peer ID implementation in JavaScript.
- [Description](#description)
- [Example](#example)
- [Installation](#installation)
- [npm](#npm)
- [Setup](#setup)
- [Node.js](#nodejs)
- [Browser: Browserify, Webpack, other bundlers](#browser-browserify-webpack-other-bundlers)
- [Browser: `<script>` Tag](#browser-script-tag)
- [API](#api)
- [Create](#create)
- [`new PeerId(id[, privKey, pubKey])`](#new-peeridid-privkey-pubkey)
- [`create([opts], callback)`](#createopts-callback)
- [Import](#import)
- [`createFromHexString(str)`](#createfromhexstringstr)
- [`createFromBytes(buf)`](#createfrombytesbuf)
- [`createFromB58String(str)`](#createfromb58stringstr)
- [`createFromPubKey(pubKey)`](#createfrompubkeypubkey)
- [`createFromPrivKey(privKey)`](#createfromprivkeyprivkey)
- [`createFromJSON(obj)`](#createfromjsonobj)
- [Export](#export)
- [`toHexString()`](#tohexstring)
- [`toBytes()`](#tobytes)
- [`toB58String()`](#tob58string)
- [`toJSON()`](#tojson)
- [`toPrint()`](#toprint)
- [License](#license)
# Description # Description
Generate, import, and export PeerIDs, for use with [IPFS](https://github.com/ipfs/ipfs). Generate, import, and export PeerIDs, for use with [IPFS](https://github.com/ipfs/ipfs).
*A Peer ID is the SHA-256 [multihash](https://github.com/jbenet/multihash) of a *A Peer ID is the SHA-256 [multihash](https://github.com/multiformats/multihash) of a
public key.* public key.*
*The public key is a base64 encoded string of a protobuf containing an RSA DER *The public key is a base64 encoded string of a protobuf containing an RSA DER
@ -26,17 +57,17 @@ to the multihash for ID generation.*
var PeerId = require('peer-id') var PeerId = require('peer-id')
var bs58 = require('bs58') var bs58 = require('bs58')
var id = PeerId.create({ bits: 32 }) PeerId.create({ bits: 1024 }, (err, id) => {
console.log(JSON.stringify(id.toJSON(), null, 2)
console.log('id ', id.toB58String()) })
console.log('priv key ', bs58.encode(id.privKey))
console.log('pub key ', bs58.encode(id.pubKey))
``` ```
``` ```
id QmeeLFb92nkZJGj3gXLqXrEMzCMYs6uBgQLVNbrcXEvYXk {
priv key 6ibrcPAbevzvPpkq6EA6XmLyuhmUrJrEvUfgQDtEiSEPzGnGU8Ejwf6b11DVm6opnFGo "id": "Qma9T5YraSnpRDZqRR4krcSJabThc8nwZuJV3LercPHufi",
pub key 2BeBZVKJ9RQs4i4LbGv4ReEeuBA5dck2Gje3wt67e44XuyyPq5jE "privKey": "CAAS4AQwggJcAgEAAoGBAMBgbIqyOL26oV3nGPBYrdpbv..",
"pubKey": "CAASogEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMBgbIqyOL26oV3nGPBYrdpbvzCY..."
}
``` ```
# Installation # Installation
@ -51,7 +82,7 @@ pub key 2BeBZVKJ9RQs4i4LbGv4ReEeuBA5dck2Gje3wt67e44XuyyPq5jE
## Node.js ## Node.js
```JavaScript ```js
var PeerId = require('peer-id') var PeerId = require('peer-id')
``` ```
@ -62,7 +93,7 @@ transpiled version with the right shims added. This means that you can require
it and use with your favourite bundler without having to adjust asset management it and use with your favourite bundler without having to adjust asset management
process. process.
```JavaScript ```js
var PeerId = require('peer-id') var PeerId = require('peer-id')
``` ```
@ -72,9 +103,9 @@ Loading this module through a script tag will make the `PeerId` obj available in
the global namespace. the global namespace.
```html ```html
<script src="https://npmcdn.com/peer-id/dist/index.min.js"></script> <script src="https://unpkg.com/peer-id/dist/index.min.js"></script>
<!-- OR --> <!-- OR -->
<script src="https://npmcdn.com/peer-id/dist/index.js"></script> <script src="https://unpkg.com/peer-id/dist/index.js"></script>
``` ```
# API # API
@ -85,50 +116,57 @@ const PeerId = require('peer-id')
## Create ## Create
### PeerId.create() ### `new PeerId(id[, privKey, pubKey])`
Generates a new Peer ID, complete with public/private keypair. A Peer ID has the - `id: Buffer` - The multihash of the publick key as `Buffer`
following properties: - `privKey: RsaPrivateKey` - The private key
- `pubKey: RsaPublicKey` - The public key
- `pubKey` - Buffer containing the public key bytes The key format is detailed in [libp2p-crypto](https://github.com/libp2p/js-libp2p-crypto).
- `privKey` - Buffer containing the private key bytes
- `id` - Buffer containing the multihash bytes ### `create([opts], callback)`
Generates a new Peer ID, complete with public/private keypair.
- `opts: Object`: Default: `{bits: 2048}`
- `callback: Function`
Calls back `callback` with `err, id`.
## Import ## Import
### PeerId.createFromHexString(str) ### `createFromHexString(str)`
Creates a Peer ID from hex string representing the key's multihash. Creates a Peer ID from hex string representing the key's multihash.
### PeerId.createFromBytes(buf) ### `createFromBytes(buf)`
Creates a Peer ID from a buffer representing the key's multihash. Creates a Peer ID from a buffer representing the key's multihash.
### PeerId.createFromB58String(str) ### `createFromB58String(str)`
Creates a Peer ID from a Base58 string representing the key's multihash. Creates a Peer ID from a Base58 string representing the key's multihash.
### PeerId.createFromPubKey(pubKey) ### `createFromPubKey(pubKey)`
- `publicKey: Buffer`
Creates a Peer ID from a buffer containing a public key. Creates a Peer ID from a buffer containing a public key.
### PeerId.createFromPrivKey(privKey) ### `createFromPrivKey(privKey)`
- `privKey: Buffer`
Creates a Peer ID from a buffer containing a private key. Creates a Peer ID from a buffer containing a private key.
### `createFromJSON(obj)`
- `obj.id: String` - The multihash encoded in `base58`
- `obj.pubKey: String` - The public key in protobuf format, encoded in 'base64'
- `obj.privKey: String` - The private key in protobuf format, encoded in 'base 64'
## Export ## Export
### id.toPrint() ### `toHexString()`
Returns an object with the ID's properties in hex format:
```js
{
id: 'QmckZzdVd72h9QUFuJJpQqhsZqGLwjhh81qSvZ9BhB2FQi',
privKey: '080012a609308204a20201000282010100a608889914da08959d3a3db0734cee812c96...',
pubKey: '080012a60230820122300d06092a864886f70d01010105000382010f003082010a0282010...'
}
```
### id.toHexString()
Returns the Peer ID's `id` as a hex string. Returns the Peer ID's `id` as a hex string.
@ -136,16 +174,15 @@ Returns the Peer ID's `id` as a hex string.
1220d6243998f2fc56343ad7ed0342ab7886a4eb18d736f1b67d44b37fcc81e0f39f 1220d6243998f2fc56343ad7ed0342ab7886a4eb18d736f1b67d44b37fcc81e0f39f
``` ```
### id.toBytes() ### `toBytes()`
Returns the Peer ID's `id` as a buffer. Returns the Peer ID's `id` as a buffer.
``` ```
<Buffer 12 20 d6 24 39 98 f2 fc 56 34 3a d7 ed 03 42 ab 78 86 a4 eb 18 d7 36 f1 b6 7d 44 b3 7f cc 81 e0 f3 9f> <Buffer 12 20 d6 24 39 98 f2 fc 56 34 3a d7 ed 03 42 ab 78 86 a4 eb 18 d7 36 f1 b6 7d 44 b3 7f cc 81 e0 f3 9f>
``` ```
### id.toB58String() ### `toB58String()`
Returns the Peer ID's `id` as a base58 string. Returns the Peer ID's `id` as a base58 string.
@ -153,6 +190,20 @@ Returns the Peer ID's `id` as a base58 string.
QmckZzdVd72h9QUFuJJpQqhsZqGLwjhh81qSvZ9BhB2FQi QmckZzdVd72h9QUFuJJpQqhsZqGLwjhh81qSvZ9BhB2FQi
``` ```
### `toJSON()`
Returns an `obj` of the form
- `obj.id: String` - The multihash encoded in `base58`
- `obj.pubKey: String` - The public key in protobuf format, encoded in 'base64'
- `obj.privKey: String` - The private key in protobuf format, encoded in 'base 64'
### `toPrint()`
Alias for `.toJSON()`.
# License # License
MIT MIT

View File

@ -1,10 +1,9 @@
{ {
"name": "peer-id", "name": "peer-id",
"version": "0.6.7", "version": "0.8.0",
"description": "IPFS Peer Id implementation in Node.js", "description": "IPFS Peer Id implementation in Node.js",
"main": "lib/index.js", "main": "src/index.js",
"bin": "src/bin.js", "bin": "src/bin.js",
"jsnext:main": "src/index.js",
"scripts": { "scripts": {
"lint": "aegir-lint", "lint": "aegir-lint",
"build": "aegir-build", "build": "aegir-build",
@ -12,6 +11,8 @@
"test:node": "aegir-test node", "test:node": "aegir-test node",
"test:browser": "aegir-test browser", "test:browser": "aegir-test browser",
"release": "aegir-release", "release": "aegir-release",
"release-minor": "aegir-release --type minor",
"release-major": "aegir-release --type major",
"coverage": "aegir-coverage", "coverage": "aegir-coverage",
"coverage-publish": "aegir-coverage publish" "coverage-publish": "aegir-coverage publish"
}, },
@ -25,42 +26,34 @@
"test" "test"
], ],
"engines": { "engines": {
"node": "^4.3.0" "node": ">=4.0.0"
}, },
"bugs": { "bugs": {
"url": "https://github.com/diasdavid/js-peer-id/issues" "url": "https://github.com/libp2p/js-peer-id/issues"
}, },
"homepage": "https://github.com/diasdavid/js-peer-id", "homepage": "https://github.com/libp2p/js-peer-id",
"devDependencies": { "devDependencies": {
"aegir": "^3.0.4", "aegir": "^9.0.1",
"buffer-loader": "0.0.1",
"chai": "^3.5.0", "chai": "^3.5.0",
"pre-commit": "^1.1.2" "pre-commit": "^1.1.3"
}, },
"dependencies": { "dependencies": {
"bs58": "^3.0.0", "async": "^2.0.1",
"multihashing": "^0.2.0", "libp2p-crypto": "^0.7.0",
"node-forge": "^0.6.38", "multihashes": "^0.2.2"
"protocol-buffers": "^3.1.4"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/diasdavid/js-peer-id.git" "url": "https://github.com/libp2p/js-peer-id.git"
},
"aegir": {
"webpack": {
"resolve": {
"alias": {
"node-forge": "../vendor/forge.bundle.js"
}
}
}
}, },
"contributors": [ "contributors": [
"David Dias <daviddias.p@gmail.com>", "David Dias <daviddias.p@gmail.com>",
"David Dias <mail@daviddias.me>", "David Dias <mail@daviddias.me>",
"Friedel Ziegelmayer <dignifiedquire@gmail.com>",
"Richard Littauer <richard.littauer@gmail.com>",
"Stephen Whitmore <stephen.whitmore@gmail.com>", "Stephen Whitmore <stephen.whitmore@gmail.com>",
"dignifiedquire <dignifiedquire@gmail.com>", "greenkeeperio-bot <support@greenkeeper.io>",
"nginnever <ginneversource@gmail.com>" "nginnever <ginneversource@gmail.com>",
"npmcdn-to-unpkg-bot <npmcdn-to-unpkg-bot@users.noreply.github.com>"
] ]
} }

View File

@ -1,13 +0,0 @@
enum KeyType {
RSA = 0;
}
message PublicKey {
required KeyType Type = 1;
required bytes Data = 2;
}
message PrivateKey {
required KeyType Type = 1;
required bytes Data = 2;
}

View File

@ -4,4 +4,10 @@
const PeerId = require('./index.js') const PeerId = require('./index.js')
console.log(JSON.stringify(PeerId.create().toJSON(), null, ' ')) PeerId.create((err, id) => {
if (err) {
throw err
}
console.log(JSON.stringify(id.toJSON(), null, 2))
})

View File

@ -4,137 +4,111 @@
'use strict' 'use strict'
const fs = require('fs') const mh = require('multihashes')
const multihashing = require('multihashing') const crypto = require('libp2p-crypto')
const base58 = require('bs58') const assert = require('assert')
const forge = require('node-forge') const waterfall = require('async/waterfall')
const protobuf = require('protocol-buffers')
const path = require('path')
const pbCrypto = protobuf(fs.readFileSync(path.resolve(__dirname, '../protos/crypto.proto'))) class PeerId {
constructor (id, privKey, pubKey) {
assert(Buffer.isBuffer(id), 'invalid id provided')
exports = module.exports = PeerId if (privKey && pubKey) {
assert(privKey.public.bytes.equals(pubKey.bytes), 'inconsistent arguments')
}
exports.Buffer = Buffer this.id = id
this._privKey = privKey
function PeerId (id, privKey, pubKey) { this._pubKey = pubKey
const self = this
if (!(self instanceof PeerId)) {
throw new Error('Id must be called with new')
} }
self.privKey = privKey get privKey () {
self.pubKey = pubKey return this._privKey
self.id = id // multihash - sha256 - buffer }
// pretty print get pubKey () {
self.toPrint = function () { if (this._pubKey) {
return { return this._pubKey
id: self.toB58String(), }
privKey: privKey.toString('hex'),
pubKey: pubKey.toString('hex') if (this.privKey) {
return this.privKey.public
} }
} }
self.toJSON = function () { // Return the protobuf version of the public key,
// matching go ipfs formatting
marshalPubKey () {
if (this.pubKey) {
return crypto.marshalPublicKey(this.pubKey)
}
}
// Return the protobuf version of the private key,
// matching go ipfs formatting
marshalPrivKey () {
if (this.privKey) {
return crypto.marshalPrivateKey(this.privKey)
}
}
// pretty print
toPrint () {
return this.toJSON()
}
// return the jsonified version of the key, matching the formatting
// of go-ipfs for its config file
toJSON () {
return { return {
id: self.id.toString('hex'), id: mh.toB58String(this.id),
privKey: self.privKey.toString('hex'), privKey: toB64Opt(this.marshalPrivKey()),
pubKey: self.pubKey.toString('hex') pubKey: toB64Opt(this.marshalPubKey())
} }
} }
// encode/decode functions // encode/decode functions
self.toHexString = function () { toHexString () {
return self.id.toString('hex') return mh.toHexString(this.id)
} }
self.toBytes = function () { toBytes () {
return self.id return this.id
} }
self.toB58String = function () { toB58String () {
return base58.encode(self.id) return mh.toB58String(this.id)
} }
} }
// unwrap the private key protobuf exports = module.exports = PeerId
function keyUnmarshal (key) { exports.Buffer = Buffer
return pbCrypto.PrivateKey.decode(key)
}
// create a public key protobuf to be base64 string stored in config
function keyMarshal (data, type) {
const RSA = 0
let epb
if (type === 'Public') {
epb = pbCrypto.PublicKey.encode({
Type: RSA,
Data: data
})
}
if (type === 'Private') {
epb = pbCrypto.PrivateKey.encode({
Type: RSA,
Data: data
})
}
return epb
}
// this returns a base64 encoded protobuf of the public key
function formatKey (key, type) {
// create der buffer of public key asn.1 object
const der = forge.asn1.toDer(key)
// create forge buffer of der public key buffer
const fDerBuf = forge.util.createBuffer(der.data, 'binary')
// convert forge buffer to node buffer public key
const nDerBuf = new Buffer(fDerBuf.getBytes(), 'binary')
// protobuf the new DER bytes to the PublicKey Data: field
const marsheledKey = keyMarshal(nDerBuf, type)
// encode the protobuf public key to base64 string
const b64 = marsheledKey.toString('base64')
return b64
}
// generation // generation
exports.create = function (opts) { exports.create = function (opts, callback) {
if (typeof opts === 'function') {
callback = opts
opts = {}
}
opts = opts || {} opts = opts || {}
opts.bits = opts.bits || 2048 opts.bits = opts.bits || 2048
// generate keys waterfall([
const pair = forge.rsa.generateKeyPair({ (cb) => crypto.generateKeyPair('RSA', opts.bits, cb),
bits: opts.bits, (privKey, cb) => privKey.public.hash((err, digest) => {
e: 0x10001 cb(err, digest, privKey)
})
], (err, digest, privKey) => {
if (err) {
return callback(err)
}
callback(null, new PeerId(digest, privKey))
}) })
// return the RSA public/private key to asn1 object
const asnPub = forge.pki.publicKeyToAsn1(pair.publicKey)
const asnPriv = forge.pki.privateKeyToAsn1(pair.privateKey)
// format the keys to protobuf base64 encoded string
const protoPublic64 = formatKey(asnPub, 'Public')
const protoPrivate64 = formatKey(asnPriv, 'Private')
// store the keys as a buffer
const bufProtoPub64 = new Buffer(protoPublic64, 'base64')
const bufProtoPriv64 = new Buffer(protoPrivate64, 'base64')
const mhId = multihashing(new Buffer(protoPublic64, 'base64'), 'sha2-256')
return new PeerId(mhId, bufProtoPriv64, bufProtoPub64)
} }
exports.createFromHexString = function (str) { exports.createFromHexString = function (str) {
return new PeerId(new Buffer(str, 'hex')) return new PeerId(mh.fromHexString(str))
} }
exports.createFromBytes = function (buf) { exports.createFromBytes = function (buf) {
@ -142,51 +116,102 @@ exports.createFromBytes = function (buf) {
} }
exports.createFromB58String = function (str) { exports.createFromB58String = function (str) {
return new PeerId(new Buffer(base58.decode(str))) return new PeerId(mh.fromB58String(str))
} }
// Public Key input will be a buffer // Public Key input will be a buffer
exports.createFromPubKey = function (pubKey) { exports.createFromPubKey = function (key, callback) {
const buf = new Buffer(pubKey, 'base64') let buf = key
const mhId = multihashing(buf, 'sha2-256') if (typeof buf === 'string') {
return new PeerId(mhId, null, pubKey) buf = new Buffer(key, 'base64')
}
if (typeof callback !== 'function') {
throw new Error('callback is required')
}
const pubKey = crypto.unmarshalPublicKey(buf)
pubKey.hash((err, digest) => {
if (err) {
return callback(err)
}
callback(null, new PeerId(digest, null, pubKey))
})
} }
// Private key input will be a string // Private key input will be a string
exports.createFromPrivKey = function (privKey) { exports.createFromPrivKey = function (key, callback) {
// create a buffer from the base64 encoded string let buf = key
const buf = new Buffer(privKey, 'base64') if (typeof buf === 'string') {
buf = new Buffer(key, 'base64')
}
// get the private key data from the protobuf if (typeof callback !== 'function') {
const mpk = keyUnmarshal(buf) throw new Error('callback is required')
}
// create a forge buffer waterfall([
const fbuf = forge.util.createBuffer(mpk.Data.toString('binary')) (cb) => crypto.unmarshalPrivateKey(buf, cb),
(privKey, cb) => privKey.public.hash((err, digest) => {
cb(err, digest, privKey)
})
], (err, digest, privKey) => {
if (err) {
return callback(err)
}
// create an asn1 object from the private key bytes saved in the protobuf Data: field callback(null, new PeerId(digest, privKey))
const asnPriv = forge.asn1.fromDer(fbuf) })
// get the RSA privatekey data from the asn1 object
const privateKey = forge.pki.privateKeyFromAsn1(asnPriv)
// set the RSA public key to the modulus and exponent of the private key
const publicKey = forge.pki.rsa.setPublicKey(privateKey.n, privateKey.e)
// return the RSA public key to asn1 object
const asnPub = forge.pki.publicKeyToAsn1(publicKey)
// format the public key
const protoPublic64 = formatKey(asnPub, 'Public')
// buffer the public key for consistency before storing
const bufProtoPub64 = new Buffer(protoPublic64, 'base64')
const mhId = multihashing(new Buffer(protoPublic64, 'base64'), 'sha2-256')
return new PeerId(mhId, privKey, bufProtoPub64)
} }
exports.createFromJSON = function (obj) { exports.createFromJSON = function (obj, callback) {
return new PeerId( if (typeof callback !== 'function') {
new Buffer(obj.id, 'hex'), throw new Error('callback is required')
new Buffer(obj.privKey, 'hex'), }
new Buffer(obj.pubKey, 'hex'))
const id = mh.fromB58String(obj.id)
const rawPrivKey = obj.privKey && new Buffer(obj.privKey, 'base64')
const rawPubKey = obj.pubKey && new Buffer(obj.pubKey, 'base64')
const pub = rawPubKey && crypto.unmarshalPublicKey(rawPubKey)
if (rawPrivKey) {
waterfall([
(cb) => crypto.unmarshalPrivateKey(rawPrivKey, cb),
(priv, cb) => priv.public.hash((err, digest) => {
cb(err, digest, priv)
}),
(privDigest, priv, cb) => {
if (pub) {
pub.hash((err, pubDigest) => {
cb(err, privDigest, priv, pubDigest)
})
} else {
cb(null, privDigest, priv)
}
}
], (err, privDigest, priv, pubDigest) => {
if (err) {
return callback(err)
}
if (pub && !privDigest.equals(pubDigest)) {
return callback(new Error('Public and private key do not match'))
}
if (id && !privDigest.equals(id)) {
return callback(new Error('Id and private key do not match'))
}
callback(null, new PeerId(id, priv, pub))
})
} else {
callback(null, new PeerId(id, null, pub))
}
}
function toB64Opt (val) {
if (val) {
return val.toString('base64')
}
} }

6
test/fixtures/go-private-key.js vendored Normal file
View File

@ -0,0 +1,6 @@
'use strict'
module.exports = {
id: 'QmRLoXS3E73psYaUsma1VSbboTa2J8Z9kso1tpiGLk9WQ4',
privKey: 'CAASpwkwggSjAgEAAoIBAQDWBEbO8kc6a5kEks09CKPQargY3p0DCmCczoCT52/RYFqxvH9dI+s+u4ZAvF9aLWOBvFomL7jHZODPxKDrbiNCmyEbViNgZYK+PNbwh0V3ZGbB27X3q8yZtLvYA8dhcNkz/2SHBarSoC4QLA5MXUuSWtVaYMY3MzMnzBF57Jc9Ase7NvHOIUI90M7aN5izP7hxPXpZ+shiN+TyjM8mFxYONG7ZSsY3IxUhtrU5MRzFX+tp1o/gb/aa51mHf7AL3N02j5ABiYbCK97Rbwr03hsBcwgMxoDPJmP3WZ+D5yyPcOIIF1Vd7+4/f7FQJnIw3xr9/jvaFbPyDCVbBOhr9oyxAgMBAAECggEALlrgx2Q8v0+c5hux7p1XdgYXd/OHyKfPw0cLHH4NfylCm6q7X34vLvhJHO5wLMUV/3y/ffPqLu4Pr5DkVfoWExAsvJIMuY1jIzdkStbR2glaJHUlVc7VUxmNcj1nSxi5QwT3TjORC2v8bi5Mroeqnbmk6p15cW1akC0oP+NZ4rG48+WFHRqsBaBusdSOVfA+IiZUqSd1ILysJ1w7aVN3EC7jLjDG43i+P/2BcEHy8TVClGOknJL341bHe3UPdEpmeu6k6aHGlDI4blUMXahCIUh0IdZuj+Vi/TxQME9+3bKIOjQb8RCNm3U3j/uz5gs9SyTjBuYIib9Scj/jDbLh0QKBgQDfLr3go3Q/AR0jb12QjGALJz1lc9ZRX2RQJkqqmYkZwOlHHyl+YJgqOZiO80fUkN0sJ29CmKecXU4gXuHir913Fdceei1ScBSsvZpWtBLhEZXKrRJYq8U0atKUFQADDMGutyB/uGCNeNwR6VcJezHPICvHxQfmWlWHA5VIOEtRPQKBgQD1fID76SkIpF/EaJMnN2alXWWnzKhUBUPGpQtbpwgSfaCBiZ4vr3NQwKBntOOB5QwHmifNZMoqaFQLzC4B/uyTNUcQMQQ6arYav7WQXqXTmW6poTsjUSuSOPx1swsHlYX09SmUwWDfd94XF9UOU0KUfA2/c85ixzNlV5ejkFA4hQKBgEvP3uQN4hD82d8Nl2TgqkdfnvV1cdnWY4buWvK0kOPUqelk5n1tZoMBaZc1gLLuOpMjGiIvJNByyXUpheWxA7POEXLi4b5dIEjFZ0YIiVk21gEw5UiFoMl7d+ihcY2Xqbslrb507SdhZLAY6V3pITRQo06K2XIgQWlJiE4uATepAoGBALZ2vEiBnYZW5vfN4tKbUyhGq3B1pggNgbr8odyV4mIcDlk6OOGov0WeZ5ut0AyUesSLyFnaOIoc0ZuTP/8rxBwG1bMrO8FP39sx83pDX25P9PkQZixyALjGsp+pXOFeOhtAvo9azO5M4j638Bydtjc3neBX62dwOLtyx7tDYN0hAoGAVLmr3w7XMVHTfEuCSzKHyRrOaN2PAuSX31QAji1PwlwVKMylVrb8rRvBOpTicA/wXPX9Q5O/yjegqhqLT/LXAm9ziFzy5b9/9SzXPukKebXXbvc0FOmcsrcxtijlPyUzf9fKM1ShiwqqsgM9eNyZ9GWUJw2GFATCWW7pl7rtnWk='
}

7
test/fixtures/sample-id.js vendored Normal file
View File

@ -0,0 +1,7 @@
'use strict'
module.exports = {
id: '122019318b6e5e0cf93a2314bf01269a2cc23cd3dcd452d742cdb9379d8646f6e4a9',
privKey: 'CAASpgkwggSiAgEAAoIBAQC2SKo/HMFZeBml1AF3XijzrxrfQXdJzjePBZAbdxqKR1Mc6juRHXij6HXYPjlAk01BhF1S3Ll4Lwi0cAHhggf457sMg55UWyeGKeUv0ucgvCpBwlR5cQ020i0MgzjPWOLWq1rtvSbNcAi2ZEVn6+Q2EcHo3wUvWRtLeKz+DZSZfw2PEDC+DGPJPl7f8g7zl56YymmmzH9liZLNrzg/qidokUv5u1pdGrcpLuPNeTODk0cqKB+OUbuKj9GShYECCEjaybJDl9276oalL9ghBtSeEv20kugatTvYy590wFlJkkvyl+nPxIH0EEYMKK9XRWlu9XYnoSfboiwcv8M3SlsjAgMBAAECggEAZtju/bcKvKFPz0mkHiaJcpycy9STKphorpCT83srBVQi59CdFU6Mj+aL/xt0kCPMVigJw8P3/YCEJ9J+rS8BsoWE+xWUEsJvtXoT7vzPHaAtM3ci1HZd302Mz1+GgS8Epdx+7F5p80XAFLDUnELzOzKftvWGZmWfSeDnslwVONkL/1VAzwKy7Ce6hk4SxRE7l2NE2OklSHOzCGU1f78ZzVYKSnS5Ag9YrGjOAmTOXDbKNKN/qIorAQ1bovzGoCwx3iGIatQKFOxyVCyO1PsJYT7JO+kZbhBWRRE+L7l+ppPER9bdLFxs1t5CrKc078h+wuUr05S1P1JjXk68pk3+kQKBgQDeK8AR11373Mzib6uzpjGzgNRMzdYNuExWjxyxAzz53NAR7zrPHvXvfIqjDScLJ4NcRO2TddhXAfZoOPVH5k4PJHKLBPKuXZpWlookCAyENY7+Pd55S8r+a+MusrMagYNljb5WbVTgN8cgdpim9lbbIFlpN6SZaVjLQL3J8TWH6wKBgQDSChzItkqWX11CNstJ9zJyUE20I7LrpyBJNgG1gtvz3ZMUQCn3PxxHtQzN9n1P0mSSYs+jBKPuoSyYLt1wwe10/lpgL4rkKWU3/m1Myt0tveJ9WcqHh6tzcAbb/fXpUFT/o4SWDimWkPkuCb+8j//2yiXk0a/T2f36zKMuZvujqQKBgC6B7BAQDG2H2B/ijofp12ejJU36nL98gAZyqOfpLJ+FeMz4TlBDQ+phIMhnHXA5UkdDapQ+zA3SrFk+6yGk9Vw4Hf46B+82SvOrSbmnMa+PYqKYIvUzR4gg34rL/7AhwnbEyD5hXq4dHwMNsIDq+l2elPjwm/U9V0gdAl2+r50HAoGALtsKqMvhv8HucAMBPrLikhXP/8um8mMKFMrzfqZ+otxfHzlhI0L08Bo3jQrb0Z7ByNY6M8epOmbCKADsbWcVre/AAY0ZkuSZK/CaOXNX/AhMKmKJh8qAOPRY02LIJRBCpfS4czEdnfUhYV/TYiFNnKRj57PPYZdTzUsxa/yVTmECgYBr7slQEjb5Onn5mZnGDh+72BxLNdgwBkhO0OCdpdISqk0F0Pxby22DFOKXZEpiyI9XYP1C8wPiJsShGm2yEwBPWXnrrZNWczaVuCbXHrZkWQogBDG3HGXNdU4MAWCyiYlyinIBpPpoAJZSzpGLmWbMWh28+RJS6AQX6KHrK1o2uw==',
pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2SKo/HMFZeBml1AF3XijzrxrfQXdJzjePBZAbdxqKR1Mc6juRHXij6HXYPjlAk01BhF1S3Ll4Lwi0cAHhggf457sMg55UWyeGKeUv0ucgvCpBwlR5cQ020i0MgzjPWOLWq1rtvSbNcAi2ZEVn6+Q2EcHo3wUvWRtLeKz+DZSZfw2PEDC+DGPJPl7f8g7zl56YymmmzH9liZLNrzg/qidokUv5u1pdGrcpLuPNeTODk0cqKB+OUbuKj9GShYECCEjaybJDl9276oalL9ghBtSeEv20kugatTvYy590wFlJkkvyl+nPxIH0EEYMKK9XRWlu9XYnoSfboiwcv8M3SlsjAgMBAAE='
}

View File

@ -1,104 +1,225 @@
/* eslint max-nested-callbacks: ["error", 8] */
/* eslint-env mocha */ /* eslint-env mocha */
'use strict' 'use strict'
const expect = require('chai').expect const expect = require('chai').expect
const crypto = require('libp2p-crypto')
const mh = require('multihashes')
const parallel = require('async/parallel')
const PeerId = require('../src') const PeerId = require('../src')
const testId = { const testId = require('./fixtures/sample-id')
id: '1220151ab1658d8294ab34b71d5582cfe20d06414212f440a69366f1bc31deb5c72d', const testIdHex = testId.id
privKey: 'CAASpgkwggSiAgEAAoIBAQC2SKo/HMFZeBml1AF3XijzrxrfQXdJzjePBZAbdxqKR1Mc6juRHXij6HXYPjlAk01BhF1S3Ll4Lwi0cAHhggf457sMg55UWyeGKeUv0ucgvCpBwlR5cQ020i0MgzjPWOLWq1rtvSbNcAi2ZEVn6+Q2EcHo3wUvWRtLeKz+DZSZfw2PEDC+DGPJPl7f8g7zl56YymmmzH9liZLNrzg/qidokUv5u1pdGrcpLuPNeTODk0cqKB+OUbuKj9GShYECCEjaybJDl9276oalL9ghBtSeEv20kugatTvYy590wFlJkkvyl+nPxIH0EEYMKK9XRWlu9XYnoSfboiwcv8M3SlsjAgMBAAECggEAZtju/bcKvKFPz0mkHiaJcpycy9STKphorpCT83srBVQi59CdFU6Mj+aL/xt0kCPMVigJw8P3/YCEJ9J+rS8BsoWE+xWUEsJvtXoT7vzPHaAtM3ci1HZd302Mz1+GgS8Epdx+7F5p80XAFLDUnELzOzKftvWGZmWfSeDnslwVONkL/1VAzwKy7Ce6hk4SxRE7l2NE2OklSHOzCGU1f78ZzVYKSnS5Ag9YrGjOAmTOXDbKNKN/qIorAQ1bovzGoCwx3iGIatQKFOxyVCyO1PsJYT7JO+kZbhBWRRE+L7l+ppPER9bdLFxs1t5CrKc078h+wuUr05S1P1JjXk68pk3+kQKBgQDeK8AR11373Mzib6uzpjGzgNRMzdYNuExWjxyxAzz53NAR7zrPHvXvfIqjDScLJ4NcRO2TddhXAfZoOPVH5k4PJHKLBPKuXZpWlookCAyENY7+Pd55S8r+a+MusrMagYNljb5WbVTgN8cgdpim9lbbIFlpN6SZaVjLQL3J8TWH6wKBgQDSChzItkqWX11CNstJ9zJyUE20I7LrpyBJNgG1gtvz3ZMUQCn3PxxHtQzN9n1P0mSSYs+jBKPuoSyYLt1wwe10/lpgL4rkKWU3/m1Myt0tveJ9WcqHh6tzcAbb/fXpUFT/o4SWDimWkPkuCb+8j//2yiXk0a/T2f36zKMuZvujqQKBgC6B7BAQDG2H2B/ijofp12ejJU36nL98gAZyqOfpLJ+FeMz4TlBDQ+phIMhnHXA5UkdDapQ+zA3SrFk+6yGk9Vw4Hf46B+82SvOrSbmnMa+PYqKYIvUzR4gg34rL/7AhwnbEyD5hXq4dHwMNsIDq+l2elPjwm/U9V0gdAl2+r50HAoGALtsKqMvhv8HucAMBPrLikhXP/8um8mMKFMrzfqZ+otxfHzlhI0L08Bo3jQrb0Z7ByNY6M8epOmbCKADsbWcVre/AAY0ZkuSZK/CaOXNX/AhMKmKJh8qAOPRY02LIJRBCpfS4czEdnfUhYV/TYiFNnKRj57PPYZdTzUsxa/yVTmECgYBr7slQEjb5Onn5mZnGDh+72BxLNdgwBkhO0OCdpdISqk0F0Pxby22DFOKXZEpiyI9XYP1C8wPiJsShGm2yEwBPWXnrrZNWczaVuCbXHrZkWQogBDG3HGXNdU4MAWCyiYlyinIBpPpoAJZSzpGLmWbMWh28+RJS6AQX6KHrK1o2uw==', const testIdBytes = mh.fromHexString(testId.id)
pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2SKo/HMFZeBml1AF3XijzrxrfQXdJzjePBZAbdxqKR1Mc6juRHXij6HXYPjlAk01BhF1S3Ll4Lwi0cAHhggf457sMg55UWyeGKeUv0ucgvCpBwlR5cQ020i0MgzjPWOLWq1rtvSbNcAi2ZEVn6+Q2EcHo3wUvWRtLeKz+DZSZfw2PEDC+DGPJPl7f8g7zl56YymmmzH9liZLNrzg/qidokUv5u1pdGrcpLuPNeTODk0cqKB+OUbuKj9GShYECCEjaybJDl9276oalL9ghBtSeEv20kugatTvYy590wFlJkkvyl+nPxIH0EEYMKK9XRWlu9XYnoSfboiwcv8M3SlsjAgMBAAE=' const testIdB58String = mh.toB58String(testIdBytes)
}
const testIdHex = '1220151ab1658d8294ab34b71d5582cfe20d06414212f440a69366f1bc31deb5c72d' const goId = require('./fixtures/go-private-key')
const testIdBytes = new Buffer('1220151ab1658d8294ab34b71d5582cfe20d06414212f440a69366f1bc31deb5c72d', 'hex') describe('PeerId', () => {
it('create an id without \'new\'', () => {
const testIdB58String = 'QmQ2zigjQikYnyYUSXZydNXrDRhBut2mubwJBaLXobMt3A'
describe('id', function (done) {
this.timeout(30000)
it('create an id without \'new\'', (done) => {
expect(PeerId).to.throw(Error) expect(PeerId).to.throw(Error)
done()
}) })
it('create a new id', (done) => { it('create a new id', (done) => {
const id = PeerId.create() PeerId.create((err, id) => {
expect(id.toB58String().length).to.equal(46) expect(err).to.not.exist
done() expect(id.toB58String().length).to.equal(46)
done()
})
}) })
it('recreate an Id from Hex string', (done) => { it('recreate an Id from Hex string', () => {
const id = PeerId.createFromHexString(testIdHex) const id = PeerId.createFromHexString(testIdHex)
expect(testIdBytes).to.deep.equal(id.id) expect(testIdBytes).to.deep.equal(id.id)
done()
}) })
it('Recreate an Id from a Buffer', (done) => { it('Recreate an Id from a Buffer', () => {
const id = PeerId.createFromBytes(testIdBytes) const id = PeerId.createFromBytes(testIdBytes)
expect(testId.id).to.equal(id.toHexString()) expect(testId.id).to.equal(id.toHexString())
done()
}) })
it('Recreate a B58 String', (done) => { it('Recreate a B58 String', () => {
const id = PeerId.createFromB58String(testIdB58String) const id = PeerId.createFromB58String(testIdB58String)
expect(testIdB58String).to.equal(id.toB58String()) expect(testIdB58String).to.equal(id.toB58String())
done()
}) })
it('Recreate from a Public Key', (done) => { it('Recreate from a Public Key', (done) => {
const id = PeerId.createFromPubKey(testId.pubKey) PeerId.createFromPubKey(testId.pubKey, (err, id) => {
expect(testIdB58String).to.equal(id.toB58String()) expect(err).to.not.exist
done() expect(testIdB58String).to.equal(id.toB58String())
done()
})
}) })
it('Recreate from a Private Key', (done) => { it('Recreate from a Private Key', (done) => {
const id = PeerId.createFromPrivKey(testId.privKey) PeerId.createFromPrivKey(testId.privKey, (err, id) => {
expect(testIdB58String).to.equal(id.toB58String()) expect(err).to.not.exist
done() expect(testIdB58String).to.equal(id.toB58String())
const encoded = new Buffer(testId.privKey, 'base64')
PeerId.createFromPrivKey(encoded, (err, id2) => {
expect(err).to.not.exist
expect(testIdB58String).to.equal(id2.toB58String())
done()
})
})
}) })
it('Compare generated ID with one created from PubKey', (done) => { it('Compare generated ID with one created from PubKey', (done) => {
const id1 = PeerId.create() PeerId.create((err, id1) => {
const id2 = PeerId.createFromPubKey(id1.pubKey) expect(err).to.not.exist
expect(id2.id).to.deep.equal(id1.id)
done() PeerId.createFromPubKey(id1.marshalPubKey(), (err, id2) => {
expect(err).to.not.exist
expect(id1.id).to.be.eql(id2.id)
done()
})
})
}) })
it('Non-default # of bits', (done) => { it('Non-default # of bits', (done) => {
const shortId = PeerId.create({ bits: 128 }) PeerId.create({ bits: 1024 }, (err, shortId) => {
const longId = PeerId.create({ bits: 256 }) expect(err).to.not.exist
expect(shortId.privKey.length).is.below(longId.privKey.length) PeerId.create({ bits: 4096 }, (err, longId) => {
done() expect(err).to.not.exist
expect(shortId.privKey.bytes.length).is.below(longId.privKey.bytes.length)
done()
})
})
}) })
it('Pretty printing', (done) => { it('Pretty printing', (done) => {
const id = PeerId.createFromPrivKey(testId.privKey) PeerId.create((err, id1) => {
var out = id.toPrint() expect(err).to.not.exist
var expected = { PeerId.createFromPrivKey(id1.toPrint().privKey, (err, id2) => {
id: 'QmQ2zigjQikYnyYUSXZydNXrDRhBut2mubwJBaLXobMt3A', expect(err).to.not.exist
privKey: 'CAASpgkwggSiAgEAAoIBAQC2SKo/HMFZeBml1AF3XijzrxrfQXdJzjePBZAbdxqKR1Mc6juRHXij6HXYPjlAk01BhF1S3Ll4Lwi0cAHhggf457sMg55UWyeGKeUv0ucgvCpBwlR5cQ020i0MgzjPWOLWq1rtvSbNcAi2ZEVn6+Q2EcHo3wUvWRtLeKz+DZSZfw2PEDC+DGPJPl7f8g7zl56YymmmzH9liZLNrzg/qidokUv5u1pdGrcpLuPNeTODk0cqKB+OUbuKj9GShYECCEjaybJDl9276oalL9ghBtSeEv20kugatTvYy590wFlJkkvyl+nPxIH0EEYMKK9XRWlu9XYnoSfboiwcv8M3SlsjAgMBAAECggEAZtju/bcKvKFPz0mkHiaJcpycy9STKphorpCT83srBVQi59CdFU6Mj+aL/xt0kCPMVigJw8P3/YCEJ9J+rS8BsoWE+xWUEsJvtXoT7vzPHaAtM3ci1HZd302Mz1+GgS8Epdx+7F5p80XAFLDUnELzOzKftvWGZmWfSeDnslwVONkL/1VAzwKy7Ce6hk4SxRE7l2NE2OklSHOzCGU1f78ZzVYKSnS5Ag9YrGjOAmTOXDbKNKN/qIorAQ1bovzGoCwx3iGIatQKFOxyVCyO1PsJYT7JO+kZbhBWRRE+L7l+ppPER9bdLFxs1t5CrKc078h+wuUr05S1P1JjXk68pk3+kQKBgQDeK8AR11373Mzib6uzpjGzgNRMzdYNuExWjxyxAzz53NAR7zrPHvXvfIqjDScLJ4NcRO2TddhXAfZoOPVH5k4PJHKLBPKuXZpWlookCAyENY7+Pd55S8r+a+MusrMagYNljb5WbVTgN8cgdpim9lbbIFlpN6SZaVjLQL3J8TWH6wKBgQDSChzItkqWX11CNstJ9zJyUE20I7LrpyBJNgG1gtvz3ZMUQCn3PxxHtQzN9n1P0mSSYs+jBKPuoSyYLt1wwe10/lpgL4rkKWU3/m1Myt0tveJ9WcqHh6tzcAbb/fXpUFT/o4SWDimWkPkuCb+8j//2yiXk0a/T2f36zKMuZvujqQKBgC6B7BAQDG2H2B/ijofp12ejJU36nL98gAZyqOfpLJ+FeMz4TlBDQ+phIMhnHXA5UkdDapQ+zA3SrFk+6yGk9Vw4Hf46B+82SvOrSbmnMa+PYqKYIvUzR4gg34rL/7AhwnbEyD5hXq4dHwMNsIDq+l2elPjwm/U9V0gdAl2+r50HAoGALtsKqMvhv8HucAMBPrLikhXP/8um8mMKFMrzfqZ+otxfHzlhI0L08Bo3jQrb0Z7ByNY6M8epOmbCKADsbWcVre/AAY0ZkuSZK/CaOXNX/AhMKmKJh8qAOPRY02LIJRBCpfS4czEdnfUhYV/TYiFNnKRj57PPYZdTzUsxa/yVTmECgYBr7slQEjb5Onn5mZnGDh+72BxLNdgwBkhO0OCdpdISqk0F0Pxby22DFOKXZEpiyI9XYP1C8wPiJsShGm2yEwBPWXnrrZNWczaVuCbXHrZkWQogBDG3HGXNdU4MAWCyiYlyinIBpPpoAJZSzpGLmWbMWh28+RJS6AQX6KHrK1o2uw==', expect(id1.toPrint()).to.be.eql(id2.toPrint())
pubKey: '080012a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b648aa3f1cc1597819a5d401775e28f3af1adf417749ce378f05901b771a8a47531cea3b911d78a3e875d83e3940934d41845d52dcb9782f08b47001e18207f8e7bb0c839e545b278629e52fd2e720bc2a41c25479710d36d22d0c8338cf58e2d6ab5aedbd26cd7008b6644567ebe43611c1e8df052f591b4b78acfe0d94997f0d8f1030be0c63c93e5edff20ef3979e98ca69a6cc7f658992cdaf383faa2768914bf9bb5a5d1ab7292ee3cd79338393472a281f8e51bb8a8fd1928581020848dac9b24397ddbbea86a52fd82106d49e12fdb492e81ab53bd8cb9f74c05949924bf297e9cfc481f410460c28af5745696ef57627a127dba22c1cbfc3374a5b230203010001' done()
} })
expect(out.id).to.equal(expected.id) })
expect(out.privKey).to.equal(expected.privKey)
expect(out.pubKey).to.equal(expected.pubKey)
done()
}) })
it('toBytes', (done) => { it('toBytes', () => {
const id = PeerId.createFromHexString(testIdHex) const id = PeerId.createFromHexString(testIdHex)
expect(id.toBytes().toString('hex')).to.equal(testIdBytes.toString('hex')) expect(id.toBytes().toString('hex')).to.equal(testIdBytes.toString('hex'))
done()
}) })
it('toJSON', (done) => { describe('fromJSON', () => {
const id = PeerId.create() it('full node', (done) => {
expect(id.toB58String()).to.equal(PeerId.createFromJSON(id.toJSON()).toB58String()) PeerId.create({bits: 1024}, (err, id) => {
expect(id.privKey).to.deep.equal(PeerId.createFromJSON(id.toJSON()).privKey) expect(err).to.not.exist
expect(id.pubKey).to.deep.equal(PeerId.createFromJSON(id.toJSON()).pubKey)
done() PeerId.createFromJSON(id.toJSON(), (err, other) => {
expect(err).to.not.exist
expect(
id.toB58String()
).to.equal(
other.toB58String()
)
expect(
id.privKey.bytes
).to.deep.equal(
other.privKey.bytes
)
expect(
id.pubKey.bytes
).to.deep.equal(
other.pubKey.bytes
)
done()
})
})
})
it('only id', (done) => {
crypto.generateKeyPair('RSA', 1024, (err, key) => {
expect(err).to.not.exist
key.public.hash((err, digest) => {
expect(err).to.not.exist
const id = PeerId.createFromBytes(digest)
expect(id.privKey).to.not.exist
expect(id.pubKey).to.not.exist
PeerId.createFromJSON(id.toJSON(), (err, other) => {
expect(err).to.not.exist
expect(
id.toB58String()
).to.equal(
other.toB58String()
)
done()
})
})
})
})
it('go interop', (done) => {
PeerId.createFromJSON(goId, (err, id) => {
expect(err).to.not.exist
id.privKey.public.hash((err, digest) => {
expect(err).to.not.exist
expect(
mh.toB58String(digest)
).to.be.eql(
goId.id
)
done()
})
})
})
})
describe('throws on inconsistent data', () => {
let k1, k2, k3
before((done) => {
parallel([
(cb) => crypto.generateKeyPair('RSA', 1024, cb),
(cb) => crypto.generateKeyPair('RSA', 1024, cb),
(cb) => crypto.generateKeyPair('RSA', 1024, cb)
], (err, keys) => {
if (err) {
return done(err)
}
k1 = keys[0]
k2 = keys[1]
k3 = keys[2]
done()
})
})
it('missmatch private - public key', (done) => {
k1.public.hash((err, digest) => {
expect(err).to.not.exist
expect(
() => new PeerId(digest, k1, k2.public)
).to.throw(
/inconsistent arguments/
)
done()
})
})
it('missmatch id - private - public key', (done) => {
k1.public.hash((err, digest) => {
expect(err).to.not.exist
expect(
() => new PeerId(digest, k1, k3.public)
).to.throw(
/inconsistent arguments/
)
done()
})
})
it('invalid id', () => {
expect(
() => new PeerId('hello world')
).to.throw(
/invalid id/
)
})
}) })
}) })

29552
vendor/forge.bundle.js vendored

File diff suppressed because it is too large Load Diff