git ssb

2+

cel / scuttlebot.io



Commit 286c5a13bb466f90d3f96a763984132a5e818755

add protocol guides

Paul Frazee committed on 3/17/2016, 12:32:12 AM
Parent: 254c89b83aef67583e5b1b6f6cd5fdba4fb0b493

Files changed

tmpl/docs/advanced/links.mdchanged
tmpl/docs/advanced/advanced-queries.mddeleted
tmpl/guides/concepts/private-box.html.jsdeleted
tmpl/guides/concepts/secret-handshake.html.jsdeleted
tmpl/guides/concepts/secure-scuttlebutt.html.jsdeleted
tmpl/guides/concepts/shs.pdfdeleted
tmpl/guides/concepts/social.html.jsdeleted
tmpl/guides/protocols/private-box.html.jsadded
tmpl/guides/protocols/secret-handshake.html.jsadded
tmpl/guides/protocols/secure-scuttlebutt.html.jsadded
tmpl/guides/protocols/shs.pdfadded
tmpl/guides/protocols/social.html.jsadded
tmpl/index.html.jschanged
tmpl/leftnav.part.jschanged
tmpl/tabs.part.jschanged
tmpl/docs/advanced/links.mdView
@@ -1,5 +1,5 @@
1-# Content-Hash Linking
1+## Content-Hash Linking
22
33 Messages, feeds, and blobs are addressable by specially-formatted identifiers.
44 Message and blob IDs are content-hashes, while feed IDs are public keys.
55
tmpl/docs/advanced/advanced-queries.mdView
@@ -1,19 +1,0 @@
1-## About-user messages
2-
3-```js
4-var pull = require('pull-stream')
5-pull(
6- sbot.links({ dest: userId, rel: 'about', values: true }),
7- pull.collect(function (err, msgs) { ... })
8-)
9-```
10-```bash
11-sbot links --dest {userId} --rel about --values
12-```
13-
14-[About messages](/docs/message-types/about.html) put their name & image attributes outside of the link, so we need `links` to fetch the full message-value.
15-That's why `values: true` is set.
16-
17-[→ links API](/apis/scuttlebot/ssb.html#links-source)
18-
19-
tmpl/guides/concepts/private-box.html.jsView
@@ -1,190 +1,0 @@
1-var page = require('../../page.part')
2-var com = require('../../com.part')
3-
4-module.exports = () => page({
5- section: 'guides',
6- tab: 'guides-concepts',
7- path: '/protocols/private-box.html',
8- content: `
9- <h2>Private Box</h2>
10- <p>
11- Private-box is a format for encrypting a private message to many parties.
12- You can <strong><a href="https://github.com/auditdrivencrypto/private-box">find the repository on GitHub</a></strong>.
13- </p>
14-
15- <h2 id="properties">Properties</h2>
16- <p>
17- This protocol was designed for use with secure-scuttlebutt.
18- In this place, messages are placed in public, and the sender is known via a signature,
19- but we can hide the recipient and the content.
20- </p>
21-
22- <h4 id="-recipients-are-hidden-">Recipients are hidden.</h4>
23- <p>
24- An eaves-dropper cannot know the recipients or their number.
25- Since the message is encrypted to each recipient, and then placed in public,
26- to receive a message you will have to decrypt every message posted.
27- This would not be scalable if you had to decrypt every message on the internet,
28- but if you can restrict the number of messages you might have to decrypt,
29- then it&#39;s reasonable. For example, if you frequented a forum which contained these messages,
30- then it would only be a reasonable number of messages, and posting a message would only
31- reveal that you where talking to some other member of that forum.
32- </p>
33- <p>Hiding access to such a forum is another problem that&#39;s out of the current scope.</p>
34-
35- <h4 id="-the-number-of-recipients-are-hidden-">The number of recipients are hidden.</h4>
36- <p>
37- If the number of recipients was not hidden, then sometimes it would be possible
38- to deanonymise the recipients, if there was a large group discussion with
39- an unusual number of recipients. Encrypting the number of recipients means that,
40- when a message is not encrypted to you, you will attempt to decrypt same number of times
41- as the maximum recipients.
42- </p>
43-
44- <h4 id="-a-valid-recipient-does-not-know-the-other-recipients-">A valid recipient does not know the other recipients.</h4>
45- <p>
46- A valid recipient knows the number of recipients but now who they are.
47- This is more a sideeffect of the design than an intentional design element.
48- The plaintext contents may reveal the recipients, if needed.
49- </p>
50-
51- <h4 id="-by-providing-the-key-for-a-message-an-outside-party-could-decrypt-the-message-">By providing the key for a message, an outside party could decrypt the message.</h4>
52- <p>
53- When you tell someone a secret you must trust them not to reveal it.
54- Anyone who knows the key could reveal that to some other party who could then read the message content,
55- but not the recipients (unless the sender revealed the ephemeral secret key).
56- </p>
57-
58- <h2 id="assumptions">Assumptions</h2>
59- <p>
60- Messages will be posted in public, so that the sender is likely to be known,
61- and everyone can read the messages. (This makes it possible to hide the recipient,
62- but probably not the sender.)
63- </p>
64- <p>Resisting traffic analysis of the timing or size of messages is out of scope of this spec.</p>
65-
66- <h2 id="prior-art">Prior Art</h2>
67- <h4 id="-pgp-">PGP</h4>
68- <p>
69- In PGP the recipient, the sender, and the subject are sent as plaintext.
70- If the recipient is known, then the metadata graph of who is communicating with who can be read,
71- which, since it is easier to analyze than the content, is important to protect.
72- </p>
73- <h4 id="-sodium-seal-">Sodium seal</h4>
74- <p>
75- The Sodium library provides a <em>seal</em> function that generates an ephemeral keypair,
76- derives a shared key to encrypt a message, and then sends the ephemeral public key and the message.
77- The recipient is hidden, and it is forward secure if the sender throws out the ephemeral key.
78- However, it&#39;s only possible to have one recipient.
79- </p>
80-
81- <h4 id="-minilock-">Minilock</h4>
82- <p>
83- Minilock uses a similar approach to <code>private-box</code> but does not hide the
84- number of recipients. In the case of a group discussion where multiple rounds
85- of messages are sent to everyone, this may enable an eavesdropper to deanonymize
86- the participiants of a discussion if the sender of each message is known.
87- </p>
88-
89- <h2 id="api">API</h2>
90-
91- <h4 id="-encrypt-plaintext-buffer-recipients-array-curve25519_pk-">encrypt (plaintext Buffer, recipients Array<curve25519_pk>)</h4>
92- <p>
93- Takes a plaintext buffer of the message you want to encrypt,
94- and an array of recipient public keys.
95- Returns a message that is encrypted to all recipients
96- and openable by them with <code>PrivateBox.decrypt</code>.
97- The recipients must be between 1 and 7 items long.
98- </p>
99- <p>
100- The encrypted length will be <code>56 + (recipients.length * 33) + plaintext.length</code> bytes long,
101- between 89 and 287 bytes longer than the plaintext.
102- </p>
103-
104- <h4 id="-decrypt-cyphertext-buffer-secretkey-curve25519_sk-">decrypt (cyphertext Buffer, secretKey curve25519_sk)</h4>
105- <p>
106- Attempt to decrypt a private-box message, using your secret key.
107- If you where an intended recipient then the plaintext will be returned.
108- If it was not for you, then <code>undefined</code> will be returned.
109- </p>
110-
111- <h2 id="protocol">Protocol</h2>
112- <h4 id="-encryption-">Encryption</h4>
113- <p>Private-box generates:</p>
114- <ul>
115- <li><code>ephemeral</code>: an ephemeral curve25519 keypair that will only be used with this message.</li>
116- <li><code>body_key</code>: a random key that will be used to encrypt the plaintext body.</li>
117- </ul>
118- <p>
119- First, private-box outputs the ephemeral public key, then multiplies each recipient public key
120- with its secret to produce ephemeral shared keys (<code>shared_keys[1..n]</code>).
121- Then, private-box concatenates <code>body_key</code> with the number of recipients,
122- encrypts that to each shared key, and concatenates the encrypted body.
123- </p>
124- ${ com.code({ js: `
125-function encrypt (plaintext, recipients) {
126- var ephemeral = keypair()
127- var nonce = random(24)
128- var body_key = random(32)
129- var body_key_with_length = concat([
130- body_key,
131- recipients.length
132- ])
133- return concat([
134- nonce,
135- ephemeral.publicKey,
136- concat(recipients.map(function (publicKey) {
137- return secretbox(
138- body_key_with_length,
139- nonce,
140- scalarmult(publicKey, ephemeral.secretKey)
141- )
142- }),
143- secretbox(plaintext, nonce, body_key)
144- ])
145-}` }) }
146-
147- <h4 id="-decryption-">Decryption</h4>
148- <p>
149- <code>private-box</code> takes the nonce and ephemeral public key,
150- multiplies that with your secret key, then tests each possible
151- recipient slot until it either decrypts a key or runs out of slots.
152- If it runs out of slots, the message was not addressed to you,
153- so <code>undefined</code> is returned. Else, the message is found and the body
154- is decrypted.
155- </p>
156- ${ com.code({ js: `
157-function decrypt (cyphertext, secretKey) {
158- var next = reader(cyphertext) // next() will read
159- // the passed N bytes
160- var nonce = next(24)
161- var publicKey = next(32)
162- var sharedKey = salarmult(publicKey, secretKey)
163-
164- for(var i = 0; i &lt; 7; i++) {
165- var maybe_key = next(33)
166- var key_with_length = secretbox_open(
167- maybe_key,
168- nonce,
169- sharedKey
170- )
171- if (key_with_length) { // decrypted!
172- var key = key_with_length.slice(0, 32)
173- var length = key_with_length[32]
174- return secretbox_open(
175- key,
176- cyphertext.slice(
177- 56 + 33*(length+1),
178- cyphertext.length
179- ),
180- )
181- }
182- }
183- // this message was not addressed
184- // to the owner of secretKey
185- return undefined
186-}` }) }
187-
188- <p class="next"><a href="/modules/ssb-client.html">SSB-Client</a></p>
189- `
190-})
tmpl/guides/concepts/secret-handshake.html.jsView
@@ -1,16 +1,0 @@
1-var page = require('../../page.part')
2-module.exports = () => page({
3- section: 'docs',
4- tab: 'guides-concepts',
5- path: '/protocols/secret-handshake.html',
6- content: `
7- <h2>Secret Handshake</h1>
8- <p>
9- Secret Handshake is an encrypted channel protocol based on a mutually authenticating key agreement handshake, with forward secure identity metadata.
10- It&#39;s used by Scuttlebot to authenticate and encrypt peer connections.
11- </p>
12- <p><a href="/protocols/shs.pdf">Read the White Paper</a></p>
13-
14- <p class="next"><a href="/protocols/private-box.html">Private Box</a></p>
15- `
16-})
tmpl/guides/concepts/secure-scuttlebutt.html.jsView
@@ -1,150 +1,0 @@
1-var page = require('../../page.part')
2-var com = require('../../com.part')
3-
4-module.exports = () => page({
5- section: 'docs',
6- tab: 'guides-concepts',
7- path: '/protocols/secure-scuttlebutt.html',
8- content: `
9- <h2>Secure Scuttlebutt</h2>
10- <p>Secure Scuttlebutt is a database protocol for unforgeable append-only message feeds.</p>
11- <p>
12- &quot;Unforgeable&quot; means that only the owner of a feed can update that feed, as enforced by digital signing (see <a href="#security-properties">Security properties</a>).
13- This property makes Secure Scuttlebutt useful for peer-to-peer applications.
14- Secure Scuttlebutt also makes it easy to encrypt messages.
15- </p>
16-
17- <hr>
18-
19- <h2 id="concepts">Concepts</h2>
20- <p>Building upon Secure Scuttlebutt requires understanding a few concepts that it uses to ensure the unforgeability of message feeds.</p>
21-
22- <h3 id="identities">Identities</h3>
23- <p>
24- An identity is simply a <a href="http://ed25519.cr.yp.to/">ed25519 key pair</a>.
25- The public key is used as the identifier.
26- </p>
27- <p>
28- There is no worldwide store of identities.
29- Users must exchange pubkeys, either by publishing them on their feeds, or out-of-band.
30- </p>
31-
32- <h3 id="feeds">Feeds</h3>
33- <p>
34- A feed is a signed append-only sequence of messages.
35- Each identity has exactly one feed.
36- </p>
37- <p>
38- Note that append-only means you cannot delete an existing message, or change your history.
39- This is enforced by a per-feed blockchain.
40- This is to ensure the entire network converges on the same state.
41- </p>
42-
43- <h3 id="messages">Messages</h3>
44- <p>Each message contains:</p>
45- <ul>
46- <li>A signature</li>
47- <li>The signing public key</li>
48- <li>A content-hash of the previous message</li>
49- <li>A sequence number</li>
50- <li>A timestamp</li>
51- <li>An identifier of the hashing algorithm in use (currently only &quot;sha256&quot; is supported)</li>
52- <li>A content object</li>
53- </ul>
54- <p>Here&#39;s an example message:</p>
55- ${ com.code({ js: `{
56- "previous": "%26AC+gU0t74jRGVeDY01...MnutGGHM=.sha256",
57- "author": "@hxGxqPrplLjRG2vtjQL87...0nNwE=.ed25519",
58- "sequence": 216,
59- "timestamp": 1442590513298,
60- "hash": "sha256",
61- "content": {
62- "type": "vote",
63- "vote": {
64- "link": "%WbQ4dq0m/zu5jxll9zUb...KjZ80JvI=.sha256",
65- "value": 1
66- }
67- },
68- "signature": "Sjq1C3yiKdmi1TWvNqxI...gmAQ==.sig.ed25519"
69-}` }) }
70-
71- <h3 id="entity-references-links-">Entity References (Links)</h3>
72- <p>
73- Messages can reference three types of Secure Scuttlebutt entities: messages, feeds, and blobs (i.e. files).
74- Messages and blobs are referred to by their hashes, but a feed is referred to by its signing public key.
75- </p>
76-
77- <h3 id="confidentiality">Confidentiality</h3>
78- <p>
79- For private sharing, Scuttlebot uses <a href="http://doc.libsodium.org/">libsodium</a> to encrypt confidential log-entries.
80- Feed IDs are public keys, and so once two feeds are mutually following each other, they can exchange confidential data freely.
81- </p>
82-
83- <h3 id="following">Following</h3>
84- <p>
85- Users choose which feeds to synchronize by following them.
86- Presently, <a href="/modules/scuttlebot-replicate.html">Scuttlebot&#39;s replicate plugin</a>, which is enabled by default, looks on the master user&#39;s feed for <code>type:contact</code> messages to know which users are currently followed.
87- </p>
88-
89- <h3 id="replication">Replication</h3>
90- <p>
91- Since feeds are append-only, replication is simple: request all messages in the feed that are newer than the latest message you know about.
92- Scuttlebot maintains a table of known peers, which it cycles through, asking for updates for all followed feeds.
93- </p>
94-
95- <h3 id="gossip">Gossip</h3>
96- <p>
97- The protocol creates a <a href="https://en.wikipedia.org/wiki/Gossip_protocol">global gossip network</a>.
98- This means that information is able to distribute across multiple machines, without requiring direct connections between them.
99- </p>
100- <p><img src="/img/gossip-graph1.png" alt="Gossip graph"></p>
101- <p>Even though Alice and Dan lack a direct connection, they can still exchange feeds:</p>
102- <p><img src="/img/gossip-graph2.png" alt="Gossip graph 2"></p>
103- <p>
104- This is because gossip creates &quot;transitive&quot; connections between computers.
105- Dan&#39;s messages travel through Carla and the Pub to reach Alice, and visa-versa.
106- </p>
107-
108- <h3 id="lan-connectivity">LAN connectivity</h3>
109- <p>
110- SSB is hostless: each computer installs the same copy of software and has equal rights in the network.
111- Devices discover each other over the LAN with multicast UDP and sync automatically.
112- </p>
113-
114- <h3 id="pub-servers">Pub Servers</h3>
115- <p>
116- To sync across the Internet, &quot;Pub&quot; nodes run at public IPs and follow users.
117- They are essentially mail-bots which improve uptime and availability.
118- Users generate invite-codes to command Pubs to follow their friends.
119- The Scuttlebot community runs some Pubs, and anybody can create and introduce their own.
120- </p>
121-
122- <h2 id="security-properties">Security properties</h2>
123- <p>
124- Secure Scuttlebutt maintains useful security properties even when it is connected to a malicious Secure Scuttlebutt database.
125- This makes it ideal as a store for peer-to-peer applications.
126- </p>
127- <p>
128- Imagine that we want to read from a feed for which we know the identity, but we&#39;re connected to a malicious Secure Scuttlebutt instance.
129- As long as the malicious database does not have the private key:
130- </p>
131- <ul>
132- <li>The malicious database cannot create a new feed with the same identifier</li>
133- <li>The malicious database cannot write new fake messages to the feed</li>
134- <li>The malicious database cannot reorder the messages in the feed</li>
135- <li>The malicious database cannot send us a new copy of the feed that omits messages from the middle</li>
136- <li>The malicious database <em>can</em> refuse to send us the feed, or only send us the first <em>N</em> messages in the feed</li>
137- <li>Messages may optionally be encrypted</li>
138- </ul>
139- <p>
140- Additionally there is a protection from the feed owner, through the blockchain.
141- The <code>previous</code> content-hash them from changing the feed history after publishing, as a newly-created message wouldn&#39;t match the hash of later messages which were already replicated.
142- This ensures the append-only constraint, and thus safe network convergence.
143- </p>
144-
145- <p class="next"><a href="/protocols/secret-handshake.html">Secret Handshake</a></p>
146- <ul class="see-also">
147- <li><a href="/docs/social/social-network.html">Social Network</a></li>
148- </ul>
149- `
150-})
tmpl/guides/concepts/shs.pdfView
The diff is too large to show. Use a local git client to view these changes.
Old file size: 219079 bytes
New file size: 0 bytes
tmpl/guides/concepts/social.html.jsView
@@ -1,47 +1,0 @@
1-var page = require('../../page.part')
2-module.exports = () => page({
3- section: 'docs',
4- tab: 'guides-concepts',
5- path: '/social/social-network.html',
6- content: `
7- <h2>Social network</h2>
8- <p>
9- Scuttlebot forms a global cryptographic social network with its peers.
10- Each user is identified by a public key, and publishes a log of signed messages, which other users "follow."
11- </p>
12- <p>
13- Scuttlebot searches the P2P mesh for new messages and files from followed users and from FoaFs.
14- The messages and files are stored locally, indefinitely, for applications to read.
15- </p>
16-
17- <h3>Identity</h3>
18- <p>
19- Users are identified by confirmations in the social graph.
20- This is known as a Web-of-Trust.
21- There is no global registry of usernames.
22- Instead, users name themselves, and share petnames for each other.
23- </p>
24- <p>
25- Discovery occurs by examining the social graph, or by out-of-band sharing.
26- Applications can analyze the follow-graph, and look for "flag" messages, to determine who is trust-worthy in the network.
27- </p>
28-
29- <h3>Pub Servers</h3>
30- <p>
31- "Pubs" are bot-users that have public IPs.
32- They follow users and rehost the messages to other peers, ensuring good uptime and no firewall blockage.
33- </p>
34- <p>
35- Pubs have no special privileges, and are not trusted by users.
36- However, because Scuttlebot has no DHT or NAT-traversal utilities, users must "join" a Pub to distribute their messages on the WAN.
37- </p>
38- <p>
39- Scuttlebot can change Pubs, or join more than one, and sync directly over Wifi.
40- Identity is not tied to the Pubs.
41- </p>
42- <p class="next"><a href="/docs/social/follow-users.html">Follow users</a></p>
43- <ul class="see-also">
44- <li><a href="/whitepapers/secure-scuttlebutt.html">Secure Scuttlebutt</a></li>
45- </ul>
46- `
47-})
tmpl/guides/protocols/private-box.html.jsView
@@ -1,0 +1,188 @@
1+var page = require('../../page.part')
2+var com = require('../../com.part')
3+
4+module.exports = () => page({
5+ section: 'guides',
6+ tab: 'guides-protocols',
7+ path: '/guides/protocols/private-box.html',
8+ content: `
9+ <h2>Private Box</h2>
10+ <p>
11+ Private-box is a format for encrypting a private message to many parties.
12+ You can <strong><a href="https://github.com/auditdrivencrypto/private-box">find the repository on GitHub</a></strong>.
13+ </p>
14+
15+ <h2 id="properties">Properties</h2>
16+ <p>
17+ This protocol was designed for use with secure-scuttlebutt.
18+ In this place, messages are placed in public, and the sender is known via a signature,
19+ but we can hide the recipient and the content.
20+ </p>
21+
22+ <h4 id="-recipients-are-hidden-">Recipients are hidden.</h4>
23+ <p>
24+ An eaves-dropper cannot know the recipients or their number.
25+ Since the message is encrypted to each recipient, and then placed in public,
26+ to receive a message you will have to decrypt every message posted.
27+ This would not be scalable if you had to decrypt every message on the internet,
28+ but if you can restrict the number of messages you might have to decrypt,
29+ then it&#39;s reasonable. For example, if you frequented a forum which contained these messages,
30+ then it would only be a reasonable number of messages, and posting a message would only
31+ reveal that you where talking to some other member of that forum.
32+ </p>
33+ <p>Hiding access to such a forum is another problem that&#39;s out of the current scope.</p>
34+
35+ <h4 id="-the-number-of-recipients-are-hidden-">The number of recipients are hidden.</h4>
36+ <p>
37+ If the number of recipients was not hidden, then sometimes it would be possible
38+ to deanonymise the recipients, if there was a large group discussion with
39+ an unusual number of recipients. Encrypting the number of recipients means that,
40+ when a message is not encrypted to you, you will attempt to decrypt same number of times
41+ as the maximum recipients.
42+ </p>
43+
44+ <h4 id="-a-valid-recipient-does-not-know-the-other-recipients-">A valid recipient does not know the other recipients.</h4>
45+ <p>
46+ A valid recipient knows the number of recipients but now who they are.
47+ This is more a sideeffect of the design than an intentional design element.
48+ The plaintext contents may reveal the recipients, if needed.
49+ </p>
50+
51+ <h4 id="-by-providing-the-key-for-a-message-an-outside-party-could-decrypt-the-message-">By providing the key for a message, an outside party could decrypt the message.</h4>
52+ <p>
53+ When you tell someone a secret you must trust them not to reveal it.
54+ Anyone who knows the key could reveal that to some other party who could then read the message content,
55+ but not the recipients (unless the sender revealed the ephemeral secret key).
56+ </p>
57+
58+ <h2 id="assumptions">Assumptions</h2>
59+ <p>
60+ Messages will be posted in public, so that the sender is likely to be known,
61+ and everyone can read the messages. (This makes it possible to hide the recipient,
62+ but probably not the sender.)
63+ </p>
64+ <p>Resisting traffic analysis of the timing or size of messages is out of scope of this spec.</p>
65+
66+ <h2 id="prior-art">Prior Art</h2>
67+ <h4 id="-pgp-">PGP</h4>
68+ <p>
69+ In PGP the recipient, the sender, and the subject are sent as plaintext.
70+ If the recipient is known, then the metadata graph of who is communicating with who can be read,
71+ which, since it is easier to analyze than the content, is important to protect.
72+ </p>
73+ <h4 id="-sodium-seal-">Sodium seal</h4>
74+ <p>
75+ The Sodium library provides a <em>seal</em> function that generates an ephemeral keypair,
76+ derives a shared key to encrypt a message, and then sends the ephemeral public key and the message.
77+ The recipient is hidden, and it is forward secure if the sender throws out the ephemeral key.
78+ However, it&#39;s only possible to have one recipient.
79+ </p>
80+
81+ <h4 id="-minilock-">Minilock</h4>
82+ <p>
83+ Minilock uses a similar approach to <code>private-box</code> but does not hide the
84+ number of recipients. In the case of a group discussion where multiple rounds
85+ of messages are sent to everyone, this may enable an eavesdropper to deanonymize
86+ the participiants of a discussion if the sender of each message is known.
87+ </p>
88+
89+ <h2 id="api">API</h2>
90+
91+ <h4 id="-encrypt-plaintext-buffer-recipients-array-curve25519_pk-">encrypt (plaintext Buffer, recipients Array<curve25519_pk>)</h4>
92+ <p>
93+ Takes a plaintext buffer of the message you want to encrypt,
94+ and an array of recipient public keys.
95+ Returns a message that is encrypted to all recipients
96+ and openable by them with <code>PrivateBox.decrypt</code>.
97+ The recipients must be between 1 and 7 items long.
98+ </p>
99+ <p>
100+ The encrypted length will be <code>56 + (recipients.length * 33) + plaintext.length</code> bytes long,
101+ between 89 and 287 bytes longer than the plaintext.
102+ </p>
103+
104+ <h4 id="-decrypt-cyphertext-buffer-secretkey-curve25519_sk-">decrypt (cyphertext Buffer, secretKey curve25519_sk)</h4>
105+ <p>
106+ Attempt to decrypt a private-box message, using your secret key.
107+ If you where an intended recipient then the plaintext will be returned.
108+ If it was not for you, then <code>undefined</code> will be returned.
109+ </p>
110+
111+ <h2 id="protocol">Protocol</h2>
112+ <h4 id="-encryption-">Encryption</h4>
113+ <p>Private-box generates:</p>
114+ <ul>
115+ <li><code>ephemeral</code>: an ephemeral curve25519 keypair that will only be used with this message.</li>
116+ <li><code>body_key</code>: a random key that will be used to encrypt the plaintext body.</li>
117+ </ul>
118+ <p>
119+ First, private-box outputs the ephemeral public key, then multiplies each recipient public key
120+ with its secret to produce ephemeral shared keys (<code>shared_keys[1..n]</code>).
121+ Then, private-box concatenates <code>body_key</code> with the number of recipients,
122+ encrypts that to each shared key, and concatenates the encrypted body.
123+ </p>
124+ ${ com.code({ js: `
125+function encrypt (plaintext, recipients) {
126+ var ephemeral = keypair()
127+ var nonce = random(24)
128+ var body_key = random(32)
129+ var body_key_with_length = concat([
130+ body_key,
131+ recipients.length
132+ ])
133+ return concat([
134+ nonce,
135+ ephemeral.publicKey,
136+ concat(recipients.map(function (publicKey) {
137+ return secretbox(
138+ body_key_with_length,
139+ nonce,
140+ scalarmult(publicKey, ephemeral.secretKey)
141+ )
142+ }),
143+ secretbox(plaintext, nonce, body_key)
144+ ])
145+}` }) }
146+
147+ <h4 id="-decryption-">Decryption</h4>
148+ <p>
149+ <code>private-box</code> takes the nonce and ephemeral public key,
150+ multiplies that with your secret key, then tests each possible
151+ recipient slot until it either decrypts a key or runs out of slots.
152+ If it runs out of slots, the message was not addressed to you,
153+ so <code>undefined</code> is returned. Else, the message is found and the body
154+ is decrypted.
155+ </p>
156+ ${ com.code({ js: `
157+function decrypt (cyphertext, secretKey) {
158+ var next = reader(cyphertext) // next() will read
159+ // the passed N bytes
160+ var nonce = next(24)
161+ var publicKey = next(32)
162+ var sharedKey = salarmult(publicKey, secretKey)
163+
164+ for(var i = 0; i &lt; 7; i++) {
165+ var maybe_key = next(33)
166+ var key_with_length = secretbox_open(
167+ maybe_key,
168+ nonce,
169+ sharedKey
170+ )
171+ if (key_with_length) { // decrypted!
172+ var key = key_with_length.slice(0, 32)
173+ var length = key_with_length[32]
174+ return secretbox_open(
175+ key,
176+ cyphertext.slice(
177+ 56 + 33*(length+1),
178+ cyphertext.length
179+ ),
180+ )
181+ }
182+ }
183+ // this message was not addressed
184+ // to the owner of secretKey
185+ return undefined
186+}` }) }
187+ `
188+})
tmpl/guides/protocols/secret-handshake.html.jsView
@@ -1,0 +1,15 @@
1+var page = require('../../page.part')
2+module.exports = () => page({
3+ section: 'guides',
4+ tab: 'guides-protocols',
5+ path: '/guides/protocols/secret-handshake.html',
6+ content: `
7+ <h2>Secret Handshake</h1>
8+ <p>
9+ Secret Handshake is an encrypted channel protocol based on a mutually authenticating key agreement handshake, with forward secure identity metadata.
10+ It&#39;s used by Scuttlebot to authenticate and encrypt peer connections.
11+ </p>
12+ <p><a href="./shs.pdf">Read the White Paper</a></p>
13+ `,
14+ next: ['/guides/protocols/private-box.html', 'Private Box']
15+})
tmpl/guides/protocols/secure-scuttlebutt.html.jsView
@@ -1,0 +1,146 @@
1+var page = require('../../page.part')
2+var com = require('../../com.part')
3+
4+module.exports = () => page({
5+ section: 'guides',
6+ tab: 'guides-protocols',
7+ path: '/guides/protocols/secure-scuttlebutt.html',
8+ content: `
9+ <h2>Secure Scuttlebutt</h2>
10+ <p>Secure Scuttlebutt is a database protocol for unforgeable append-only message feeds.</p>
11+ <p>
12+ &quot;Unforgeable&quot; means that only the owner of a feed can update that feed, as enforced by digital signing (see <a href="#security-properties">Security properties</a>).
13+ This property makes Secure Scuttlebutt useful for peer-to-peer applications.
14+ Secure Scuttlebutt also makes it easy to encrypt messages.
15+ </p>
16+
17+ <hr>
18+
19+ <h2 id="concepts">Concepts</h2>
20+ <p>Building upon Secure Scuttlebutt requires understanding a few concepts that it uses to ensure the unforgeability of message feeds.</p>
21+
22+ <h3 id="identities">Identities</h3>
23+ <p>
24+ An identity is simply a <a href="http://ed25519.cr.yp.to/">ed25519 key pair</a>.
25+ The public key is used as the identifier.
26+ </p>
27+ <p>
28+ There is no worldwide store of identities.
29+ Users must exchange pubkeys, either by publishing them on their feeds, or out-of-band.
30+ </p>
31+
32+ <h3 id="feeds">Feeds</h3>
33+ <p>
34+ A feed is a signed append-only sequence of messages.
35+ Each identity has exactly one feed.
36+ </p>
37+ <p>
38+ Note that append-only means you cannot delete an existing message, or change your history.
39+ This is enforced by a per-feed blockchain.
40+ This is to ensure the entire network converges on the same state.
41+ </p>
42+
43+ <h3 id="messages">Messages</h3>
44+ <p>Each message contains:</p>
45+ <ul>
46+ <li>A signature</li>
47+ <li>The signing public key</li>
48+ <li>A content-hash of the previous message</li>
49+ <li>A sequence number</li>
50+ <li>A timestamp</li>
51+ <li>An identifier of the hashing algorithm in use (currently only &quot;sha256&quot; is supported)</li>
52+ <li>A content object</li>
53+ </ul>
54+ <p>Here&#39;s an example message:</p>
55+ ${ com.code({ js: `{
56+ "previous": "%26AC+gU0t74jRGVeDY01...MnutGGHM=.sha256",
57+ "author": "@hxGxqPrplLjRG2vtjQL87...0nNwE=.ed25519",
58+ "sequence": 216,
59+ "timestamp": 1442590513298,
60+ "hash": "sha256",
61+ "content": {
62+ "type": "vote",
63+ "vote": {
64+ "link": "%WbQ4dq0m/zu5jxll9zUb...KjZ80JvI=.sha256",
65+ "value": 1
66+ }
67+ },
68+ "signature": "Sjq1C3yiKdmi1TWvNqxI...gmAQ==.sig.ed25519"
69+}` }) }
70+
71+ <h3 id="entity-references-links-">Entity References (Links)</h3>
72+ <p>
73+ Messages can reference three types of Secure Scuttlebutt entities: messages, feeds, and blobs (i.e. files).
74+ Messages and blobs are referred to by their hashes, but a feed is referred to by its signing public key.
75+ </p>
76+
77+ <h3 id="confidentiality">Confidentiality</h3>
78+ <p>
79+ For private sharing, Scuttlebot uses <a href="http://doc.libsodium.org/">libsodium</a> to encrypt confidential log-entries.
80+ Feed IDs are public keys, and so once two feeds are mutually following each other, they can exchange confidential data freely.
81+ </p>
82+
83+ <h3 id="following">Following</h3>
84+ <p>
85+ Users choose which feeds to synchronize by following them.
86+ Presently, <a href="/modules/scuttlebot-replicate.html">Scuttlebot&#39;s replicate plugin</a>, which is enabled by default, looks on the master user&#39;s feed for <code>type:contact</code> messages to know which users are currently followed.
87+ </p>
88+
89+ <h3 id="replication">Replication</h3>
90+ <p>
91+ Since feeds are append-only, replication is simple: request all messages in the feed that are newer than the latest message you know about.
92+ Scuttlebot maintains a table of known peers, which it cycles through, asking for updates for all followed feeds.
93+ </p>
94+
95+ <h3 id="gossip">Gossip</h3>
96+ <p>
97+ The protocol creates a <a href="https://en.wikipedia.org/wiki/Gossip_protocol">global gossip network</a>.
98+ This means that information is able to distribute across multiple machines, without requiring direct connections between them.
99+ </p>
100+ <p><img src="/img/gossip-graph1.png" alt="Gossip graph"></p>
101+ <p>Even though Alice and Dan lack a direct connection, they can still exchange feeds:</p>
102+ <p><img src="/img/gossip-graph2.png" alt="Gossip graph 2"></p>
103+ <p>
104+ This is because gossip creates &quot;transitive&quot; connections between computers.
105+ Dan&#39;s messages travel through Carla and the Pub to reach Alice, and visa-versa.
106+ </p>
107+
108+ <h3 id="lan-connectivity">LAN connectivity</h3>
109+ <p>
110+ SSB is hostless: each computer installs the same copy of software and has equal rights in the network.
111+ Devices discover each other over the LAN with multicast UDP and sync automatically.
112+ </p>
113+
114+ <h3 id="pub-servers">Pub Servers</h3>
115+ <p>
116+ To sync across the Internet, &quot;Pub&quot; nodes run at public IPs and follow users.
117+ They are essentially mail-bots which improve uptime and availability.
118+ Users generate invite-codes to command Pubs to follow their friends.
119+ The Scuttlebot community runs some Pubs, and anybody can create and introduce their own.
120+ </p>
121+
122+ <h2 id="security-properties">Security properties</h2>
123+ <p>
124+ Secure Scuttlebutt maintains useful security properties even when it is connected to a malicious Secure Scuttlebutt database.
125+ This makes it ideal as a store for peer-to-peer applications.
126+ </p>
127+ <p>
128+ Imagine that we want to read from a feed for which we know the identity, but we&#39;re connected to a malicious Secure Scuttlebutt instance.
129+ As long as the malicious database does not have the private key:
130+ </p>
131+ <ul>
132+ <li>The malicious database cannot create a new feed with the same identifier</li>
133+ <li>The malicious database cannot write new fake messages to the feed</li>
134+ <li>The malicious database cannot reorder the messages in the feed</li>
135+ <li>The malicious database cannot send us a new copy of the feed that omits messages from the middle</li>
136+ <li>The malicious database <em>can</em> refuse to send us the feed, or only send us the first <em>N</em> messages in the feed</li>
137+ <li>Messages may optionally be encrypted</li>
138+ </ul>
139+ <p>
140+ Additionally there is a protection from the feed owner, through the blockchain.
141+ The <code>previous</code> content-hash them from changing the feed history after publishing, as a newly-created message wouldn&#39;t match the hash of later messages which were already replicated.
142+ This ensures the append-only constraint, and thus safe network convergence.
143+ </p>
144+ `,
145+ next: ['/guides/protocols/secret-handshake.html', 'Secret Handshake']
146+})
tmpl/guides/protocols/shs.pdfView
The diff is too large to show. Use a local git client to view these changes.
Old file size: 0 bytes
New file size: 219079 bytes
tmpl/guides/protocols/social.html.jsView
@@ -1,0 +1,47 @@
1+var page = require('../../page.part')
2+module.exports = () => page({
3+ section: 'docs',
4+ tab: 'guides-protocols',
5+ path: '/social/social-network.html',
6+ content: `
7+ <h2>Social network</h2>
8+ <p>
9+ Scuttlebot forms a global cryptographic social network with its peers.
10+ Each user is identified by a public key, and publishes a log of signed messages, which other users "follow."
11+ </p>
12+ <p>
13+ Scuttlebot searches the P2P mesh for new messages and files from followed users and from FoaFs.
14+ The messages and files are stored locally, indefinitely, for applications to read.
15+ </p>
16+
17+ <h3>Identity</h3>
18+ <p>
19+ Users are identified by confirmations in the social graph.
20+ This is known as a Web-of-Trust.
21+ There is no global registry of usernames.
22+ Instead, users name themselves, and share petnames for each other.
23+ </p>
24+ <p>
25+ Discovery occurs by examining the social graph, or by out-of-band sharing.
26+ Applications can analyze the follow-graph, and look for "flag" messages, to determine who is trust-worthy in the network.
27+ </p>
28+
29+ <h3>Pub Servers</h3>
30+ <p>
31+ "Pubs" are bot-users that have public IPs.
32+ They follow users and rehost the messages to other peers, ensuring good uptime and no firewall blockage.
33+ </p>
34+ <p>
35+ Pubs have no special privileges, and are not trusted by users.
36+ However, because Scuttlebot has no DHT or NAT-traversal utilities, users must "join" a Pub to distribute their messages on the WAN.
37+ </p>
38+ <p>
39+ Scuttlebot can change Pubs, or join more than one, and sync directly over Wifi.
40+ Identity is not tied to the Pubs.
41+ </p>
42+ <p class="next"><a href="/docs/social/follow-users.html">Follow users</a></p>
43+ <ul class="see-also">
44+ <li><a href="/whitepapers/secure-scuttlebutt.html">Secure Scuttlebutt</a></li>
45+ </ul>
46+ `
47+})
tmpl/index.html.jsView
@@ -22,9 +22,9 @@
2222 Localhosted frontend applications read and write freely to the local instance, and, in the background, the database syncs with known peers.<br>
2323 <br>
2424 Users are identified by public keys, and follow each other to form a web-of-trust.
2525 Peers do not have to be trusted, and can share logs and files on behalf of other peers.
26- <a href="/protocols/secure-scuttlebutt.html">Read about the protocol.</a>
26+ <a href="/guides/protocols/secure-scuttlebutt.html">Read about the protocol.</a>
2727 </p>
2828 </div>
2929 `,
3030 content: installTheDatabase.content()
tmpl/leftnav.part.jsView
@@ -104,10 +104,12 @@
104104 ${item(c, '/apis/community/ssb-notifier.html', 'SSB-Notifier')}
105105 ${item(c, '/apis/community/patchwork-threads.html', 'Patchwork-Threads')}
106106 </ul>`
107107
108-module.exports['guides-concepts'] = (c) => `<ul class="nav">
109- ${item(c, '/guides/concepts/intro.html', 'Intro')}
108+module.exports['guides-protocols'] = (c) => `<ul class="nav">
109+ ${item(c, '/guides/protocols/secure-scuttlebutt.html', 'Secure Scuttlebutt')}
110+ ${item(c, '/guides/protocols/secret-handshake.html', 'Secret Handshake')}
111+ ${item(c, '/guides/protocols/private-box.html', 'Private Box')}
110112 </ul>`
111113
112114 module.exports['guides-how-to-use-pull-streams'] = (c) => `<ul class="nav">
113115 ${item(c, '/guides/how-to-use-pull-streams/intro.html', 'Intro')}
tmpl/tabs.part.jsView
@@ -8,9 +8,9 @@
88 module.exports.sections = (c) => `<div class="tabs big">
99 ${item(c, 'docs', '/docs/basics/install-the-database.html', 'Docs')}
1010 ${item(c, 'apis', '/apis/scuttlebot/ssb.html', 'APIs')}
1111 ${item(c, 'apps', '/apps/patchwork.html', 'Apps')}
12- ${item(c, 'guides', '/guides/what-can-you-build-with-sbot/intro.html', 'Guides')}
12+ ${item(c, 'guides', '/guides/protocols/secure-scuttlebutt.html', 'Guides')}
1313 </div>`
1414
1515 module.exports.docs = (c) => `<div class="tabs small">
1616 ${item(c, 'docs-basics', '/docs/basics/install-the-database.html', 'Basics')}
@@ -35,10 +35,9 @@
3535 ${item(c, 'protocols', '/protocols/secure-scuttlebutt.html', 'Protocols')}
3636 </div>`
3737
3838 module.exports.guides = (c) => `<div class="tabs small">
39- ${item(c, 'basics', '/basics/install-the-database.html', 'Basics')}
40- ${item(c, 'social', '/social/social-network.html', 'Social')}
41- ${item(c, 'messages', '/messages/post.html', 'Message Types')}
42- ${item(c, 'advanced', '/advanced/writing-applications.html', 'Advanced')}
43- ${item(c, 'protocols', '/protocols/secure-scuttlebutt.html', 'Protocols')}
39+ ${item(c, 'guides-protocols', '/guides/protocols/secure-scuttlebutt.html', 'Protocols')}
40+ ${item(c, 'guides-social-feed=app', '/social/social-network.html', 'Social Feed App')}
41+ ${item(c, 'private messaging app', '/messages/post.html', 'Private Messaging App')}
42+ ${item(c, 'todo list app', '/advanced/writing-applications.html', 'Todo List App')}
4443 </div>`

Built with git-ssb-web