Rename project from "cox" to "sodium.cr".

This commit is contained in:
Didactic Drunk 2019-06-28 16:17:09 -07:00
parent 8e939b9518
commit a4b1b8071c
33 changed files with 135 additions and 136 deletions

View File

@ -3,7 +3,7 @@ os:
- linux
- osx
install:
- COX_BUILD_DEBUG=1 LIBSODIUM_BUILD_DIR=$HOME/libsodium ./build/libsodium_install.sh
- SODIUM_BUILD_DEBUG=1 LIBSODIUM_BUILD_DIR=$HOME/libsodium ./build/libsodium_install.sh
before_script:
- export LIBSODIUM_BUILD_DIR=$HOME/libsodium
after_failure:

View File

@ -1,6 +1,6 @@
# cox
[![Build Status](https://travis-ci.org/didactic-drunk/cox.svg?branch=master)](https://travis-ci.org/didactic-drunk/cox)
[![Docs](https://img.shields.io/badge/docs-available-brightgreen.svg)](https://didactic-drunk.github.io/cox/)
# sodium.cr
[![Build Status](https://travis-ci.org/didactic-drunk/sodium.cr.svg?branch=master)](https://travis-ci.org/didactic-drunk/sodium.cr)
[![Docs](https://img.shields.io/badge/docs-available-brightgreen.svg)](https://didactic-drunk.github.io/sodium.cr/)
Updated Crystal bindings for the [libsodium API](https://libsodium.gitbook.io/doc/)
@ -56,8 +56,8 @@ Add this to your application's `shard.yml`:
```yaml
dependencies:
cox:
github: didactic-drunk/cox
sodium.cr:
github: didactic-drunk/sodium.cr
```
## What should I use for my application?
@ -65,16 +65,16 @@ dependencies:
| Class | |
| --- | --- |
| `CryptoBox` `Sign` `SecretBox` | I don't know much about crypto. |
| [`Cox::CryptoBox::SecretKey`](https://didactic-drunk.github.io/cox/Cox/CryptoBox/SecretKey.html) | I want to encrypt + authenticate data using public key encryption. |
| [`Cox::Sign::SecretKey`](https://didactic-drunk.github.io/cox/Cox/Sign/SecretKey.html) | I want to sign or verify messages without encryption. |
| [`Cox::SecretBox`](https://didactic-drunk.github.io/cox/Cox/SecretBox.html) | I have a shared key and want to encrypt + authenticate data. |
| [`Sodium::CryptoBox::SecretKey`](https://didactic-drunk.github.io/sodium.cr/Sodium/CryptoBox/SecretKey.html) | I want to encrypt + authenticate data using public key encryption. |
| [`Sodium::Sign::SecretKey`](https://didactic-drunk.github.io/sodium.cr/Sodium/Sign/SecretKey.html) | I want to sign or verify messages without encryption. |
| [`Sodium::SecretBox`](https://didactic-drunk.github.io/sodium.cr/Sodium/SecretBox.html) | I have a shared key and want to encrypt + authenticate data. |
| AEAD | I have a shared key and want encrypt + authenticate streamed data. (Not implemented yet) |
| [`Cox::Digest::Blake2b`](https://didactic-drunk.github.io/cox/Cox/Digest::Blake2b.html) | I want to hash data fast and securely. |
| `Cox::Digest::SipHash` | I want to hash data really fast and less securely. (Not implemented yet) |
| `Cox::Pwhash` | I want to hash a password and store it. |
| `Cox::Pwhash` | I want to derive a key from a password. |
| `Cox::Kdf` | I have a high quality master key and want to make subkeys. |
| [`Cox::Cipher::Chalsa`](https://didactic-drunk.github.io/cox/Cox/Cipher/Chalsa.html) | What goes with guacamole? |
| [`Sodium::Digest::Blake2b`](https://didactic-drunk.github.io/sodium.cr/Sodium/Digest::Blake2b.html) | I want to hash data fast and securely. |
| `Sodium::Digest::SipHash` | I want to hash data really fast and less securely. (Not implemented yet) |
| `Sodium::Pwhash` | I want to hash a password and store it. |
| `Sodium::Pwhash` | I want to derive a key from a password. |
| `Sodium::Kdf` | I have a high quality master key and want to make subkeys. |
| [`Sodium::Cipher::Chalsa`](https://didactic-drunk.github.io/sodium.cr/Sodium/Cipher/Chalsa.html) | What goes with guacamole? |
| Everything else | I want to design my own crypto protocol and probably do it wrong. |
@ -84,15 +84,15 @@ The `specs` provide the best examples of how to use or misuse this shard.
### CryptoBox easy encryption
```crystal
require "cox"
require "sodium"
data = "Hello World!"
# Alice is the sender
alice = Cox::CryptoBox::SecretKey.new
alice = Sodium::CryptoBox::SecretKey.new
# Bob is the recipient
bob = Cox::CryptoBox::SecretKey.new
bob = Sodium::CryptoBox::SecretKey.new
# Precompute a shared secret between alice and bob.
pair = alice.pair bob.public_key
@ -105,7 +105,7 @@ nonce, encrypted = pair.encrypt data
bob.pair alice.public_key do |pair|
# 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)
decrypted = Sodium.decrypt(encrypted, nonce, alice.public, bob.secret)
String.new(decrypted) # => "Hello World!"
end
@ -115,41 +115,41 @@ end
```crystal
message = "Hello World!"
secret_key = Cox::Sign::SecretKey.new
secret_key = Sodium::Sign::SecretKey.new
# Sign the message
signature = secret_key.sign_detached message
# Send secret_key.public_key to the recipient
public_key = Cox::Sign::PublicKey.new key_bytes
public_key = Sodium::Sign::PublicKey.new key_bytes
# raises Cox::Error::VerificationFailed on failure.
# raises Sodium::Error::VerificationFailed on failure.
public_key.verify_detached message, signature
```
### Secret Key Encryption
```crystal
key = Cox::SecretKey.new
key = Sodium::SecretKey.new
message = "foobar"
encrypted, nonce = key.encrypt_easy message
# On the other side.
key = Cox::SecretKey.new key
key = Sodium::SecretKey.new key
message = key.decrypt_easy encrypted, nonce
```
### Blake2b
```crystal
key = Bytes.new Cox::Digest::Blake2B::KEY_SIZE
salt = Bytes.new Cox::Digest::Blake2B::SALT_SIZE
personal = Bytes.new Cox::Digest::Blake2B::PERSONAL_SIZE
out_size = 64 # bytes between Cox::Digest::Blake2B::OUT_SIZE_MIN and Cox::Digest::Blake2B::OUT_SIZE_MAX
key = Bytes.new Sodium::Digest::Blake2B::KEY_SIZE
salt = Bytes.new Sodium::Digest::Blake2B::SALT_SIZE
personal = Bytes.new Sodium::Digest::Blake2B::PERSONAL_SIZE
out_size = 64 # bytes between Sodium::Digest::Blake2B::OUT_SIZE_MIN and Sodium::Digest::Blake2B::OUT_SIZE_MAX
data = "data".to_slice
# output_size, key, salt, and personal are optional.
digest = Cox::Digest::Blake2b.new out_size, key: key, salt: salt, personal: personal
digest = Sodium::Digest::Blake2b.new out_size, key: key, salt: salt, personal: personal
digest.update data
output = d.hexdigest
@ -160,7 +160,7 @@ output = d.hexdigest
### Key derivation
```crystal
kdf = Cox::Kdf.new
kdf = Sodium::Kdf.new
# kdf.derive(8_byte_context, subkey_id, subkey_size)
subkey1 = kdf.derive "context1", 0, 16
@ -171,10 +171,10 @@ subkey4 = kdf.derive "context2", 1, 64
### Password Hashing
```crystal
pwhash = Cox::Pwhash.new
pwhash = Sodium::Pwhash.new
pwhash.memlimit = Cox::Pwhash::MEMLIMIT_MIN
pwhash.opslimit = Cox::Pwhash::OPSLIMIT_MIN
pwhash.memlimit = Sodium::Pwhash::MEMLIMIT_MIN
pwhash.opslimit = Sodium::Pwhash::OPSLIMIT_MIN
pass = "1234"
hash = pwhash.hash_str pass
@ -203,7 +203,7 @@ Ops limit →
## Contributing
1. Fork it ( https://github.com/didactic-drunk/cox/fork )
1. Fork it ( https://github.com/didactic-drunk/sodium.cr/fork )
2. **Install a formatting check git hook (ln -sf ../../scripts/git/pre-commit .git/hooks)**
3. Create your feature branch (git checkout -b my-new-feature)
4. Commit your changes (git commit -am 'Add some feature')

View File

@ -1,5 +1,5 @@
require "benchmark"
require "../src/cox"
require "../src/sodium"
require "openssl"
require "openssl/digest"
@ -13,19 +13,19 @@ puts "'crystal run --release benchmarks/blake2b.cr sha1 sha256'"
Benchmark.ips(warmup: 0.5) do |bm|
sizes.each_with_index do |size, i|
bm.report "blake2b new obj per iter #{size}" do
d = Cox::Digest::Blake2b.new 64
d = Sodium::Digest::Blake2b.new 64
d.update bufs[i]
d.digest
end
d = Cox::Digest::Blake2b.new output_size
d = Sodium::Digest::Blake2b.new output_size
bm.report "blake2b reset per iter #{size}" do
d.reset
d.update bufs[i]
d.digest
end
d = Cox::Digest::Blake2b.new output_size
d = Sodium::Digest::Blake2b.new output_size
dst = Bytes.new d.digest_size
bm.report "blake2b reset reusing buffer per iter #{size}" do
d.reset

View File

@ -52,7 +52,7 @@ openssl speed -evp blake2b512 md5
Doing md5 for 3s on 16384 size blocks: 125954 md5's in 2.99s
# In all tests crystal Cox::Blake2b(512) beats crystal OpenSSL::Digest::SHA256.
# In all tests crystal Sodium::Digest::Blake2b(512) beats crystal OpenSSL::Digest::SHA256.
# Using .reset instead of creating new objects gives a significant performance boost when hashing small data sizes.
# Reusing an output buffer with .reset gives a further performance boost when hashing small data sizes.
# New objects have a significant penalty for hashing small data sizes. Only problematic with iterative hashing or in a tight loop.

View File

@ -9,7 +9,7 @@ export MIN_LIBSODIUM_VERSION=1.0.18
export LIBSODIUM_SHA256=6f504490b342a4f8a4c4a02fc9b866cbef8622d5df4e5452b46be121e46636c1
[ ! -z "$COX_BUILD_DEBUG" ] && export COX_BUILD_VERBOSE=1
[ ! -z "$SODIUM_BUILD_DEBUG" ] && export SODIUM_BUILD_VERBOSE=1
function version { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; }
@ -17,13 +17,13 @@ if `pkg-config libsodium --exists`; then
PKG_VER=`pkg-config libsodium --modversion`
if [ $(version "$PKG_VER") -ge $(version "$MIN_LIBSODIUM_VERSION") ]; then
[ ! -z "$COX_BUILD_VERBOSE" ] && echo "Using packaged libsodium."
[ ! -z "$SODIUM_BUILD_VERBOSE" ] && echo "Using packaged libsodium."
else
[ ! -z "$COX_BUILD_VERBOSE" ] echo "System packaged libsodium is too old."
[ ! -z "$SODIUM_BUILD_VERBOSE" ] echo "System packaged libsodium is too old."
export LIBSODIUM_INSTALL=1
fi
else
[ ! -z "$COX_BUILD_VERBOSE" ] && echo "Missing libsodium system package."
[ ! -z "$SODIUM_BUILD_VERBOSE" ] && echo "Missing libsodium system package."
export LIBSODIUM_INSTALL=1
fi

View File

@ -12,8 +12,8 @@ set -e
#export LIBSODIUM_INSTALL=1
if [ "$LIBSODIUM_INSTALL" != "1" ]; then
[ ! -z "$COX_BUILD_VERBOSE" ] echo "Skipping libsodium build."
exit
[ ! -z "$SODIUM_BUILD_VERBOSE" ] && echo "Skipping libsodium build."
exit 0
fi
@ -22,7 +22,7 @@ cd "$LIBSODIUM_BUILD_DIR"
if [ ! -f "$LIBSODIUM_INSTALL_PATH/include/sodium.h" ]; then
[ ! -z "$COX_BUILD_DEBUG" ] && set -x
[ ! -z "$SODIUM_BUILD_DEBUG" ] && set -x
DIRNAME=libsodium-"$MIN_LIBSODIUM_VERSION"
TGZ_FILENAME="$DIRNAME".tar.gz
@ -58,11 +58,11 @@ if [ ! -f "$LIBSODIUM_INSTALL_PATH/include/sodium.h" ]; then
touch .make.install.done
fi
[ ! -z "$COX_BUILD_VERBOSE" ] && echo "Finished building libsodium."
[ ! -z "$SODIUM_BUILD_VERBOSE" ] && echo "Finished building libsodium."
else
# find "$LIBSODIUM_INSTALL_PATH"
[ ! -z "$COX_BUILD_VERBOSE" ] && echo "Using already built libsodium."
[ ! -z "$SODIUM_BUILD_VERBOSE" ] && echo "Using already built libsodium."
fi
exit 0

View File

@ -1,5 +1,4 @@
require "../src/cox"
require "tallboy"
require "../src/sodium"
if ARGV.empty?
puts "Help select Pwhash ops/mem limits for your application."
@ -15,8 +14,8 @@ time_limit = if t = ARGV.shift?
else
time_min * 4
end
mem_limit = (ARGV.shift?.try &.to_i || (Cox::Pwhash::MEMLIMIT_MAX)).to_u64
pwhash = Cox::Pwhash.new
mem_limit = (ARGV.shift?.try &.to_i || (Sodium::Pwhash::MEMLIMIT_MAX)).to_u64
pwhash = Sodium::Pwhash.new
pass = "1234"
# data = Array(Array({UInt64, UInt64, Float64})).new
@ -36,9 +35,9 @@ def bytes_str(b)
"%5d#{suffix}" % b
end
pwhash.memlimit = Cox::Pwhash::MEMLIMIT_MIN
pwhash.memlimit = Sodium::Pwhash::MEMLIMIT_MIN
loop do
pwhash.opslimit = Cox::Pwhash::OPSLIMIT_MIN
pwhash.opslimit = Sodium::Pwhash::OPSLIMIT_MIN
row = ["%5dK" % (pwhash.memlimit / 1024)]
data << row
@ -72,7 +71,7 @@ loop do
puts ""
break if pwhash.memlimit >= mem_limit
break if pwhash.opslimit == Cox::Pwhash::OPSLIMIT_MIN # Couldn't get past 1 iteration before going over time.
break if pwhash.opslimit == Sodium::Pwhash::OPSLIMIT_MIN # Couldn't get past 1 iteration before going over time.
pwhash.memlimit *= 4
end
# header << "Ops limit"

View File

@ -1,4 +1,4 @@
name: cox
name: sodium.cr
version: 0.1.0
authors:
@ -8,6 +8,6 @@ development_dependencies:
ghshard:
github: bcardiff/ghshard
crystal: 0.24.1
crystal: 0.28.0
license: MIT

View File

@ -1,6 +1,6 @@
require "./spec_helper"
describe Cox do
describe Sodium do
# Finished in 71 microseconds
# 1 examples, 2 failures, 5 errors, 0 pending
# What a man.

View File

@ -23,10 +23,10 @@ test_vectors = [
},
]
describe Cox::Digest::Blake2b do
describe Sodium::Digest::Blake2b do
it "libsodium comparisons" do
libsodium_comparisons.each do |vec|
d = Cox::Digest::Blake2b.new vec[:out_size], key: vec[:key].try(&.hexbytes)
d = Sodium::Digest::Blake2b.new vec[:out_size], key: vec[:key].try(&.hexbytes)
d.update vec[:input].hexbytes
d.hexdigest.should eq vec[:output]
end
@ -34,31 +34,31 @@ describe Cox::Digest::Blake2b do
it "test vectors" do
test_vectors.each do |vec|
d = Cox::Digest::Blake2b.new 64, key: vec[:key].hexbytes
d = Sodium::Digest::Blake2b.new 64, key: vec[:key].hexbytes
d.update vec[:input].hexbytes
d.hexdigest.should eq vec[:output]
end
end
it "produces different output with different salt or personal params" do
key = Bytes.new Cox::Digest::Blake2b::KEY_SIZE
salt = Bytes.new Cox::Digest::Blake2b::SALT_SIZE
salt2 = Bytes.new Cox::Digest::Blake2b::SALT_SIZE
key = Bytes.new Sodium::Digest::Blake2b::KEY_SIZE
salt = Bytes.new Sodium::Digest::Blake2b::SALT_SIZE
salt2 = Bytes.new Sodium::Digest::Blake2b::SALT_SIZE
salt2 = salt.dup
salt2[0] = 1
personal = Bytes.new Cox::Digest::Blake2b::PERSONAL_SIZE
personal = Bytes.new Sodium::Digest::Blake2b::PERSONAL_SIZE
personal2 = personal.dup
personal2[0] = 1
d = Cox::Digest::Blake2b.new key: key, salt: salt, personal: personal
d = Sodium::Digest::Blake2b.new key: key, salt: salt, personal: personal
d.update "foo".to_slice
output = d.hexdigest
d = Cox::Digest::Blake2b.new key: key, salt: salt2, personal: personal
d = Sodium::Digest::Blake2b.new key: key, salt: salt2, personal: personal
d.update "foo".to_slice
saltout = d.hexdigest
d = Cox::Digest::Blake2b.new key: key, salt: salt, personal: personal2
d = Sodium::Digest::Blake2b.new key: key, salt: salt, personal: personal2
d.update "foo".to_slice
personalout = d.hexdigest
@ -69,19 +69,19 @@ describe Cox::Digest::Blake2b do
it "raises on invalid " do
expect_raises ArgumentError do
Cox::Digest::Blake2b.new key: Bytes.new(128)
Sodium::Digest::Blake2b.new key: Bytes.new(128)
end
expect_raises ArgumentError do
Cox::Digest::Blake2b.new salt: Bytes.new(1)
Sodium::Digest::Blake2b.new salt: Bytes.new(1)
end
expect_raises ArgumentError do
Cox::Digest::Blake2b.new salt: Bytes.new(128)
Sodium::Digest::Blake2b.new salt: Bytes.new(128)
end
expect_raises ArgumentError do
Cox::Digest::Blake2b.new personal: Bytes.new(128)
Sodium::Digest::Blake2b.new personal: Bytes.new(128)
end
end
end

View File

@ -1,13 +1,13 @@
require "../../spec_helper"
require "../../../src/cox/cipher/chalsa"
require "../../../src/sodium/cipher/chalsa"
{% for name in %w(XSalsa20 Salsa20 XChaCha20 ChaCha20Ietf ChaCha20) %}
# TODO: verify against test vectors.
describe Cox::Cipher::{{ name.id }} do
describe Sodium::Cipher::{{ name.id }} do
it "xors" do
data = Bytes.new(100)
cipher1 = Cox::Cipher::{{ name.id }}.new
cipher2 = Cox::Cipher::{{ name.id }}.new
cipher1 = Sodium::Cipher::{{ name.id }}.new
cipher2 = Sodium::Cipher::{{ name.id }}.new
key = cipher1.random_key
nonce = cipher1.random_nonce
output = cipher1.update data

View File

@ -1,14 +1,14 @@
require "../../spec_helper"
describe Cox::CryptoBox::SecretKey do
describe Sodium::CryptoBox::SecretKey do
it "easy encrypt/decrypt" do
data = "Hello World!"
# Alice is the sender
alice = Cox::CryptoBox::SecretKey.new
alice = Sodium::CryptoBox::SecretKey.new
# Bob is the recipient
bob = Cox::CryptoBox::SecretKey.new
bob = Sodium::CryptoBox::SecretKey.new
# Encrypt a message for Bob using his public key, signing it with Alice's
# secret key

View File

@ -2,12 +2,12 @@ require "../spec_helper"
CONTEXT = "8_bytess"
describe Cox::Kdf do
describe Sodium::Kdf do
it "generates master key" do
kdf1 = Cox::Kdf.new
kdf1 = Sodium::Kdf.new
# verify loading saved key
kdf2 = Cox::Kdf.from_base64 kdf1.to_base64
kdf2 = Sodium::Kdf.from_base64 kdf1.to_base64
# verify generated subkey's are the same after loading
key1_s1 = kdf1.derive CONTEXT, 0, 16
@ -16,7 +16,7 @@ describe Cox::Kdf do
end
it "generates different keys" do
kdf1 = Cox::Kdf.new
kdf1 = Sodium::Kdf.new
subkey1 = kdf1.derive CONTEXT, 0, 16
subkey2 = kdf1.derive CONTEXT, 1, 16
subkey1.should_not eq subkey2

View File

@ -1,27 +1,27 @@
require "../spec_helper"
private def pw_min
pwhash = Cox::Pwhash.new
pwhash = Sodium::Pwhash.new
# set to minimum to speed up tests
pwhash.memlimit = Cox::Pwhash::MEMLIMIT_MIN
pwhash.opslimit = Cox::Pwhash::OPSLIMIT_MIN
pwhash.memlimit = Sodium::Pwhash::MEMLIMIT_MIN
pwhash.opslimit = Sodium::Pwhash::OPSLIMIT_MIN
pwhash
end
describe Cox::Pwhash do
describe Sodium::Pwhash do
it "hashes and verifies a password" do
pwhash = pw_min
pass = "1234"
hash = pwhash.store pass
pwhash.verify hash, pass
expect_raises(Cox::Pwhash::PasswordVerifyError) do
expect_raises(Sodium::Pwhash::PasswordVerifyError) do
pwhash.verify hash, "5678"
end
pwhash.needs_rehash?(hash).should be_false
pwhash.opslimit = Cox::Pwhash::OPSLIMIT_MAX
pwhash.opslimit = Sodium::Pwhash::OPSLIMIT_MAX
pwhash.needs_rehash?(hash).should be_true
end
@ -34,7 +34,7 @@ describe Cox::Pwhash do
it "derives a key from a password" do
pwhash = pw_min
pwhash.algorithm = Cox::Pwhash::Algorithm::Argon2id13
pwhash.algorithm = Sodium::Pwhash::Algorithm::Argon2id13
salt = pwhash.salt
key1 = pwhash.key_derive salt, "foo", 16
key2 = pwhash.key_derive salt, "foo", 16

View File

@ -1,15 +1,15 @@
require "../spec_helper"
describe Cox::SecretBox do
describe Sodium::SecretBox do
it "encrypts/decrypts" do
key = Cox::SecretBox.new
key = Sodium::SecretBox.new
message = "foobar"
encrypted, nonce = key.encrypt_easy message
decrypted = key.decrypt_easy encrypted, nonce
message.should eq String.new(decrypted)
expect_raises(Cox::Error::DecryptionFailed) do
expect_raises(Sodium::Error::DecryptionFailed) do
key.decrypt_easy "badmsgbadmsgbadmsgbadmsgbadmsg".to_slice, nonce
end
end

View File

@ -1,10 +1,10 @@
require "../../spec_helper"
require "../../../src/cox/sign/secret_key"
require "../../../src/sodium/sign/secret_key"
describe Cox::Sign::SecretKey do
describe Sodium::Sign::SecretKey do
it "signs and verifies" do
message = "foo"
skey = Cox::Sign::SecretKey.new
skey = Sodium::Sign::SecretKey.new
sig = skey.sign_detached message
skey.public_key.verify_detached message, sig
@ -12,10 +12,10 @@ describe Cox::Sign::SecretKey do
it "signs and fails" do
message = "foo"
skey = Cox::Sign::SecretKey.new
skey = Sodium::Sign::SecretKey.new
sig = skey.sign_detached message
expect_raises Cox::Error::VerificationFailed do
expect_raises Sodium::Error::VerificationFailed do
skey.public_key.verify_detached "bar", sig
end
end

View File

@ -1,2 +1,2 @@
require "spec"
require "../src/cox"
require "../src/sodium"

View File

@ -1,6 +1,6 @@
require "random/secure"
module Cox
module Sodium
class Error < ::Exception
class VerificationFailed < Error
end
@ -14,8 +14,8 @@ module Cox
end
end
require "./cox/**"
require "./sodium/**"
if Cox::LibSodium.sodium_init == -1
if Sodium::LibSodium.sodium_init == -1
abort "Failed to init libsodium"
end

View File

@ -1,6 +1,6 @@
require "../lib_sodium"
module Cox::Cipher
module Sodium::Cipher
# The great beat you can eat!
#
# What? They're both dance?
@ -69,7 +69,7 @@ module Cox::Cipher
#
# This class mimicks the OpenSSL::Cipher interface with minor differences.
#
# See `spec/cox/cipher/chalsa_spec.cr` for examples on how to use this class.
# See `spec/sodium/cipher/chalsa_spec.cr` for examples on how to use this class.
class {{ key.id }} < Chalsa
# Xor's src with the cipher output and places in dst.
#
@ -78,12 +78,12 @@ module Cox::Cipher
if (key = @key) && (nonce = @nonce)
raise ArgumentError.new("src and dst bytesize must be identical") if src.bytesize != dst.bytesize
if LibSodium.crypto_stream_{{ val.id }}_xor_ic(dst, src, src.bytesize, nonce, @offset, key) != 0
raise Cox::Error.new("crypto_stream_{{ val.id }}_xor_ic")
raise Sodium::Error.new("crypto_stream_{{ val.id }}_xor_ic")
end
@offset += src.bytesize
dst
else
raise Cox::Error.new("key and nonce must be set before calling update #{@key.nil?} #{@nonce.nil?}")
raise Sodium::Error.new("key and nonce must be set before calling update #{@key.nil?} #{@nonce.nil?}")
end
end

View File

@ -1,6 +1,6 @@
require "../lib_sodium"
module Cox::CryptoBox
module Sodium::CryptoBox
class Pair
include Wipe

View File

@ -1,6 +1,6 @@
require "../lib_sodium"
module Cox::CryptoBox
module Sodium::CryptoBox
class PublicKey < Key
include Wipe
KEY_SIZE = LibSodium::PUBLIC_KEY_SIZE

View File

@ -1,6 +1,6 @@
require "../lib_sodium"
module Cox::CryptoBox
module Sodium::CryptoBox
class SecretKey < Key
include Wipe
KEY_SIZE = LibSodium::SECRET_KEY_SIZE

View File

@ -1,6 +1,6 @@
require "openssl/digest/digest_base"
module Cox::Digest
module Sodium::Digest
class Blake2b
# provides copying digest/hexdigest methods
include OpenSSL::DigestBase
@ -57,13 +57,13 @@ module Cox::Digest
personal = @have_personal ? @personal.to_unsafe : nil
if LibSodium.crypto_generichash_blake2b_init_salt_personal(@state, key, @key_size, @digest_size, salt, personal) != 0
raise Cox::Error.new("blake2b_init_key_salt_personal")
raise Sodium::Error.new("blake2b_init_key_salt_personal")
end
end
def update(data : Bytes)
if LibSodium.crypto_generichash_blake2b_update(@state, data, data.bytesize) != 0
raise Cox::Error.new("crypto_generichash_blake2b_update")
raise Sodium::Error.new("crypto_generichash_blake2b_update")
end
self
@ -81,7 +81,7 @@ module Cox::Digest
# Use .digest or .hexdigest instead.
def finish(dst : Bytes) : Bytes
if LibSodium.crypto_generichash_blake2b_final(@state, dst, dst.bytesize) != 0
raise Cox::Error.new("crypto_generichash_blake2b_final")
raise Sodium::Error.new("crypto_generichash_blake2b_final")
end
dst

View File

@ -1,4 +1,4 @@
module Cox
module Sodium
class Kdf
property bytes : Bytes
@ -25,7 +25,7 @@ module Cox
subkey = Bytes.new subkey_size
if (ret = LibSodium.crypto_kdf_derive_from_key(subkey, subkey.bytesize, subkey_id, context, @bytes)) != 0
raise Cox::Error.new("crypto_kdf_derive_from_key returned #{ret} (subkey size is probably out of range)")
raise Sodium::Error.new("crypto_kdf_derive_from_key returned #{ret} (subkey size is probably out of range)")
end
subkey
end

View File

@ -1,4 +1,4 @@
module Cox
module Sodium
abstract class Key
abstract def bytes

View File

@ -1,4 +1,4 @@
module Cox
module Sodium
@[Link(ldflags: "`#{__DIR__}/../../build/pkg-libs.sh #{__DIR__}/../..`")]
lib LibSodium
fun sodium_init : LibC::Int

View File

@ -1,7 +1,7 @@
require "./lib_sodium"
require "random/secure"
module Cox
module Sodium
class Nonce
NONCE_SIZE = LibSodium::NONCE_SIZE

View File

@ -1,11 +1,11 @@
module Cox
module Sodium
# [Argon2 Password Hashing](https://libsodium.gitbook.io/doc/password_hashing/the_argon2i_function)
# * #store #verify #needs_rehash? are used together for password verification.
# * #key_derive is used on it's own to generate password based keys.
#
# See `examples/pwhash_selector.cr` for help on selecting parameters.
class Pwhash
class PasswordVerifyError < Cox::Error
class PasswordVerifyError < Sodium::Error
end
OPSLIMIT_MIN = LibSodium.crypto_pwhash_opslimit_min
@ -39,7 +39,7 @@ module Cox
def store(pass)
outstr = Bytes.new LibSodium::PWHASH_STR_SIZE
if LibSodium.crypto_pwhash_str(outstr, pass, pass.bytesize, @opslimit, @memlimit) != 0
raise Cox::Error.new("crypto_pwhash_str")
raise Sodium::Error.new("crypto_pwhash_str")
end
outstr
end
@ -65,7 +65,7 @@ module Cox
when 1
true
else
raise Cox::Error.new("crypto_pwhash_str_needs_rehash")
raise Sodium::Error.new("crypto_pwhash_str_needs_rehash")
end
end
@ -76,7 +76,7 @@ module Cox
if alg = algorithm
key = Bytes.new key_bytes
if LibSodium.crypto_pwhash(key, key.bytesize, pass, pass.bytesize, salt, @opslimit, @memlimit, alg) != 0
raise Cox::Error.new("crypto_pwhash_str")
raise Sodium::Error.new("crypto_pwhash_str")
end
key
else

View File

@ -1,15 +1,15 @@
require "./lib_sodium"
module Cox
module Sodium
# [https://libsodium.gitbook.io/doc/secret-key_cryptography](https://libsodium.gitbook.io/doc/secret-key_cryptography)
#
# ```crystal
# key = Cox::SecretKey.new
# key = Sodium::SecretKey.new
# message = "foobar"
# encrypted, nonce = key.encrypt_easy message
#
# # On the other side.
# key = Cox::SecretKey.new key
# key = Sodium::SecretKey.new key
# message = key.decrypt_easy encrypted, nonce
# ```
class SecretBox < Key
@ -54,14 +54,14 @@ module Cox
raise ArgumentError.new("dst.bytesize must be src.bytesize + MAC_SIZE, got #{dst.bytesize}")
end
if LibSodium.crypto_secretbox_easy(dst, src, src.bytesize, nonce.to_slice, @bytes) != 0
raise Cox::Error.new("crypto_secretbox_easy")
raise Sodium::Error.new("crypto_secretbox_easy")
end
dst
end
def decrypt_easy(data : Bytes, nonce : Nonce) : Bytes
output_size = data.bytesize - MAC_SIZE
raise Cox::Error::DecryptionFailed.new("encrypted data too small #{data.bytesize}") if output_size <= 0
raise Sodium::Error::DecryptionFailed.new("encrypted data too small #{data.bytesize}") if output_size <= 0
output = Bytes.new output_size
decrypt_easy(data, output, nonce)
end
@ -71,7 +71,7 @@ module Cox
raise ArgumentError.new("dst.bytesize must be src.bytesize - MAC_SIZE, got #{dst.bytesize}")
end
if LibSodium.crypto_secretbox_open_easy(dst, src, src.bytesize, nonce.to_slice, @bytes) != 0
raise Cox::Error::DecryptionFailed.new("crypto_secretbox_easy")
raise Sodium::Error::DecryptionFailed.new("crypto_secretbox_easy")
end
dst
end

View File

@ -1,6 +1,6 @@
require "../lib_sodium"
module Cox
module Sodium
class Sign::PublicKey < Key
include Wipe
KEY_SIZE = LibSodium::PUBLIC_SIGN_SIZE
@ -24,7 +24,7 @@ module Cox
v = LibSodium.crypto_sign_verify_detached sig, message, message.bytesize, @bytes
if v != 0
raise Cox::Error::VerificationFailed.new("crypto_sign_verify_detached")
raise Sodium::Error::VerificationFailed.new("crypto_sign_verify_detached")
end
end
end

View File

@ -1,7 +1,7 @@
require "../lib_sodium"
module Cox
class Sign::SecretKey < Cox::Key
module Sodium
class Sign::SecretKey < Sodium::Key
include Wipe
KEY_SIZE = LibSodium::SECRET_SIGN_SIZE

View File

@ -1,3 +1,3 @@
module Cox
module Sodium
VERSION = "0.1.0"
end

View File

@ -1,4 +1,4 @@
module Cox::Wipe
module Sodium::Wipe
@closed = false
def close
@ -9,7 +9,7 @@ module Cox::Wipe
protected def wipe
return if @closed
Cox.memzero @bytes
Sodium.memzero @bytes
end
def finalize