fsteff / hyperpubsub

Hypercore Protocol Extension for a simple PubSub system
MIT License
8 stars 1 forks source link

What am I doing wrongly and / or missing when using `Private Messages` ? #3

Open raphael10-collab opened 3 years ago

raphael10-collab commented 3 years ago

Hi @fsteff !

I'm trying to send and receive private (crypted) messages and then decrypt them:

This is the complete snippet I'm using on both PC and laptop connected on the local network:

const {PubSub} = require('hyperpubsub').debug()
const {Server, Client} = require('hyperspace')
const sodium = require('sodium-universal')

const publicKey = Buffer.alloc(sodium.crypto_box_PUBLICKEYBYTES)
const secretKey = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES)

sodium.crypto_box_keypair(publicKey, secretKey)

async function setUpHyperspace() {
  let client, server
  try {
    client = new Client()
    await client.ready()
  } catch(e) {
    console.log('no hyperspace server running, starting up a new one')
    server = new Server()
    await server.ready()
    client = new Client()
    await client.ready()
  }
  return {client, server}
}

setUpHyperspace().then(({client}) => {

  const pubsub = new PubSub(client.network, {application: 'example app', onError: console.error})

  pubsub.sub('some topic', (msg, app) => console.log(msg.toString('utf-8')), true) // messages are binary blobs
  //pubsub.sub('some topic', (chipheredmsg, app) => console.log(pubsub.privateMsgOpen(chipheredmsg, publicKey, secretKey).toString('utf-8')), true)

  pubsub.subPrivateMsg('some-topic', publicKey, secretKey, (cipheredmsg) => {
   //console.log(msg.toString('utf-8'))
    let msg = pubsub.privateMsgOpen(chipheredmsg, publicKey, secretKey)
    console.log(msg.toString('utf-8'))
  })

  setInterval(send, 1000)
  function send() {
      //pubsub.pub('some topic', Buffer.from('hello', 'utf-8'))

      pubsub.pubPrivateMsg(publicKey, Buffer.from('hello', 'utf-8'))

  }
})

Executing on both laptop and PC I get this output:

(laptop):

(base) marco@marco-U36SG:~/hypercore/hyperswarm/hyperpubsub$ node simple_example_no_simulator_private.js
no hyperspace server running, starting up a new one
joined topic "some topic" (bce5935f9a6ade33d955c843f9b906e1b1fe769be6f1757fff6ca0f644506e42)
<- sub some topic broadcast
joined topic "5311f5f8b90fa0e4e6254c5dd29a71a05e4b045ea06e8e364bbabe4fe166bc07" (0f64f41883d92f7bee892d007c24bfcbb38fab402d84d22247f2157f76f67a3b)
<- sub 5311f5f8b90fa0e4e6254c5dd29a71a05e4b045ea06e8e364bbabe4fe166bc07 broadcast
peer-add 192.168.1.7
<- sub some topic to 192.168.1.7
<- sub 5311f5f8b90fa0e4e6254c5dd29a71a05e4b045ea06e8e364bbabe4fe166bc07 to 192.168.1.7
peer-add ::ffff:192.168.1.7
<- sub some topic to ::ffff:192.168.1.7
<- sub 5311f5f8b90fa0e4e6254c5dd29a71a05e4b045ea06e8e364bbabe4fe166bc07 to ::ffff:192.168.1.7
peer-remove 192.168.1.7
-> msg sub some topic from ::ffff:192.168.1.7
subscriber ::ffff:192.168.1.7 added to topic some topic
-> msg sub 5311f5f8b90fa0e4e6254c5dd29a71a05e4b045ea06e8e364bbabe4fe166bc07 from ::ffff:192.168.1.7
subscriber ::ffff:192.168.1.7 added to topic 5311f5f8b90fa0e4e6254c5dd29a71a05e4b045ea06e8e364bbabe4fe166bc07
-> msg sub some topic from ::ffff:192.168.1.7
-> msg sub 5311f5f8b90fa0e4e6254c5dd29a71a05e4b045ea06e8e364bbabe4fe166bc07 from ::ffff:192.168.1.7

(PC) : 

