Go to file
Didactic Drunk 8da7fb47ec PWhash add key derivation. 2019-06-27 08:03:33 -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 PWhash add key derivation. 2019-06-27 08:03:33 -07:00
spec PWhash add key derivation. 2019-06-27 08:03:33 -07:00
src PWhash add key derivation. 2019-06-27 08:03:33 -07:00
.editorconfig
.gitignore
.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
README.md Documentation additions [ci skip] 2019-06-27 06:12:20 -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

README.md

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
    • Salsa20
    • XSalsa20
    • ChaCha20
    • XChaCha20
  • 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.

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