<commit_before># Pact
An experimental cryptographic messaging application which implements the experimental cryptographic 
library [MSG](https://github.com/MattSurabian/msg).

## What Is Pact?
Pact is a CLI application that enables messages to be shared securely between many parties without the 
need for out of band secret sharing. Pact does this by relying on asymmetric cryptography to safeguard a
symmetric key. This allows two or more parties to communicate securely after exchanging only their public keys.

Pact offloads all of its crypto to the [MSG library](https://github.com/MattSurabian/msg) but this README 
will review the crypto operations as if Pact was doing all the heavy lifting so potential Pact users are given
sufficient context. As of this writing Pact is the only implementation of the MSG library.

If you're curious to take a deeper dive, effort was made to extensively document the [MSG library](https://github.com/MattSurabian/msg);
code explainations can be found in the comments and test cases.

### Asymmetric and Symmetric Crypto!?
Yes, but they are not used on top of one another. Unlike PGP, Pact does not rely on RSA or DSA public-key crypto. 
Instead, Pact uses [NaCl](http://nacl.cr.yp.to/), a more modern approach to public-key cryptography with 
secure keys that are only 32 bytes long. NaCl's simplicity and security come at a price. Multiple party
decryption of a single ciphertext is not possible without shared keys. Instead, new cipher
text must be created for each individual with which a user intends to communicate.

Pact solves this problem by using AES-256-GCM ([Galois/Counter Mode](https://en.wikipedia.org/wiki/Galois/Counter_Mode)) to secure the initial message and then
encrypts the secret key used for AES with NaCl. The final ciphertext is the concatenation of the AES-256-GCM cipher text
with fixed size repeating blocks of NaCl ciphertext containing the key necessary to decrypt the original message. 

### Why Not Just Use PGP?
Frankly, you probably should. This project is an experiment aimed at making NaCl easier to use.
The only real benefit to Pact is that the keys required for secure communication are 16 
times smaller than the currently recommended 4096-bit RSA keys used for PGP. Pact also aims to be marginally 
easier to use.

### How Does Pact Secure A Message
When Pact encrypts a message it does so using AES-256 in [Galois/Counter Mode](https://en.wikipedia.org/wiki/Galois/Counter_Mode)
with a [randomly generated nonce and key](https://github.com/MattSurabian/msg/blob/master/entropy.go#L25-L37). 
Messages are encrypted for a specific pact, or group of people, which are represented by a collection of public keys stored 
in Pact's configuration file (use `pact list` to see them). Pact loops through these public keys and encrypts the randomly 
generated AES-256-GCM key with each pact member's public key. That payload is then prefixed with the [fingerprint of the public
key](https://github.com/MattSurabian/msg/blob/master/keys.go#L106-L115) used for encryption, so on decryption the recipient can 
immediately know [which chunk of bytes to decrypt first](https://github.com/MattSurabian/msg/blob/master/decrypter.go#L43-L59)
in order to learn the key necessary to decrypt the original message.

### Isn't Combining Cryptographic Method Insecure?
Combining, yes. Concatenating, no. We assume that both AES-256-GCM and NaCl are PRPs(pseudo-random-permutations) 
or at worst PRFs (pseudo-random-functions); which is to say the output they produce is sufficiently indistinguishable 
from actual random output. The concatenation of two pseudo-random blocks is itself pseudo random. All parallelizable 
crypto algorithms rely on this principal. Pact takes advantage of producing a psuedo random block which can be intelligently 
sliced appart by an authorized recipient and securely decrypted.

## Getting Started
There are a couple of ways to get started with Pact. The easiest method is to download a compiled binary for your platform and just start using it. 
Unfortauntely I'm not yet setup to cross compile, so you'll have to do it yourself. The following steps should get you there:

1. Clone this repository anywhere you like.
1. Run `make`. This should create a `pact` binary which you can use directly like so: `./pact`; you can also copy the binary to `/usr/bin/` or `/usr/local/bin` to use it directly.
1. Run `pact config` to generate a config file. This will also generate a keypair if one does not already exist, and configure the "self" pact which will contain your own public key.
1. Running `pact list` will show all your pacts and the public keys they contain. A fresh configuration will only have a `self` pact
1. You should now be able to run the create and read methods! Try it: `pact create self "some message" | pact read`<commit_msg>Update readme with release link<commit_after># Pact
An experimental cryptographic messaging application which implements the experimental cryptographic 
library [MSG](https://github.com/MattSurabian/msg).

## Getting Started
There are a couple of ways to get started with Pact. The easiest method is to [download a compiled binary for your platform](https://github.com/MattSurabian/pact/releases) and just start using it. 
If you're interested in compiling it yourself, here's how to do it:

1. Clone this repository anywhere you like.
1. Run `make`. This should create a `pact` binary which you can use directly like so: `./pact`; you can also copy the binary to `/usr/bin/` or `/usr/local/bin` to use it directly.
1. Run `pact config` to generate a config file. This will also generate a keypair if one does not already exist, and configure the "self" pact which will contain your own public key.
1. Running `pact list` will show all your pacts and the public keys they contain. A fresh configuration will only have a `self` pact
1. You should now be able to run the create and read methods! Try it: `pact create self "some message" | pact read`

Of note, the `Makefile` and vendoring script are provided for user convenience, using them is not mandatory. This package is able to be built using the standard
Golang workflow.

## What Is Pact?
Pact is a CLI application that enables messages to be shared securely between many parties without the 
need for out of band secret sharing. Pact does this by relying on asymmetric cryptography to safeguard a
symmetric key. This allows two or more parties to communicate securely after exchanging only their public keys.

Pact offloads all of its crypto to the [MSG library](https://github.com/MattSurabian/msg) but this README 
will review the crypto operations as if Pact was doing all the heavy lifting so potential Pact users are given
sufficient context. As of this writing Pact is the only implementation of the MSG library.

If you're curious to take a deeper dive, effort was made to extensively document the [MSG library](https://github.com/MattSurabian/msg);
code explainations can be found in the comments and test cases.

### Asymmetric and Symmetric Crypto!?
Yes, but they are not used on top of one another. Unlike PGP, Pact does not rely on RSA or DSA public-key crypto. 
Instead, Pact uses [NaCl](http://nacl.cr.yp.to/), a more modern approach to public-key cryptography with 
secure keys that are only 32 bytes long. NaCl's simplicity and security come at a price. Multiple party
decryption of a single ciphertext is not possible without shared keys. Instead, new cipher
text must be created for each individual with which a user intends to communicate.

Pact solves this problem by using AES-256-GCM ([Galois/Counter Mode](https://en.wikipedia.org/wiki/Galois/Counter_Mode)) to secure the initial message and then
encrypts the secret key used for AES with NaCl. The final ciphertext is the concatenation of the AES-256-GCM cipher text
with fixed size repeating blocks of NaCl ciphertext containing the key necessary to decrypt the original message. 

### Why Not Just Use PGP?
Frankly, you probably should. This project is an experiment aimed at making NaCl easier to use.
The only real benefit to Pact is that the keys required for secure communication are 16 
times smaller than the currently recommended 4096-bit RSA keys used for PGP. Pact also aims to be marginally 
easier to use.

### How Does Pact Secure A Message
When Pact encrypts a message it does so using AES-256 in [Galois/Counter Mode](https://en.wikipedia.org/wiki/Galois/Counter_Mode)
with a [randomly generated nonce and key](https://github.com/MattSurabian/msg/blob/master/entropy.go#L25-L37). 
Messages are encrypted for a specific pact, or group of people, which are represented by a collection of public keys stored 
in Pact's configuration file (use `pact list` to see them). Pact loops through these public keys and encrypts the randomly 
generated AES-256-GCM key with each pact member's public key. That payload is then prefixed with the [fingerprint of the public
key](https://github.com/MattSurabian/msg/blob/master/keys.go#L106-L115) used for encryption, so on decryption the recipient can 
immediately know [which chunk of bytes to decrypt first](https://github.com/MattSurabian/msg/blob/master/decrypter.go#L43-L59)
in order to learn the key necessary to decrypt the original message.

### Isn't Combining Cryptographic Method Insecure?
Combining, yes. Concatenating, no. We assume that both AES-256-GCM and NaCl are PRPs(pseudo-random-permutations) 
or at worst PRFs (pseudo-random-functions); which is to say the output they produce is sufficiently indistinguishable 
from actual random output. The concatenation of two pseudo-random blocks is itself pseudo random. All parallelizable 
crypto algorithms rely on this principal. Pact takes advantage of producing a psuedo random block which can be intelligently 
sliced appart by an authorized recipient and securely decrypted.
{'fraction_non_alphanumeric': 0.056198011767092715, 'fraction_numerical': 0.00852099817407182, 'mean_word_length': 4.53876404494382, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 17, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2665090', 'n_tokens_mistral': 2722, 'n_tokens_neox': 2508, 'n_words': 1434}