Add Sodium::Nonce.random
Improve Nonce used detection Improve Nonce documentationmaster
parent
ca9b905b73
commit
c75a51c078
|
@ -2,6 +2,8 @@ require "./lib_sodium"
|
||||||
require "random/secure"
|
require "random/secure"
|
||||||
|
|
||||||
module Sodium
|
module Sodium
|
||||||
|
# This class implements best effort nonce reuse detection **when multithreading is disabled**
|
||||||
|
# Race conditions may occur if using the same object in multiple Fibers with multithreading enabled.
|
||||||
class Nonce
|
class Nonce
|
||||||
class Error < Sodium::Error
|
class Error < Sodium::Error
|
||||||
class Reused < Error
|
class Reused < Error
|
||||||
|
@ -13,7 +15,7 @@ module Sodium
|
||||||
getter? used = false
|
getter? used = false
|
||||||
|
|
||||||
# Only use with single use keys.
|
# Only use with single use keys.
|
||||||
property? reusable = false
|
getter reusable = false
|
||||||
|
|
||||||
# Returns bytes
|
# Returns bytes
|
||||||
delegate_to_slice to: @bytes
|
delegate_to_slice to: @bytes
|
||||||
|
@ -26,22 +28,35 @@ module Sodium
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.random
|
def self.random(random_source = Random::Secure)
|
||||||
self.new Random::Secure.random_bytes(NONCE_SIZE)
|
self.new random_source.random_bytes(NONCE_SIZE)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.zero
|
def self.zero
|
||||||
self.new Bytes.new(NONCE_SIZE)
|
self.new Bytes.new(NONCE_SIZE)
|
||||||
end
|
end
|
||||||
|
|
||||||
def increment
|
def increment : Nil
|
||||||
LibSodium.sodium_increment @bytes, @bytes.bytesize
|
LibSodium.sodium_increment @bytes, @bytes.bytesize
|
||||||
@used = false
|
@used = false
|
||||||
end
|
end
|
||||||
|
|
||||||
def used!
|
def random(random_source = Random::Secure) : Nil
|
||||||
|
random_source.random_bytes @bytes
|
||||||
|
@used = false
|
||||||
|
end
|
||||||
|
|
||||||
|
def used! : Nil
|
||||||
|
return if @reusable
|
||||||
raise Error::Reused.new("attempted nonce reuse") if @used
|
raise Error::Reused.new("attempted nonce reuse") if @used
|
||||||
@used = true unless @reusable
|
@used = true
|
||||||
|
end
|
||||||
|
|
||||||
|
def reusable=(val : Bool) : Bool
|
||||||
|
raise Error.new("trying to set reusable=true but already used") if val && @used
|
||||||
|
@reusable = val
|
||||||
|
@used = false if val
|
||||||
|
val
|
||||||
end
|
end
|
||||||
|
|
||||||
def dup
|
def dup
|
||||||
|
|
|
@ -40,7 +40,7 @@ module Sodium
|
||||||
|
|
||||||
@sbuf = SecureBuffer.new bytes, erase: erase
|
@sbuf = SecureBuffer.new bytes, erase: erase
|
||||||
if pk = pkey
|
if pk = pkey
|
||||||
@public_key = PublicKey.new pkey
|
@public_key = PublicKey.new pk
|
||||||
else
|
else
|
||||||
@public_key = PublicKey.new
|
@public_key = PublicKey.new
|
||||||
if LibSodium.crypto_sign_ed25519_sk_to_pk(@public_key.to_slice, self.to_slice) != 0
|
if LibSodium.crypto_sign_ed25519_sk_to_pk(@public_key.to_slice, self.to_slice) != 0
|
||||||
|
|
Loading…
Reference in New Issue