Compare commits

...

35 Commits

Author SHA1 Message Date
David Dias
bbf6bae073 chore: release version v0.6.5 2016-04-12 21:28:27 +01:00
David Dias
e45a9f4083 Merge pull request #17 from diasdavid/jsnext-add
jsnext add
2016-04-12 21:24:11 +01:00
David Dias
13f98c8913 jsnext add 2016-04-12 21:09:41 +01:00
David Dias
f374ab4411 chore: release version v0.6.4 2016-04-12 17:31:47 +01:00
David Dias
2f4cdd3725 Merge pull request #16 from noffle/docs-and-examples
readme <3
2016-04-12 17:28:37 +01:00
David Dias
d2f90ff447 Merge pull request #15 from noffle/coverage
100% coverage
2016-04-12 17:27:29 +01:00
Stephen Whitmore
f2a75f1188 100% coverage badge 2016-04-12 09:07:59 -07:00
Stephen Whitmore
dab90bd3b6 other bundlers 2016-04-12 09:04:02 -07:00
Stephen Whitmore
e9fdc0a27e applies readme love 2016-04-11 15:23:34 -07:00
Stephen Whitmore
f0a17a9bd9 100% coverage 2016-04-11 14:43:50 -07:00
David Dias
57ab8406c0 chore: release version v0.6.3 2016-04-07 19:47:53 -04:00
David Dias
f16c08e7fd update the readme 2016-04-07 19:45:21 -04:00
David Dias
be5d4f9b41 chore: release version v0.6.2 2016-04-07 19:41:09 -04:00
David Dias
35a3ccca3d update coverage script 2016-04-07 19:38:43 -04:00
David Dias
989c3fb7a5 add .npmignore 2016-04-07 19:30:19 -04:00
David Dias
bbe67df1c8 Merge pull request #12 from dignifiedquire/dignified
Use dignified.js
2016-04-07 19:27:13 -04:00
dignifiedquire
8849d90d6a Use dignified.js 1.0.0 2016-04-07 21:22:53 +02:00
dignifiedquire
2552871bcc Update travis 2016-03-22 17:03:51 +01:00
dignifiedquire
ab76788771 Use dignified.js 2016-03-22 17:01:46 +01:00
David Dias
f62023f8a7 Release v0.6.1. 2016-03-15 23:28:07 +00:00
David Dias
95367871ac Merge pull request #11 from noffle/bits
exposes opts + bits
2016-03-15 23:22:41 +00:00
Stephen Whitmore
352a6cfa17 tests # of bits 2016-03-15 12:15:44 -07:00
Stephen Whitmore
727355c4f5 exposes opts + bits 2016-03-14 17:10:02 -07:00
David Dias
bd185f8081 Release v0.6.0. 2016-03-10 19:43:32 +00:00
David Dias
d4c3de1ecb codestyle 2016-03-10 19:43:23 +00:00
David Dias
b692394116 chore: dist 2016-03-10 19:40:52 +00:00
David Dias
a8e591525b update readme 2016-03-10 19:36:47 +00:00
David Dias
6ad5d85f76 Merge pull request #10 from nginnever/master
buffer the public key for consistency
2016-03-10 19:31:47 +00:00
nginnever
ca9cef6de7 comparing buffers 2016-03-10 11:25:59 -08:00
nginnever
f55eebcef7 buffer the public key for consistency 2016-03-10 10:32:48 -08:00
David Dias
6442bb4b59 Release v0.5.3. 2016-03-05 21:56:53 +00:00
David Dias
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
David Dias
bbeb6fc0f6 add git repo and fix codestyle issues 2016-03-05 21:54:18 +00:00
David Dias
f518ced776 add git repo to the package.json 2016-03-05 21:49:26 +00:00
nginnever
73b42ff2aa dist file 2016-03-03 14:19:10 -08:00
10 changed files with 239 additions and 155 deletions

3
.gitignore vendored
View File

@@ -25,3 +25,6 @@ build/Release
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
lib
dist

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,10 +1,7 @@
language: node_js
node_js:
- "4.0"
branches:
only:
- master
- 4
- 5
before_install:
- npm i -g npm
@@ -18,4 +15,5 @@ before_script:
- sh -e /etc/init.d/xvfb start
script:
- npm run lint
- npm test

174
README.md
View File

