# Zooming in: Packet structure of private key material
## A look at Alice's (unencrypted) private key packets
Let's take a look at the key material packets of [Alice's key](alice_priv).
To inspect the internal structure of Alice's key, we run the Sequoia-PGP tool `sq` (using the `packet dump` subcommand). The output of `sq` is one big block of text. To discuss the relevant content, we'll only show the output for the packets that contain key data, here:
```text
$ sq packet dump --hex alice.priv
```
### Primary Secret-Key packet
The output starts with the (primary) [Secret-Key packet](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-secret-key-packet-formats):
```text
Secret-Key Packet, new CTB, 2 header bytes + 75 bytes
The Secret-Key packet consists in large part of the actual cryptographic key data. Notice that its content is almost entirely the same as the Public-Key packet [seen in the previous chapter](public_key). Let's look at the packet field by field:
-`CTB: 0xc5`[^CTB]: The [packet type ID](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-packet-headers) for this packet. The binary representation of the value `0xc5` is `11000101`. Bits 7 and 6 show that the packet is in *OpenPGP packet format* (as opposed to in *Legacy packet format*). The remaining 6 bits encode the type ID's value: "5". This is the value for a Secret-Key packet, as shown in the list of [packet type IDs](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-packet-tags).
-`length: 0x4b`: The remaining length of this packet.
[^CTB]: Sequoia uses the term CTB (Cipher Type Byte) to refer to the RFC's [packet type ID](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-packet-headers). In previous versions, the RFC called this field "Packet Tag".
The packet type id defines the semantics of the remaining data in the packet. We're looking at a Secret-Key packet, which is a kind of [Key Material Packet](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-key-material-packets).
-`version: 0x06`: The key material is in version 6 format
This means that the next part of the packet follows the structure of [Version 6 Public Keys](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-version-6-public-keys)
-`creation_time: 0x6516eaa6`: "The time that the key was created" (also see [Time Fields](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-time-fields))
-`pk_algo: 0x1b`: "The public-key algorithm ID of this key" (decimal value 27, see the list of [Public-Key Algorithms](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-public-key-algorithms))
-`public_len: 0x00000020`: "Octet count for the following public key material" (in this case, the length of the following `ed25519_public` field)
-`ed25519_public`: [Algorithm-specific representation](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-algorithm-specific-part-for-ed2) of the public key material (the format is based on the value of `pk_algo`), in this case 32 bytes of Ed25519 public key
This concludes the Public Key section of the packet. The remaining data follows the [Secret-Key packet format](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-secret-key-packet-formats):
-`s2k_usage: 0x00`: The [*S2K usage* value](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-secret-key-encryption-s2k-u) of `0x00` specifies that the secret-key data is not encrypted
-`ed25519_secret`: [Algorithm-specific representation](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-algorithm-specific-part-for-ed2) of the secret key data (the format is based on the value of `pk_algo`). Because the private key material in this packet is not encrypted, this field
```{tip}
The overall structure of OpenPGP packets is described in the [Packet Syntax](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-packet-syntax) chapter of the RFC.
```
Note that the *Secret-Key packet* contains both the private and the public part of the key.
### Secret-Subkey packet
Further down in the "packet dump" of Alice's key, we see the encryption subkey, which we already inspected in its Public-Subkey packet format, [above](zoom_enc_subkey):
```text
Secret-Subkey Packet, new CTB, 2 header bytes + 75 bytes
00000010 cc 42 af 99 34 c5 c2 5c ca fa b7 4a c8 43 fc 86
00000020 35 2a 46 01 f3 cc 00 f5 4a 09 3e 3f
0000002c 00 s2k_usage
0000002d 28 7d cd x25519_secret
00000030 da 26 16 37 8d ea 24 c7 ce e7 70 c7 9b e5 6f 0a
00000040 c9 77 fb bd 23 41 73 c9 57 5a bf 7c 4c
```
Again, this packet consists of the same content as its Public-Subkey equivalent, followed by two additional fields:
- The "S2K usage" field, which indicated whether the private key material is encrypted. Like Alice's primary key (above), this subkey is not encrypted.
- The private key material: in this case, the algorithm-specific private key data consists of 32 bytes of `x25519_secret` data.
As with the public key material, the difference between the format of this subkey packet and the private key packet is minimal: Only the packet type ID differs.
## Bob's (encrypted) private key material
Now we look at the primary key material packet of [Bob's key](bob_priv), which uses passphrase protection.
```text
Secret-Key Packet, new CTB, 2 header bytes + 134 bytes
00000070 b4 51 52 ba 6d f9 7c 1a ee 9f e6 b1 fb 63 d1 ca
00000080 4a 3f 33 d9 2c c9 26 46
```
The first portion of Bob's Secret-Key packet has the same structure as Alice's, but beginning at the `s2k_usage`, we see different data. The format of this data is described in [Secret-Key Packet Formats](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-secret-key-packet-formats).
-`s2k_usage: 0xfe`: [S2K usage](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-secret-key-encryption-s2k-u) is set to `AEAD`, here (decimal value 253).
-`parameters_len: 0x16` (decimal value: 22): "Cumulative length of all the following conditionally included string-to-key parameter fields."
-`sym_algo: 0x9`: [Symmetric-Key Algorithm](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-symmetric-key-algorithms) specifies that AES 256 is used as the AEAD algorithm
-`s2k_len: 0x14` (decimal value 20): "[..] count of the size of the one field following this octet"
The next set of data is the "string-to-key (S2K) specifier." Its format depends on the type.
-`s2k_type: 0x04` [String-to-Key (S2K) Specifier Type](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-string-to-key-s2k-specifier-), set to *Argon2* here.
The next fields are [specific to Argon2](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-11.html#name-argon2):
-`argon2_salt`: "16-octet salt value"
-`argon2_t`: "number of passes t"
-`argon2_p`: "degree of parallelism p"
-`argon2_m`: "the exponent of the memory size"
```{admonition} TODO
:class: warning
Where is that IV:
["If string-to-key usage octet was 253 (AEAD), an initialization vector (IV) of size specified by the AEAD algorithm (see Section 5.13.2), which is used as the nonce for the AEAD algorithm"](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-11.html#section-5.5.3-3.4.2.5)
Is the example key wrong?!
```
"Plain or encrypted multiprecision integers comprising the secret key data. This is algorithm-specific and described in Section 5.5.5. If the string-to-key usage octet is 253 (AEAD), then an AEAD authentication tag is at the end of that data."