Fix KEY_SIZE and NONCE_SIZE for non-ietf salsa/chacha ciphers.
Allow dupping various classes.master
parent
d7f5b6e717
commit
ea4fc4e9a6
|
@ -178,14 +178,14 @@ public_key.verify_detached message, signature
|
|||
|
||||
### Secret Key Encryption
|
||||
```crystal
|
||||
key = Sodium::SecretKey.new
|
||||
box = Sodium::SecretBox.new
|
||||
|
||||
message = "foobar"
|
||||
encrypted, nonce = key.encrypt message
|
||||
encrypted, nonce = box.encrypt message
|
||||
|
||||
# On the other side.
|
||||
key = Sodium::SecretKey.new key
|
||||
message = key.decrypt encrypted, nonce
|
||||
box = Sodium::SecretKey.new key
|
||||
message = box.decrypt encrypted, nonce: nonce
|
||||
```
|
||||
|
||||
### Blake2b
|
||||
|
|
|
@ -87,6 +87,18 @@ end
|
|||
box.encrypt_detached message.to_slice, nonce: nonce
|
||||
end
|
||||
end
|
||||
|
||||
it "dups" do
|
||||
box1 = Sodium::Cipher::Aead::{{ name.id }}.new Bytes.new(Sodium::Cipher::Aead::{{ name.id }}::KEY_SIZE)
|
||||
box2 = box1.dup
|
||||
|
||||
key1 = box1.key
|
||||
key2 = box2.key
|
||||
key2.readwrite
|
||||
|
||||
key2.to_slice[0] = 1_u8
|
||||
key1.to_slice[0].should eq 0_u8
|
||||
end
|
||||
end
|
||||
|
||||
describe Sodium::Cipher::Aead do
|
||||
|
|
|
@ -25,5 +25,16 @@ require "../../../src/sodium/cipher/chalsa"
|
|||
cipher2.update(output).should eq data
|
||||
cipher2.final.should eq Bytes.new(0)
|
||||
end
|
||||
|
||||
it "dups" do
|
||||
cipher1 = Sodium::Cipher::{{ name.id }}.new Bytes.new(Sodium::Cipher::{{ name.id }}::KEY_SIZE)
|
||||
cipher2 = cipher1.dup
|
||||
|
||||
key1 = cipher1.key
|
||||
key2 = cipher2.key
|
||||
|
||||
key2.to_slice[0] = 1_u8
|
||||
key1.to_slice[0].should eq 0_u8
|
||||
end
|
||||
end
|
||||
{% end %}
|
||||
|
|
|
@ -90,4 +90,7 @@ describe Sodium::Digest::Blake2b do
|
|||
Sodium::Digest::Blake2b.new personal: Bytes.new(128)
|
||||
end
|
||||
end
|
||||
|
||||
pending "dups" do
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,4 +28,12 @@ describe Sodium::Nonce do
|
|||
nonce.to_slice.should eq one
|
||||
nonce.used?.should be_false
|
||||
end
|
||||
|
||||
it "dups" do
|
||||
nonce1 = Sodium::Nonce.zero
|
||||
nonce2 = nonce1.dup
|
||||
|
||||
nonce2.to_slice[0] = 1_u8
|
||||
nonce1.to_slice[0].should eq 0_u8
|
||||
end
|
||||
end
|
||||
|
|
|
@ -79,6 +79,10 @@ module Sodium::Cipher::Aead
|
|||
abstract def decrypt_detached(src : Bytes, dst : Bytes? = nil, *, nonce : Sodium::Nonce, mac : Bytes, additional : String | Bytes | Nil = nil) : Bytes
|
||||
protected abstract def key_size : Int32
|
||||
protected abstract def mac_size : Int32
|
||||
|
||||
def dup
|
||||
self.class.new @key.dup
|
||||
end
|
||||
end
|
||||
|
||||
{% for key, val in {"XChaCha20Poly1305Ietf" => "_xchacha20poly1305_ietf"} %}
|
||||
|
|
|
@ -12,10 +12,13 @@ module Sodium::Cipher
|
|||
# Advanced usage. Don't touch.
|
||||
property offset = 0
|
||||
|
||||
getter! key
|
||||
getter! nonce
|
||||
|
||||
def initialize
|
||||
end
|
||||
|
||||
def initialize(key, nonce)
|
||||
def initialize(key = nil, nonce = nil)
|
||||
self.key = key if key
|
||||
self.nonce = nonce if nonce
|
||||
end
|
||||
|
@ -45,10 +48,12 @@ module Sodium::Cipher
|
|||
update src, Bytes.new(src.bytesize)
|
||||
end
|
||||
|
||||
private FINAL_BYTES = Bytes.new 0
|
||||
|
||||
# Provided for compatibility with block or tagged ciphers.
|
||||
# Stream ciphers don't have additional data.
|
||||
def final
|
||||
Bytes.new(0)
|
||||
FINAL_BYTES
|
||||
end
|
||||
|
||||
# Use as a CSPRNG.
|
||||
|
@ -74,9 +79,15 @@ module Sodium::Cipher
|
|||
abstract def update(src : Bytes, dst : Bytes)
|
||||
abstract def key_size : Int32
|
||||
abstract def nonce_size : Int32
|
||||
|
||||
def dup
|
||||
self.class.new key: @key.try(&.dup), nonce: @nonce.try(&.dup)
|
||||
end
|
||||
end
|
||||
|
||||
{% for key, val in {"XSalsa20" => "xsalsa20", "Salsa20" => "salsa20", "XChaCha20" => "xchacha20", "ChaCha20Ietf" => "chacha20_ietf", "ChaCha20" => "chacha20"} %}
|
||||
{% for key, valtup in {"Xchacha16" => {"xchacha16", false}, "XSalsa20" => {"xsalsa20", false}, "Salsa20" => {"salsa20", false}, "XChaCha20" => {"xchacha20", false}, "ChaCha20Ietf" => {"chacha20_ietf", true}, "ChaCha20" => {"chacha20", false}} %}
|
||||
{% val = valtup[0] %}
|
||||
{% ietf = valtup[1] %}
|
||||
# These classes can be used to generate pseudo-random data from a key,
|
||||
# or as building blocks for implementing custom constructions, but they
|
||||
# are not alternatives to secretbox.
|
||||
|
@ -89,6 +100,9 @@ module Sodium::Cipher
|
|||
#
|
||||
# WARNING: Not validated against test vectors. You should probably write some before using this class.
|
||||
class {{ key.id }} < Chalsa
|
||||
KEY_SIZE = LibSodium.crypto_stream_chacha20_{{ ietf ? "ietf_".id : "".id }}keybytes.to_i32
|
||||
NONCE_SIZE = LibSodium.crypto_stream_chacha20_{{ ietf ? "ietf_".id : "".id }}noncebytes.to_i32
|
||||
|
||||
# Xor's src with the cipher output and places in dst.
|
||||
#
|
||||
# src and dst may be the same object but should not overlap.
|
||||
|
@ -106,11 +120,11 @@ module Sodium::Cipher
|
|||
end
|
||||
|
||||
def key_size : Int32
|
||||
LibSodium.crypto_stream_chacha20_ietf_keybytes.to_i32
|
||||
KEY_SIZE
|
||||
end
|
||||
|
||||
def nonce_size : Int32
|
||||
LibSodium.crypto_stream_chacha20_ietf_noncebytes.to_i32
|
||||
NONCE_SIZE
|
||||
end
|
||||
end
|
||||
{% end %}
|
||||
|
|
|
@ -44,6 +44,10 @@ module Sodium
|
|||
@used = true unless @reusable
|
||||
end
|
||||
|
||||
def dup
|
||||
self.class.new @bytes.dup
|
||||
end
|
||||
|
||||
module SerializeConverter
|
||||
def self.to_json(value : Nonce, json : JSON::Builder)
|
||||
json.string Base64.strict_encode(value.to_slice)
|
||||
|
|
Loading…
Reference in New Issue