# Copyright (C) all contributors # License: AGPL-3.0+ # OpenSSL exception added in commit 22711f81f4e79da6b796820e37803a05cae14645 # (README: add OpenSSL exception, 2015-10-05) # Replaces most uses of Digest::SHA with OpenSSL via Net::SSLeay if # possible. OpenSSL SHA-256 is nearly twice as fast as Digest::SHA on # x86-64, and SHA-1 is a bit faster as well. # I don't think we can implement Digest::SHA->clone with what Net::SSLeay # gives us... (maybe EVP_MD_CTX_copy+EVP_MD_CTX_copy_ex need to be added # to Net::SSLeay?) package PublicInbox::SHA; use v5.12; require Exporter; our @EXPORT_OK = qw(sha1_hex sha256_hex sha256 sha_all); use autodie qw(sysread); our @ISA; BEGIN { push @ISA, 'Exporter'; unless (eval(<<'EOM')) { use Net::SSLeay 1.43; my %SHA = ( 1 => Net::SSLeay::EVP_sha1(), 256 => Net::SSLeay::EVP_sha256(), ); sub new { my ($cls, $n) = @_; my $mdctx = Net::SSLeay::EVP_MD_CTX_create(); Net::SSLeay::EVP_DigestInit($mdctx, $SHA{$n}) or die "EVP_DigestInit $n: $!"; bless \$mdctx, $cls; } sub add { my $self = shift; Net::SSLeay::EVP_DigestUpdate($$self, $_) for @_; $self; } sub digest { Net::SSLeay::EVP_DigestFinal(${$_[0]}) }; sub hexdigest { unpack('H*', Net::SSLeay::EVP_DigestFinal(${$_[0]})) } sub DESTROY { Net::SSLeay::EVP_MD_CTX_destroy(${$_[0]}) }; sub sha1_hex { unpack('H*', Net::SSLeay::SHA1($_[0])) }; sub sha256_hex { unpack('H*', Net::SSLeay::SHA256($_[0])) }; *sha256 = \&Net::SSLeay::SHA256; # end of eval EOM require Digest::SHA; # stdlib fallback push @ISA, 'Digest::SHA'; *sha1_hex = \&Digest::SHA::sha1_hex; *sha256_hex = \&Digest::SHA::sha256_hex; *sha256 = \&Digest::SHA::sha256; } } # /BEGIN sub sha_all ($$) { my ($n, $fh) = @_; my ($dig, $buf) = (PublicInbox::SHA->new($n)); while (sysread($fh, $buf, 65536)) { $dig->add($buf) } $dig } 1;