Sign:
Add `.copy_from` `.move_from` instead of *erase* Prefer `.random` Deprecate old `.initialize`master
parent
98c3a2bff4
commit
f036295aa3
|
@ -20,7 +20,7 @@ Crystal bindings for the [libsodium API](https://libsodium.gitbook.io/doc/)
|
|||
- [Public-Key Cryptography](https://libsodium.gitbook.io/doc/public-key_cryptography)
|
||||
- [x] ☑ [Crypto Box Easy](https://libsodium.gitbook.io/doc/public-key_cryptography/authenticated_encryption)
|
||||
- [x] [Sealed Box](https://libsodium.gitbook.io/doc/public-key_cryptography/sealed_boxes)
|
||||
- [ ] [Combined Signatures](https://libsodium.gitbook.io/doc/public-key_cryptography/public-key_signatures)
|
||||
- [x] [Combined Signatures](https://libsodium.gitbook.io/doc/public-key_cryptography/public-key_signatures)
|
||||
- [x] ☑ [Detached Signatures](https://libsodium.gitbook.io/doc/public-key_cryptography/public-key_signatures)
|
||||
- [ ] [Pre-hashed Signatures](https://libsodium.gitbook.io/doc/public-key_cryptography/public-key_signatures)
|
||||
- [Secret-Key Cryptography](https://libsodium.gitbook.io/doc/secret-key_cryptography)
|
||||
|
|
|
@ -31,18 +31,9 @@ end
|
|||
|
||||
describe Sodium::Sign::SecretKey do
|
||||
it "loads keys" do
|
||||
key1 = Sodium::Sign::SecretKey.new
|
||||
key1 = Sodium::Sign::SecretKey.random
|
||||
key2 = key1.key.readonly do |kslice|
|
||||
Sodium::Sign::SecretKey.new kslice, key1.public_key.to_slice
|
||||
end
|
||||
key1.key.should eq key2.key
|
||||
key1.public_key.to_slice.should eq key2.public_key.to_slice
|
||||
end
|
||||
|
||||
it "recomputes the public key" do
|
||||
key1 = Sodium::Sign::SecretKey.new
|
||||
key2 = key1.key.readonly do |kslice|
|
||||
Sodium::Sign::SecretKey.new kslice
|
||||
Sodium::Sign::SecretKey.copy_from kslice
|
||||
end
|
||||
key1.key.should eq key2.key
|
||||
key1.public_key.to_slice.should eq key2.public_key.to_slice
|
||||
|
@ -52,7 +43,7 @@ describe Sodium::Sign::SecretKey do
|
|||
seed = Bytes.new Sodium::Sign::SecretKey::SEED_SIZE
|
||||
key1 = Sodium::Sign::SecretKey.new seed: seed
|
||||
key2 = key1.key.readonly do |kslice|
|
||||
Sodium::Sign::SecretKey.new kslice
|
||||
Sodium::Sign::SecretKey.copy_from kslice
|
||||
end
|
||||
key3 = Sodium::Sign::SecretKey.new seed: key2.seed
|
||||
key1.key.should eq key2.key
|
||||
|
@ -66,7 +57,7 @@ describe Sodium::Sign::SecretKey do
|
|||
|
||||
it "signs and verifies combined" do
|
||||
message = "foo"
|
||||
skey = Sodium::Sign::SecretKey.new
|
||||
skey = Sodium::Sign::SecretKey.random
|
||||
sig = skey.sign message
|
||||
|
||||
message2 = skey.public_key.verify_string sig
|
||||
|
@ -75,7 +66,7 @@ describe Sodium::Sign::SecretKey do
|
|||
|
||||
it "signs and verifies detached" do
|
||||
message = "foo"
|
||||
skey = Sodium::Sign::SecretKey.new
|
||||
skey = Sodium::Sign::SecretKey.random
|
||||
sig = skey.sign_detached message
|
||||
|
||||
skey.public_key.verify_detached message, sig
|
||||
|
@ -83,7 +74,7 @@ describe Sodium::Sign::SecretKey do
|
|||
|
||||
it "signs and fails" do
|
||||
message = "foo"
|
||||
skey = Sodium::Sign::SecretKey.new
|
||||
skey = Sodium::Sign::SecretKey.random
|
||||
sig = skey.sign_detached message
|
||||
|
||||
expect_raises Sodium::Error::VerificationFailed do
|
||||
|
@ -93,7 +84,7 @@ describe Sodium::Sign::SecretKey do
|
|||
|
||||
it "to_curve25519" do
|
||||
message = "foo"
|
||||
sskey = Sodium::Sign::SecretKey.new
|
||||
sskey = Sodium::Sign::SecretKey.random
|
||||
cskey = sskey.to_curve25519
|
||||
|
||||
spkey = sskey.public_key
|
||||
|
|
|
@ -18,12 +18,12 @@ module Sodium
|
|||
SIG_SIZE = LibSodium.crypto_sign_bytes.to_i
|
||||
SEED_SIZE = LibSodium.crypto_sign_seedbytes.to_i
|
||||
|
||||
getter public_key : PublicKey
|
||||
|
||||
@[Deprecated("Switching to Crypto::Secret. Use `key.readonly` or `key.readwrite`")]
|
||||
delegate_to_slice to: @key
|
||||
|
||||
getter key : Crypto::Secret
|
||||
getter public_key = PublicKey.new
|
||||
|
||||
@seed : Crypto::Secret?
|
||||
|
||||
# Generates a new random secret/public key pair.
|
||||
|
@ -37,40 +37,54 @@ module Sodium
|
|||
end
|
||||
end
|
||||
|
||||
# Use existing secret and public keys.
|
||||
# Copies secret key to a SecureBuffer.
|
||||
# Recomputes the public key from a secret key if missing.
|
||||
def initialize(bytes : Bytes, pkey : Bytes? = nil, *, erase = false)
|
||||
raise ArgumentError.new("Secret sign key must be #{KEY_SIZE}, got #{bytes.bytesize}") unless bytes.bytesize == KEY_SIZE
|
||||
|
||||
@key = SecureBuffer.new bytes, erase: erase
|
||||
if pk = pkey
|
||||
@public_key = PublicKey.new pk
|
||||
# Copies secret *key* to a `SecureBuffer`
|
||||
def self.copy_from(key : Bytes)
|
||||
new SecureBuffer.copy_from(key)
|
||||
end
|
||||
|
||||
# Copies secret *key* to a `SecureBuffer`
|
||||
# Erases *key*
|
||||
def self.move_from(key : Bytes)
|
||||
new SecureBuffer.move_from(key)
|
||||
end
|
||||
|
||||
# Copies secret *key* to a `SecureBuffer`
|
||||
@[Deprecated("Use .copy_from or .move_from")]
|
||||
def self.new(key : Bytes, erase = false)
|
||||
raise ArgumentError.new("Secret sign key must be #{KEY_SIZE}, got #{key.bytesize}") unless key.bytesize == KEY_SIZE
|
||||
|
||||
if erase
|
||||
move_from key
|
||||
else
|
||||
@public_key = PublicKey.new
|
||||
@key.readwrite do |kslice|
|
||||
if LibSodium.crypto_sign_ed25519_sk_to_pk(@public_key.to_slice, kslice) != 0
|
||||
raise Sodium::Error.new("crypto_sign_ed25519_sk_to_pk")
|
||||
end
|
||||
copy_from key
|
||||
end
|
||||
end
|
||||
|
||||
# References existing Crypto::Secret
|
||||
def initialize(@key : Crypto::Secret)
|
||||
# Set @public_key
|
||||
@key.readwrite do |kslice|
|
||||
if LibSodium.crypto_sign_ed25519_sk_to_pk(@public_key.to_slice, kslice) != 0
|
||||
raise Sodium::Error.new("crypto_sign_ed25519_sk_to_pk")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Derive a new secret/public key pair based on a consistent seed.
|
||||
# Copies seed to a SecureBuffer.
|
||||
def initialize(*, seed : Bytes, erase = false)
|
||||
# Copies seed to a `SecureBuffer`
|
||||
def self.new(*, seed : Bytes, erase = false)
|
||||
raise ArgumentError.new("Secret sign seed must be #{SEED_SIZE}, got #{seed.bytesize}") unless seed.bytesize == SEED_SIZE
|
||||
initialize(seed: SecureBuffer.new(seed, erase: erase))
|
||||
new(seed: SecureBuffer.new(seed, erase: erase))
|
||||
end
|
||||
|
||||
# Derive a new secret/public key pair based on a consistent seed.
|
||||
# References passed SecureBuffer
|
||||
def initialize(*, seed : SecureBuffer)
|
||||
# References passed `SecureBuffer`
|
||||
def initialize(*, seed : Crypto::Secret)
|
||||
raise ArgumentError.new("Secret sign seed must be #{SEED_SIZE}, got #{seed.bytesize}") unless seed.bytesize == SEED_SIZE
|
||||
@seed = seed
|
||||
|
||||
@key = SecureBuffer.new KEY_SIZE
|
||||
@public_key = PublicKey.new
|
||||
seed.readonly do |seed_slice|
|
||||
@key.readwrite do |kslice|
|
||||
if LibSodium.crypto_sign_seed_keypair(@public_key.to_slice, kslice, seed_slice) != 0
|
||||
|
@ -80,6 +94,18 @@ module Sodium
|
|||
end
|
||||
end
|
||||
|
||||
# :nodoc:
|
||||
def initialize(random : Bool)
|
||||
@key = SecureBuffer.new KEY_SIZE
|
||||
@key.readwrite do |kslice|
|
||||
if LibSodium.crypto_sign_keypair(@public_key.to_slice, kslice) != 0
|
||||
raise Sodium::Error.new("crypto_sign_keypair")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
getter seed : Crypto::Secret do
|
||||
SecureBuffer.new(SEED_SIZE).tap do |seed_buf|
|
||||
@key.readonly do |kslice|
|
||||
|
|
Loading…
Reference in New Issue