sodium.cr/src/sodium/sign/secret_key.cr
2019-06-29 18:19:01 -07:00

72 lines
2.2 KiB
Crystal

require "../lib_sodium"
module Sodium
# Usage:
# ```
# key = SecretKey.new
# sig = key.sign_detached data
# key.public_key.verify_detached data
# ```
class Sign::SecretKey < Sodium::Key
KEY_SIZE = LibSodium.crypto_sign_secretkeybytes
SIG_SIZE = LibSodium.crypto_sign_bytes
SEED_SIZE = LibSodium.crypto_sign_seedbytes
getter public_key : PublicKey
@[Wipe::Var]
getter bytes : Bytes
@[Wipe::Var]
@seed : Bytes?
# Generates a new random secret/public key pair.
def initialize
@bytes = Bytes.new(KEY_SIZE)
@public_key = PublicKey.new
if LibSodium.crypto_sign_keypair(@public_key.bytes, @bytes) != 0
raise Sodium::Error.new("crypto_sign_keypair")
end
end
# Use existing secret and public keys.
# Recomputes the public key from a secret key if missing.
def initialize(@bytes : Bytes, pkey : Bytes? = nil)
raise ArgumentError.new("Secret sign key must be #{KEY_SIZE}, got #{@bytes.bytesize}") unless @bytes.bytesize == KEY_SIZE
if pk = pkey
@public_key = PublicKey.new pkey
else
@public_key = PublicKey.new
if LibSodium.crypto_sign_ed25519_sk_to_pk(@public_key.bytes, @bytes) != 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.
def initialize(*, seed : Bytes)
raise ArgumentError.new("Secret sign seed must be #{SEED_SIZE}, got #{seed.bytesize}") unless seed.bytesize == SEED_SIZE
@seed = seed
@bytes = Bytes.new(KEY_SIZE)
@public_key = PublicKey.new
if LibSodium.crypto_sign_seed_keypair(@public_key.bytes, @bytes, seed) != 0
raise Sodium::Error.new("crypto_sign_seed_keypair")
end
end
# Signs message and returns a detached signature.
# Verify using `secret_key.public_key.verify_detached(message, sig)`
def sign_detached(message)
sign_detached message.to_slice
end
def sign_detached(message : Bytes)
sig = Bytes.new(SIG_SIZE)
if LibSodium.crypto_sign_detached(sig, out sig_len, message, message.bytesize, @bytes) != 0
raise Error.new("crypto_sign_detached")
end
sig
end
end
end