# Cryptography in the cryptutils

## Cryptography in the cryptutils

The `common`

subpackage contains the cryptographic packages.

{

`common/secret`

](https://github.com/kisom/cryptutils/blob/master/common/secret/) contains the secret key code.`common/public`

contains the public key code.

### Principles

These are the basic principles guiding the cryptography in these programs.

- NaCl is used for most cryptographic primitives.
- Ed25519 should be used for digital signatures.
- SHA-256 may be used to generate an identifier for data, though this is only used in the experimental public key programs as a key identifier.
- Random nonces should be generated for each new message. The nonce is prepended to the ciphertext.
- Scrypt should be used to derive symmetric keys from passphrases. Passphrases are UTF-8 encoded octet strings. The salt is a randomly-generated 32-byte octet string; the salt will be prepended to any data encrypted using a passphrase. The Scrypt parameters are N=1048576, r=8, p=4 to provide a high cost for deriving symmetric keys.
- The operating system’s PRNG (on Linux, this is
`/dev/urandom`

) is used as the source of randomness. - Cryptographic operations return boolean success indicators: the cause of the error is not returned.

### Symmetric cryptography

Symmetric cryptography uses NaCl’s secretbox, which means XSalsa20 and Poly1305. Plaintext is encrypted as such:

- A 24-byte nonce for the message is randomly generated.
- The message is encrypted with the key.
- The resulting ciphertext is appended to the nonce.

Files are encrypted similarly, but the package only provides functions for encrypting and decrypting using passphrases.

- The user presents a file path, a UTF-8-encoded passphrase, and an octet string containing the plaintext.
- A random, 32-byte salt is generated.
- This newly-generated salt and the passphrase are sent to Scrypt (N=1048576, r=8, p=4) to generate a 32-byte secretbox key.
- The plaintext is encrypted as per the previous section.
- The ciphertext is appended to the salt, and the resulting octet string is written to disk to the path requested.

### Public-key cryptography

The public-key cryptography used in these programs employ the following key structure:

```
type PrivateKey struct {
// Curve25519
D *[32]byte // Decryption key (encryption private key).
// Ed25519
S *[64]byte // Signature key (signing private key).
*PublicKey
}
type PublicKey struct {
// Curve25519
E *[32]byte // Encryption key (encryption public key).
// Ed25519
V *[32]byte // Verification key (signing public key).
}
```

These keys are passed around as octet strings, where the private key packs the `D`

, `S`

, `E`

, and `V`

values in; public keys pack in the `E`

and `V`

values in. Packing is done by appending the values to each other.

Encryption is done as follows:

- An ephemeral Curve25519 key pair is generated.
- The ephemeral key pair is used to perform a key exchange with the peer’s public key. The private key is then discarded.
- The key exchange produces a symmetric key, and the plaintext is encrypted as in the symmetric section.
- The resulting ciphertext is appended to the ephemeral public key.

There is an encrypt-and-verify operation that expects a signature to be appended to the plaintext. There is currently no way to distinguish between a signed and unsigned message. The encrypt-and-sign is done exactly as encryption, except that the message is signed prior to encryption and this signature is appended to the message. Signatures are a fixed size (64 bytes), so the decrypt-and-verify decrypts the message, then verifies the plaintext is large enough to have a signature and uses the final 64 bytes as the signature.