57 lines
1.7 KiB
Crystal
57 lines
1.7 KiB
Crystal
require "../lib_sodium"
|
|
|
|
module Sodium
|
|
class Sign::PublicKey < Key
|
|
KEY_SIZE = LibSodium.crypto_sign_publickeybytes.to_i
|
|
SIG_SIZE = LibSodium.crypto_sign_bytes.to_i
|
|
|
|
# Returns key
|
|
delegate to_slice, to: @bytes
|
|
|
|
# :nodoc:
|
|
# Only used by SecretKey
|
|
def initialize
|
|
@bytes = Bytes.new(KEY_SIZE)
|
|
end
|
|
|
|
def initialize(@bytes : Bytes)
|
|
if bytes.bytesize != KEY_SIZE
|
|
raise ArgumentError.new("Public key must be #{KEY_SIZE} bytes, got #{bytes.bytesize}")
|
|
end
|
|
end
|
|
|
|
# Verify signature made by `secret_key.sign_detached(message)`
|
|
# Raises on verification failure.
|
|
def verify_detached(message, sig : Bytes)
|
|
verify_detached message.to_slice, sig
|
|
end
|
|
|
|
def verify_detached(message : Bytes, sig : Bytes)
|
|
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
|
|
if v != 0
|
|
raise Sodium::Error::VerificationFailed.new("crypto_sign_verify_detached")
|
|
end
|
|
end
|
|
|
|
module SerializeConverter
|
|
def self.to_json(value : PublicKey, json : JSON::Builder)
|
|
json.string Base64.strict_encode(value.to_slice)
|
|
end
|
|
|
|
def self.from_json(value : JSON::PullParser) : PublicKey
|
|
PublicKey.new Base64.decode(value.read_string)
|
|
end
|
|
|
|
def self.to_yaml(value : PublicKey, yaml : YAML::Nodes::Builder)
|
|
yaml.scalar Base64.strict_encode(value.to_slice)
|
|
end
|
|
|
|
def self.from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : PublicKey
|
|
node.raise "Expected scalar, not #{node.class}" unless node.is_a?(YAML::Nodes::Scalar)
|
|
PublicKey.new Base64.decode(node.value)
|
|
end
|
|
end
|
|
end
|
|
end
|