From c979efb30ceb0b239da895d7ef7a10ef3354e8ee Mon Sep 17 00:00:00 2001 From: mkg20001 Date: Sat, 3 Feb 2018 13:42:11 +0100 Subject: [PATCH] feat: Add compact protobuf format --- package.json | 3 ++- src/index.js | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index c86b69a..7616067 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,8 @@ "async": "^2.6.0", "libp2p-crypto": "~0.12.1", "lodash": "^4.17.5", - "multihashes": "~0.4.13" + "multihashes": "~0.4.13", + "protons": "^1.0.1" }, "repository": { "type": "git", diff --git a/src/index.js b/src/index.js index 87145c6..e262a30 100644 --- a/src/index.js +++ b/src/index.js @@ -9,6 +9,9 @@ const crypto = require('libp2p-crypto') const assert = require('assert') const waterfall = require('async/waterfall') +const protons = require('protons') +const {PeerIdProto} = protons('message PeerIdProto { required bytes id = 1; bytes pubKey = 2; bytes privKey = 3; }') + class PeerId { constructor (id, privKey, pubKey) { assert(Buffer.isBuffer(id), 'invalid id provided') @@ -67,6 +70,15 @@ class PeerId { } } + // Return the protobuf version of the peer-id + marshal (excludePriv) { + return PeerIdProto.encode({ + id: this.toBytes(), + pubKey: this.marshalPubKey(), + privKey: excludePriv ? null : this.marshalPrivKey() + }) + } + // pretty print toPrint () { return this.toJSON() @@ -221,6 +233,62 @@ exports.createFromPrivKey = function (key, callback) { }) } +exports.createFromProtobuf = function (buf, callback) { + if (typeof callback !== 'function') { + throw new Error('callback is required') + } + + let obj + let id + let rawPrivKey + let rawPubKey + let pub + + try { + obj = PeerIdProto.decode(buf) + id = obj.id + rawPrivKey = obj.privKey + rawPubKey = obj.pubKey + pub = rawPubKey && crypto.keys.unmarshalPublicKey(rawPubKey) + } catch (err) { + return callback(err) + } + + if (rawPrivKey) { + waterfall([ + (cb) => crypto.keys.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)) + } +} + exports.createFromJSON = function (obj, callback) { if (typeof callback !== 'function') { throw new Error('callback is required')