From 475ce2e5c830e614a05364993358ed85880fae40 Mon Sep 17 00:00:00 2001 From: Didactic Drunk <1479616+didactic-drunk@users.noreply.github.com> Date: Tue, 3 May 2022 13:45:38 -0700 Subject: [PATCH] Chalsa: Prefer .random over .new Add #decrypt_secret Add #decrypt_string Optimize #decrypt* --- spec/sodium/cipher/aead/chalsa_spec.cr | 6 ++--- src/sodium/cipher/aead/chalsa.cr | 31 +++++++++++++++++++------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/spec/sodium/cipher/aead/chalsa_spec.cr b/spec/sodium/cipher/aead/chalsa_spec.cr index 811ad9d..8b11687 100644 --- a/spec/sodium/cipher/aead/chalsa_spec.cr +++ b/spec/sodium/cipher/aead/chalsa_spec.cr @@ -28,7 +28,7 @@ end {% for name in %w(XChaCha20Poly1305Ietf) %} describe Sodium::Cipher::Aead::{{ name.id }} do it "encrypts/decrypts in combined mode" do - box = Sodium::Cipher::Aead::{{ name.id }}.new + box = Sodium::Cipher::Aead::{{ name.id }}.random message = "foo" additional = "bar" @@ -53,7 +53,7 @@ end end it "encrypts/decrypts in detached mode" do - box = Sodium::Cipher::Aead::{{ name.id }}.new + box = Sodium::Cipher::Aead::{{ name.id }}.random message = "foo" additional = "bar" @@ -78,7 +78,7 @@ end end it "can't encrypt twice using the same nonce" do - box = Sodium::Cipher::Aead::{{ name.id }}.new + box = Sodium::Cipher::Aead::{{ name.id }}.random message = "foo" mac, encrypted, nonce = box.encrypt_detached message diff --git a/src/sodium/cipher/aead/chalsa.cr b/src/sodium/cipher/aead/chalsa.cr index 9c03736..5e21bac 100644 --- a/src/sodium/cipher/aead/chalsa.cr +++ b/src/sodium/cipher/aead/chalsa.cr @@ -34,6 +34,17 @@ module Sodium::Cipher::Aead {dst, nonce} end + # Decrypts `src` and returns plaintext as a `Crypto::Secret` + # Must supply `nonce` + # Must supply `additional` if supplied to #encrypt + def decrypt_secret(src, dst : Crypto::Secret? = nil, *, nonce : Nonce, additional = nil) : Crypto::Secret + dst ||= Sodium::SecureBuffer.new(src.bytesize - mac_size) + dst.readwrite do |dslice| + decrypt src, dslice, nonce: nonce, additional: additional + end + dst.readonly + end + # Decrypts `src` and returns plaintext # Must supply `nonce` # Must supply `additional` if supplied to #encrypt @@ -48,10 +59,12 @@ module Sodium::Cipher::Aead # Decrypts `src` and returns plaintext # Must supply `nonce` # Must supply `additional` if supplied to #encrypt - def decrypt_string(src, dst : Bytes? = nil, *, nonce : Nonce, additional = nil) : String - buf = decrypt src, dst, nonce: nonce, additional: additional - # TODO: optimize - String.new buf + def decrypt_string(src, *, nonce : Nonce, additional = nil) : String + dsize = src.bytesize - mac_size + String.new(dsize) do |dst| + decrypt src, dst.to_slice(dsize), nonce: nonce, additional: additional + {dsize, dsize} + end end # Encrypts `src` and returns {mac, ciphertext, nonce} @@ -69,10 +82,12 @@ module Sodium::Cipher::Aead # Decrypts `src` and returns plaintext # Must supply `mac` and `nonce` # Must supply `additional` if supplied to #encrypt - def decrypt_detached_string(src, dst : Bytes? = nil, *, nonce = nil, mac : Bytes? = nil, additional = nil) : String - buf = decrypt_detached src.to_slice, dst, mac: mac, nonce: nonce, additional: additional - # TODO: optimize - String.new buf + def decrypt_detached_string(src, *, nonce = nil, mac : Bytes? = nil, additional = nil) : String + dsize = src.bytesize + String.new(dsize) do |dst| + decrypt_detached src.to_slice, dst.to_slice(dsize), mac: mac, nonce: nonce, additional: additional + {dsize, dsize} + end end abstract def encrypt_detached(src : Bytes, dst : Bytes? = nil, *, nonce : Sodium::Nonce? = nil, mac : Bytes? = nil, additional : String | Bytes | Nil = nil) : {Bytes, Bytes, Sodium::Nonce}