Expand description

EZNaCl is an MPL2.0-licensed library that wraps around LibSodium and gets as close to push-button cryptography as a developer can feasibly be. At the same time, because it’s cryptography, be very careful applying it–you can still shoot yourself in the foot.

No guarantees of any kind are provided with the library even though it has been written with care.

Also, please don’t use this code to place important crypto keys in your code or embed backdoors. No one needs that kind of drama.

Encryption and Decryption

Regardless of whether or not you are using public key or secret key cryptography, the usage is the same:

  1. Instantiate your key, either using generate() or from an existing CryptoString.
  2. Call encrypt() or decrypt() on your data
  3. Profit

Encryption Example

use eznacl::*;

let keypair = EncryptionPair::generate("CURVE25519").unwrap();

let testdata = "This is some encryption test data";
let encrypted_data = keypair.encrypt(testdata.as_bytes()).unwrap();

println!(
	"\nUnencrypted data:\n{}\nEncrypted data:\n{}",
	testdata,
	encrypted_data.as_str());

The structs to use for encryption and decryption are EncryptionPair and SecretKey. If you only have access to a public key, then you will use EncryptionKey instead. It is possible to substitute SecretKey for EncryptionPair in the above example and achieve the same results using symmetric encryption.

Signing and Verification

Signature-handling is little different. Instead of using EncryptionPair, you will use SigningPair.

use eznacl::*;

let signpair = SigningPair::generate("ED25519").unwrap();

let testdata = "This is some test data to sign";
let signature = match signpair.sign(testdata.as_bytes()) {
	Ok(cs) => cs,
	Err(_) => panic!("signing failure"),
};
println!("\nSignature for data: {}", signature);

match signpair.verify(testdata.as_bytes(), &signature) {
	Ok(v) => {
		if v {
			println!("Verified signature")
		} else {
			println!("Signature failed to verify")
		}
	},
	Err(e) => {
		println!("Error verifying signature: {}", e);
	}
}

Hashing

Generating hashes of data is literally as simple as possible for cases where data will fit into memory.

use eznacl::*;
let testdata = "This is some test data to hash";
let hash = get_hash("sha-256", testdata.as_bytes()).unwrap();
println!("\nTest data:\n{}\nHash of test data:\n{}\n", testdata, hash);

Keep in mind that this form of hashing is not intended for passwords. This is because these hash algorithms are designed to be fast and will not provide protection against brute force attacks. Instead, use EzNaCl’s password hashing facilities.

use eznacl::*;
let password = "This is my secret password";
let pwdhash = hash_password(&password, &HashStrength::Basic);
println!("\nPassword: {}\nPassword Hash:\n{}\n", password, pwdhash);

Note: the password hashing API is not 100% stabilized and may see minor changes in the future.

Despite the name, the Basic level of hashing strength is suitable for most situations. In its current implementation, the different password levels utilize different amounts of RAM.

  • Basic: 1MB
  • Extra: 2MB
  • Secret: 4MB
  • Extreme: 8MB

On an Intel i5-4590S, the Basic level of protection requires roughly 1 second to hash the password and only smaller differences on more or less powerful computers. For those situations requiring greater control over password hashing parameters, see hash_password_enhanced().

Using Existing Keys and Other Miscellaneous

EzNaCl is designed to interact with keys, signatures, and hashes as strings, not raw binary data. If you have existing binary key(s) you wish to utilize, create CryptoStrings from them using from_bytes() and supplying the algorithm used. From there, create the key/keypair itself using the from method.

For more information on supported algorithms, see the documentation for the corresponding functions:

Structs

A class to store cryptography-related binary data encoded as text and associated with an algorithm.
A Curve25519 encryption key
An asymmetric encryption keypair
An XSalsa20 symmetric encryption key
An Ed25519 asymmetric signing keypair
An Ed25519 verification key

Enums

The HashStrength type specifies how strong of a password hash is requested. Despite the term ‘Basic’, it provides the recommended 1 second processing time on a 4th-generation Intel i5 and an acceptable processing time on computers with less or more processor power. The other levels increase the memory cost, increasing processing time without undue strain on weaker hardware.
The KeyUsage type denotes the usage of a cryptography key, such as encryption, decryption, or both.

Traits

The CryptoInfo trait is implemented by encryption- and signature-related keys to convey what they are and what operation(s) they are to be used for.
The Decryptor trait is implemented by any decryption key
The Encryptor trait is implemented by any encryption key
The Private trait defines an interface for getting the key data in various formats
The PublicKey trait defines an interface for getting the key data in various formats
The Sign trait is implemented by any private signing key
The Verify trait is implemented by any public signature verification key

Functions

Returns a true if the given password matches the given hash
GetHash generates a CryptoString hash of the supplied data. Currently the supported algorithms are BLAKE2B-256, BLAKE2B-512, K12-256, BLAKE3-256, and SHA-256.
Returns the name of the hash algorithm recommended for the library based on if a certified algorithm is required.
Returns the asymmetric encryption algorithms supported by the library. Currently the only supported algorithm is Curve25519, which is included in drafts for FIPS 186-5. This is because of how tricky RSA can be to get right in addition to the massive key sizes required for good security.
Returns the hash algorithms supported by the library. NOTE: these algorithms are NOT for creating password hashes. Please use the hash_password() call for password hashing.
Returns the cryptographic signing algorithms supported by the library. Currently the only supported signing algorithm available is Ed25519, although ECDSA is planned.
Returns the symmetric encryption algorithms supported by the library. Currently the only supported encryption algorithm is XSalsa20, although AES support is planned.
hash_password is a simple function to turn a string into a 256-bit Argon2 password hash. If you don’t want to bother fine-tuning your Argon2id parameters and just want something simple and secure for day-to-day use, use this.
hash_password_enhanced() provides greater control over the password hashing process. Generally speaking, threads should be double your available CPU cores. Dial in the memory cost to roughly achieve your computation time and then adjust the time cost from there.
Initializes the underlying SodiumOxide library, which is needed for thread safety.
Returns true if the specified algorithm is one supported by the library, regardless of type.