Compare commits

...

120 Commits

Author SHA1 Message Date
4575a1589a chore: release version v0.8.3 2017-03-16 17:06:56 +00:00
1beebb65c1 chore: update contributors 2017-03-16 17:06:55 +00:00
3dbd9a718d chore: update aegir and fix lint 2017-03-16 17:06:13 +00:00
3da91b92fa chore: release version v0.8.2 2017-02-09 08:10:40 -08:00
ad9a43b7c8 chore: update contributors 2017-02-09 08:10:40 -08:00
c67bf150f2 chore: ^ to ~ 2017-02-09 08:08:43 -08:00
6624c27d8d chore: release version v0.8.1 2016-12-18 08:06:16 +00:00
26ac06d21c chore: update contributors 2016-12-18 08:06:16 +00:00
f0d72b7bfe Merge pull request #44 from libp2p/feat/cache
feat: cache b58 id
2016-12-18 08:05:41 +00:00
78d96d0b14 feat: create b58 string on creation and throw on id mutation 2016-12-18 09:02:37 +01:00
bebb0a7eae feat: cache b58 id 2016-12-14 09:05:07 +01:00
5d6a962b6c chore(package): update aegir to version 9.2.1 (#43)
https://greenkeeper.io/
2016-12-10 11:59:28 -08:00
531c9f1086 Fix typo in README example (#42) 2016-12-04 21:52:26 -08:00
06f93cd961 chore(package): update aegir to version 9.1.2 (#39)
https://greenkeeper.io/
2016-11-28 15:52:39 +00:00
1452f233c8 chore(package): update multihashes to version 0.3.0 (#40)
https://greenkeeper.io/
2016-11-28 15:34:50 +00:00
77900c7b45 chore(package): update aegir to version 9.1.0 (#38)
https://greenkeeper.io/
2016-11-03 17:59:54 +00:00
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
7635cfcfda chore: release version v0.6.7 2016-05-23 15:32:57 +01:00
afbd96edda chore: update contributors 2016-05-23 15:32:57 +01:00
c1e18ee420 Merge pull request #24 from diasdavid/feat/marshal-unmarshal
Feat/marshal unmarshal
2016-05-23 15:31:38 +01:00
b358530dfb add toJSON and fromJSOn and cli to quickly generate 2016-05-23 15:25:30 +01:00
4afbedb525 update dependencies 2016-05-23 14:16:30 +01:00
e9b107fc55 Merge pull request #21 from diasdavid/aegir
refactor: use aegir
2016-04-15 14:13:57 +01:00
855a97956d refactor: use aegir 2016-04-15 13:20:05 +02:00
dee54d3dcc Merge pull request #20 from noffle/circle
circle-ci config
2016-04-14 00:01:25 +01:00
167b726dad Merge pull request #19 from noffle/readme-formatting
fixes README formatting
2016-04-14 00:01:05 +01:00
3b9f8af2e7 circle-ci config 2016-04-13 10:11:39 -07:00
771b994d7e fixes README formatting 2016-04-13 10:00:26 -07:00
524fc37877 chore: release version v0.6.6 2016-04-12 22:14:58 +01:00
3c55473a45 Merge pull request #18 from diasdavid/fix-jsnext
fix jsnext:main
2016-04-12 22:13:03 +01:00
8771627ce4 fix it 2016-04-12 22:06:12 +01:00
bbf6bae073 chore: release version v0.6.5 2016-04-12 21:28:27 +01:00
e45a9f4083 Merge pull request #17 from diasdavid/jsnext-add
jsnext add
2016-04-12 21:24:11 +01:00
13f98c8913 jsnext add 2016-04-12 21:09:41 +01:00
f374ab4411 chore: release version v0.6.4 2016-04-12 17:31:47 +01:00
2f4cdd3725 Merge pull request #16 from noffle/docs-and-examples
readme <3
2016-04-12 17:28:37 +01:00
d2f90ff447 Merge pull request #15 from noffle/coverage
100% coverage
2016-04-12 17:27:29 +01:00
f2a75f1188 100% coverage badge 2016-04-12 09:07:59 -07:00
dab90bd3b6 other bundlers 2016-04-12 09:04:02 -07:00
e9fdc0a27e applies readme love 2016-04-11 15:23:34 -07:00
f0a17a9bd9 100% coverage 2016-04-11 14:43:50 -07:00
57ab8406c0 chore: release version v0.6.3 2016-04-07 19:47:53 -04:00
f16c08e7fd update the readme 2016-04-07 19:45:21 -04:00
be5d4f9b41 chore: release version v0.6.2 2016-04-07 19:41:09 -04:00
35a3ccca3d update coverage script 2016-04-07 19:38:43 -04:00
989c3fb7a5 add .npmignore 2016-04-07 19:30:19 -04:00
bbe67df1c8 Merge pull request #12 from dignifiedquire/dignified
Use dignified.js
2016-04-07 19:27:13 -04:00
8849d90d6a Use dignified.js 1.0.0 2016-04-07 21:22:53 +02:00
2552871bcc Update travis 2016-03-22 17:03:51 +01:00
ab76788771 Use dignified.js 2016-03-22 17:01:46 +01:00
f62023f8a7 Release v0.6.1. 2016-03-15 23:28:07 +00:00
95367871ac Merge pull request #11 from noffle/bits
exposes opts + bits
2016-03-15 23:22:41 +00:00
352a6cfa17 tests # of bits 2016-03-15 12:15:44 -07:00
727355c4f5 exposes opts + bits 2016-03-14 17:10:02 -07:00
bd185f8081 Release v0.6.0. 2016-03-10 19:43:32 +00:00
d4c3de1ecb codestyle 2016-03-10 19:43:23 +00:00
b692394116 chore: dist 2016-03-10 19:40:52 +00:00
a8e591525b update readme 2016-03-10 19:36:47 +00:00
6ad5d85f76 Merge pull request #10 from nginnever/master
buffer the public key for consistency
2016-03-10 19:31:47 +00:00
ca9cef6de7 comparing buffers 2016-03-10 11:25:59 -08:00
f55eebcef7 buffer the public key for consistency 2016-03-10 10:32:48 -08:00
6442bb4b59 Release v0.5.3. 2016-03-05 21:56:53 +00:00
33ff2aa608 Merge pull request #8 from diasdavid/update/git-repo
add git repo and fix codestyle issues
2016-03-05 21:56:36 +00:00
bbeb6fc0f6 add git repo and fix codestyle issues 2016-03-05 21:54:18 +00:00
f518ced776 add git repo to the package.json 2016-03-05 21:49:26 +00:00
73b42ff2aa dist file 2016-03-03 14:19:10 -08:00
b3e3dbe3c0 Release v0.5.1. 2016-03-03 17:45:53 +00:00
b2b90bfbb5 remove jshintrc and jshintignore 2016-03-03 17:43:30 +00:00
d9113d55e0 Merge pull request #6 from diasdavid/cleanup
came to fix a square bracket, ended up touch a bunch of other things :)
2016-03-03 17:39:14 +00:00
59b89039b6 came to fix a square bracket, ended up touch a bunch of other things :) 2016-03-03 17:31:33 +00:00
1cdbf19857 Release v0.5.0. 2016-02-14 07:37:10 +00:00
845bd088fe add coverage, fix codestyle 2016-02-14 07:32:09 +00:00
1f72aaf7b7 Merge pull request #4 from nginnever/master
public key derivation from private key stored in go-ipfs config file
2016-02-14 07:24:06 +00:00
effa21b892 removed node forge bundle comment 2016-02-13 13:46:33 -08:00
91bc56eb05 small grammar changes 2016-02-13 07:49:51 -08:00
3cc3cb31f0 removed uneeded dev deps 2016-02-12 20:09:42 -08:00
de572bd15f Merge branch 'master' of https://github.com/nginnever/js-peer-id 2016-02-12 19:56:37 -08:00
1a336f9289 cleanup changes 2016-02-12 19:55:44 -08:00
77790571aa Delete id-test.js 2016-02-12 19:50:55 -08:00
d9b9ca8812 Delete crypto.proto 2016-02-12 19:45:50 -08:00
67c26ec546 travis addons 2016-02-12 16:38:29 -08:00
58fe038e07 time out increased 2016-02-12 16:13:09 -08:00
61c0c663d6 new timeout set 2016-02-12 16:06:40 -08:00
8adbdd0d6e Merge https://github.com/diasdavid/js-peer-id 2016-02-12 15:29:26 -08:00
7ae9be8f71 new tests 2016-02-12 14:55:05 -08:00
16c77433f9 getting ready to rewrite tests 2016-02-10 13:55:59 -08:00
6ce01ab434 keys now generated and derived match with go client 2016-02-04 12:02:18 -08:00
5cb511c646 added create id from private key 2016-02-04 12:01:58 -08:00
370e5c55b1 Release v0.4.0. 2015-11-05 18:51:53 +00:00
e3cc273a14 Merge pull request #3 from diasdavid/update
tests, browser tests, move to RSA based key (instead of ECDH), conform with go-ipfs
2015-11-05 18:51:21 +00:00
2c1874a689 merge latest master 2015-11-05 18:48:13 +00:00
3c0c9a3b19 tests and browser tests setup 2015-11-05 18:46:02 +00:00
d7ab4bd8fb complement readme 2015-11-05 17:47:44 +00:00
9aee5bf670 abandon ECD for RSA, in order to conform with go impl 2015-11-05 17:35:23 +00:00
5e9bf9837d Release v0.3.4. 2015-10-28 22:06:37 +00:00
f82d0d6ac5 Merge pull request #1 from diasdavid/rn
update README and package.json
2015-10-28 22:05:12 +00:00
0b30a0964c update README and package.json 2015-10-28 22:04:55 +00:00
14 changed files with 741 additions and 119 deletions

2
.gitignore vendored
View File

@ -25,3 +25,5 @@ build/Release
# Dependency directory # Dependency directory
# 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
dist

View File

@ -1 +0,0 @@
node_modules

View File

@ -1,10 +0,0 @@
{
"node": true,
"curly": true,
"latedef": true,
"quotmark": true,
"undef": true,
"unused": true,
"trailing": true
}

28
.npmignore Normal file
View File

@ -0,0 +1,28 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
test

View File

@ -1,13 +1,37 @@
sudo: false
language: node_js language: node_js
node_js:
- "4.0"
branches: matrix:
only: include:
- master - node_js: 4
env: CXX=g++-4.8
- node_js: 6
env:
- SAUCE=true
- CXX=g++-4.8
- node_js: stable
env: CXX=g++-4.8
# Make sure we have new NPM.
before_install: before_install:
- npm i -g npm - npm install -g npm
# Workaround for a permissions issue with Travis virtual machine images
script: script:
- npm run lint
- npm test - npm test
- npm run coverage
before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
after_success:
- npm run coverage-publish
addons:
firefox: latest
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8

235
README.md
View File

@ -1,66 +1,209 @@
peer-id Node.js implementation # peer-id
==============================
[![](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) ![Build Status](https://travis-ci.org/diasdavid/node-peer-id.svg?style=flat-square)](https://travis-ci.org/diasdavid/node-peer-id) ![](https://img.shields.io/badge/coverage-%3F-yellow.svg?style=flat-square) [![Dependency Status](https://david-dm.org/diasdavid/node-peer-id.svg?style=flat-square)](https://david-dm.org/diasdavid/node-peer-id) [![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/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)
[![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/libp2p/js-peer-id/badge.svg?branch=master)](https://coveralls.io/github/libp2p/js-peer-id?branch=master)
[![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)
![](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)
> IPFS Peer Id implementation in Node.js [![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.
- [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
A IPFS Peer Id is based on a sha256 has of the peer public key, using [multihash](https://github.com/jbenet/multihash) Generate, import, and export PeerIDs, for use with [IPFS](https://github.com/ipfs/ipfs).
# Usage *A Peer ID is the SHA-256 [multihash](https://github.com/multiformats/multihash) of a
public key.*
### Installing *The public key is a base64 encoded string of a protobuf containing an RSA DER
buffer. This uses a node buffer to pass the base64 encoded public key protobuf
to the multihash for ID generation.*
``` # Example
$ npm install peer-id
```js
var PeerId = require('peer-id')
var bs58 = require('bs58')
PeerId.create({ bits: 1024 }, (err, id) => {
console.log(JSON.stringify(id.toJSON(), null, 2))
})
``` ```
### Creating a new Id
``` ```
var PeerId = require('ipfs-peer') {
"id": "Qma9T5YraSnpRDZqRR4krcSJabThc8nwZuJV3LercPHufi",
// Create a new Id "privKey": "CAAS4AQwggJcAgEAAoGBAMBgbIqyOL26oV3nGPBYrdpbv..",
var id = new PeerId.create() "pubKey": "CAASogEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMBgbIqyOL26oV3nGPBYrdpbvzCY..."
}
// Recreate an Id from Hex string
var id = new PeerId.createFromHexString(str)
// Recreate an Id from a Buffer
var id = new PeerId.createFromBytes(buf)
// Recreate an B58 String
var id = new PeerId.createFromB58String(str)
// Recreate from a Public Key
var id = new PeerId.createFromPubKey(pubKey)
// Recreate from a Private Key
var id = new PeerId.createFromPrivKey(privKey)
``` ```
### Exporting an Id # Installation
``` ## npm
// Print friendly format
id.toPrint() // returns an object with id, privKey and pubKey in hex format
// Export to an hex string ```sh
id.toHexString() > npm i peer-id
// Export to Buffer
id.toBytes() (same as id.id)
// Export to a B58 string
id.toB58String()
``` ```
### Id format # Setup
## Node.js
```js
var PeerId = require('peer-id')
```
## Browser: Browserify, Webpack, other bundlers
The code published to npm that gets loaded on require is in fact a ES5
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
process.
```js
var PeerId = require('peer-id')
```
## Browser: `<script>` Tag
Loading this module through a script tag will make the `PeerId` obj available in
the global namespace.
```html
<script src="https://unpkg.com/peer-id/dist/index.min.js"></script>
<!-- OR -->
<script src="https://unpkg.com/peer-id/dist/index.js"></script>
```
# API
```js
const PeerId = require('peer-id')
```
## Create
### `new PeerId(id[, privKey, pubKey])`
- `id: Buffer` - The multihash of the publick key as `Buffer`
- `privKey: RsaPrivateKey` - The private key
- `pubKey: RsaPublicKey` - The public key
The key format is detailed in [libp2p-crypto](https://github.com/libp2p/js-libp2p-crypto).
### `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
### `createFromHexString(str)`
Creates a Peer ID from hex string representing the key's multihash.
### `createFromBytes(buf)`
Creates a Peer ID from a buffer representing the key's multihash.
### `createFromB58String(str)`
Creates a Peer ID from a Base58 string representing the key's multihash.
### `createFromPubKey(pubKey)`
- `publicKey: Buffer`
Creates a Peer ID from a buffer containing a public key.
### `createFromPrivKey(privKey)`
- `privKey: Buffer`
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
### `toHexString()`
Returns the Peer ID's `id` as a hex string.
``` ```
id.pubKey // Buffer containing the Public Key 1220d6243998f2fc56343ad7ed0342ab7886a4eb18d736f1b67d44b37fcc81e0f39f
id.privKey // Buffer containing the Private Key
id.id // Buffer containing the multihash
``` ```
### `toBytes()`
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>
```
### `toB58String()`
Returns the Peer ID's `id` as a base58 string.
```
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
MIT

12
circle.yml Normal file
View File

@ -0,0 +1,12 @@
machine:
node:
version: stable
dependencies:
pre:
- google-chrome --version
- wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
- sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
- sudo apt-get update
- sudo apt-get --only-upgrade install google-chrome-stable
- google-chrome --version

View File

@ -1,14 +1,20 @@
{ {
"name": "peer-id", "name": "peer-id",
"version": "0.3.3", "version": "0.8.3",
"description": "IPFS Peer Id implementation in Node.js", "description": "IPFS Peer Id implementation in Node.js",
"main": "src/index.js", "main": "src/index.js",
"bin": "src/bin.js",
"scripts": { "scripts": {
"test": "./node_modules/.bin/lab tests/*-test.js", "lint": "aegir-lint",
"coverage": "./node_modules/.bin/lab -t 100 tests/*-test.js", "build": "aegir-build",
"codestyle": "./node_modules/.bin/standard --format", "test": "aegir-test",
"lint": "jshint .", "test:node": "aegir-test node",
"validate": "npm ls" "test:browser": "aegir-test browser",
"release": "aegir-release",
"release-minor": "aegir-release --type minor",
"release-major": "aegir-release --type major",
"coverage": "aegir-coverage",
"coverage-publish": "aegir-coverage publish"
}, },
"keywords": [ "keywords": [
"IPFS" "IPFS"
@ -16,24 +22,41 @@
"author": "David Dias <daviddias@ipfs.io>", "author": "David Dias <daviddias@ipfs.io>",
"license": "MIT", "license": "MIT",
"pre-commit": [ "pre-commit": [
"codestyle", "lint",
"test" "test"
], ],
"engines": { "engines": {
"node": "^4.0.0" "node": ">=4.0.0",
"npm": ">=3.0.0"
}, },
"bugs": { "bugs": {
"url": "https://github.com/diasdavid/node-peer-id/issues" "url": "https://github.com/libp2p/js-peer-id/issues"
}, },
"homepage": "https://github.com/diasdavid/node-peer-id", "homepage": "https://github.com/libp2p/js-peer-id",
"devDependencies": { "devDependencies": {
"code": "^1.4.1", "aegir": "^11.0.0",
"lab": "^5.13.0", "chai": "^3.5.0",
"pre-commit": "^1.1.1", "dirty-chai": "^1.2.2",
"standard": "^4.5.2" "pre-commit": "^1.2.2"
}, },
"dependencies": { "dependencies": {
"bs58": "^2.0.1", "libp2p-crypto": "~0.8.6",
"multihashing": "^0.1.3" "multihashes": "~0.4.4",
} "async": "^2.1.5"
},
"repository": {
"type": "git",
"url": "https://github.com/libp2p/js-peer-id.git"
},
"contributors": [
"David Dias <daviddias.p@gmail.com>",
"David Dias <mail@daviddias.me>",
"Friedel Ziegelmayer <dignifiedquire@gmail.com>",
"Greenkeeper <support@greenkeeper.io>",
"Prashanth Chandra <coolshanth94@gmail.com>",
"Richard Littauer <richard.littauer@gmail.com>",
"Stephen Whitmore <stephen.whitmore@gmail.com>",
"nginnever <ginneversource@gmail.com>",
"npmcdn-to-unpkg-bot <npmcdn-to-unpkg-bot@users.noreply.github.com>"
]
} }

13
src/bin.js Executable file
View File

@ -0,0 +1,13 @@
#!/usr/local/bin/node
'use strict'
const PeerId = require('./index.js')
PeerId.create((err, id) => {
if (err) {
throw err
}
console.log(JSON.stringify(id.toJSON(), null, 2))
})

View File

@ -2,77 +2,225 @@
* Id is an object representation of a peer Id. a peer Id is a multihash * Id is an object representation of a peer Id. a peer Id is a multihash
*/ */
var multihashing = require('multihashing') 'use strict'
var base58 = require('bs58')
var crypto = require('crypto')
exports = module.exports = Id const mh = require('multihashes')
const crypto = require('libp2p-crypto')
const assert = require('assert')
const waterfall = require('async/waterfall')
function Id (id, privKey, pubKey) { class PeerId {
var self = this constructor (id, privKey, pubKey) {
assert(Buffer.isBuffer(id), 'invalid id provided')
if (!(self instanceof Id)) { if (privKey && pubKey) {
throw new Error('Id must be called with new') assert(privKey.public.bytes.equals(pubKey.bytes), 'inconsistent arguments')
} }
self.privKey = privKey this._id = id
self.pubKey = pubKey this._idB58String = mh.toB58String(this.id)
self.id = id // multihash - sha256 - buffer this._privKey = privKey
this._pubKey = pubKey
}
get id () {
return this._id
}
set id (val) {
throw new Error('Id is immutable')
}
get privKey () {
return this._privKey
}
get pubKey () {
if (this._pubKey) {
return this._pubKey
}
if (this.privKey) {
return this.privKey.public
}
}
// 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 // pretty print
toPrint () {
return this.toJSON()
}
self.toPrint = function () { // return the jsonified version of the key, matching the formatting
// of go-ipfs for its config file
toJSON () {
return { return {
id: id.toHexString(), id: this.toB58String(),
privKey: privKey.toString('hex'), privKey: toB64Opt(this.marshalPrivKey()),
pubKey: pubKey.toString('hex') pubKey: toB64Opt(this.marshalPubKey())
} }
} }
// encode/decode functions // encode/decode functions
toHexString () {
self.toHexString = function () { return mh.toHexString(this.id)
return self.id.toString('hex')
} }
self.toBytes = function () { toBytes () {
return self.id return this.id
} }
self.toB58String = function () { toB58String () {
return base58.encode(self.id) return this._idB58String
} }
} }
exports = module.exports = PeerId
exports.Buffer = Buffer
// generation // generation
exports.create = function (opts, callback) {
if (typeof opts === 'function') {
callback = opts
opts = {}
}
opts = opts || {}
opts.bits = opts.bits || 2048
exports.create = function () { waterfall([
var ecdh = crypto.createECDH('secp256k1') (cb) => crypto.generateKeyPair('RSA', opts.bits, cb),
ecdh.generateKeys() (privKey, cb) => privKey.public.hash((err, digest) => {
cb(err, digest, privKey)
})
], (err, digest, privKey) => {
if (err) {
return callback(err)
}
var mhId = multihashing(ecdh.getPublicKey(), 'sha2-256') callback(null, new PeerId(digest, privKey))
})
return new Id(mhId, ecdh.getPrivateKey(), ecdh.getPublicKey())
} }
exports.createFromHexString = function (str) { exports.createFromHexString = function (str) {
return new Id(new Buffer(str), 'hex') return new PeerId(mh.fromHexString(str))
} }
exports.createFromBytes = function (buf) { exports.createFromBytes = function (buf) {
return new Id(buf) return new PeerId(buf)
} }
exports.createFromB58String = function (str) { exports.createFromB58String = function (str) {
return new Id(new Buffer(base58.decode(str))) return new PeerId(mh.fromB58String(str))
} }
exports.createFromPubKey = function (pubKey) { // Public Key input will be a buffer
var mhId = multihashing(pubKey, 'sha2-256') exports.createFromPubKey = function (key, callback) {
return new Id(mhId, null, pubKey) let buf = key
if (typeof buf === 'string') {
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))
})
} }
exports.createFromPrivKey = function () { // Private key input will be a string
// TODO(daviddias) derive PubKey from priv exports.createFromPrivKey = function (key, callback) {
let buf = key
if (typeof buf === 'string') {
buf = new Buffer(key, 'base64')
}
if (typeof callback !== 'function') {
throw new Error('callback is required')
}
waterfall([
(cb) => crypto.unmarshalPrivateKey(buf, cb),
(privKey, cb) => privKey.public.hash((err, digest) => {
cb(err, digest, privKey)
})
], (err, digest, privKey) => {
if (err) {
return callback(err)
}
callback(null, new PeerId(digest, privKey))
})
}
exports.createFromJSON = function (obj, callback) {
if (typeof callback !== 'function') {
throw new Error('callback is required')
}
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='
}

227
test/index.spec.js Normal file
View File

@ -0,0 +1,227 @@
/* eslint max-nested-callbacks: ["error", 8] */
/* eslint-env mocha */
'use strict'
const chai = require('chai')
const dirtyChai = require('dirty-chai')
chai.use(dirtyChai)
const expect = chai.expect
const crypto = require('libp2p-crypto')
const mh = require('multihashes')
const parallel = require('async/parallel')
const PeerId = require('../src')
const testId = require('./fixtures/sample-id')
const testIdHex = testId.id
const testIdBytes = mh.fromHexString(testId.id)
const testIdB58String = mh.toB58String(testIdBytes)
const goId = require('./fixtures/go-private-key')
describe('PeerId', () => {
it('create an id without \'new\'', () => {
expect(PeerId).to.throw(Error)
})
it('create a new id', (done) => {
PeerId.create((err, id) => {
expect(err).to.not.exist()
expect(id.toB58String().length).to.equal(46)
done()
})
})
it('throws on changing the id', (done) => {
PeerId.create((err, id) => {
expect(err).to.not.exist()
expect(id.toB58String().length).to.equal(46)
expect(() => {
id.id = new Buffer('hello')
}).to.throw(/immutable/)
done()
})
})
it('recreate an Id from Hex string', () => {
const id = PeerId.createFromHexString(testIdHex)
expect(testIdBytes).to.deep.equal(id.id)
})
it('Recreate an Id from a Buffer', () => {
const id = PeerId.createFromBytes(testIdBytes)
expect(testId.id).to.equal(id.toHexString())
})
it('Recreate a B58 String', () => {
const id = PeerId.createFromB58String(testIdB58String)
expect(testIdB58String).to.equal(id.toB58String())
})
it('Recreate from a Public Key', (done) => {
PeerId.createFromPubKey(testId.pubKey, (err, id) => {
expect(err).to.not.exist()
expect(testIdB58String).to.equal(id.toB58String())
done()
})
})
it('Recreate from a Private Key', (done) => {
PeerId.createFromPrivKey(testId.privKey, (err, id) => {
expect(err).to.not.exist()
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) => {
PeerId.create((err, id1) => {
expect(err).to.not.exist()
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) => {
PeerId.create({ bits: 1024 }, (err, shortId) => {
expect(err).to.not.exist()
PeerId.create({ bits: 4096 }, (err, longId) => {
expect(err).to.not.exist()
expect(shortId.privKey.bytes.length).is.below(longId.privKey.bytes.length)
done()
})
})
})
it('Pretty printing', (done) => {
PeerId.create((err, id1) => {
expect(err).to.not.exist()
PeerId.createFromPrivKey(id1.toPrint().privKey, (err, id2) => {
expect(err).to.not.exist()
expect(id1.toPrint()).to.be.eql(id2.toPrint())
done()
})
})
})
it('toBytes', () => {
const id = PeerId.createFromHexString(testIdHex)
expect(id.toBytes().toString('hex')).to.equal(testIdBytes.toString('hex'))
})
describe('fromJSON', () => {
it('full node', (done) => {
PeerId.create({ bits: 1024 }, (err, id) => {
expect(err).to.not.exist()
PeerId.createFromJSON(id.toJSON(), (err, other) => {
expect(err).to.not.exist()
expect(id.toB58String()).to.equal(other.toB58String())
expect(id.privKey.bytes).to.eql(other.privKey.bytes)
expect(id.pubKey.bytes).to.eql(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/
)
})
})
})

View File