@@ -0,0 +1,145 @@
7+Here we give a technical overview of how Ames implements cryptography.
11+By default, all [packets are encrypted](#packets) with 256-bit
12+[AES](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) symmetric key
13+encryption, whose key is obtained by [Diffie-Hellman key exchange](#key-exchange),
14+with public/private keys generated using elliptic curve
15+[Curve25519](https://en.wikipedia.org/wiki/Curve25519). The only exception to
16+this are comet [self-attestation packets](#comets), which are unencrypted.
18+All packets are also [signed](#packets) using [Elliptic Curve Digital Signature
19+Algorithm](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm).
21+The `$ames-state` includes a [`+acru:ames`](#crypto-core) core, an interface
22+core into which one of the cryptosuites in `zuse` may be implemented. Some, but
23+not all, of the calls to cryptography-related tasks (encryption, signing,
24+decrypting, and authenticating) are peformed utilizing the `+acru` core.
26+## Packet encryption and authentication {#packets}
28+Each Urbit ship possesses two networking keypairs: one for encryption, and one
29+for authentication. We often refer to these two keypairs as though they were a
30+single keypair because they are stored as a single atom. [Elliptic Curve
31+Diffie-Hellman](https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman)
32+is used for encryption, while [Elliptic Curve Digital Signature
33+Algorithm](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm)
34+is used for authentication
36+The encrypted payload of each packet is a `$shut-packet`, which is the `+jam` of
37+a cell with the `bone`, message number, and message fragment or ack (see
38+[Ames](@/docs/ames/ames.md) for more information on packet structure). The
39+message fragment is signed using the authentication key. It is encrypted using
40+[`+en:crub:crypto`](@/docs/arvo/reference/cryptography.md#en) found in
41+`sys/zuse.hoon`, which utilizes the 256-bit AES-SIV algorithm.
43+## Diffie-Hellman key exchange {#key-exchange}
45+For each foreign ship a given ship has communicated with, `$ames-state` contains a
46+`$peer-state`, inside which the `$symmetric-key` (an atom which nests under
47+`@uw`) is utilized for encrypting all Ames packets shared between the two ships.
48+The `symmetric-key` is derived using [`+shar:ed:crypto`](@/docs/arvo/reference/cryptography.md#shar) found in `sys/zuse.hoon`,
49+which is an arm utilized for generating the symmetric key for elliptic curve
51+exchange](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange)
52+with [curve25519](https://en.wikipedia.org/wiki/Curve25519). Briefly, each ship
53+in a two-way conversation computes the shared symmetric key for that
54+conversation by computing the product of their own private key and the public
55+key of the other party.
57+## Comet self-attestation {#comets}
59+Recall that the `@p` of a comet is the hash of their 128-bit public key cast as
60+a `@p`. Since the public key of a comet is not stored on Azimuth, a comet proves
61+its identity with an "attestation packet". This is an unencrypted packet whose
62+payload is the comet's signature created with its private key. This is the only
63+circumstance under which a ship will send an unencrypted packet. The signature
65+[`+sign:as:crub`](@/docs/arvo/reference/cryptography.md#sign-as) found in
68+Upon hearing an attestation packet, the receiving ship will generate a symmetric
69+key for communications with the comet, according to the [key
70+exchange](#key-exchange) protocol.
72+The fact that the first packet exchanged between a comet and another ship must
73+be an attestation packet is why comets are unable to initiate communication with
74+one another, and also why comets must be the first to initiate communication
75+with a non-comet. This is a technical limitation with a planned workaround.
77+## `+acru:ames` {#crypto-core}
79+The `+crypto-core` in `$ames-state` is an `+acru:ames` core, a
80+[lead](@/docs/hoon/reference/advanced.md#dry-polymorphism-and-core-nesting-rules)
81+interface core for asymmetric cryptosuites found in `sys/lull.hoon` which
82+handles encryption, decryption, signing, and verifying. In practice, the only
83+cryptosuite in use is [`+crub:crypto`](#crub), which implements [Suite B
84+Cryptography](https://en.wikipedia.org/wiki/NSA_Suite_B_Cryptography).
87+ ++ acru $_ ^? :: asym cryptosuite
90+ |% ++ seal |~([a=pass b=@] *@) :: encrypt to a
91+ ++ sign |~(a=@ *@) :: certify as us
92+ ++ sure |~(a=@ *(unit @)) :: authenticate from us
93+ ++ tear |~([a=pass b=@] *(unit @)) :: accept from a
95+ ++ de |~([a=@ b=@] *(unit @)) :: symmetric de, soft
96+ ++ dy |~([a=@ b=@] *@) :: symmetric de, hard
97+ ++ en |~([a=@ b=@] *@) :: symmetric en
99+ |% ++ fig *@uvH :: fingerprint
100+ ++ pac *@uvG :: default passcode
101+ ++ pub *pass :: public key
102+ ++ sec *ring :: private key
104+ ++ nu ^? :: reconstructors
105+ |% ++ pit |~([a=@ b=@] ^?(..nu)) :: from [width seed]
106+ ++ nol |~(a=ring ^?(..nu)) :: from ring
107+ ++ com |~(a=pass ^?(..nu)) :: from pass
112+As the `+acru` core is merely an interface, the details on how it is implemented
113+may vary according to the cryptosuite. We summarize what each
114+core is utilized for here, but see
115+[`crub:crypto`](@/docs/arvo/reference/cryptography.md#crub) for more details on
116+how the specific cryptosuite utilized by Ames is implemented.
120+This core is used for the standard asymmetric cryptographic operations: encrypting
121+(`+seal`), signing (`+sign`), authenticating (`+sure`), and decrypting (`+tear`).
125+This core is used to extract keys and their fingerprints. `+sec` is the secret key (which
126+may be empty), `+pub` is the public key associated to the secret key, `+pac` is
127+the fingerprint associated to the secret key, and `+fig` is the fingerprint
128+associated to the public key. We note that when the core contains both
129+encryption and authentication keys, they are typically concatenated to be
130+returned as a single atom.
134+This core contains constructors for the `+acru` core. `+pit:nu` is used to
135+construct an `+acru` core with both a private and public key (i.e. both
136+`+sec:ex` and `+pub:ex` are set) from a bitlength and seed. `+nol:nu` can then be
137+called from an `+acru` core created with `+pit:nu` to get an `+acru` core with
138+only the secret key, while `+com:nu` can be called to get an `+acru` core with
141+#### `+en:acru`, `+de:acru`, and `+dy:acru`
143+These arms are for symmetric encryption (`+en`) and decryption (`+de` and
144+`+dy`). The difference between the decryption arms is that `+de` returns null
145+and `+dy` crashes upon failure.