-
Notifications
You must be signed in to change notification settings - Fork 13
/
public_key.cr
63 lines (51 loc) · 1.92 KB
/
public_key.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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
def to_curve25519 : CryptoBox::PublicKey
pk = CryptoBox::PublicKey.new
LibSodium.crypto_sign_ed25519_pk_to_curve25519 pk.to_slice, @bytes
pk
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