1 1
(ns caesium.crypto.box
2
  "Bindings to the public key authenticated encryption scheme."
3
  (:require [caesium.binding :as b]
4
            [caesium.crypto.scalarmult :as s]
5
            [caesium.byte-bufs :as bb])
6
  (:import [java.nio ByteBuffer]))
7

8 1
(b/defconsts [seedbytes
9
              publickeybytes
10
              secretkeybytes
11
              noncebytes
12
              macbytes
13
              sealbytes
14
              primitive])
15

16 1
(defn keypair-to-buf!
17
  "Generate a key pair into provided pk (public key) and sk (secret
18
  key) bufs. If also passed a seed, uses it to seed the key pair.
19

20
  This API matches libsodium's `crypto_box_keypair` and
21
  `crypto_box_seed_keypair`."
22
  ([pk sk]
23 1
   (b/call! keypair pk sk))
24
  ([pk sk seed]
25 1
   (b/call! seed-keypair pk sk seed)))
26

27 1
(defn keypair!
28
  "Create a `crypto_box` keypair.
29

30
  This fn will take either:
31

32
  - nothing, generating the key pair from scratch securely
33
  - a seed, generating the key pair from the seed
34

35
  Previously, this API matched Kalium, where the seed would be used as the
36
  secret key directly. Now, it matches libsodium, where the seed is hashed
37
  before being used as a secret. The old behavior can be useful in some cases,
38
  e.g. if you are storage-constrained and only want to store secret keys, and
39
  you care that it is _really_ the secret key and not some value derived from
40
  it (you probably don't). See [[sk->keypair]] for details.
41

42
  Returns a map containing the public and private key bytes (mutable
43
  arrays)."
44
  ([]
45 1
   (let [pk (bb/alloc publickeybytes)
46 1
         sk (bb/alloc secretkeybytes)]
47 1
     (keypair-to-buf! pk sk)
48 1
     {:public pk :secret sk}))
49
  ([seed]
50 1
   (let [pk (bb/alloc publickeybytes)
51 1
         sk (bb/alloc secretkeybytes)]
52 1
     (keypair-to-buf! pk sk (bb/->indirect-byte-buf seed))
53 1
     {:public pk :secret sk})))
54

55 1
(def ^:deprecated generate-keypair
56
  "Deprecated alias for [[keypair!]].
57

58
  Please note that there was a breaking backwards-incompatible change between
59
  0.4.0 and 0.5.0+ if you specify a seed; see [[keypair!]] docs for details."
60 1
  keypair!)
61

62 1
(defn sk->keypair
63
  "Generates a key pair from a secret key.
64

65
  This is different from generating a key pair from a seed. The former
66
  uses the libsodium API which will first hash the secret to an array
67
  of appropriate length; this will use the secret key verbatim. To be
68
  precise: it will use the secret key as a scalar to perform the
69
  Curve25519 scalar mult."
70
  [sk]
71 1
  (let [pk (bb/alloc publickeybytes)]
72 1
    (s/scalarmult-to-buf! pk sk)
73 1
    {:public pk :secret sk}))
74

75 1
(defn box-easy-to-buf!
76
  "Encrypts ptext into out with `crypto_box_easy` using given nonce,
77
  public key and secret key.
78

79
  All arguments must be `java.nio.ByteBuffer`.
80

81
  This function is only useful if you're managing your own output
82
  buffer, which includes in-place encryption. You probably
83
  want [[box-easy]]."
84
  [c m n pk sk]
85 1
  (b/call! easy c m plen n pk sk)
86 1
  c)
87

88 1
(defn box-open-easy-to-buf!
89
  "Decrypts ptext into out with `crypto_box_open_easy` using given
90
  nonce, public key and secret key.
91

92
  All arguments must be `java.nio.ByteBuffer`.
93

94
  This function is only useful if you're managing your own output
95
  buffer, which includes in-place decryption. You probably
96
  want [[box-open-easy]]."
97
  [m c n pk sk]
98 1
  (let [res (b/call! open-easy m c n pk sk)]
99 1
    (if (zero? res)
100 1
      m
101 1
      (throw (RuntimeException. "Ciphertext verification failed")))))
102

103 1
(defn box-seal-to-buf!
104
  "Encrypts ptext into out with `crypto_box_seal` using given public key.
105

106
  All arguments must be `java.nio.ByteBuffer`.
107

108
  This function is only useful if you're managing your own output
109
  buffer, which includes in-place encryption. You probably
110
  want [[box-seal]]."
111
  [c m pk]
112 1
  (b/call! box-seal c m plen pk)
113 1
  c)
114

115 1
(defn box-seal-open-to-buf!
116
  "Decrypts ptext into out with `crypto_box_seal_open` using given
117
  public key and secret key.
118

119
  All arguments must be `java.nio.ByteBuffer`.
120

121
  This function is only useful if you're managing your own output
122
  buffer, which includes in-place decryption. You probably
123
  want [[box-seal-open]]."
124
  [m c pk sk]
125 1
  (let [res (b/call! seal-open m c plen pk sk)]
126 1
    (if (zero? res)
127 1
      m
128 1
      (throw (RuntimeException. "Ciphertext verification failed")))))
129

130 1
(defn mlen->clen
131
  "Given a plaintext length, return the ciphertext length.
132

133
  This should be an implementation detail unless you want to manage
134
  your own output buffer together with [[box-easy-to-buf!]]."
135
  [mlen]
136 1
  (+ mlen macbytes))
137

138 1
(defn clen->mlen
139
  "Given a ciphertext length, return the plaintext length.
140

141
  This should be an implementation detail unless you want to manage
142
  your own output buffer together with [[box-open-easy-to-buf!]]."
143
  [clen]
144 1
  (- clen macbytes))
145

146 1
(defn box-easy
147
  "Encrypts ptext with `crypto_box_easy` using given nonce, public key
148
  and secret key.
149

150
  This creates the output ciphertext byte array for you, which is
151
  probably what you want. If you would like to manage the array
152
  yourself, or do in-place encryption, see [[box-easy-to-buf!]]."
153
  [ptext nonce pk sk]
154 1
  (let [out (bb/alloc (mlen->clen (bb/buflen ptext)))]
155 1
    (box-easy-to-buf!
156 1
     out
157 1
     (bb/->indirect-byte-buf ptext)
158 1
     (bb/->indirect-byte-buf nonce)
159 1
     (bb/->indirect-byte-buf pk)
160 1
     (bb/->indirect-byte-buf sk))
161 1
    (bb/->bytes out)))
162

163 1
(defn box-open-easy
164
  "Decrypts ptext with `crypto_box_open_easy` using given nonce, public
165
  key and secret key.
166

167
  This creates the output plaintext byte array for you, which is probably what
168
  you want. If you would like to manage the array yourself, or do in-place
169
  decryption, see [[box-open-easy-to-buf!]]."
170
  [ctext nonce pk sk]
171 1
  (let [out (bb/alloc (clen->mlen (bb/buflen ctext)))]
172 1
    (box-open-easy-to-buf!
173 1
     out
174 1
     (bb/->indirect-byte-buf ctext)
175 1
     (bb/->indirect-byte-buf nonce)
176 1
     (bb/->indirect-byte-buf pk)
177 1
     (bb/->indirect-byte-buf sk))
178 1
    (bb/->bytes out)))
179

180 1
(defn box-seal
181
  "Encrypts ptext with `crypto_box_seal` using given public key.
182

183
  This creates the output ciphertext byte array for you, which is
184
  probably what you want. If you would like to manage the array
185
  yourself, or do in-place encryption, see [[box-seal-to-buf!]]."
186
  [ptext pk]
187 1
  (let [out (bb/alloc (+ (bb/buflen ptext) sealbytes))]
188 1
    (box-seal-to-buf!
189 1
     out
190 1
     (bb/->indirect-byte-buf ptext)
191 1
     (bb/->indirect-byte-buf pk))
192 1
    (bb/->bytes out)))
193

194 1
(defn box-seal-open
195
  "Decrypts ptext with `crypto_box_seal_open` using given public key, and
196
  secret key.
197

198
  This creates the output plaintext byte array for you, which is probably what
199
  you want. If you would like to manage the array yourself, or do in-place
200
  decryption, see [[box-seal-open-to-buf!]]."
201
  [ctext pk sk]
202 1
  (let [out (bb/alloc (- (bb/buflen ctext) sealbytes))]
203 1
    (box-seal-open-to-buf!
204 1
     out
205 1
     (bb/->indirect-byte-buf ctext)
206 1
     (bb/->indirect-byte-buf pk)
207 1
     (bb/->indirect-byte-buf sk))
208 1
    (bb/->bytes out)))
209

210 1
(defn encrypt
211
  "Encrypt with `crypto_box_easy`.
212

213
  To encrypt, use the recipient's public key and the sender's secret
214
  key.
215

216
  This is an alias for [[box-easy]] with a different argument
217
  order. [[box-easy]] follows the same argument order as the libsodium
218
  function."
219
  [pk sk nonce ptext]
220 1
  (box-easy ptext nonce pk sk))
221

222 1
(defn decrypt
223
  "Decrypt with `crypto_box_open_easy`.
224

225
  To decrypt, use the sender's public key and the recipient's secret
226
  key.
227

228
  This is an alias for [[box-open-easy]] with a different argument
229
  order. [[box-open-easy]] follows the same argument order as the
230
  libsodium function."
231
  [pk sk nonce ctext]
232 1
  (box-open-easy ctext nonce pk sk))
233

234 1
(defn anonymous-encrypt
235
  "Encrypt with `crypto_box_seal`.
236

237
  To encrypt, use the recipient's public key.
238

239
  This is an alias for [[box-seal]] with a different argument
240
  order. [[box-seal]] follows the same argument order as the libsodium
241
  function."
242
  [pk ptext]
243 1
  (box-seal ptext pk))
244

245 1
(defn anonymous-decrypt
246
  "Decrypt with `crypto_box_seal_open`.
247

248
  To decrypt, use the recipient's public key and recipient' secret
249
  key.
250

251
  This is an alias for [[box-seal-open]] with a different argument
252
  order. [[box-seal-open]] follows the same argument order as the
253
  libsodium function."
254
  [pk sk ctext]
255 1
  (box-seal-open ctext pk sk))
256

257 1
(defn box-detached-to-bufs! [c mac m mlen n pk sk]
258 1
  (b/call! detached c mac m mlen n pk sk))
259

260 1
(defn box-detached [ptext nonce pk sk]
261 1
  (let [c (bb/alloc (bb/buflen ptext))
262 1
        mac (bb/alloc macbytes)]
263 1
    (box-detached-to-bufs!
264 1
     c
265 1
     mac
266 1
     (bb/->indirect-byte-buf ptext)
267 1
     (bb/buflen ptext)
268 1
     (bb/->indirect-byte-buf nonce)
269 1
     (bb/->indirect-byte-buf pk)
270 1
     (bb/->indirect-byte-buf sk))
271 1
    {:c (bb/->bytes c)
272 1
     :mac (bb/->bytes mac)}))
273

274 1
(defn box-open-detached-to-bufs! [m c mac clen n pk sk]
275 1
  (let [res (b/call! open_detached m c mac clen n pk sk)]
276 1
    (if (zero? res)
277 1
      m
278 1
      (throw (RuntimeException. "Ciphertext verification failed")))))
279

280 1
(defn box-open-detached [ctext mac nonce pk sk]
281 1
  (let [m (bb/alloc (bb/buflen ctext))]
282 1
    (box-open-detached-to-bufs!
283 1
     m
284 1
     (bb/->indirect-byte-buf ctext)
285 1
     (bb/->indirect-byte-buf mac)
286 1
     (bb/buflen ctext)
287 1
     (bb/->indirect-byte-buf nonce)
288 1
     (bb/->indirect-byte-buf pk)
289 1
     (bb/->indirect-byte-buf sk))
290 1
    (bb/->bytes m)))

Read our documentation on viewing source code .

Loading