(base) raphy@pc:~/hypercore/hyperswarm/hyperpubsub$ node simple_example_no_simulator_private.js 
no hyperspace server running, starting up a new one
peer-add 192.168.1.9
<- sub some topic to 192.168.1.9
<- sub 5311f5f8b90fa0e4e6254c5dd29a71a05e4b045ea06e8e364bbabe4fe166bc07 to 192.168.1.9
-> msg sub some topic from 192.168.1.9
subscriber 192.168.1.9 added to topic some topic
-> msg sub 5311f5f8b90fa0e4e6254c5dd29a71a05e4b045ea06e8e364bbabe4fe166bc07 from 192.168.1.9
subscriber 192.168.1.9 added to topic 5311f5f8b90fa0e4e6254c5dd29a71a05e4b045ea06e8e364bbabe4fe166bc07
joined topic "some topic" (bce5935f9a6ade33d955c843f9b906e1b1fe769be6f1757fff6ca0f644506e42)
<- sub some topic broadcast
joined topic "5311f5f8b90fa0e4e6254c5dd29a71a05e4b045ea06e8e364bbabe4fe166bc07" (0f64f41883d92f7bee892d007c24bfcbb38fab402d84d22247f2157f76f67a3b)
<- sub 5311f5f8b90fa0e4e6254c5dd29a71a05e4b045ea06e8e364bbabe4fe166bc07 broadcast

But, if I execute the snippet without crypting, which is the following:

const {PubSub} = require('hyperpubsub').debug()
const {Server, Client} = require('hyperspace')
const sodium = require('sodium-universal')

const publicKey = Buffer.alloc(sodium.crypto_box_PUBLICKEYBYTES)
const secretKey = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES)

sodium.crypto_box_keypair(publicKey, secretKey)

async function setUpHyperspace() {
  let client, server
  try {
    client = new Client()
    await client.ready()
  } catch(e) {
    console.log('no hyperspace server running, starting up a new one')
    server = new Server()
    await server.ready()
    client = new Client()
    await client.ready()
  }
  return {client, server}
}

setUpHyperspace().then(({client}) => {

  const pubsub = new PubSub(client.network, {application: 'example app', onError: console.error})

  pubsub.sub('some topic', (msg, app) => console.log(msg.toString('utf-8')), true) // messages are binary blobs

  setInterval(send, 1000)
  function send() {
      pubsub.pub('some topic', Buffer.from('hello', 'utf-8'))
  }
})

I get a continuous, never-stopping, flow of messages between the two machines, which is what I expected also with the private messages version :

(laptop) :

(base) marco@marco-U36SG:~/hypercore/hyperswarm/hyperpubsub$ node simple_example_without_simulator.js
no hyperspace server running, starting up a new one
joined topic "some topic" (bce5935f9a6ade33d955c843f9b906e1b1fe769be6f1757fff6ca0f644506e42)
<- sub some topic broadcast
peer-add 192.168.1.7
<- sub some topic to 192.168.1.7
peer-add ::ffff:192.168.1.7
<- sub some topic to ::ffff:192.168.1.7
peer-remove 192.168.1.7
-> msg sub some topic from ::ffff:192.168.1.7
subscriber ::ffff:192.168.1.7 added to topic some topic
-> msg sub some topic from ::ffff:192.168.1.7
<- msg some topic to ::ffff:192.168.1.7
-> msg data some topic from ::ffff:192.168.1.7
hello
<- msg some topic to ::ffff:192.168.1.7
-> msg data some topic from ::ffff:192.168.1.7
hello
<- msg some topic to ::ffff:192.168.1.7
-> msg data some topic from ::ffff:192.168.1.7
hello
<- msg some topic to ::ffff:192.168.1.7
-> msg data some topic from ::ffff:192.168.1.7
hello
<- msg some topic to ::ffff:192.168.1.7
-> msg data some topic from ::ffff:192.168.1.7
hello
<- msg some topic to ::ffff:192.168.1.7
-> msg data some topic from ::ffff:192.168.1.7
hello
<- msg some topic to ::ffff:192.168.1.7
-> msg data some topic from ::ffff:192.168.1.7
hello
<- msg some topic to ::ffff:192.168.1.7
-> msg data some topic from ::ffff:192.168.1.7
hello
<- msg some topic to ::ffff:192.168.1.7
-> msg data some topic from ::ffff:192.168.1.7
hello
<- msg some topic to ::ffff:192.168.1.7
-> msg data some topic from ::ffff:192.168.1.7
hello
<- msg some topic to ::ffff:192.168.1.7
-> msg data some topic from ::ffff:192.168.1.7
hello
<- msg some topic to ::ffff:192.168.1.7
-> msg data some topic from ::ffff:192.168.1.7
hello
<- msg some topic to ::ffff:192.168.1.7
-> msg data some topic from ::ffff:192.168.1.7
hello
<- msg some topic to ::ffff:192.168.1.7
-> msg data some topic from ::ffff:192.168.1.7
hello
<- msg some topic to ::ffff:192.168.1.7
-> msg data some topic from ::ffff:192.168.1.7
hello
peer-remove ::ffff:192.168.1.7
subscriber ::ffff:192.168.1.7 removed from topic some topic

