git ssb

2+

cel / scuttlebot.io



Tree: c0c9508d732a53b79ef287fd75268ac0d50dda3a

Files: c0c9508d732a53b79ef287fd75268ac0d50dda3a / tmpl / more / protocols / private-box.html.js

7990 bytesRaw
1var page = require('../../page.part')
2var com = require('../../com.part')
3
4module.exports = () => page({
5 title: 'Private Box',
6 section: 'more',
7 tab: 'more-protocols',
8 path: '/more/protocols/private-box.html',
9 content: `
10 <h2>Private Box</h2>
11 <p>
12 Private-box is a format for encrypting a private message to many parties.
13 You can <strong><a href="https://github.com/auditdrivencrypto/private-box">find the repository on GitHub</a></strong>.
14 </p>
15
16 <h2 id="properties">Properties</h2>
17 <p>
18 This protocol was designed for use with secure-scuttlebutt.
19 In this place, messages are placed in public, and the sender is known via a signature,
20 but we can hide the recipient and the content.
21 </p>
22
23 <h4 id="-recipients-are-hidden-">Recipients are hidden.</h4>
24 <p>
25 An eaves-dropper cannot know the recipients or their number.
26 Since the message is encrypted to each recipient, and then placed in public,
27 to receive a message you will have to decrypt every message posted.
28 This would not be scalable if you had to decrypt every message on the internet,
29 but if you can restrict the number of messages you might have to decrypt,
30 then it&#39;s reasonable. For example, if you frequented a forum which contained these messages,
31 then it would only be a reasonable number of messages, and posting a message would only
32 reveal that you where talking to some other member of that forum.
33 </p>
34 <p>Hiding access to such a forum is another problem that&#39;s out of the current scope.</p>
35
36 <h4 id="-the-number-of-recipients-are-hidden-">The number of recipients are hidden.</h4>
37 <p>
38 If the number of recipients was not hidden, then sometimes it would be possible
39 to deanonymise the recipients, if there was a large group discussion with
40 an unusual number of recipients. Encrypting the number of recipients means that,
41 when a message is not encrypted to you, you will attempt to decrypt same number of times
42 as the maximum recipients.
43 </p>
44
45 <h4 id="-a-valid-recipient-does-not-know-the-other-recipients-">A valid recipient does not know the other recipients.</h4>
46 <p>
47 A valid recipient knows the number of recipients but now who they are.
48 This is more a sideeffect of the design than an intentional design element.
49 The plaintext contents may reveal the recipients, if needed.
50 </p>
51
52 <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>
53 <p>
54 When you tell someone a secret you must trust them not to reveal it.
55 Anyone who knows the key could reveal that to some other party who could then read the message content,
56 but not the recipients (unless the sender revealed the ephemeral secret key).
57 </p>
58
59 <h2 id="assumptions">Assumptions</h2>
60 <p>
61 Messages will be posted in public, so that the sender is likely to be known,
62 and everyone can read the messages. (This makes it possible to hide the recipient,
63 but probably not the sender.)
64 </p>
65 <p>Resisting traffic analysis of the timing or size of messages is out of scope of this spec.</p>
66
67 <h2 id="prior-art">Prior Art</h2>
68 <h4 id="-pgp-">PGP</h4>
69 <p>
70 In PGP the recipient, the sender, and the subject are sent as plaintext.
71 If the recipient is known, then the metadata graph of who is communicating with who can be read,
72 which, since it is easier to analyze than the content, is important to protect.
73 </p>
74 <h4 id="-sodium-seal-">Sodium seal</h4>
75 <p>
76 The Sodium library provides a <em>seal</em> function that generates an ephemeral keypair,
77 derives a shared key to encrypt a message, and then sends the ephemeral public key and the message.
78 The recipient is hidden, and it is forward secure if the sender throws out the ephemeral key.
79 However, it&#39;s only possible to have one recipient.
80 </p>
81
82 <h4 id="-minilock-">Minilock</h4>
83 <p>
84 Minilock uses a similar approach to <code>private-box</code> but does not hide the
85 number of recipients. In the case of a group discussion where multiple rounds
86 of messages are sent to everyone, this may enable an eavesdropper to deanonymize
87 the participiants of a discussion if the sender of each message is known.
88 </p>
89
90 <h2 id="api">API</h2>
91
92 <h4 id="-encrypt-plaintext-buffer-recipients-array-curve25519_pk-">encrypt (plaintext Buffer, recipients Array<curve25519_pk>)</h4>
93 <p>
94 Takes a plaintext buffer of the message you want to encrypt,
95 and an array of recipient public keys.
96 Returns a message that is encrypted to all recipients
97 and openable by them with <code>PrivateBox.decrypt</code>.
98 The recipients must be between 1 and 7 items long.
99 </p>
100 <p>
101 The encrypted length will be <code>56 + (recipients.length * 33) + plaintext.length</code> bytes long,
102 between 89 and 287 bytes longer than the plaintext.
103 </p>
104
105 <h4 id="-decrypt-cyphertext-buffer-secretkey-curve25519_sk-">decrypt (cyphertext Buffer, secretKey curve25519_sk)</h4>
106 <p>
107 Attempt to decrypt a private-box message, using your secret key.
108 If you where an intended recipient then the plaintext will be returned.
109 If it was not for you, then <code>undefined</code> will be returned.
110 </p>
111
112 <h2 id="protocol">Protocol</h2>
113 <h4 id="-encryption-">Encryption</h4>
114 <p>Private-box generates:</p>
115 <ul>
116 <li><code>ephemeral</code>: an ephemeral curve25519 keypair that will only be used with this message.</li>
117 <li><code>body_key</code>: a random key that will be used to encrypt the plaintext body.</li>
118 </ul>
119 <p>
120 First, private-box outputs the ephemeral public key, then multiplies each recipient public key
121 with its secret to produce ephemeral shared keys (<code>shared_keys[1..n]</code>).
122 Then, private-box concatenates <code>body_key</code> with the number of recipients,
123 encrypts that to each shared key, and concatenates the encrypted body.
124 </p>
125 ${ com.code({ js: `
126function encrypt (plaintext, recipients) {
127 var ephemeral = keypair()
128 var nonce = random(24)
129 var body_key = random(32)
130 var body_key_with_length = concat([
131 body_key,
132 recipients.length
133 ])
134 return concat([
135 nonce,
136 ephemeral.publicKey,
137 concat(recipients.map(function (publicKey) {
138 return secretbox(
139 body_key_with_length,
140 nonce,
141 scalarmult(publicKey, ephemeral.secretKey)
142 )
143 }),
144 secretbox(plaintext, nonce, body_key)
145 ])
146}` }) }
147
148 <h4 id="-decryption-">Decryption</h4>
149 <p>
150 <code>private-box</code> takes the nonce and ephemeral public key,
151 multiplies that with your secret key, then tests each possible
152 recipient slot until it either decrypts a key or runs out of slots.
153 If it runs out of slots, the message was not addressed to you,
154 so <code>undefined</code> is returned. Else, the message is found and the body
155 is decrypted.
156 </p>
157 ${ com.code({ js: `
158function decrypt (cyphertext, secretKey) {
159 var next = reader(cyphertext) // next() will read
160 // the passed N bytes
161 var nonce = next(24)
162 var publicKey = next(32)
163 var sharedKey = salarmult(publicKey, secretKey)
164
165 for(var i = 0; i &lt; 7; i++) {
166 var maybe_key = next(33)
167 var key_with_length = secretbox_open(
168 maybe_key,
169 nonce,
170 sharedKey
171 )
172 if (key_with_length) { // decrypted!
173 var key = key_with_length.slice(0, 32)
174 var length = key_with_length[32]
175 return secretbox_open(
176 key,
177 cyphertext.slice(
178 56 + 33*(length+1),
179 cyphertext.length
180 ),
181 )
182 }
183 }
184 // this message was not addressed
185 // to the owner of secretKey
186 return undefined
187}` }) }
188 `
189})

Built with git-ssb-web