github.com/jincm/wesharechain@v0.0.0-20210122032815-1537409ce26a/chain/swarm/pss/README.md (about) 1 # Postal Services over Swarm 2 3 `pss` enables message relay over swarm. This means nodes can send messages to each other without being directly connected with each other, while taking advantage of the efficient routing algorithms that swarm uses for transporting and storing data. 4 5 ### CONTENTS 6 7 * Status of this document 8 * Core concepts 9 * Caveat 10 * Examples 11 * API 12 * Retrieve node information 13 * Receive messages 14 * Send messages using public key encryption 15 * Send messages using symmetric encryption 16 * Querying peer keys 17 * Handshakes 18 19 ### STATUS OF THIS DOCUMENT 20 21 `pss` is under active development, and the first implementation is yet to be merged to the Ethereum main branch. Expect things to change. 22 23 Details on swarm routing and encryption schemes out of scope of this document. 24 25 Please refer to [ARCHITECTURE.md](ARCHITECTURE.md) for in-depth topics concerning `pss`. 26 27 ## CORE CONCEPTS 28 29 Three things are required to send a `pss` message: 30 31 1. Encryption key 32 2. Topic 33 3. Message payload 34 35 Encryption key can be a public key or a 32 byte symmetric key. It must be coupled with a peer address in the node prior to sending. 36 37 Topic is the initial 4 bytes of a hash value. 38 39 Message payload is an arbitrary byte slice of data. 40 41 Upon sending the message it is encrypted and passed on from peer to peer. Any node along the route that can successfully decrypt the message is regarded as a recipient. Recipients continue to pass on the message to their peers, to make traffic analysis attacks more difficult. 42 43 The Address that is coupled with the encryption keys are used for routing the message. This does *not* need to be a full addresses; the network will route the message to the best of its ability with the information that is available. If *no* address is given (zero-length byte slice), routing is effectively deactivated, and the message is passed to all peers by all peers. 44 45 ## CAVEAT 46 47 `pss` connectivity resembles UDP. This means there is no delivery guarantee for a message. Furthermore there is no strict definition of what a connection between two nodes communicating via `pss` is. Reception acknowledgements and keepalive-schemes is the responsibility of the application. 48 49 Due to the inherent properties of the `swarm` routing algorithm, a node may receive the same message more than once. Message deduplication *cannot be guaranteed* by `pss`, and must be handled in the application layer to ensure predictable results. 50 51 ## EXAMPLES 52 53 The code tutorial [p2p programming in go-ethereum](https://github.com/nolash/go-ethereum-p2p-demo) by [@nolash](https://github.com/nolash) provides step-by-step code examples for usage of `pss` API with `go-ethereum` nodes. 54 55 A quite unpolished example using `javascript` is available here: [https://github.com/nolash/pss-js/tree/withcrypt](https://github.com/nolash/pss-js/tree/withcrypt) 56 57 ## API 58 59 The `pss` API is available through IPC and Websockets. There is currently no `web3.js` implementation, as this does not support message subscription. 60 61 For `golang` clients, please use the `rpc.Client` provided by the `go-ethereum` repository. The return values may have special types in `golang`. Please refer to `godoc` for details. 62 63 ### RETRIEVE NODE INFORMATION 64 65 #### pss_getPublicKey 66 67 Retrieves the public key of the node, in hex format 68 69 ``` 70 parameters: 71 none 72 73 returns: 74 1. publickey (hex) 75 ``` 76 77 #### pss_baseAddr 78 79 Retrieves the swarm overlay address of the node, in hex format 80 81 ``` 82 parameters: 83 none 84 85 returns: 86 1. swarm overlay address (hex) 87 ``` 88 89 #### pss_stringToTopic 90 91 Creates a deterministic 4 byte topic value from input, returned in hex format 92 93 ``` 94 parameters: 95 1. topic string (string) 96 97 returns: 98 1. pss topic (hex) 99 ``` 100 101 ### RECEIVE MESSAGES 102 103 #### pss_subscribe 104 105 Creates a subscription. Received messages with matching topic will be passed to subscription client. 106 107 ``` 108 parameters: 109 1. string("receive") 110 2. topic (4 bytes in hex) 111 112 returns: 113 1. subscription handle `base64(byte)` `rpc.ClientSubscription` 114 ``` 115 116 In `golang` as special method is used: 117 118 `rpc.Client.Subscribe(context.Context, "pss", chan pss.APIMsg, "receive", pss.Topic)` 119 120 Incoming messages are encapsulated in an object (`pss.APIMsg` in `golang`) with the following members: 121 122 ``` 123 1. Msg (hex) - the message payload 124 2. Asymmetric (bool) - true if message used public key encryption 125 3. Key (string) - the encryption key used 126 ``` 127 128 ### SEND MESSAGE USING PUBLIC KEY ENCRYPTION 129 130 #### pss_setPeerPublicKey 131 132 Register a peer's public key. This is done once for every topic that will be used with the peer. Address can be anything from 0 to 32 bytes inclusive of the peer's swarm overlay address. 133 134 ``` 135 parameters: 136 1. public key of peer (hex) 137 2. topic (4 bytes in hex) 138 3. address of peer (hex) 139 140 returns: 141 none 142 ``` 143 144 #### pss_sendAsym 145 146 Encrypts the message using the provided public key, and signs it using the node's private key. It then wraps it in an envelope containing the topic, and sends it to the network. 147 148 ``` 149 parameters: 150 1. public key of peer (hex) 151 2. topic (4 bytes in hex) 152 3. message (hex) 153 154 returns: 155 none 156 ``` 157 158 ### SEND MESSAGE USING SYMMETRIC ENCRYPTION 159 160 #### pss_setSymmetricKey 161 162 Register a symmetric key shared with a peer. This is done once for every topic that will be used with the peer. Address can be anything from 0 to 32 bytes inclusive of the peer's swarm overlay address. 163 164 If the fourth parameter is false, the key will *not* be added to the list of symmetric keys used for decryption attempts. 165 166 ``` 167 parameters: 168 1. symmetric key (hex) 169 2. topic (4 bytes in hex) 170 3. address of peer (hex) 171 4. use for decryption (bool) 172 173 returns: 174 1. symmetric key id (string) 175 ``` 176 177 #### pss_sendSym 178 179 Encrypts the message using the provided symmetric key, wraps it in an envelope containing the topic, and sends it to the network. 180 181 ``` 182 parameters: 183 1. symmetric key id (string) 184 2. topic (4 bytes in hex) 185 3. message (hex) 186 187 returns: 188 none 189 ``` 190 191 ### QUERY PEER KEYS 192 193 #### pss_GetSymmetricAddressHint 194 195 Return the swarm overlay address associated with the peer registered with the given symmetric key and topic combination. 196 197 ``` 198 parameters: 199 1. topic (4 bytes in hex) 200 2. symmetric key id (string) 201 202 returns: 203 1. peer address (hex) 204 ``` 205 206 #### pss_GetAsymmetricAddressHint 207 208 Return the swarm overlay address associated with the peer registered with the given symmetric key and topic combination. 209 210 ``` 211 parameters: 212 1. topic (4 bytes in hex) 213 2. public key in hex form (string) 214 215 returns: 216 1. peer address (hex) 217 ``` 218 219 ### HANDSHAKES 220 221 Convenience implementation of Diffie-Hellman handshakes using ephemeral symmetric keys. Peers keep separate sets of keys for incoming and outgoing communications. 222 223 *This functionality is an optional feature in `pss`. It is compiled in by default, but can be omitted by providing the `nopsshandshake` build tag.* 224 225 #### pss_addHandshake 226 227 Activate handshake functionality on the specified topic. 228 229 ``` 230 parameters: 231 1. topic (4 bytes in hex) 232 233 returns: 234 none 235 ``` 236 237 #### pss_removeHandshake 238 239 Remove handshake functionality on the specified topic. 240 241 ``` 242 parameters: 243 1. topic (4 bytes in hex) 244 245 returns: 246 none 247 ``` 248 249 #### pss_handshake 250 251 Instantiate handshake with peer, refreshing symmetric encryption keys. 252 253 If parameter 3 is false, the returned array will be empty. 254 255 ``` 256 parameters: 257 1. public key of peer in hex format (string) 258 2. topic (4 bytes in hex) 259 3. block calls until keys are received (bool) 260 4. flush existing incoming keys (bool) 261 262 returns: 263 1. list of symmetric keys (string[]) 264 ``` 265 266 #### pss_getHandshakeKeys 267 268 Get valid symmetric encryption keys for a specified peer and topic. 269 270 parameters: 271 1. public key of peer in hex format (string) 272 2. topic (4 bytes in hex) 273 3. include keys for incoming messages (bool) 274 4. include keys for outgoing messages (bool) 275 276 returns: 277 1. list of symmetric keys (string[]) 278 279 #### pss_getHandshakeKeyCapacity 280 281 Get amount of remaining messages the specified key is valid for. 282 283 ``` 284 parameters: 285 1. symmetric key id (string) 286 287 returns: 288 1. number of messages (uint16) 289 ``` 290 291 #### pss_getHandshakePublicKey 292 293 Get the peer's public key associated with the specified symmetric key. 294 295 ``` 296 parameters: 297 1. symmetric key id (string) 298 299 returns: 300 1. Associated public key in hex format (string) 301 ``` 302 303 #### pss_releaseHandshakeKey 304 305 Invalidate the specified key. 306 307 Normally, the key will be kept for a grace period to allow for decryption of delayed messages. If instant removal is set, this grace period is omitted, and the key removed instantaneously. 308 309 ``` 310 parameters: 311 1. public key of peer in hex format (string) 312 2. topic (4 bytes in hex) 313 3. symmetric key id to release (string) 314 4. remove keys instantly (bool) 315 316 returns: 317 1. whether key was successfully removed (bool) 318 ```