compact_argon2 0.1.1

Thin wrapper around the argon2 crate to improve ergonomics and provide a smaller serialization format
Documentation
# compact_argon2

The ergonomics of the [`argon2`](https://crates.io/crates/argon2) crate sucks.
This crate provides a thin wrapper around `argon2`'s methods and an alternate,
much smaller binary serialization format. It uses whatever the default
parameters of `argon2` current are, but uses deserialized parameters during
verification, just like the `argon2` crate. It's hardcoded to use the
`argon2id` algorithm with the default salt and output lengths because get real.

## Usage

```rs
let password = b"hunter2";

let hash = compact_argon2::hash(password).unwrap();

assert!(hash.verify(password.as_bytes()).unwrap());

// save to a file
let bytes: [u8; 64] = hash.as_bytes();
```

## `serde` compatibility

Enable the `serde` feature for `Serialize` and `Deserialize` `impl`s on `Hash`.

```rs
#[derive(Serialize, Deserialize)]
struct User {
    pub name: String,
    pub password: compact_argon2::Hash,
}
```

## hex representation

Enable the `hex` feature to convert `Hash` to/from a hex string.

```rs
let hash = compact_argon2::hash(b"hunter2").unwrap();
let hex_string = hash.to_string();
let parsed_hash = hex_string.parse().unwrap();

assert_eq!(hash, parsed_hash);

// Can also be used with serde

#[derive(Serialize, Deserialize)]
struct User {
    pub name: String,
    #[serde(with = "compact_argon2::hex")]
    pub password: compact_argon2::Hash,
}
```

## `sqlx::Postgres` compatibility

Enable the `postgres` feature to use `Hash` with sqlx's PostgeSQL driver.

```rs
#[derive(FromRow)]
struct User {
    pub name: String,
    pub password: compact_argon2::Hash,
}

let mut user: User = sqlx::query_as("SELECT * FROM users WHERE name=?")
    .bind("AzureDiamond")
    .fetch_one(&pool)
    .await?;

let new_password = compact_argon2::hash(b"hunter2").unwrap();

sqlx::query("UPDATE users SET password=? WHERE name=?")
    .bind(&new_password)
    .bind(&user.name)
    .execute(&pool)
    .await?;
```

## Serialized format

The `Hash` struct is fully stack allocated and serializes to
a nice and even 64 bytes (128 in hex).

- litte endian u32 (4 bytes) - `t_cost`
- litte endian u32 (4 bytes) - `p_cost`
- litte endian u32 (4 bytes) - `m_cost`
- litte endian u32 (4 bytes) - Version
- 16 bytes - Salt
- 32 bytes - Hash output

## Zero-copy deserialization

On little-endian targets, enable the `zerocopy` feature to deserialize
`&'a [u8]` into `&'a Hash` directly, copying only 16 bytes to verify params.

```rs
let original_hash = compact_argon2::hash(b"hunter2").unwrap();
let bytes = original_hash.as_bytes();
let reconstructed = compact_argon2::Hash::checked_cast(&bytes).unwrap();

assert_eq!(reconstructed, &original_hash);
```