sygna 0.1.3 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/sygna/crypt.rb +21 -72
- data/lib/sygna/signature.rb +7 -3
- data/lib/sygna/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 207581b951aa254c6b3db5d358a28ea78130312d96f480ecd0917c2729c9c5e0
|
4
|
+
data.tar.gz: 4f4257a9ac614e9d77c686eae821929112c6e6057de2bdc9f1e1a9f1ecf247a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74b1331f0a72b5ab457394f078fc6a19fe08cc8665140e59c84669a9859c74396ce19963a627f11f2f986d7b4d32a98e1782050b8d93277d086af915c97c41c2
|
7
|
+
data.tar.gz: 2d6f3f64d2d5c117ee1d7faba488bcf91fd3887c10a6d57ee8d86b1f7cda5398a6be99005bb6f6054b627b67dbe5802e2203947d367e7fbcfb50b944ac1d36e4
|
data/lib/sygna/crypt.rb
CHANGED
@@ -25,32 +25,14 @@ module Sygna
|
|
25
25
|
# {CIPHERS}.
|
26
26
|
# @param digest [String,OpenSSL::Digest] The digest algorithm to use for
|
27
27
|
# HMAC and KDF. Must be one of {DIGESTS}.
|
28
|
-
# @param mac_length [:half,:full] The length of the mac. If :half, the mac
|
29
|
-
# length will be equal to half the mac_digest's digest_legnth. If
|
30
|
-
# :full, the mac length will be equal to the mac_digest's
|
31
|
-
# digest_length.
|
32
|
-
# @param kdf_digest [String,OpenSSL::Digest,nil] The digest algorithm to
|
33
|
-
# use for KDF. If not specified, the `digest` argument will be used.
|
34
28
|
# @param mac_digest [String,OpenSSL::Digest,nil] The digest algorithm to
|
35
29
|
# use for HMAC. If not specified, the `digest` argument will be used.
|
36
|
-
|
37
|
-
# info used for KDF, also known as SharedInfo1.
|
38
|
-
# @param mac_shared_info [String] Optional. A string containing the shared
|
39
|
-
# info used for MAC, also known as SharedInfo2.
|
40
|
-
def initialize(cipher: 'AES-256-CTR', digest: 'SHA256', mac_length: :half, kdf_digest: nil, mac_digest: nil, kdf_shared_info: '', mac_shared_info: '')
|
30
|
+
def initialize(cipher: 'AES-256-CTR', digest: 'SHA256', mac_digest: nil)
|
41
31
|
@cipher = OpenSSL::Cipher.new(cipher)
|
42
32
|
@mac_digest = OpenSSL::Digest.new(mac_digest || digest)
|
43
|
-
@kdf_digest = OpenSSL::Digest.new(kdf_digest || digest)
|
44
|
-
@kdf_shared_info = kdf_shared_info
|
45
|
-
@mac_shared_info = mac_shared_info
|
46
33
|
|
47
34
|
CIPHERS.include?(@cipher.name) or raise "Cipher must be one of #{CIPHERS}"
|
48
35
|
DIGESTS.include?(@mac_digest.name) or raise "Digest must be one of #{DIGESTS}"
|
49
|
-
DIGESTS.include?(@kdf_digest.name) or raise "Digest must be one of #{DIGESTS}"
|
50
|
-
[:half, :full].include?(mac_length) or raise "mac_length must be :half or :full"
|
51
|
-
|
52
|
-
@mac_length = @mac_digest.digest_length
|
53
|
-
@mac_length /= 2 if mac_length == :half
|
54
36
|
end
|
55
37
|
|
56
38
|
# Encrypts a message to a public key using ECIES.
|
@@ -63,23 +45,27 @@ module Sygna
|
|
63
45
|
@cipher.reset
|
64
46
|
|
65
47
|
group_copy = OpenSSL::PKey::EC::Group.new(key.group)
|
66
|
-
|
48
|
+
|
67
49
|
ephemeral_key = OpenSSL::PKey::EC.new(group_copy).generate_key
|
68
50
|
ephemeral_public_key_octet = ephemeral_key.public_key.to_bn.to_s(2)
|
69
51
|
|
70
52
|
shared_secret = ephemeral_key.dh_compute_key(key.public_key)
|
71
53
|
|
72
|
-
|
73
|
-
|
74
|
-
|
54
|
+
hashed_secret = Digest::SHA512.digest(shared_secret)
|
55
|
+
|
56
|
+
cipher_key = hashed_secret.slice(0, 32)
|
57
|
+
hmac_key = hashed_secret.slice(32, hashed_secret.length - 32)
|
75
58
|
|
76
59
|
@cipher.encrypt
|
77
60
|
@cipher.iv = IV
|
78
61
|
@cipher.key = cipher_key
|
79
62
|
ciphertext = @cipher.update(message) + @cipher.final
|
80
63
|
|
81
|
-
|
64
|
+
data_to_mac = IV + ephemeral_public_key_octet + ciphertext
|
82
65
|
|
66
|
+
mac = OpenSSL::HMAC.digest(@mac_digest, hmac_key, data_to_mac)
|
67
|
+
|
68
|
+
# 65 + 20 + 16
|
83
69
|
ephemeral_public_key_octet + mac + ciphertext
|
84
70
|
end
|
85
71
|
|
@@ -93,25 +79,25 @@ module Sygna
|
|
93
79
|
@cipher.reset
|
94
80
|
|
95
81
|
group_copy = OpenSSL::PKey::EC::Group.new(key.group)
|
96
|
-
group_copy.point_conversion_form = :compressed
|
97
82
|
|
98
|
-
|
99
|
-
|
100
|
-
|
83
|
+
ephemeral_public_key_octet = encrypted_message.slice(0, 65)
|
84
|
+
|
85
|
+
mac = encrypted_message.slice(65, 20)
|
101
86
|
|
102
|
-
|
103
|
-
ciphertext = encrypted_message.byteslice(ephemeral_public_key_length, ciphertext_length)
|
104
|
-
mac = encrypted_message.byteslice(-@mac_length, @mac_length)
|
87
|
+
ciphertext = encrypted_message.slice(85, encrypted_message.size)
|
105
88
|
|
106
89
|
ephemeral_public_key = OpenSSL::PKey::EC::Point.new(group_copy, OpenSSL::BN.new(ephemeral_public_key_octet, 2))
|
107
90
|
|
108
91
|
shared_secret = key.dh_compute_key(ephemeral_public_key)
|
109
92
|
|
110
|
-
|
111
|
-
|
112
|
-
|
93
|
+
hashed_secret = Digest::SHA512.digest(shared_secret)
|
94
|
+
|
95
|
+
cipher_key = hashed_secret.slice(0, 32)
|
96
|
+
hmac_key = hashed_secret.slice(32, hashed_secret.length)
|
113
97
|
|
114
|
-
|
98
|
+
data_to_mac = IV + ephemeral_public_key_octet + ciphertext
|
99
|
+
|
100
|
+
computed_mac = OpenSSL::HMAC.digest("SHA1", hmac_key, data_to_mac)
|
115
101
|
computed_mac == mac or raise OpenSSL::PKey::ECError, "Invalid Message Authenticaton Code"
|
116
102
|
|
117
103
|
@cipher.decrypt
|
@@ -121,43 +107,6 @@ module Sygna
|
|
121
107
|
@cipher.update(ciphertext) + @cipher.final
|
122
108
|
end
|
123
109
|
|
124
|
-
# Key-derivation function, compatible with ANSI-X9.63-KDF
|
125
|
-
#
|
126
|
-
# @param shared_secret [String] The shared secret from which the key will
|
127
|
-
# be derived.
|
128
|
-
# @param length [Integer] The length of the key to generate.
|
129
|
-
# @param shared_info_suffix [String] The suffix to append to the
|
130
|
-
# shared_info.
|
131
|
-
# @return [String] Octet string of the derived key.
|
132
|
-
def kdf(shared_secret, length, shared_info_suffix)
|
133
|
-
length >=0 or raise "length cannot be negative"
|
134
|
-
return "" if length == 0
|
135
|
-
|
136
|
-
if length / @kdf_digest.digest_length >= 0xFF_FF_FF_FF
|
137
|
-
raise "length too large"
|
138
|
-
end
|
139
|
-
|
140
|
-
io = StringIO.new(String.new)
|
141
|
-
counter = 0
|
142
|
-
|
143
|
-
loop do
|
144
|
-
counter += 1
|
145
|
-
counter_bytes = [counter].pack('N')
|
146
|
-
|
147
|
-
io << @kdf_digest.digest(shared_secret + counter_bytes + @kdf_shared_info + shared_info_suffix)
|
148
|
-
if io.pos >= length
|
149
|
-
return io.string.byteslice(0, length)
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
# @return [String] A string representing this Crypt's parameters.
|
155
|
-
def to_s
|
156
|
-
"KDF-#{@kdf_digest.name}_" +
|
157
|
-
"HMAC-SHA-#{@mac_digest.digest_length * 8}-#{@mac_length * 8}_" +
|
158
|
-
@cipher.name
|
159
|
-
end
|
160
|
-
|
161
110
|
# Converts a hex-encoded public key to an `OpenSSL::PKey::EC`.
|
162
111
|
#
|
163
112
|
# @param hex_string [String] The hex-encoded public key.
|
data/lib/sygna/signature.rb
CHANGED
@@ -8,14 +8,18 @@ module Sygna
|
|
8
8
|
Secp256k1::Utils.encode_hex(ecdsa_private_key.ecdsa_serialize_compact(ecdsa_private_key.ecdsa_sign(object_string)))
|
9
9
|
end
|
10
10
|
|
11
|
-
def self.verify(object, signature)
|
11
|
+
def self.verify(object, signature, public_key)
|
12
12
|
object_string = object.merge(EMPTY_SIGNATURE).to_json
|
13
13
|
|
14
14
|
raw_signature = Secp256k1::Utils.decode_hex(signature)
|
15
15
|
|
16
|
-
|
16
|
+
public_key_binary = [public_key].pack("H*")
|
17
17
|
|
18
|
-
|
18
|
+
ecdsa_public_key = Secp256k1::PublicKey.new(pubkey: public_key)
|
19
|
+
|
20
|
+
signature = ecdsa_public_key.ecdsa_deserialize_compact(raw_signature)
|
21
|
+
|
22
|
+
ecdsa_public_key.ecdsa_verify(object_string, signature)
|
19
23
|
end
|
20
24
|
|
21
25
|
def self.ecdsa_private_key
|
data/lib/sygna/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sygna
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nic
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-04-
|
11
|
+
date: 2020-04-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|