Crypto::Secret

Prefer .random, .move_from, .copy_from
  Optimize #decrypt_string
This commit is contained in:
Didactic Drunk 2022-04-30 11:17:30 -07:00
parent 508dd87b67
commit 5146a383f7
2 changed files with 34 additions and 11 deletions

View File

@ -18,7 +18,7 @@ combined_test_vectors = [
] ]
private def box_from_test_vector(vec) private def box_from_test_vector(vec)
box = Sodium::SecretBox.new vec[:key].hexbytes box = Sodium::SecretBox.copy_from vec[:key].hexbytes
nonce = Sodium::Nonce.new vec[:nonce].hexbytes nonce = Sodium::Nonce.new vec[:nonce].hexbytes
plaintext = vec[:plaintext].hexbytes plaintext = vec[:plaintext].hexbytes
ciphertext = vec[:ciphertext].hexbytes ciphertext = vec[:ciphertext].hexbytes
@ -28,7 +28,7 @@ end
describe Sodium::SecretBox do describe Sodium::SecretBox do
it "encrypts/decrypts" do it "encrypts/decrypts" do
box = Sodium::SecretBox.new box = Sodium::SecretBox.random
message = "foobar" message = "foobar"
encrypted, nonce = box.encrypt message encrypted, nonce = box.encrypt message
@ -41,7 +41,7 @@ describe Sodium::SecretBox do
end end
it "can't encrypt twice using the same nonce" do it "can't encrypt twice using the same nonce" do
box = Sodium::SecretBox.new box = Sodium::SecretBox.random
message = "foobar" message = "foobar"
encrypted, nonce = box.encrypt message encrypted, nonce = box.encrypt message

View File

@ -5,6 +5,9 @@ require "./nonce"
module Sodium module Sodium
# [https://libsodium.gitbook.io/doc/secret-key_cryptography](https://libsodium.gitbook.io/doc/secret-key_cryptography) # [https://libsodium.gitbook.io/doc/secret-key_cryptography](https://libsodium.gitbook.io/doc/secret-key_cryptography)
# #
# WARNING: Only use this class for compatibility with older applications already using SecretBox.
# Use `Sodium::Cipher::Aead::XChaCha20Poly1305Ietf` for new applications.
#
# ``` # ```
# box = Sodium::SecretBox.new # box = Sodium::SecretBox.new
# message = "foobar" # message = "foobar"
@ -25,12 +28,30 @@ module Sodium
# Encryption key # Encryption key
getter key : Crypto::Secret getter key : Crypto::Secret
# Generate a new random key held in a SecureBuffer. # Generate a new random key held in a `SecureBuffer`
def self.random
new SecureBuffer.random(KEY_SIZE)
end
# Copy *key* to a new `SecureBuffer`
def self.copy_from(key : Bytes)
new SecureBuffer.copy_from(key)
end
# Copy *key* to a new `SecureBuffer`
#
# Erases *key* after copying
def self.move_from(key : Bytes)
new SecureBuffer.copy_from(key)
end
# Generate a new random key held in a `SecureBuffer`
@[Deprecated("Use .random")]
def initialize def initialize
@key = SecureBuffer.random KEY_SIZE @key = SecureBuffer.random KEY_SIZE
end end
# Use an existing Crypto::Secret. # Use an existing `Crypto::Secret`
def initialize(@key : Crypto::Secret) def initialize(@key : Crypto::Secret)
if @key.bytesize != KEY_SIZE if @key.bytesize != KEY_SIZE
raise ArgumentError.new("Secret key must be #{KEY_SIZE} bytes, got #{@key.bytesize}") raise ArgumentError.new("Secret key must be #{KEY_SIZE} bytes, got #{@key.bytesize}")
@ -38,9 +59,10 @@ module Sodium
@key.readonly @key.readonly
end end
# Copy bytes to a new SecureBuffer # Copy bytes to a new `SecureBuffer`
# #
# Optionally erases bytes after copying if erase is set. # Optionally erases bytes after copying if erase is set.
@[Deprecated("Use .copy_from or .move_from")]
def initialize(bytes : Bytes, erase = false) def initialize(bytes : Bytes, erase = false)
if bytes.bytesize != KEY_SIZE if bytes.bytesize != KEY_SIZE
raise ArgumentError.new("Secret key must be #{KEY_SIZE} bytes, got #{bytes.bytesize}") raise ArgumentError.new("Secret key must be #{KEY_SIZE} bytes, got #{bytes.bytesize}")
@ -78,11 +100,12 @@ module Sodium
end end
# Returns decrypted message as a `String`. # Returns decrypted message as a `String`.
# def decrypt_string(src, *, nonce : Nonce) : String
# Optionally supply a destination buffer. dsize = src.bytesize - MAC_SIZE
def decrypt_string(src, dst : Bytes? = nil, *, nonce : Nonce) : String String.new(dsize) do |dst|
msg = decrypt src.to_slice, dst, nonce: nonce decrypt src.to_slice, dst.to_slice(dsize), nonce: nonce
String.new msg {dsize, dsize}
end
end end
# :nodoc: # :nodoc: