Go to file
2019-06-27 13:52:09 -07:00
benchmarks Add blake2b benchmark and examples/pwhash_selector.cr 2019-06-25 19:24:21 -07:00
build Automatically detect and build libsodium from source on systems with old or missing libsodium's. 2019-06-26 18:28:08 -07:00
examples Enhance pwhash_selector example and add table output [skip ci] 2019-06-27 09:54:25 -07:00
spec Add Chalsa stream ciphers. 2019-06-27 13:52:09 -07:00
src Add Chalsa stream ciphers. 2019-06-27 13:52:09 -07:00
.editorconfig Initial commit 2017-07-11 22:15:35 -05:00
.gitignore Initial commit 2017-07-11 22:15:35 -05:00
.travis.yml Automatically detect and build libsodium from source on systems with old or missing libsodium's. 2019-06-26 18:28:08 -07:00
LICENSE Initial commit 2017-07-11 22:15:35 -05:00
README.md Add Chalsa stream ciphers. 2019-06-27 13:52:09 -07:00
shard.yml Automatically detect and build libsodium from source on systems with old or missing libsodium's. 2019-06-26 18:28:08 -07:00

cox

Build Status

Updated Crystal bindings for the libsodium API

Given a recipients public key, you can encrypt and sign a message for them. Upon receipt, they can decrypt and authenticate the message as having come from you.

Installation

Optionally Install libsodium. A recent version of libsodium is automatically downloaded and compiled if you don't install your own version.

Add this to your application's shard.yml:

dependencies:
  cox:
    github: didactic-drunk/cox

Features

  • Public-Key Cryptography
    • Crypto Box Easy
    • Sealed Box
    • Combined Signatures
    • Detached Signatures
  • Secret-Key Cryptography
    • Secret Box
    • XSalsa20
    • Salsa20
    • XChaCha20
    • ChaCha20 Ietf
    • ChaCha20
  • Hashing
    • Blake2b
    • SipHash
  • Password Hashing
    • Argon2 (Use for new applications)
    • Scrypt (For compatibility with older applications)
  • Other
    • Key Derivation
    • One time auth

Several libsodium API's are already provided by Crystal:

Usage

require "cox"

data = "Hello World!"

# Alice is the sender
alice = Cox::KeyPair.new

# Bob is the recipient
bob = Cox::KeyPair.new

# Encrypt a message for Bob using his public key, signing it with Alice's
# secret key
nonce, encrypted = Cox.encrypt(data, bob.public, alice.secret)

# Decrypt the message using Bob's secret key, and verify its signature against
# Alice's public key
decrypted = Cox.decrypt(encrypted, nonce, alice.public, bob.secret)

String.new(decrypted) # => "Hello World!"

Public key signing

message = "Hello World!"

signing_pair = Cox::SignKeyPair.new

# Sign the message
signature = Cox.sign_detached(message, signing_pair.secret)

# And verify
Cox.verify_detached(signature, message, signing_pair.public) # => true

Secret Key Encryption

key = Cox::SecretKey.random

message = "foobar"
encrypted, nonce = key.encrypt_easy message

# On the other side.
key = Cox::SecretKey.new key
message = key.decrypt_easy encrypted, nonce

Blake2b

key = Bytes.new Cox::Blake2B::KEY_SIZE
salt = Bytes.new Cox::Blake2B::SALT_SIZE
personal = Bytes.new Cox::Blake2B::PERSONAL_SIZE
out_size = 64 # bytes between Cox::Blake2B::OUT_SIZE_MIN and Cox::Blake2B::OUT_SIZE_MAX
data = "data".to_slice

# output_size, key, salt, and personal are optional.
digest = Cox::Blake2b.new out_size, key: key, salt: salt, personal: personal
digest.update data
output = d.hexdigest

digest.reset # Reuse existing object to hash again.
digest.update data
output = d.hexdigest

Key derivation

kdf = Cox::Kdf.new

# kdf.derive(8_byte_context, subkey_size, subkey_id)
subkey1 = kdf.derive "context1", 16, 0
subkey2 = kdf.derive "context1", 16, 1
subkey3 = kdf.derive "context2", 32, 0
subkey4 = kdf.derive "context2", 64, 1

Password Hashing

pwhash = Cox::Pwhash.new

pwhash.memlimit = Cox::Pwhash::MEMLIMIT_MIN
pwhash.opslimit = Cox::Pwhash::OPSLIMIT_MIN

pass = "1234"
hash = pwhash.hash_str pass
pwhash.verify hash, pass

Use examples/pwhash_selector.cr to help choose ops/mem limits.

Example output: Ops limit →

1 4 16 64 256 1024 4096 16384 65536 262144 1048576
8K 0.542s 2.114s
32K 0.513s 2.069s
128K 0.530s 2.121s
512K 0.566s 2.237s
2048K 0.567s 2.290s
8192K 0.670s 2.542s
32768K 0.684s 2.777s
131072K 0.805s 3.106s
524288K 0.504s 1.135s 3.661s
2097152K 2.119s
Memory

Contributing

  1. Fork it ( https://github.com/didactic-drunk/cox/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors