Compare commits
10 Commits
475ce2e5c8
...
2e1856fedb
Author | SHA1 | Date | |
---|---|---|---|
|
2e1856fedb | ||
|
8db8b410a2 | ||
|
527ffe9c06 | ||
|
e58c7e43e2 | ||
|
28b5467602 | ||
|
cc21ca0aba | ||
|
e350f5ad4b | ||
|
2893c5525d | ||
|
24c5a4170d | ||
|
5e03d23ed9 |
@ -3,34 +3,33 @@ require "random/pcg32"
|
|||||||
require "random/isaac"
|
require "random/isaac"
|
||||||
require "../src/sodium/cipher/chalsa"
|
require "../src/sodium/cipher/chalsa"
|
||||||
|
|
||||||
pcgrand = Random::PCG32.new 0
|
randoms = {
|
||||||
isaacrand = Random::ISAAC.new Bytes.new(32)
|
"PCG" => Random::PCG32.new(0),
|
||||||
|
"ISAAC" => Random::ISAAC.new(Bytes.new(32)),
|
||||||
|
"Secure" => Random::Secure,
|
||||||
|
}
|
||||||
|
|
||||||
ciphers = {{ Sodium::Cipher::Chalsa.subclasses }}.map do |klass|
|
ciphers = {{ Sodium::Cipher::Chalsa.subclasses }}.map do |klass|
|
||||||
cipher = klass.new.tap do |c|
|
key = Bytes.new klass.key_size
|
||||||
c.key = Bytes.new c.key_size
|
nonce = Bytes.new klass.nonce_size
|
||||||
c.nonce = Bytes.new c.nonce_size
|
cipher = klass.new key, nonce
|
||||||
end
|
|
||||||
|
|
||||||
# {short_name, cipher}
|
# {short_name, cipher}
|
||||||
{klass.to_s.split("::").last, cipher}
|
{klass.to_s.split("::").last, cipher}
|
||||||
end.to_a
|
end.to_a
|
||||||
# p ciphers
|
|
||||||
|
|
||||||
buf = Bytes.new 1024
|
buf = Bytes.new 1024
|
||||||
|
|
||||||
Benchmark.ips warmup: 0.5 do |bm|
|
Benchmark.ips warmup: 0.5 do |bm|
|
||||||
bm.report "PCG32" do
|
randoms.each do |name, random|
|
||||||
pcgrand.random_bytes buf
|
|
||||||
end
|
|
||||||
|
|
||||||
bm.report "ISAAC" do
|
|
||||||
isaacrand.random_bytes buf
|
|
||||||
end
|
|
||||||
|
|
||||||
ciphers.each do |name, cipher|
|
|
||||||
bm.report "#{name}" do
|
bm.report "#{name}" do
|
||||||
cipher.random_bytes buf
|
random.random_bytes buf
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ciphers.each do |name, random|
|
||||||
|
bm.report "#{name}" do
|
||||||
|
random.random_bytes buf
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
PCG32 606.78k ( 1.65µs) (± 1.07%) 0.0B/op 4.19× slower
|
PCG 1.29M (776.49ns) (± 1.13%) 0.0B/op 1.07× slower
|
||||||
ISAAC 373.63k ( 2.68µs) (± 1.95%) 0.0B/op 6.80× slower
|
ISAAC 530.69k ( 1.88µs) (± 0.98%) 0.0B/op 2.60× slower
|
||||||
XSalsa20 1.84M (544.61ns) (± 1.17%) 0.0B/op 1.38× slower
|
Secure 318.19k ( 3.14µs) (± 2.30%) 0.0B/op 4.33× slower
|
||||||
Salsa20 2.37M (421.53ns) (± 1.24%) 0.0B/op 1.07× slower
|
XSalsa20 1.04M (960.42ns) (± 1.34%) 0.0B/op 1.32× slower
|
||||||
XChaCha20 1.88M (530.86ns) (± 1.46%) 0.0B/op 1.35× slower
|
Salsa20 1.16M (862.14ns) (± 1.29%) 0.0B/op 1.19× slower
|
||||||
ChaCha20Ietf 2.54M (393.65ns) (± 1.22%) 0.0B/op fastest
|
XChaCha20 1.22M (818.52ns) (± 1.86%) 0.0B/op 1.13× slower
|
||||||
ChaCha20 2.51M (398.58ns) (± 1.73%) 0.0B/op 1.01× slower
|
ChaCha20Ietf 1.38M (726.43ns) (± 1.28%) 0.0B/op 1.00× slower
|
||||||
|
ChaCha20 1.38M (725.47ns) (± 1.33%) 0.0B/op fastest
|
||||||
|
@ -17,6 +17,14 @@ puts ""
|
|||||||
{% end %}
|
{% end %}
|
||||||
puts ""
|
puts ""
|
||||||
|
|
||||||
|
{% for sk in [Sodium::CryptoBox::SecretKey, Sodium::Sign::SecretKey] %}
|
||||||
|
sk = {{sk.id}}.new
|
||||||
|
pk = sk.public_key
|
||||||
|
# puts "#{sk.class} bytesize #{sk.to_slice.bytesize}"
|
||||||
|
puts "#{pk.class} bytesize #{pk.to_slice.bytesize}"
|
||||||
|
{% end %}
|
||||||
|
puts ""
|
||||||
|
|
||||||
{% for name in %w(KEY_SIZE NONCE_SIZE MAC_SIZE) %}
|
{% for name in %w(KEY_SIZE NONCE_SIZE MAC_SIZE) %}
|
||||||
puts "Sodium::SecretBox::{{ name.id }} #{Sodium::SecretBox::{{ name.id }}}"
|
puts "Sodium::SecretBox::{{ name.id }} #{Sodium::SecretBox::{{ name.id }}}"
|
||||||
{% end %}
|
{% end %}
|
||||||
@ -47,9 +55,8 @@ puts ""
|
|||||||
{% end %}
|
{% end %}
|
||||||
puts ""
|
puts ""
|
||||||
|
|
||||||
{% for sk in [Sodium::CryptoBox::SecretKey, Sodium::Sign::SecretKey] %}
|
{% for name in %w(XChaCha20 ChaCha20Ietf ChaCha20 XSalsa20 Salsa20) %}
|
||||||
sk = {{sk.id}}.new
|
c = Sodium::Cipher::{{name.id}}.random
|
||||||
pk = sk.public_key
|
# puts "#{c.class} key_size #{c.key_size}"
|
||||||
puts "#{sk.class} bytesize #{sk.to_slice.bytesize}"
|
puts "#{c.class} nonce_size #{c.nonce_size}"
|
||||||
puts "#{pk.class} bytesize #{pk.to_slice.bytesize}"
|
|
||||||
{% end %}
|
{% end %}
|
||||||
|
@ -19,6 +19,13 @@ require "../../../src/sodium/cipher/chalsa"
|
|||||||
cipher2.final.should eq Bytes.new(0)
|
cipher2.final.should eq Bytes.new(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "Random" do
|
||||||
|
cipher = Sodium::Cipher::{{ name.id }}.random
|
||||||
|
cipher.random_bytes(8).should_not eq(cipher.random_bytes(8))
|
||||||
|
r = 3.times.map { cipher.rand(65536) }.sum
|
||||||
|
r.should_not eq(0)
|
||||||
|
end
|
||||||
|
|
||||||
it "dups" do
|
it "dups" do
|
||||||
cipher1 = Sodium::Cipher::{{ name.id }}.new Bytes.new(Sodium::Cipher::{{ name.id }}::KEY_SIZE)
|
cipher1 = Sodium::Cipher::{{ name.id }}.new Bytes.new(Sodium::Cipher::{{ name.id }}::KEY_SIZE)
|
||||||
cipher2 = cipher1.dup
|
cipher2 = cipher1.dup
|
||||||
|
@ -5,11 +5,11 @@ CONTEXT = "8_bytess"
|
|||||||
|
|
||||||
describe Sodium::Kdf do
|
describe Sodium::Kdf do
|
||||||
it "generates master key" do
|
it "generates master key" do
|
||||||
kdf1 = Sodium::Kdf.new
|
kdf1 = Sodium::Kdf.random
|
||||||
|
|
||||||
# verify loading saved key
|
# verify loading saved key
|
||||||
kdf2 = kdf1.key.readonly do |kslice|
|
kdf2 = kdf1.key.readonly do |kslice|
|
||||||
Sodium::Kdf.new kslice.dup
|
Sodium::Kdf.copy_key_from kslice.dup
|
||||||
end
|
end
|
||||||
|
|
||||||
kdf1.key.should eq kdf2.key
|
kdf1.key.should eq kdf2.key
|
||||||
@ -21,7 +21,7 @@ describe Sodium::Kdf do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "generates different keys" do
|
it "generates different keys" do
|
||||||
kdf1 = Sodium::Kdf.new
|
kdf1 = Sodium::Kdf.random
|
||||||
subkey1 = kdf1.derive CONTEXT, 0, 16
|
subkey1 = kdf1.derive CONTEXT, 0, 16
|
||||||
subkey2 = kdf1.derive CONTEXT, 1, 16
|
subkey2 = kdf1.derive CONTEXT, 1, 16
|
||||||
subkey1.should_not eq subkey2
|
subkey1.should_not eq subkey2
|
||||||
|
@ -98,6 +98,9 @@ describe Sodium::Sign::SecretKey do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
pending "combined test vectors" do
|
||||||
|
end
|
||||||
|
|
||||||
it "RbNaCl detached test vectors" do
|
it "RbNaCl detached test vectors" do
|
||||||
detached_test_vectors.each do |vec|
|
detached_test_vectors.each do |vec|
|
||||||
seckey, plaintext, signature = sign_from_vec vec
|
seckey, plaintext, signature = sign_from_vec vec
|
||||||
|
@ -6,15 +6,17 @@ module Sodium::Cipher
|
|||||||
#
|
#
|
||||||
# What? They're both dance?
|
# What? They're both dance?
|
||||||
abstract class Chalsa
|
abstract class Chalsa
|
||||||
|
include Random
|
||||||
|
|
||||||
getter key : Crypto::Secret
|
getter key : Crypto::Secret
|
||||||
getter! nonce : Bytes?
|
getter! nonce : Bytes?
|
||||||
|
|
||||||
# Advanced usage. Don't touch.
|
# Advanced usage. Don't touch.
|
||||||
property offset = 0
|
property offset = 0_u64
|
||||||
|
|
||||||
def initialize(key : Crypto::Secret | Bytes, nonce = nil)
|
def initialize(key : Crypto::Secret | Bytes, nonce = nil)
|
||||||
raise ArgumentError.new("key must be #{key_size} bytes, got #{key.bytesize}") if key.bytesize != key_size
|
raise ArgumentError.new("key must be #{key_size} bytes, got #{key.bytesize}") if key.bytesize != key_size
|
||||||
@key = key.is_a?(Crypto::Secret) ? key : Sodium::SecureBuffer.new(key)
|
@key = key.is_a?(Crypto::Secret) ? key : Sodium::SecureBuffer.copy_from(key)
|
||||||
self.nonce = nonce if nonce
|
self.nonce = nonce if nonce
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -42,7 +44,7 @@ module Sodium::Cipher
|
|||||||
end
|
end
|
||||||
|
|
||||||
def random_nonce
|
def random_nonce
|
||||||
self.nonce = Random::Secure.random_bytes nonce_size
|
self.nonce = ::Random::Secure.random_bytes nonce_size
|
||||||
end
|
end
|
||||||
|
|
||||||
# Xor's src with the cipher output and returns a new Slice
|
# Xor's src with the cipher output and returns a new Slice
|
||||||
@ -60,17 +62,14 @@ module Sodium::Cipher
|
|||||||
|
|
||||||
# Use as a CSPRNG.
|
# Use as a CSPRNG.
|
||||||
def random_bytes(bytes : Bytes) : Bytes
|
def random_bytes(bytes : Bytes) : Bytes
|
||||||
# TODO: Switch to memset
|
|
||||||
Sodium.memzero bytes
|
|
||||||
update bytes, bytes
|
update bytes, bytes
|
||||||
bytes
|
bytes
|
||||||
end
|
end
|
||||||
|
|
||||||
# Use as a CSPRNG.
|
def next_u : UInt8
|
||||||
def random_bytes(size : Int) : Bytes
|
buf = uninitialized UInt8[1]
|
||||||
bytes = Bytes.new size
|
random_bytes buf.to_slice
|
||||||
update bytes, bytes
|
buf.unsafe_as(UInt8)
|
||||||
bytes
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Always returns false. Sadness...
|
# Always returns false. Sadness...
|
||||||
@ -87,26 +86,35 @@ module Sodium::Cipher
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
{% for key, valtup in {"XSalsa20" => {"xsalsa20", false}, "Salsa20" => {"salsa20", false}, "XChaCha20" => {"xchacha20", false}, "ChaCha20Ietf" => {"chacha20_ietf", true}, "ChaCha20" => {"chacha20", false}} %}
|
{% for key, val in {"XSalsa20" => "xsalsa20", "Salsa20" => "salsa20", "XChaCha20" => "xchacha20", "ChaCha20Ietf" => "chacha20_ietf", "ChaCha20" => "chacha20"} %}
|
||||||
{% val = valtup[0] %}
|
|
||||||
{% ietf = valtup[1] %}
|
|
||||||
# These classes can be used to generate pseudo-random data from a key,
|
# These classes can be used to generate pseudo-random data from a key,
|
||||||
# or as building blocks for implementing custom constructions, but they
|
# or as building blocks for implementing custom constructions, but they
|
||||||
# are not alternatives to secretbox.
|
# are not alternatives to `SecretBox`.
|
||||||
#
|
#
|
||||||
# See [https://libsodium.gitbook.io/doc/advanced/stream_ciphers](https://libsodium.gitbook.io/doc/advanced/stream_ciphers) for further information.
|
# See [https://libsodium.gitbook.io/doc/advanced/stream_ciphers](https://libsodium.gitbook.io/doc/advanced/stream_ciphers) for further information.
|
||||||
#
|
#
|
||||||
# This class mimicks the OpenSSL::Cipher interface with minor differences.
|
# This class mimicks the `OpenSSL::Cipher` interface with minor differences.
|
||||||
|
#
|
||||||
|
# Also provides a `::Random` interface.
|
||||||
|
# * Lacks forward secrecy.
|
||||||
|
# * ~3x faster than `::Random::Secure`
|
||||||
|
#
|
||||||
|
# Use with caution. When in doubt use `::Random::Secure`
|
||||||
|
#
|
||||||
|
# Possibly safe uses:
|
||||||
|
# * Test data
|
||||||
|
# * Overwriting storage with random data
|
||||||
|
# * Single player video games (maybe)
|
||||||
#
|
#
|
||||||
# See `spec/sodium/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.
|
||||||
#
|
#
|
||||||
# WARNING: Not validated against test vectors. You should probably write some before using this class.
|
# WARNING: Not validated against test vectors. You should probably write some before using this class.
|
||||||
class {{ key.id }} < Chalsa
|
class {{ key.id }} < Chalsa
|
||||||
KEY_SIZE = LibSodium.crypto_stream_chacha20_{{ ietf ? "ietf_".id : "".id }}keybytes.to_i32
|
KEY_SIZE = LibSodium.crypto_stream_{{ val.id }}_keybytes.to_i32
|
||||||
NONCE_SIZE = LibSodium.crypto_stream_chacha20_{{ ietf ? "ietf_".id : "".id }}noncebytes.to_i32
|
NONCE_SIZE = LibSodium.crypto_stream_{{ val.id }}_noncebytes.to_i32
|
||||||
|
|
||||||
def self.random
|
def self.random
|
||||||
new key: Sodium::SecureBuffer.random(KEY_SIZE), nonce: Random::Secure.random_bytes(NONCE_SIZE)
|
new key: Sodium::SecureBuffer.random(KEY_SIZE), nonce: ::Random::Secure.random_bytes(NONCE_SIZE)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Xor's src with the cipher output and places in dst.
|
# Xor's src with the cipher output and places in dst.
|
||||||
@ -128,6 +136,14 @@ module Sodium::Cipher
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.key_size : Int32
|
||||||
|
KEY_SIZE
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.nonce_size : Int32
|
||||||
|
NONCE_SIZE
|
||||||
|
end
|
||||||
|
|
||||||
def key_size : Int32
|
def key_size : Int32
|
||||||
KEY_SIZE
|
KEY_SIZE
|
||||||
end
|
end
|
||||||
|
@ -42,9 +42,6 @@ class Sodium::CryptoBox
|
|||||||
getter key : Crypto::Secret
|
getter key : Crypto::Secret
|
||||||
getter public_key : PublicKey
|
getter public_key : PublicKey
|
||||||
|
|
||||||
# Returns key
|
|
||||||
delegate_to_slice to: @key
|
|
||||||
|
|
||||||
@seed : Crypto::Secret?
|
@seed : Crypto::Secret?
|
||||||
|
|
||||||
# Generate a new random secret/public key pair.
|
# Generate a new random secret/public key pair.
|
||||||
@ -163,9 +160,12 @@ class Sodium::CryptoBox
|
|||||||
# For authenticated messages use `secret_key.box(recipient_public_key).decrypt`.
|
# For authenticated messages use `secret_key.box(recipient_public_key).decrypt`.
|
||||||
#
|
#
|
||||||
# Optionally supply a destination buffer.
|
# Optionally supply a destination buffer.
|
||||||
def decrypt_string(src, dst : Bytes? = nil) : String
|
def decrypt_string(src) : String
|
||||||
msg = decrypt src.to_slice, dst
|
dsize = src.bytesize - SEAL_SIZE
|
||||||
String.new msg
|
String.new(dsize) do |dst|
|
||||||
|
decrypt src.to_slice, dst.to_slice(dsize)
|
||||||
|
{dsize, dsize}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# :nodoc:
|
# :nodoc:
|
||||||
|
@ -7,7 +7,8 @@ module Sodium
|
|||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# ```
|
# ```
|
||||||
# kdf = KDF.new
|
# kdf = KDF.random
|
||||||
|
# kdf = KDF.move_key_from bytes
|
||||||
# subkey_id = 0
|
# subkey_id = 0
|
||||||
# output_size = 16
|
# output_size = 16
|
||||||
# subkey = kdf.derive "8bytectx", subkey_id, output_size
|
# subkey = kdf.derive "8bytectx", subkey_id, output_size
|
||||||
@ -18,7 +19,7 @@ module Sodium
|
|||||||
#
|
#
|
||||||
# It's recommended to use a #wipe block to erase the master key when no longer needed
|
# It's recommended to use a #wipe block to erase the master key when no longer needed
|
||||||
# ```
|
# ```
|
||||||
# kdf = Kdf.new
|
# kdf = Kdf.random
|
||||||
# ...
|
# ...
|
||||||
# kdf.wipe do
|
# kdf.wipe do
|
||||||
# ### Warning: abnormal exit may not wipe
|
# ### Warning: abnormal exit may not wipe
|
||||||
@ -41,16 +42,29 @@ module Sodium
|
|||||||
|
|
||||||
getter key : Crypto::Secret
|
getter key : Crypto::Secret
|
||||||
|
|
||||||
|
def self.random
|
||||||
|
new(SecureBuffer.random(KEY_SIZE))
|
||||||
|
end
|
||||||
|
|
||||||
# Use an existing KDF key.
|
# Use an existing KDF key.
|
||||||
#
|
#
|
||||||
# * Copies key to a new SecureBuffer
|
# * Copies key to a new SecureBuffer
|
||||||
# * Optionally erases bytes after copying if erase is set
|
def self.copy_key_from(bytes : Bytes)
|
||||||
def initialize(bytes : Bytes, erase = false)
|
new(SecureBuffer.copy_from(bytes))
|
||||||
if bytes.bytesize != KEY_SIZE
|
|
||||||
raise ArgumentError.new("bytes must be #{KEY_SIZE}, got #{bytes.bytesize}")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@key = SecureBuffer.new(bytes, erase).noaccess
|
# Use an existing KDF key.
|
||||||
|
#
|
||||||
|
# * Copies key to a new SecureBuffer
|
||||||
|
# * Erases bytes after copying
|
||||||
|
def self.move_key_from(bytes : Bytes)
|
||||||
|
new(SecureBuffer.move_from(bytes))
|
||||||
|
end
|
||||||
|
|
||||||
|
@[Deprecated("use .copy_key_from or .move_key_from")]
|
||||||
|
def initialize(bytes : Bytes, erase = false)
|
||||||
|
@key = SecureBuffer.new(1)
|
||||||
|
raise NotImplementedError.new("use .copy_key_from or .move_key_from")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Use an existing KDF Crypto::Secret key.
|
# Use an existing KDF Crypto::Secret key.
|
||||||
@ -61,9 +75,7 @@ module Sodium
|
|||||||
@key.noaccess
|
@key.noaccess
|
||||||
end
|
end
|
||||||
|
|
||||||
# Generate a new random KDF key.
|
@[Deprecated("use .random")]
|
||||||
#
|
|
||||||
# Make sure to save kdf.to_slice before kdf goes out of scope.
|
|
||||||
def initialize
|
def initialize
|
||||||
@key = SecureBuffer.random(KEY_SIZE).noaccess
|
@key = SecureBuffer.random(KEY_SIZE).noaccess
|
||||||
end
|
end
|
||||||
|
@ -4,7 +4,5 @@ require "./wipe"
|
|||||||
module Sodium
|
module Sodium
|
||||||
abstract class Key
|
abstract class Key
|
||||||
include Sodium::Wipe
|
include Sodium::Wipe
|
||||||
|
|
||||||
abstract def to_slice : Bytes
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -7,19 +7,20 @@ module Sodium
|
|||||||
#
|
#
|
||||||
# #initialize returns readonly or readwrite for thread safety
|
# #initialize returns readonly or readwrite for thread safety
|
||||||
# When state changes are required (such as using #noaccess) and the buffer is accessed from multiple threads wrap each #readonly/#readwrite block in a lock.
|
# When state changes are required (such as using #noaccess) and the buffer is accessed from multiple threads wrap each #readonly/#readwrite block in a lock.
|
||||||
class SecureBuffer
|
class SecureBuffer < Crypto::Secret
|
||||||
include Crypto::Secret::Stateful
|
include Crypto::Secret::Stateful
|
||||||
|
|
||||||
getter bytesize : Int32
|
getter buffer_bytesize : Int32
|
||||||
|
|
||||||
def initialize(@bytesize : Int32)
|
def initialize(@buffer_bytesize : Int32)
|
||||||
@ptr = LibSodium.sodium_malloc @bytesize
|
@ptr = LibSodium.sodium_malloc @buffer_bytesize
|
||||||
raise Error::OutOfMemory.new if @ptr.null?
|
raise Error::OutOfMemory.new("allocating #{@buffer_bytesize}") if @ptr.null?
|
||||||
end
|
end
|
||||||
|
|
||||||
# Copies bytes to a **readonly** SecureBuffer.
|
# Copies bytes to a **readonly** SecureBuffer.
|
||||||
# Optionally erases bytes after copying if erase is set
|
# Optionally erases bytes after copying if erase is set
|
||||||
# Returns a **readonly** SecureBuffer.
|
# Returns a **readonly** SecureBuffer.
|
||||||
|
@[Deprecated("Use .copy_from or .move_from")]
|
||||||
def initialize(bytes : Bytes, erase = false)
|
def initialize(bytes : Bytes, erase = false)
|
||||||
initialize bytes.bytesize
|
initialize bytes.bytesize
|
||||||
readwrite do |slice|
|
readwrite do |slice|
|
||||||
@ -32,7 +33,7 @@ module Sodium
|
|||||||
# :nodoc:
|
# :nodoc:
|
||||||
# For .dup
|
# For .dup
|
||||||
def initialize(sbuf : Crypto::Secret)
|
def initialize(sbuf : Crypto::Secret)
|
||||||
initialize sbuf.bytesize
|
initialize sbuf.buffer_bytesize
|
||||||
|
|
||||||
# Maybe not thread safe
|
# Maybe not thread safe
|
||||||
sbuf.readonly do |sslice|
|
sbuf.readonly do |sslice|
|
||||||
@ -56,18 +57,12 @@ module Sodium
|
|||||||
#
|
#
|
||||||
@[Deprecated("Use the Slice provided within a `readonly` or `readwrite` block")]
|
@[Deprecated("Use the Slice provided within a `readonly` or `readwrite` block")]
|
||||||
def to_slice : Bytes
|
def to_slice : Bytes
|
||||||
case @state
|
raise NotImplementedError.new
|
||||||
when State::Noaccess, State::Wiped
|
|
||||||
readonly
|
|
||||||
else
|
|
||||||
# Ok
|
|
||||||
end
|
|
||||||
Slice(UInt8).new @ptr, @bytesize
|
|
||||||
end
|
end
|
||||||
|
|
||||||
protected def to_slice(& : Bytes -> Nil)
|
protected def to_slice(& : Bytes -> Nil)
|
||||||
ro = @state < State::Readonly
|
ro = @state < State::Readonly
|
||||||
yield Bytes.new(@ptr, @bytesize, read_only: ro)
|
yield Bytes.new(@ptr, @buffer_bytesize, read_only: ro)
|
||||||
end
|
end
|
||||||
|
|
||||||
# :nodoc:
|
# :nodoc:
|
||||||
|
Loading…
Reference in New Issue
Block a user