(PC): (base) raphy@pc:~/hypercore/hyperswarm/hyperpubsub$ node simple_example_without_simulator.js no hyperspace server running, starting up a new one peer-add 192.168.1.9 <- sub some topic to 192.168.1.9 -> msg sub some topic from 192.168.1.9 subscriber 192.168.1.9 added to topic some topic -> msg sub some topic from 192.168.1.9 joined topic "some topic" (bce5935f9a6ade33d955c843f9b906e1b1fe769be6f1757fff6ca0f644506e42) <- sub some topic broadcast -> msg data some topic from 192.168.1.9 hello <- msg some topic to 192.168.1.9 -> msg data some topic from 192.168.1.9 hello <- msg some topic to 192.168.1.9 -> msg data some topic from 192.168.1.9 hello <- msg some topic to 192.168.1.9 -> msg data some topic from 192.168.1.9 hello <- msg some topic to 192.168.1.9 -> msg data some topic from 192.168.1.9 hello <- msg some topic to 192.168.1.9 -> msg data some topic from 192.168.1.9 hello <- msg some topic to 192.168.1.9 -> msg data some topic from 192.168.1.9 hello <- msg some topic to 192.168.1.9 -> msg data some topic from 192.168.1.9 hello <- msg some topic to 192.168.1.9 -> msg data some topic from 192.168.1.9 hello <- msg some topic to 192.168.1.9 -> msg data some topic from 192.168.1.9 hello <- msg some topic to 192.168.1.9 -> msg data some topic from 192.168.1.9 hello <- msg some topic to 192.168.1.9 -> msg data some topic from 192.168.1.9 hello <- msg some topic to 192.168.1.9 -> msg data some topic from 192.168.1.9 hello <- msg some topic to 192.168.1.9 -> msg data some topic from 192.168.1.9 hello <- msg some topic to 192.168.1.9 -> msg data some topic from 192.168.1.9 hello <- msg some topic to 192.168.1.9

So.... What am I doing wrongly and / or missing when using Private Messages ?

fsteff commented 3 years ago

In order to send private messages from one device to the other you need to somehow pass the public key of the recipient to the sender. This public key is 1) used to encrypt the message and 2) the topic is derived from it.

Also, subPrivateMsg does not have a topic parameter since the topic is derived from the public key. For debugging purposes I'd recommend not using the normal ('some topic' ) sub at all.

fsteff commented 3 years ago

For testing I'd recommend printing the public key as hex, copy pasting it to the other device and then parsing it using Buffer.from(value, 'hex').

raphael10-collab commented 3 years ago

I've tried in this way:

(PC) :

const {PubSub} = require('hyperpubsub').debug()
const {Server, Client} = require('hyperspace')
const sodium = require('sodium-universal')

async function setUpHyperspace() {
  let client, server
  try {
    client = new Client()
    await client.ready()
  } catch(e) {
    console.log('no hyperspace server running, starting up a new one')
    server = new Server()
    await server.ready()
    client = new Client()
    await client.ready()
  }
  return {client, server}
}

