Skip to content

Commit 45fdf02

Browse files
committed
Add support for SHA3. Resolves #272.
1 parent cd34477 commit 45fdf02

2 files changed

Lines changed: 43 additions & 14 deletions

File tree

lib/openssl/digest.rb

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,18 @@
1515
module OpenSSL
1616
class Digest
1717

18-
alg = %w(MD2 MD4 MD5 MDC2 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512)
18+
ALGORITHMS = %w(MD4 MD5 MDC2 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512)
19+
1920
if OPENSSL_VERSION_NUMBER < 0x10100000
20-
alg += %w(DSS DSS1 SHA)
21+
ALGORITHMS.concat %w(DSS DSS1 SHA)
22+
end
23+
24+
if !OPENSSL_VERSION.include?("LibreSSL") && OPENSSL_VERSION_NUMBER > 0x10101000
25+
ALGORITHMS.concat %w(SHA3-224 SHA3-256 SHA3-384 SHA3-512)
2126
end
2227

28+
ALGORITHMS.freeze
29+
2330
# Return the hash value computed with _name_ Digest. _name_ is either the
2431
# long name or short name of a supported digest algorithm.
2532
#
@@ -35,17 +42,20 @@ def self.digest(name, data)
3542
super(data, name)
3643
end
3744

38-
alg.each{|name|
45+
ALGORITHMS.each do |name|
3946
klass = Class.new(self) {
4047
define_method(:initialize, ->(data = nil) {super(name, data)})
4148
}
49+
4250
singleton = (class << klass; self; end)
51+
4352
singleton.class_eval{
44-
define_method(:digest){|data| new.digest(data) }
45-
define_method(:hexdigest){|data| new.hexdigest(data) }
53+
define_method(:digest) {|data| new.digest(data)}
54+
define_method(:hexdigest) {|data| new.hexdigest(data)}
4655
}
47-
const_set(name, klass)
48-
}
56+
57+
const_set(name.tr('-', '_'), klass)
58+
end
4959

5060
# Deprecated.
5161
#

test/test_digest.rb

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,21 @@ def test_reset
5353
assert_equal(dig1, dig2, "reset")
5454
end
5555

56-
def test_digest_constants
57-
algs = %w(MD4 MD5 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512)
58-
if !libressl? && !openssl?(1, 1, 0)
59-
algs += %w(DSS1 SHA)
56+
def test_required_digests
57+
algorithms = OpenSSL::Digest::ALGORITHMS
58+
required = %w{MD4 MD5 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512}
59+
60+
required.each do |name|
61+
assert_include(algorithms, name)
6062
end
61-
algs.each do |alg|
62-
assert_not_nil(OpenSSL::Digest.new(alg))
63-
klass = OpenSSL::Digest.const_get(alg)
63+
end
64+
65+
def test_digest_constants
66+
algorithms = OpenSSL::Digest::ALGORITHMS
67+
68+
algorithms.each do |name|
69+
assert_not_nil(OpenSSL::Digest.new(name))
70+
klass = OpenSSL::Digest.const_get(name)
6471
assert_not_nil(klass.new)
6572
end
6673
end
@@ -91,6 +98,18 @@ def test_sha2
9198
assert_equal(sha512_a, encode16(OpenSSL::Digest::SHA512.digest("a")))
9299
end
93100

101+
def test_sha3
102+
pend "SHA3 is not implemented" unless OpenSSL::Digest.const_defined?(:SHA3_224)
103+
s224 = '6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7'
104+
s256 = 'a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a'
105+
s384 = '0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004'
106+
s512 = 'a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26'
107+
assert_equal(OpenSSL::Digest::SHA3_224.hexdigest(""), s224)
108+
assert_equal(OpenSSL::Digest::SHA3_256.hexdigest(""), s256)
109+
assert_equal(OpenSSL::Digest::SHA3_384.hexdigest(""), s384)
110+
assert_equal(OpenSSL::Digest::SHA3_512.hexdigest(""), s512)
111+
end
112+
94113
def test_digest_by_oid_and_name_sha2
95114
check_digest(OpenSSL::ASN1::ObjectId.new("SHA224"))
96115
check_digest(OpenSSL::ASN1::ObjectId.new("SHA256"))

0 commit comments

Comments
 (0)