]> Sergey Matveev's repositories - public-inbox.git/blob - lib/PublicInbox/SHA.pm
No ext_urls
[public-inbox.git] / lib / PublicInbox / SHA.pm
1 # Copyright (C) all contributors <meta@public-inbox.org>
2 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
3 # OpenSSL exception added in commit 22711f81f4e79da6b796820e37803a05cae14645
4 # (README: add OpenSSL exception, 2015-10-05)
5
6 # Replaces most uses of Digest::SHA with OpenSSL via Net::SSLeay if
7 # possible.  OpenSSL SHA-256 is nearly twice as fast as Digest::SHA on
8 # x86-64, and SHA-1 is a bit faster as well.
9 # I don't think we can implement Digest::SHA->clone with what Net::SSLeay
10 # gives us...  (maybe EVP_MD_CTX_copy+EVP_MD_CTX_copy_ex need to be added
11 # to Net::SSLeay?)
12 package PublicInbox::SHA;
13 use v5.12;
14 require Exporter;
15 our @EXPORT_OK = qw(sha1_hex sha256_hex sha256);
16 our @ISA;
17
18 BEGIN {
19         push @ISA, 'Exporter';
20         unless (eval(<<'EOM')) {
21 use Net::SSLeay 1.43;
22 my %SHA = (
23         1 => Net::SSLeay::EVP_get_digestbyname('sha1'),
24         256 => Net::SSLeay::EVP_get_digestbyname('sha256'),
25 );
26
27 sub new {
28         my ($cls, $n) = @_;
29         my $mdctx = Net::SSLeay::EVP_MD_CTX_create();
30         Net::SSLeay::EVP_DigestInit($mdctx, $SHA{$n}) or
31                         die "EVP_DigestInit $n: $!";
32         bless \$mdctx, $cls;
33 }
34
35 sub add {
36         my $self = shift;
37         Net::SSLeay::EVP_DigestUpdate($$self, $_) for @_;
38         $self;
39 }
40
41 sub digest { Net::SSLeay::EVP_DigestFinal(${$_[0]}) };
42 sub hexdigest { unpack('H*', Net::SSLeay::EVP_DigestFinal(${$_[0]})) }
43 sub DESTROY { Net::SSLeay::EVP_MD_CTX_destroy(${$_[0]}) };
44
45 sub sha1_hex { unpack('H*', Net::SSLeay::SHA1($_[0])) };
46 sub sha256_hex { unpack('H*', Net::SSLeay::SHA256($_[0])) };
47 *sha256 = \&Net::SSLeay::SHA256;
48 # end of eval
49 EOM
50         require Digest::SHA; # stdlib fallback
51         push @ISA, 'Digest::SHA';
52         *sha1_hex = \&Digest::SHA::sha1_hex;
53         *sha256_hex = \&Digest::SHA::sha256_hex;
54         *sha256 = \&Digest::SHA::sha256;
55 }
56
57 } # /BEGIN
58 1;