setUpHyperspace().then(({client}) => {

  const pubsub = new PubSub(client.network, {application: 'example app', onError: console.error})

  const publicKey = Buffer.alloc(sodium.crypto_box_PUBLICKEYBYTES)
  const secretKey = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES)
  sodium.crypto_box_keypair(publicKey, secretKey)

  console.log("publicKey: ", publicKey.toString("hex"))

  //pubsub.sub('some topic', (msg, app) => console.log(msg.toString('utf-8')), true) // messages are binary blobs
  //pubsub.sub('some topic', (chipheredmsg, app) => console.log(pubsub.privateMsgOpen(chipheredmsg, publicKey, secretKey).toString('utf-8')), true)

  pubsub.subPrivateMsg(publicKey, secretKey, (cipheredmsg) => {
   //console.log(msg.toString('utf-8'))
    let msg = pubsub.privateMsgOpen(chipheredmsg, publicKey, secretKey)
    console.log(msg.toString('utf-8'))
  })

  setInterval(send, 1000)
  function send() {
      //pubsub.pub('some topic', Buffer.from('hello', 'utf-8'))
      pubsub.pubPrivateMsg(publicKey, Buffer.from('hello', 'utf-8'))
  }
})

Executing :

(base) raphy@pc:~/hypercore/automerge/react-automerge-demo/src/lib$ ts-node simple_example_no_simulator_private.js 
no hyperspace server running, starting up a new one
publicKey:  fbc0bf280258f07bd18166e65380c5e450555cd279b2a297df7549969def3a73
joined topic "c86f84c52ef28719d35c02085cf7c7d22503d59bb6bb95bd04a5e16eed3ea260" (3bcb1949e456211ee45066487995df02a997ebcac0940607b2dd0d1e6943d9db)
<- sub c86f84c52ef28719d35c02085cf7c7d22503d59bb6bb95bd04a5e16eed3ea260 broadcast

(laptop) :

const {PubSub} = require('hyperpubsub').debug()
const {Server, Client} = require('hyperspace')
const sodium = require('sodium-universal')

async function setUpHyperspace() {

  let client, server   try {     client = new Client()     await client.ready()   } catch(e) {     console.log('no hyperspace server running, starting up a new one')     server = new Server()     await server.ready()     client = new Client()     await client.ready()   }   return {client, server} }

