From 903b6669432b1c2dd7950ae469d719bc394f54e3 Mon Sep 17 00:00:00 2001 From: Didactic Drunk <1479616+didactic-drunk@users.noreply.github.com> Date: Wed, 29 May 2019 16:29:41 -0700 Subject: [PATCH] Makes Cox::Blake2b#finish public and allows providing existing buffer. --- src/cox/blake2b.cr | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/cox/blake2b.cr b/src/cox/blake2b.cr index f290d14..1848277 100644 --- a/src/cox/blake2b.cr +++ b/src/cox/blake2b.cr @@ -17,17 +17,20 @@ module Cox OUT_SIZE_MIN = LibSodium.crypto_generichash_blake2b_bytes_min.to_i32 OUT_SIZE_MAX = LibSodium.crypto_generichash_blake2b_bytes_max.to_i32 + getter digest_size + @state = StaticArray(UInt8, 384).new 0 @key_size = 0 @have_salt = false @have_personal = false + # implemented as static array's so clone works without jumping through hoops. @key = StaticArray(UInt8, 64).new 0 @salt = StaticArray(UInt8, 16).new 0 @personal = StaticArray(UInt8, 16).new 0 - def initialize(@out_size : Int32 = OUT_SIZE, key : Bytes? = nil, salt : Bytes? = nil, personal : Bytes? = nil) + def initialize(@digest_size : Int32 = OUT_SIZE, key : Bytes? = nil, salt : Bytes? = nil, personal : Bytes? = nil) if k = key raise ArgumentError.new("key larger than KEY_SIZE_MAX, got #{k.bytesize}") if k.bytesize > KEY_SIZE_MAX @key_size = k.bytesize @@ -54,7 +57,7 @@ module Cox salt = @have_salt ? @salt.to_unsafe : nil personal = @have_personal ? @personal.to_unsafe : nil - if LibSodium.crypto_generichash_blake2b_init_salt_personal(@state, key, @key_size, @out_size, salt, personal) != 0 + 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") end end @@ -67,12 +70,22 @@ module Cox self end + # Destructive operation. Assumes you know what you are doing. + # Use .digest or .hexdigest instead. def finish - data = Bytes.new @out_size - if LibSodium.crypto_generichash_blake2b_final(@state, data, data.bytesize) != 0 + dst = Bytes.new @digest_size + finish dst + dst + end + + # Destructive operation. Assumes you know what you are doing. + # 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") end - data + + dst end def clone