Experimental Sign combined mode

This commit is contained in:
Didactic Drunk 2022-04-27 01:04:11 -07:00
parent bbbbcbd856
commit 24ffdce5c3
3 changed files with 55 additions and 8 deletions

View File

@ -64,7 +64,16 @@ describe Sodium::Sign::SecretKey do
key1.seed.should eq key3.seed key1.seed.should eq key3.seed
end end
it "signs and verifies" do it "signs and verifies combined" do
message = "foo"
skey = Sodium::Sign::SecretKey.new
sig = skey.sign message
message2 = skey.public_key.verify_string sig
message2.should eq message
end
it "signs and verifies detached" do
message = "foo" message = "foo"
skey = Sodium::Sign::SecretKey.new skey = Sodium::Sign::SecretKey.new
sig = skey.sign_detached message sig = skey.sign_detached message

View File

@ -20,13 +20,37 @@ module Sodium
end end
end end
# Verify signature made by `secret_key.sign_detached(message)` # Verify signature made by `secret_key.sign(message)`
# Raises on verification failure. # Raises on verification failure.
def verify_detached(message, sig : Bytes) #
verify_detached message.to_slice, sig # WARNING: returns pointer to message within messagesig (zerocopy)
# If you reuse messagesig, `#dup` the returned message
# `secret_key.verify(messagesig).dup`
@[Experimental]
def verify(messagesig) : Bytes
messagesig = messagesig.to_slice
bs = messagesig.bytesize
raise Sodium::Error::VerificationFailed.new("message shorter than SIG_SIZE") unless bs >= SIG_SIZE
message = messagesig[SIG_SIZE, bs - SIG_SIZE]
sig = messagesig[0, SIG_SIZE]
verify_detached message, sig
message
end end
def verify_detached(message : Bytes, sig : Bytes) @[Experimental]
def verify_string(messagesig) : String
String.new(verify(messagesig))
end
# Verify signature made by `secret_key.sign_detached(message)`
# Raises on verification failure.
def verify_detached(message, sig) : Nil
verify_detached message.to_slice, sig.to_slice
end
def verify_detached(message : Bytes, sig : Bytes) : Nil
raise ArgumentError.new("Signature must be #{SIG_SIZE} bytes, got #{sig.bytesize}") if sig.bytesize != SIG_SIZE raise ArgumentError.new("Signature must be #{SIG_SIZE} bytes, got #{sig.bytesize}") if sig.bytesize != SIG_SIZE
v = LibSodium.crypto_sign_verify_detached sig, message, message.bytesize, @bytes v = LibSodium.crypto_sign_verify_detached sig, message, message.bytesize, @bytes

View File

@ -91,14 +91,28 @@ module Sodium
end.readonly end.readonly
end end
# Signs message and returns a combined signature.
# Verify using `secret_key.public_key.verify(messagesig).dup`
# See warning about object reuse in `#verify` if you don't `#dup`
@[Experimental]
def sign(message) : Bytes
message = message.to_slice
Bytes.new(SIG_SIZE + message.bytesize).tap do |msgsig|
sign_detached message, msgsig[0, SIG_SIZE]
message.copy_to msgsig[SIG_SIZE, message.bytesize]
end
end
# Signs message and returns a detached signature. # Signs message and returns a detached signature.
# Verify using `secret_key.public_key.verify_detached(message, sig)` # Verify using `secret_key.public_key.verify_detached(message, sig)`
def sign_detached(message) def sign_detached(message) : Bytes
sign_detached message.to_slice sign_detached message.to_slice
end end
def sign_detached(message : Bytes) def sign_detached(message : Bytes, sig : Bytes? = nil) : Bytes
sig = Bytes.new(SIG_SIZE) raise ArgumentError.new("expected sig to be #{SIG_SIZE}, got #{sig.try(&.bytesize).inspect}") if sig && sig.bytesize != SIG_SIZE
sig ||= Bytes.new(SIG_SIZE)
@key.readonly do |kslice| @key.readonly do |kslice|
if LibSodium.crypto_sign_detached(sig, out sig_len, message, message.bytesize, kslice) != 0 if LibSodium.crypto_sign_detached(sig, out sig_len, message, message.bytesize, kslice) != 0
raise Error.new("crypto_sign_detached") raise Error.new("crypto_sign_detached")