Skip to content

Commit e38298f

Browse files
committed
General improvements
1 parent 9853092 commit e38298f

File tree

1 file changed

+150
-42
lines changed

1 file changed

+150
-42
lines changed

Documentation/README.md

Lines changed: 150 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,43 @@
1+
# Contents
2+
* [General Paseto Overview](#general-paseto-overview)
3+
4+
* [General Paseto Usage](#general-paseto-usage)
5+
6+
* [The Paseto Message](#the-paseto-message)
7+
* [Creating a Paseto Message](#creating-a-paseto-message)
8+
* [⚠️ Accessing the Footer Prior to Decryption or Verification](#accessing-the-footer-prior-to-decryption-or-verification)
9+
* [Transferable Formats](#transferable-formats)
10+
11+
* [Paseto Keys](#paseto-keys)
12+
* [General Keys](#general-keys)
13+
* [General Key Methods](#general-key-methods)
14+
* [Constructing a General Key from Key Material](#constructing-a-general-key-from-key-material)
15+
* [Exporting a General Key from Key Material](#exporting-a-general-key-from-key-material)
16+
17+
* [Additional General Key Methods](#additional-general-key-methods)
18+
19+
* [Symmetric Keys](#symmetric-keys)
20+
* [Generating a new Symmetric Key](#generating-a-new-symmetric-key)
21+
* [Exporting a Symmetric Key for Storage](#exporting-a-symmetric-key-for-storage)
22+
23+
* [Asymmetric Secret Keys](#asymmetric-secret-keys)
24+
* [Generating a new Asymmetric Secret Key / Keypair](#generating-a-new-asymmetric-secret-key-keypair)
25+
* [Exporting an Asymmetric Secret Key for Storage](#exporting-an-asymmetric-secret-key-for-storage)
26+
27+
* [Asymmetric Public Keys](#asymmetric-public-keys)
28+
* [Obtaining a Public Key from a Secret Key](#obtaining-a-public-key-from-a-secret-key)
29+
* [Obtaining a Public Key from Key Material](#obtaining-a-public-key-from-key-material)
30+
* [Generating a new Public Key](#generating-a-new-public-key)
31+
* [Exporting an Asymmetric Public Key for Storage](#exporting-an-asymmetric-public-key-for-storage)
32+
33+
* [Wrapping up](#wrapping-up)
34+
* [Example](#example)
35+
36+
137
# General Paseto Overview
238
Each version of Paseto provides a ciphersuite with a selection of
3-
implementaions for: authenticated encryption and decryption, signatures and
4-
verification.
39+
implementaions for: authenticated encryption, authenticated decryption,
40+
signatures, and verification.
541

642
If you need to keep data secret, you are looking for the `local` part of API,
743
which performs encryption and decryption.
@@ -13,8 +49,8 @@ All modes verify the message integrity (i.e. there does not exist an
1349
unauthenticated mode of encryption).
1450

1551
In all modes, you may optionally provide an authentication tag
16-
("footer" henceforth). **The footer is never encrypted**, but it is **always**
17-
authenticated. You wish to use this to provide additional information
52+
("footer", henceforth). **The footer is never encrypted**, but it is **always**
53+
authenticated. You may wish to use this to provide additional information
1854
that does not itself need to be kept secret. Because this footer is always
1955
authenticated it cannot be modified in transit without detection.
2056

@@ -26,7 +62,7 @@ Forewarning that the following goes into vigorous detail. You should treat
2662
this all as required reading, however actual usage is very simple, see
2763
[wrapping up](#example) for a full usage example.
2864

29-
In the Swift library, each version of Paseto will have the following methods.
65+
In the Swift library, each version of Paseto will have the following methods:
3066
```swift
3167
encrypt(_:with:footer:)
3268
decrypt(_:with:)
@@ -39,9 +75,10 @@ that needs encrypting or signing, or a recieved Paseto message that needs
3975
decrypting or verifying.
4076
The second argument `with:` will be a key which is *appropriate* for the given
4177
task.
42-
For the encrypt and sign functions, additionally you may provide a footer
43-
(as defined above). There are overloads available that will set the footer
44-
to empty (no footer), so this argument may be omitted you do not require it.
78+
79+
> The *appropriate* key for any given encrypt, decrypt, sign, or verify
80+
> operation for any version is a type safety checked requirement. Providing a
81+
> key which is not *appropriate* is therefore a compile error by design.
4582
4683
In particular, each version will implement the following protocol:
4784

@@ -69,20 +106,24 @@ All methods are (at worst) throwing, but individual implementations may
69106
provide non-throwing versions of some of these functions as appropriate.
70107

71108
In addition to these methods, there are various convenience overloads
72-
implemented in protocol extensions in terms of these four base methods (
73-
thus any specific implementation will have these available).
109+
implemented in protocol extensions in terms of these four base methods
110+
(thus any specific implementation will have these available).
74111

75-
In particular, as mentioned overloads exist that allow omitting the footer,
76-
as well as overloads that will take a `String` in place of `Data`. If a `String`
77-
is provided, `UTF-8` encoding will be used to represent the `String` as bytes
78-
when transforming to `Data`.
112+
In particular, and for example: overloads exist that allow omission of the
113+
footer, as well as overloads that will take a `String` in place of `Data`. If a
114+
`String` is provided, `UTF-8` encoding will be used to represent the `String`
115+
as bytes when transforming to `Data`.
79116

80117
# The Paseto Message
81-
The Paseto message is what will be produced by encrypting and signing methods,
82-
and is what should be given to decrypting and verifying methods.
118+
The Paseto message is what will be produced by the encrypting and signing
119+
methods, and is what should be given to the decrypting and verification methods.
83120

84121
In the Swift library, a Paseto message is implemented as `Blob<P: Payload>`,
85122
where the generic argument is a type of `Payload`.
123+
> Before explaining the detail, it helps to see an example of this written out
124+
> explicitly. For example, `Blob<Signed<Version2>>` is a Paseto message which
125+
> has been signed using version 2 of Paseto's ciphersuite selection.
126+
86127
The only valid `Payload` types are: `Encrypted<V: Implementation>`, and
87128
`Signed<V: Implementation>`, where `V` is an `Implementation` (the protocol
88129
is defined above).
@@ -97,11 +138,21 @@ struct Blob<P: Payload> {
97138
}
98139
```
99140

100-
`init?(_:)` is a failible initializer, which is where you should provide
141+
*there are computed properties which are accessible too, these will be
142+
covered later*.
143+
144+
## Creating a Paseto Message
145+
146+
Paseto messages can be constructed by either encrypting or signing data,
147+
in which case a Paseto message (as a `Blob`) will be the output format.
148+
149+
A Paseto messages can also be constructed from a recieved message:
150+
151+
`init?(_:)` is a failible initializer, and is where you should provide
101152
a received Paseto message in its `String` representation.
102153

103154
For example, if you expect `message` to store a version 2 signed Paseto message
104-
as a `String`, then you should use the following:
155+
as a `String`, use the following:
105156

106157
```swift
107158
guard let blob = Blob<Signed<Version2>>(message) else { ... }
@@ -152,6 +203,29 @@ simultaneously):
152203
guard statements are used within the switch-case construct. Force unwrapping
153204
here instead would allow the possibility of unhandled errors at runtime.
154205

206+
207+
## Accessing the Footer Prior to Decryption or Verification
208+
209+
> ⚠️  **WARNING: Do not trust a footer value until you have successfully
210+
> decrypted or verified the blob.**
211+
>
212+
> This value is made available pre-verification/decryption because it may
213+
> be useful for, for example placing a key id in the footer. This could be used
214+
> so that the blob itself can indicate which of your trusted keys it requires
215+
> for decryption/verification.
216+
>
217+
> **Be aware that early extraction of the footer is a completely
218+
> unauthenticated claim until the authenticity of the blob has been proved**
219+
> (by either success of decryption or verification with a trusted key).
220+
221+
To access the footer of an already constructed Blob `blob`, use
222+
223+
```swift
224+
let blobFooter = blob.footer
225+
```
226+
227+
## Transferable Formats
228+
155229
If you have produced a `Blob` you will need to convert it to a `String` or
156230
`Data` in order to send or store it anywhere. To do this given a Blob `blob`,
157231
use either one of (as required):
@@ -180,27 +254,40 @@ For example: `SymmetricKey<Version2>` refers to a version 2 symmetric key.
180254
Any of the above keys will implement the `Key` protocol, which means you can
181255
expect all keys to have the following public API:
182256

257+
### General Key Methods
258+
183259
```swift
184-
protocol Key {
185-
associatedtype VersionType: Implementation
260+
protocol Key {
261+
associatedtype VersionType: Implementation
186262

187-
var material: Data { get }
188-
init (material: Data) throws
189-
}
263+
var material: Data { get }
264+
init (material: Data) throws
265+
}
190266
```
191267

192268
For any of the above keys, `VersionType` will hold the type parameter `V`.
193269

270+
#### Constructing a General Key from Key Material
271+
194272
`init (material:)` should be provided with the raw key material in bytes as
195273
`Data`. This method will throw if the key is not valid for the particular
196274
implementation.
197275

276+
#### Exporting a General Key from Key Material
277+
198278
`var material: Data` will return the material provided to the key upon
199279
initialization.
200280

281+
You should ensure that this key is stored safely if it is not intended to
282+
be shared with third parties!
283+
284+
285+
### Additional General Key Methods
286+
201287
Additionally, every key will inherit the following convenience API via
202288
a protocol extension:
203289

290+
204291
```swift
205292
extension Key {
206293
var encode: String
@@ -229,8 +316,11 @@ If you are using the `local` part of the API, you will need to use the same
229316
symmetric key (`SymmetricKey<V: Implementation>`) for both encryption and
230317
decryption.
231318

232-
In addition to the above methods common to all keys, `SymmetricKey<V: Implementation>` will have a default initializer `init ()`. Calling
233-
this will generate a new key from random data according to the specific
319+
### Generating a new Symmetric Key
320+
321+
In addition to the above methods common to all keys,
322+
`SymmetricKey<V: Implementation>` will have a default initializer `init ()`.
323+
Calling this will generate a new key from random data according to the specific
234324
requirements of the particular implementation.
235325

236326
For example,
@@ -244,7 +334,10 @@ ciphersuite.
244334

245335
Because this is a new key, it is important that you save the underlying key
246336
material so that you can later decrypt any messages you encrypt this key with.
247-
You should also ensure that this key is stored safely! If the exported material
337+
338+
### Exporting a Symmetric Key for Storage
339+
340+
You should ensure that this key is stored safely! If the exported material
248341
of this key becomes known to a third party you must discontinue use of the key
249342
and cease to trust the authenticity of messages encrypted with this key.
250343

@@ -267,6 +360,8 @@ We will cover asymmetric secret keys first because their implementations contain
267360
data required to reconstruct the keypair. A public key can always be exported
268361
from a secret key, however a secret key can never be exported from a public key.
269362

363+
### Generating a new Asymmetric Secret Key / Keypair
364+
270365
In addition to the methods common to all keys,
271366
`AsymmetricSecretKey<V: Implementation>` will have a default initializer
272367
`init ()`.
@@ -288,6 +383,9 @@ ciphersuite.
288383
Because this is a new key, it is important that you save the underlying key
289384
material so that you can continue to sign messages that can be verified by the
290385
corresponding public key.
386+
387+
### Exporting an Asymmetric Secret Key for Storage
388+
291389
You should also ensure that this key is stored safely! If the exported material
292390
of this key becomes known to a third party you must discontinue use of the key
293391
and cease to trust the authenticity of messages signed with this key.
@@ -304,28 +402,38 @@ If you are using the `public` part of the API, you will need to use
304402
a public key (`AsymmetricPublicKey<V: Implementation>`) to verify messages.
305403

306404
There are two ways to obtain a public key:
307-
1. If you have a secret key, you can export the corresponding public key,
308-
which will produce a key of the same version.
309-
Given a secret key `secretKey`, use the following to do this:
310-
```swift
311-
let publicKey = secretKey.publicKey
312-
```
313-
2. If you have public key material, use one of the initializers specified
314-
in the `Key` protocol to construct a `AsymmetricPublicKey<V: Implementation>`
315-
from this material.
316405

317-
For example to construct a public key from raw material `material` intended
318-
for Version 2 of Paseto, use the following:
319-
```swift
320-
guard let publicKey = try? AsymmetricPublicKey<Version2>(material) else {
321-
/* bad material given */
322-
}
323-
```
406+
### Obtaining a Public Key from a Secret Key
407+
408+
If you have a secret key, you can export the corresponding public key,
409+
which will produce a key of the same version.
410+
Given a secret key `secretKey`, use the following to do this:
411+
```swift
412+
let publicKey = secretKey.publicKey
413+
```
414+
415+
### Obtaining a Public Key from Key Material
416+
417+
If you have public key material, use one of the initializers specified
418+
in the `Key` protocol to construct a `AsymmetricPublicKey<V: Implementation>`
419+
from this material.
420+
421+
For example to construct a public key from raw material `material` intended
422+
for Version 2 of Paseto, use the following:
423+
```swift
424+
guard let publicKey = try? AsymmetricPublicKey<Version2>(material) else {
425+
/* bad material given */
426+
}
427+
```
428+
429+
### Generating a new Public Key
324430

325431
Public keys cannot be generated without a corresponding secret key. If you have
326432
neither you should generate a new secret key and then export its corresponding
327433
public key.
328434

435+
### Exporting an Asymmetric Public Key for Storage
436+
329437
If you wish to export your public key to share, so that a recipient of one
330438
of your signed messages may verify its integrity, use the following:
331439

0 commit comments

Comments
 (0)