setUpHyperspace().then(({client}) => {

  const pubsub = new PubSub(client.network, {application: 'example app', onError: console.error})

  //const publicKey = Buffer.alloc(sodium.crypto_box_PUBLICKEYBYTES)   const publicKey = Buffer.from("fbc0bf280258f07bd18166e65380c5e450555cd279b2a297df7549969def3a73", "hex")   const secretKey = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES)   sodium.crypto_box_keypair(publicKey, secretKey)

  //pubsub.sub('some topic', (msg, app) => console.log(msg.toString('utf-8')), true) // messages are binary blobs   //pubsub.sub('some topic', (chipheredmsg, app) => console.log(pubsub.privateMsgOpen(chipheredmsg, publicKey, secretKey).toString('utf-8')), true)

  pubsub.subPrivateMsg(publicKey, secretKey, (cipheredmsg) => {     //console.log(msg.toString('utf-8'))     let msg = pubsub.privateMsgOpen(chipheredmsg, publicKey, secretKey)     console.log(msg.toString('utf-8'))   })

  setInterval(send, 1000)   function send() {       //pubsub.pub('some topic', Buffer.from('hello', 'utf-8'))       pubsub.pubPrivateMsg(publicKey, Buffer.from('hello', 'utf-8'))   } })

Executing on the laptop:

(base) marco@marco-U36SG:~/hypercore/hyperswarm/hyperpubsub$ node simple_example_no_simulator_private.js
no hyperspace server running, starting up a new one
joined topic "6759911790d54a5c1818cf924a56ea2efcf0f91f3004a2eaff28ed5a67491568" (1a1ddc083af8600b69000ca4ec67f030729e099133fc90d2b0b4c543edb372b4)
<- sub 6759911790d54a5c1818cf924a56ea2efcf0f91f3004a2eaff28ed5a67491568 broadcast

But I do not see any messages exchanged

fsteff commented 3 years ago

You can see the topic is a different one. Use joinPublicKey to connect to a peer that listens using subPrivateMsg. And don't mix to keypairs, that won't work. In your example the first device should only listen and the second only sends.

fsteff commented 3 years ago

If I find some time I'll publish a working example, but that likely will not be earlier than the end of the next week.

raphael10-collab commented 3 years ago

I tried also like this:

(PC: sender) :

const {PubSub} = require('hyperpubsub').debug()
const {Server, Client} = require('hyperspace')
const sodium = require('sodium-universal')

async function setUpHyperspace() {
  let client, server
  try {
    client = new Client()
    await client.ready()
  } catch(e) {
    console.log('no hyperspace server running, starting up a new one')
    server = new Server()
    await server.ready()
    client = new Client()
    await client.ready()
  }
  return {client, server}
}

setUpHyperspace().then(({client}) => {

  const pubsub = new PubSub(client.network, {application: 'example app', onError: console.error})

  const publicKey = Buffer.alloc(sodium.crypto_box_PUBLICKEYBYTES)
  const secretKey = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES)

  sodium.crypto_box_keypair(publicKey, secretKey)

  console.log("publicKey: ", publicKey.toString("hex"))

  pubsub.joinPublicKey(publicKey)    

  setInterval(send, 1000)
  function send() {
      pubsub.pubPrivateMsg(publicKey, Buffer.from('hello', 'utf-8'))

  }
})

(laptop: the listener) :

const {PubSub} = require('hyperpubsub').debug()
const {Server, Client} = require('hyperspace')
const sodium = require('sodium-universal')

async function setUpHyperspace() {

  let client, server   try {     client = new Client()     await client.ready()   } catch(e) {     console.log('no hyperspace server running, starting up a new one')     server = new Server()     await server.ready()     client = new Client()     await client.ready()   }   return {client, server} }

setUpHyperspace().then(({client}) => {

  const pubsub = new PubSub(client.network, {application: 'example app', onError: console.error})

  //const publicKey = Buffer.alloc(sodium.crypto_box_PUBLICKEYBYTES)   const publicKey = Buffer.from("7d5b31bcb46e5a4769da00148dfce95d8c6dd449b8fadbe6c35e1edc7752997a", "hex")   const secretKey = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES)   sodium.crypto_box_keypair(publicKey, secretKey)

  pubsub.joinPublicKey(publicKey)

  pubsub.subPrivateMsg(publicKey, secretKey, (cipheredmsg) => {     let msg = pubsub.privateMsgOpen(chipheredmsg, publicKey, secretKey)     console.log(msg.toString('utf-8'))   })

})

Executing :
(PC: the sender) :

(base) raphy@pc:~/hypercore/hyperswarm/hyperpubsub$ node simple_example_no_simulator_private.js 
no hyperspace server running, starting up a new one
publicKey:  7d5b31bcb46e5a4769da00148dfce95d8c6dd449b8fadbe6c35e1edc7752997a
joined topic "4ebf239a3f382c714067354bf19a9bfac8c8bf6b84e4c8ea31cb3a2a23056902" (73bc849ac10167b513099a0bf9aab0beaaa27ec43d5c92f5178f20716d7bd6f1)

(laptop: the listener):

  (base) marco@marco-U36SG:~/hypercore/hyperswarm/hyperpubsub$ node simple_example_no_simulator_private.js 
  no hyperspace server running, starting up a new one
  joined topic "e54f003c906e438c7deb044aa813a4d4669a7b06f91b1e186db66f6148adb509" (6fa044f4f5086ff40730df3bc21b61038fdd6a2504cf4d95b6e81aa97bdc3227)
  joined topic "e54f003c906e438c7deb044aa813a4d4669a7b06f91b1e186db66f6148adb509" (6fa044f4f5086ff40730df3bc21b61038fdd6a2504cf4d95b6e81aa97bdc3227)
  <- sub e54f003c906e438c7deb044aa813a4d4669a7b06f91b1e186db66f6148adb509 broadcast

Still the topic is different from the sender's topic

fsteff commented 3 years ago

@raphael10-collab I've added an example for private messages Also, in case you're using the hyperspace version I've set in the dev dependencies, make sure to check out the latest version of hyperspace (run npm update). It uses hyperswarm v3 (beta), which yesterday made a breaking change in the testnet(!).