@@ -1,93 +1,157 @@
peer-id JavaScript 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/js-peer-id.svg?style=flat-square)](https://travis-ci.org/diasdavid/js-peer-id)
![](https://img.shields.io/badge/coverage-95%25-yellow.svg?style=flat-square)
![](https://img.shields.io/badge/coverage-100%25-brightgreen.svg?style=flat-square)
[![Dependency Status](https://david-dm.org/diasdavid/js-peer-id.svg?style=flat-square)](https://david-dm.org/diasdavid/js-peer-id)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard)
> IPFS Peer Id implementation in JavaScript
> [IPFS](https://github.com/ipfs/ipfs) Peer ID implementation in JavaScript.
# Description
An IPFS Peer Id is based on a sha256 hash 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).
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.
*A Peer ID is the SHA-256 [multihash](https://github.com/jbenet/multihash) of a
public key.*
*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.*
# Usage
# Example
### In Node.js through npm
```js
var PeerId = require('peer-id')
var bs58 = require('bs58')
```bash
> npm install --save peer-id
var id = PeerId.create({ bits: 32 })
console.log('id ', id.toB58String())
console.log('priv key ', bs58.encode(id.privKey))
console.log('pub key ', bs58.encode(id.pubKey))
```
```javascript
```
id QmeeLFb92nkZJGj3gXLqXrEMzCMYs6uBgQLVNbrcXEvYXk
priv key 6ibrcPAbevzvPpkq6EA6XmLyuhmUrJrEvUfgQDtEiSEPzGnGU8Ejwf6b11DVm6opnFGo
pub key 2BeBZVKJ9RQs4i4LbGv4ReEeuBA5dck2Gje3wt67e44XuyyPq5jE
```
# Installation
## npm
```sh
> npm i peer-id
```
# Setup
## Node.js
```JavaScript
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.
```JavaScript
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://npmcdn.com/peer-id/dist/index.min.js"></script>
<!-- OR -->
<script src="https://npmcdn.com/peer-id/dist/index.js"></script>
```
# API
```js
const PeerId = require('peer-id')
```
### In the Browser through browserify
## Create
Same as in Node.js, you just have to [browserify](https://github.com/substack/node-browserify) the code before serving it. See the browserify repo for how to do that.
### PeerId.create()
### In the Browser through `<script>` tag
Generates a new Peer ID, complete with public/private keypair. A Peer ID has the
following properties:
Make the [peer-id.min.js](/dist/peer-id.min.js) available through your server and load it using a normal `<script>` tag, this will export the `peerId` constructor on the `window` object, such that:
- `pubKey` - Buffer containing the public key bytes
- `privKey` - Buffer containing the private key bytes
- `id` - Buffer containing the multihash bytes
```JavaScript
const PeerId = window.PeerId
## Import
### PeerId.createFromHexString(str)
Creates a Peer ID from hex string representing the key's multihash.
### PeerId.createFromBytes(buf)
Creates a Peer ID from a buffer representing the key's multihash.
### PeerId.createFromB58String(str)
Creates a Peer ID from a Base58 string representing the key's multihash.
### PeerId.createFromPubKey(pubKey)
Creates a Peer ID from a buffer containing a public key.
### PeerId.createFromPrivKey(privKey)
Creates a Peer ID from a buffer containing a private key.
## Export
### id.toPrint()
Returns an object with the ID's properties in hex format:
```js
{
id: 'QmckZzdVd72h9QUFuJJpQqhsZqGLwjhh81qSvZ9BhB2FQi',
privKey: '080012a609308204a20201000282010100a608889914da08959d3a3db0734cee812c96...',
pubKey: '080012a60230820122300d06092a864886f70d01010105000382010f003082010a0282010...'
}
```
#### Gotchas
### id.toHexString()
You will need to use Node.js `Buffer` API compatible, if you are running inside the browser, you can access it by `PeerId.Buffer` or you can install Feross's [Buffer](https://github.com/feross/buffer).
Returns the Peer ID's `id` as a hex string.
### Creating a new Id
```js
1220d6243998f2fc56343ad7ed0342ab7886a4eb18d736f1b67d44b37fcc81e0f39f```
```
const PeerId = require('ipfs-peer')
### id.toBytes()
// Create a new Id
const id = PeerId.create()
Returns the Peer ID's `id` as a buffer.
// Recreate an Id from Hex string
const id = PeerId.createFromHexString(str)
// Recreate an Id from a Buffer
const id = PeerId.createFromBytes(buf)
// Recreate an B58 String
const id = PeerId.createFromB58String(str)
// Recreate from a Public Key
const id = PeerId.createFromPubKey(pubKey)
// Recreate from a Private Key
const id = PeerId.createFromPrivKey(privKey)
```js
<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>
```
### Exporting an Id
### id.toB58String()
```
// Print friendly format
id.toPrint() // returns an object with id, privKey and pubKey in hex format
Returns the Peer ID's `id` as a base58 string.
// Export to an hex string
id.toHexString()
// Export to Buffer
id.toBytes() (same as id.id)
// Export to a B58 string
id.toB58String()
```js
QmckZzdVd72h9QUFuJJpQqhsZqGLwjhh81qSvZ9BhB2FQi
```
### Id format
# License
```
id.pubKey // Buffer containing the Public Key
id.privKey // Buffer containing the Private Key
id.id // Buffer containing the multihash
```
MIT

View File

@@ -1,57 +0,0 @@
module.exports = (config) => {
const path = require('path')
const node_modules_dir = path.join(__dirname, 'node_modules')
const deps = [
'deps/forge.bundle.js'
]
config.set({
basePath: '',
frameworks: ['mocha'],
files: [
'tests/test.js'
],
preprocessors: {
'tests/*': ['webpack']
},
webpack: {
resolve: {
extensions: ['', '.js', '.json'],
alias: { 'node-forge': path.resolve(__dirname, 'deps/forge.bundle.js') }
},
externals: {
fs: '{}'
},
node: {
Buffer: true
},
module: {
loaders: [
{ test: /\.json$/, loader: 'json' }
],
noParse: []
}
},
webpackMiddleware: {
noInfo: true,
stats: {
colors: true
}
},
reporters: ['spec'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: process.env.TRAVIS ? ['Firefox'] : ['Chrome'],
singleRun: true
})
deps.forEach((dep) => {
const depPath = path.resolve(node_modules_dir, dep)
config.webpack.module.noParse.push(depPath)
})
}

View File

@@ -1,14 +1,17 @@
{
"name": "peer-id",
"version": "0.5.1",
"version": "0.6.5",
"description": "IPFS Peer Id implementation in Node.js",
"main": "src/index.js",
"main": "lib/index.js",
"jsnext": "src/index.js",
"scripts": {
"lint": "standard",
"test": "npm run test:node && npm run test:browser",
"test:node": "mocha tests/test.js",
"test:browser": "karma start karma.conf.js",
"coverage": "istanbul cover --print both -- _mocha tests/test.js"
"lint": "dignified-lint",
"build": "dignified-build",
"test": "dignified-test",
"test:node": "dignified-test node",
"test:browser": "dignified-test browser",
"release": "dignified-release",
"coverage": "dignified-coverage"
},
"keywords": [
"IPFS"
@@ -19,12 +22,6 @@
"lint",
"test"
],
"standard": {
"ignore": [
"dist",
"deps"
]
},
"engines": {
"node": "^4.3.0"
},
@@ -35,24 +32,27 @@
"devDependencies": {
"buffer-loader": "0.0.1",
"chai": "^3.5.0",
"dignified.js": "^1.0.0",
"istanbul": "^0.4.2",
"json-loader": "^0.5.4",
"karma": "^0.13.19",
"karma-chrome-launcher": "^0.2.2",
"karma-cli": "^0.1.2",
"karma-firefox-launcher": "^0.1.7",
"karma-mocha": "^0.2.1",
"karma-spec-reporter": "0.0.24",
"karma-webpack": "^1.7.0",
"mocha": "^2.4.5",
"pre-commit": "^1.1.1",
"standard": "^6.0.7",
"webpack": "^1.12.13"
"pre-commit": "^1.1.1"
},
"dependencies": {
"bs58": "^3.0.0",
"multihashing": "^0.2.0",
"node-forge": "^0.6.38",
"protocol-buffers": "^3.1.4"
},
"repository": {
"type": "git",
"url": "https://github.com/diasdavid/js-peer-id.git"
},
"dignified": {
"webpack": {
"resolve": {
"alias": {
"node-forge": "../vendor/forge.bundle.js"
}
}
}
}
}

View File

@@ -1,6 +1,7 @@
/*
* Id is an object representation of a peer Id. a peer Id is a multihash
*/
'use strict'
const fs = require('fs')
const multihashing = require('multihashing')
@@ -9,11 +10,8 @@ const forge = require('node-forge')
const protobuf = require('protocol-buffers')
const path = require('path')
const isNode = !global.window
// protobuf read from file
const messages = isNode ? protobuf(fs.readFileSync(path.resolve(__dirname, 'pb/crypto.proto')))
: protobuf(require('buffer!./pb/crypto.proto'))
const messages = protobuf(fs.readFileSync(path.resolve(__dirname, '../protos/crypto.proto')))
exports = module.exports = Id
@@ -31,7 +29,6 @@ function Id (id, privKey, pubKey) {
self.id = id // multihash - sha256 - buffer
// pretty print
self.toPrint = function () {
return {
id: self.toB58String(),
@@ -41,7 +38,6 @@ function Id (id, privKey, pubKey) {
}
// encode/decode functions
self.toHexString = function () {
return self.id.toString('hex')
}
@@ -100,9 +96,15 @@ function formatKey (key, type) {
}
// generation
exports.create = function () {
exports.create = function (opts) {
opts = opts || {}
opts.bits = opts.bits || 2048
// generate keys
const pair = forge.rsa.generateKeyPair({ bits: 2048, e: 0x10001 })
const pair = forge.rsa.generateKeyPair({
bits: opts.bits,
e: 0x10001
})
// return the RSA public/private key to asn1 object
const asnPub = forge.pki.publicKeyToAsn1(pair.publicKey)
@@ -112,9 +114,13 @@ exports.create = function () {
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 Id(mhId, protoPrivate64, protoPublic64)
return new Id(mhId, bufProtoPriv64, bufProtoPub64)
}
exports.createFromHexString = function (str) {
@@ -129,12 +135,14 @@ exports.createFromB58String = function (str) {
return new Id(new Buffer(base58.decode(str)))
}
// Public Key input will be a buffer
exports.createFromPubKey = function (pubKey) {
const buf = new Buffer(pubKey, 'base64')
const mhId = multihashing(buf, 'sha2-256')
return new Id(mhId, null, pubKey)
}
// Private key input will be a string
exports.createFromPrivKey = function (privKey) {
// create a buffer from the base64 encoded string
const buf = new Buffer(privKey, 'base64')
@@ -159,6 +167,9 @@ exports.createFromPrivKey = function (privKey) {
// 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 Id(mhId, privKey, protoPublic64)
return new Id(mhId, privKey, bufProtoPub64)
}

View File

@@ -1,5 +1,4 @@
/* globals describe, it */
/* eslint-env mocha */
'use strict'
const expect = require('chai').expect
@@ -20,6 +19,11 @@ const testIdB58String = 'QmQ2zigjQikYnyYUSXZydNXrDRhBut2mubwJBaLXobMt3A'
describe('id', function (done) {
this.timeout(30000)
it('create an id without \'new\'', (done) => {
expect(PeerId).to.throw(Error)
done()
})
it('create a new id', (done) => {
const id = PeerId.create()
expect(id.toB58String().length).to.equal(46)
@@ -55,5 +59,38 @@ describe('id', function (done) {
expect(testIdB58String).to.equal(id.toB58String())
done()
})
})
it('Compare generated ID with one created from PubKey', (done) => {
const id1 = PeerId.create()
const id2 = PeerId.createFromPubKey(id1.pubKey)
expect(id2.id).to.deep.equal(id1.id)
done()
})
it('Non-default # of bits', (done) => {
const shortId = PeerId.create({ bits: 128 })
const longId = PeerId.create({ bits: 256 })
expect(shortId.privKey.length).is.below(longId.privKey.length)
done()
})
it('Pretty printing', (done) => {
const id = PeerId.createFromPrivKey(testId.privKey)
var out = id.toPrint()
var expected = {
id: 'QmQ2zigjQikYnyYUSXZydNXrDRhBut2mubwJBaLXobMt3A',
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: '080012a60230820122300d06092a864886f70d01010105000382010f003082010a0282010100b648aa3f1cc1597819a5d401775e28f3af1adf417749ce378f05901b771a8a47531cea3b911d78a3e875d83e3940934d41845d52dcb9782f08b47001e18207f8e7bb0c839e545b278629e52fd2e720bc2a41c25479710d36d22d0c8338cf58e2d6ab5aedbd26cd7008b6644567ebe43611c1e8df052f591b4b78acfe0d94997f0d8f1030be0c63c93e5edff20ef3979e98ca69a6cc7f658992cdaf383faa2768914bf9bb5a5d1ab7292ee3cd79338393472a281f8e51bb8a8fd1928581020848dac9b24397ddbbea86a52fd82106d49e12fdb492e81ab53bd8cb9f74c05949924bf297e9cfc481f410460c28af5745696ef57627a127dba22c1cbfc3374a5b230203010001'
}
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) => {
const id = PeerId.createFromHexString(testIdHex)
expect(id.toBytes().toString('hex')).to.equal(testIdBytes.toString('hex'))
done()
})
})