LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2012 The Go Authors. All rights reserved. | 1 // Copyright 2012 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 /* | 5 /* |
6 Package secretbox encrypts and authenticates small messages. | 6 Package secretbox encrypts and authenticates small messages. |
7 | 7 |
8 Secretbox uses XSalsa20 and Poly1305 to encrypt and authenticate messages with | 8 Secretbox uses XSalsa20 and Poly1305 to encrypt and authenticate messages |
9 secret-key cryptography. The length of messages is not hidden. | 9 with secret-key cryptography. The length of messages is not hidden. |
10 | 10 |
11 It is the caller's responsibility to ensure the uniqueness of nonces—for | 11 It is the caller's responsibility to ensure the uniqueness of nonces—for |
12 example, by using nonce 1 for the first message, nonce 2 for the second | 12 example, by using nonce 1 for the first message, nonce 2 for the second |
13 message, etc. Nonces are long enough that randomly generated nonces have | 13 message, etc. Nonces are long enough that randomly generated nonces have |
14 negligible risk of collision. | 14 negligible risk of collision. |
15 | 15 |
16 This package is interoperable with NaCl: http://nacl.cr.yp.to/secretbox.html. | 16 This package is interoperable with NaCl: http://nacl.cr.yp.to/secretbox.html. |
17 */ | 17 */ |
18 package secretbox | 18 package secretbox |
19 | 19 |
(...skipping 10 matching lines...) Expand all Loading... |
30 // We use XSalsa20 for encryption so first we need to generate a | 30 // We use XSalsa20 for encryption so first we need to generate a |
31 // key and nonce with HSalsa20. | 31 // key and nonce with HSalsa20. |
32 var hNonce [16]byte | 32 var hNonce [16]byte |
33 copy(hNonce[:], nonce[:]) | 33 copy(hNonce[:], nonce[:]) |
34 salsa.HSalsa20(subKey, &hNonce, key, &salsa.Sigma) | 34 salsa.HSalsa20(subKey, &hNonce, key, &salsa.Sigma) |
35 | 35 |
36 // The final 8 bytes of the original nonce form the new nonce. | 36 // The final 8 bytes of the original nonce form the new nonce. |
37 copy(counter[:], nonce[16:]) | 37 copy(counter[:], nonce[16:]) |
38 } | 38 } |
39 | 39 |
40 // Seal appends an encrypted and authenticated copy of message to out, which | 40 // Seal appends an encrypted and authenticated copy of message to out, |
41 // must not overlap message. The key and nonce pair must be unique for each | 41 // which must not overlap message, and returns the new part of out. |
42 // distinct message and the output will be Overhead bytes longer than message. | 42 // The key and nonce pair must be unique for each distinct message and |
| 43 // the output will be Overhead bytes longer than message. |
43 func Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte { | 44 func Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte { |
44 var subKey [32]byte | 45 var subKey [32]byte |
45 var counter [16]byte | 46 var counter [16]byte |
46 setup(&subKey, &counter, nonce, key) | 47 setup(&subKey, &counter, nonce, key) |
47 | 48 |
48 // The Poly1305 key is generated by encrypting 32 bytes of zeros. Since | 49 // The Poly1305 key is generated by encrypting 32 bytes of zeros. Since |
49 // Salsa20 works with 64-byte blocks, we also generate 32 bytes of | 50 // Salsa20 works with 64-byte blocks, we also generate 32 bytes of |
50 // keystream as a side effect. | 51 // keystream as a side effect. |
51 var firstBlock [64]byte | 52 var firstBlock [64]byte |
52 salsa.XORKeyStream(firstBlock[:], firstBlock[:], &counter, &subKey) | 53 salsa.XORKeyStream(firstBlock[:], firstBlock[:], &counter, &subKey) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 salsa.XORKeyStream(out, message, &counter, &subKey) | 88 salsa.XORKeyStream(out, message, &counter, &subKey) |
88 | 89 |
89 var tag [poly1305.TagSize]byte | 90 var tag [poly1305.TagSize]byte |
90 poly1305.Sum(&tag, ciphertext, &poly1305Key) | 91 poly1305.Sum(&tag, ciphertext, &poly1305Key) |
91 copy(tagOut, tag[:]) | 92 copy(tagOut, tag[:]) |
92 | 93 |
93 return tagOut | 94 return tagOut |
94 } | 95 } |
95 | 96 |
96 // Open authenticates and decrypts a box produced by Seal and appends the | 97 // Open authenticates and decrypts a box produced by Seal and appends the |
97 // message to out, which must not overlap box. The output will be Overhead | 98 // message to out, which must not overlap box. It returns the new part of out. |
98 // bytes smaller than box. | 99 // The output will be Overhead bytes smaller than box. |
99 func Open(out []byte, box []byte, nonce *[24]byte, key *[32]byte) ([]byte, bool)
{ | 100 func Open(out []byte, box []byte, nonce *[24]byte, key *[32]byte) ([]byte, bool)
{ |
100 if len(box) < Overhead { | 101 if len(box) < Overhead { |
101 return nil, false | 102 return nil, false |
102 } | 103 } |
103 | 104 |
104 var subKey [32]byte | 105 var subKey [32]byte |
105 var counter [16]byte | 106 var counter [16]byte |
106 setup(&subKey, &counter, nonce, key) | 107 setup(&subKey, &counter, nonce, key) |
107 | 108 |
108 // The Poly1305 key is generated by encrypting 32 bytes of zeros. Since | 109 // The Poly1305 key is generated by encrypting 32 bytes of zeros. Since |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 box = box[len(firstMessageBlock):] | 147 box = box[len(firstMessageBlock):] |
147 plaintext := out | 148 plaintext := out |
148 out = out[len(firstMessageBlock):] | 149 out = out[len(firstMessageBlock):] |
149 | 150 |
150 // Now decrypt the rest. | 151 // Now decrypt the rest. |
151 counter[8] = 1 | 152 counter[8] = 1 |
152 salsa.XORKeyStream(out, box, &counter, &subKey) | 153 salsa.XORKeyStream(out, box, &counter, &subKey) |
153 | 154 |
154 return plaintext, true | 155 return plaintext, true |
155 } | 156 } |
LEFT | RIGHT |