File Coverage

blib/lib/Digest/SHA/PurePerl.pm
Criterion Covered Total %
statement 978 1138 85.9
branch 142 254 55.9
condition 11 24 45.8
subroutine 126 157 80.2
pod 56 56 100.0
total 1313 1629 80.6


line stmt bran cond sub pod time code
1             package Digest::SHA::PurePerl;
2              
3             require 5.003000;
4              
5 24     24   25769 use strict;
  24         169  
  24         603  
6 24     24   108 use warnings;
  24         44  
  24         875  
7 24     24   133 use vars qw($VERSION @ISA @EXPORT_OK $errmsg);
  24         41  
  24         1998  
8 24     24   149 use Fcntl qw(O_RDONLY O_RDWR);
  24         55  
  24         1317  
9 24     24   10627 use integer;
  24         339  
  24         105  
10 24     24   757 use Carp qw(croak);
  24         43  
  24         98221  
11              
12             $VERSION = '6.02';
13              
14             require Exporter;
15             @ISA = qw(Exporter);
16             @EXPORT_OK = ('$errmsg'); # see "SHA and HMAC-SHA functions" below
17              
18             # Inherit from Digest::base if possible
19              
20             eval {
21             require Digest::base;
22             push(@ISA, 'Digest::base');
23             };
24              
25             # ref. src/sha.c and sha/sha64bit.c from Digest::SHA
26              
27             my $MAX32 = 0xffffffff;
28              
29             my $uses64bit = (((1 << 16) << 16) << 16) << 15;
30              
31             my @H01 = ( # SHA-1 initial hash value
32             0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476,
33             0xc3d2e1f0
34             );
35              
36             my @H0224 = ( # SHA-224 initial hash value
37             0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
38             0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
39             );
40              
41             my @H0256 = ( # SHA-256 initial hash value
42             0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
43             0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
44             );
45              
46             my(@H0384, @H0512, @H0512224, @H0512256); # filled in later if $uses64bit
47              
48             # Routines with a "_c_" prefix return Perl code-fragments which are
49             # eval'ed at initialization. This technique emulates the behavior
50             # of the C preprocessor, allowing the optimized transform code from
51             # Digest::SHA to be more easily translated into Perl.
52              
53             sub _c_SL32 { # code to shift $x left by $n bits
54 19200     19200   24975 my($x, $n) = @_;
55 19200         45103 "($x << $n)"; # even works for 64-bit integers
56             # since the upper 32 bits are
57             # eventually discarded in _digcpy
58             }
59              
60             sub _c_SR32 { # code to shift $x right by $n bits
61 21504     21504   27373 my($x, $n) = @_;
62 21504         25198 my $mask = (1 << (32 - $n)) - 1;
63 21504         87422 "(($x >> $n) & $mask)"; # "use integer" does arithmetic
64             # shift, so clear upper bits
65             }
66              
67 2016     2016   3044 sub _c_Ch { my($x, $y, $z) = @_; "($z ^ ($x & ($y ^ $z)))" }
  2016         5390  
68 960     960   1446 sub _c_Pa { my($x, $y, $z) = @_; "($x ^ $y ^ $z)" }
  960         2620  
69 2016     2016   3042 sub _c_Ma { my($x, $y, $z) = @_; "(($x & $y) | ($z & ($x | $y)))" }
  2016         10716  
70              
71             sub _c_ROTR { # code to rotate $x right by $n bits
72 13824     13824   17859 my($x, $n) = @_;
73 13824         17349 "(" . _c_SR32($x, $n) . " | " . _c_SL32($x, 32 - $n) . ")";
74             }
75              
76             sub _c_ROTL { # code to rotate $x left by $n bits
77 5376     5376   7692 my($x, $n) = @_;
78 5376         7251 "(" . _c_SL32($x, $n) . " | " . _c_SR32($x, 32 - $n) . ")";
79             }
80              
81             sub _c_SIGMA0 { # ref. NIST SHA standard
82 1536     1536   2042 my($x) = @_;
83 1536         1931 "(" . _c_ROTR($x, 2) . " ^ " . _c_ROTR($x, 13) . " ^ " .
84             _c_ROTR($x, 22) . ")";
85             }
86              
87             sub _c_SIGMA1 {
88 1536     1536   1922 my($x) = @_;
89 1536         1996 "(" . _c_ROTR($x, 6) . " ^ " . _c_ROTR($x, 11) . " ^ " .
90             _c_ROTR($x, 25) . ")";
91             }
92              
93             sub _c_sigma0 {
94 1152     1152   1567 my($x) = @_;
95 1152         1506 "(" . _c_ROTR($x, 7) . " ^ " . _c_ROTR($x, 18) . " ^ " .
96             _c_SR32($x, 3) . ")";
97             }
98              
99             sub _c_sigma1 {
100 1152     1152   1573 my($x) = @_;
101 1152         1541 "(" . _c_ROTR($x, 17) . " ^ " . _c_ROTR($x, 19) . " ^ " .
102             _c_SR32($x, 10) . ")";
103             }
104              
105             sub _c_M1Ch { # ref. Digest::SHA sha.c (sha1 routine)
106 480     480   846 my($a, $b, $c, $d, $e, $k, $w) = @_;
107 480         754 "$e += " . _c_ROTL($a, 5) . " + " . _c_Ch($b, $c, $d) .
108             " + $k + $w; $b = " . _c_ROTL($b, 30) . ";\n";
109             }
110              
111             sub _c_M1Pa {
112 960     960   1521 my($a, $b, $c, $d, $e, $k, $w) = @_;
113 960         1409 "$e += " . _c_ROTL($a, 5) . " + " . _c_Pa($b, $c, $d) .
114             " + $k + $w; $b = " . _c_ROTL($b, 30) . ";\n";
115             }
116              
117             sub _c_M1Ma {
118 480     480   834 my($a, $b, $c, $d, $e, $k, $w) = @_;
119 480         782 "$e += " . _c_ROTL($a, 5) . " + " . _c_Ma($b, $c, $d) .
120             " + $k + $w; $b = " . _c_ROTL($b, 30) . ";\n";
121             }
122              
123 96     96   191 sub _c_M11Ch { my($k, $w) = @_; _c_M1Ch('$a', '$b', '$c', '$d', '$e', $k, $w) }
  96         191  
124 192     192   376 sub _c_M11Pa { my($k, $w) = @_; _c_M1Pa('$a', '$b', '$c', '$d', '$e', $k, $w) }
  192         358  
125 96     96   171 sub _c_M11Ma { my($k, $w) = @_; _c_M1Ma('$a', '$b', '$c', '$d', '$e', $k, $w) }
  96         187  
126 96     96   214 sub _c_M12Ch { my($k, $w) = @_; _c_M1Ch('$e', '$a', '$b', '$c', '$d', $k, $w) }
  96         179  
127 192     192   322 sub _c_M12Pa { my($k, $w) = @_; _c_M1Pa('$e', '$a', '$b', '$c', '$d', $k, $w) }
  192         322  
128 96     96   193 sub _c_M12Ma { my($k, $w) = @_; _c_M1Ma('$e', '$a', '$b', '$c', '$d', $k, $w) }
  96         189  
129 96     96   179 sub _c_M13Ch { my($k, $w) = @_; _c_M1Ch('$d', '$e', '$a', '$b', '$c', $k, $w) }
  96         172  
130 192     192   327 sub _c_M13Pa { my($k, $w) = @_; _c_M1Pa('$d', '$e', '$a', '$b', '$c', $k, $w) }
  192         352  
131 96     96   164 sub _c_M13Ma { my($k, $w) = @_; _c_M1Ma('$d', '$e', '$a', '$b', '$c', $k, $w) }
  96         199  
132 96     96   180 sub _c_M14Ch { my($k, $w) = @_; _c_M1Ch('$c', '$d', '$e', '$a', '$b', $k, $w) }
  96         194  
133 192     192   320 sub _c_M14Pa { my($k, $w) = @_; _c_M1Pa('$c', '$d', '$e', '$a', '$b', $k, $w) }
  192         332  
134 96     96   170 sub _c_M14Ma { my($k, $w) = @_; _c_M1Ma('$c', '$d', '$e', '$a', '$b', $k, $w) }
  96         187  
135 96     96   581 sub _c_M15Ch { my($k, $w) = @_; _c_M1Ch('$b', '$c', '$d', '$e', '$a', $k, $w) }
  96         207  
136 192     192   348 sub _c_M15Pa { my($k, $w) = @_; _c_M1Pa('$b', '$c', '$d', '$e', '$a', $k, $w) }
  192         346  
137 96     96   169 sub _c_M15Ma { my($k, $w) = @_; _c_M1Ma('$b', '$c', '$d', '$e', '$a', $k, $w) }
  96         167  
138              
139 3072     3072   4099 sub _c_W11 { my($s) = @_; '$W[' . (($s + 0) & 0xf) . ']' }
  3072         6468  
140 1536     1536   2063 sub _c_W12 { my($s) = @_; '$W[' . (($s + 13) & 0xf) . ']' }
  1536         2888  
141 1536     1536   1977 sub _c_W13 { my($s) = @_; '$W[' . (($s + 8) & 0xf) . ']' }
  1536         2881  
142 1536     1536   2039 sub _c_W14 { my($s) = @_; '$W[' . (($s + 2) & 0xf) . ']' }
  1536         2627  
143              
144             sub _c_A1 {
145 1536     1536   2453 my($s) = @_;
146 1536         2107 my $tmp = _c_W11($s) . " ^ " . _c_W12($s) . " ^ " .
147             _c_W13($s) . " ^ " . _c_W14($s);
148 1536         2775 "((\$tmp = $tmp), (" . _c_W11($s) . " = " . _c_ROTL('$tmp', 1) . "))";
149             }
150              
151             # The following code emulates the "sha1" routine from Digest::SHA sha.c
152              
153             my $sha1_code = '
154              
155             my($K1, $K2, $K3, $K4) = ( # SHA-1 constants
156             0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
157             );
158              
159             sub _sha1 {
160             my($self, $block) = @_;
161             my(@W, $a, $b, $c, $d, $e, $tmp);
162              
163             @W = unpack("N16", $block);
164             ($a, $b, $c, $d, $e) = @{$self->{H}};
165             ' .
166             _c_M11Ch('$K1', '$W[ 0]' ) . _c_M12Ch('$K1', '$W[ 1]' ) .
167             _c_M13Ch('$K1', '$W[ 2]' ) . _c_M14Ch('$K1', '$W[ 3]' ) .
168             _c_M15Ch('$K1', '$W[ 4]' ) . _c_M11Ch('$K1', '$W[ 5]' ) .
169             _c_M12Ch('$K1', '$W[ 6]' ) . _c_M13Ch('$K1', '$W[ 7]' ) .
170             _c_M14Ch('$K1', '$W[ 8]' ) . _c_M15Ch('$K1', '$W[ 9]' ) .
171             _c_M11Ch('$K1', '$W[10]' ) . _c_M12Ch('$K1', '$W[11]' ) .
172             _c_M13Ch('$K1', '$W[12]' ) . _c_M14Ch('$K1', '$W[13]' ) .
173             _c_M15Ch('$K1', '$W[14]' ) . _c_M11Ch('$K1', '$W[15]' ) .
174             _c_M12Ch('$K1', _c_A1( 0) ) . _c_M13Ch('$K1', _c_A1( 1) ) .
175             _c_M14Ch('$K1', _c_A1( 2) ) . _c_M15Ch('$K1', _c_A1( 3) ) .
176             _c_M11Pa('$K2', _c_A1( 4) ) . _c_M12Pa('$K2', _c_A1( 5) ) .
177             _c_M13Pa('$K2', _c_A1( 6) ) . _c_M14Pa('$K2', _c_A1( 7) ) .
178             _c_M15Pa('$K2', _c_A1( 8) ) . _c_M11Pa('$K2', _c_A1( 9) ) .
179             _c_M12Pa('$K2', _c_A1(10) ) . _c_M13Pa('$K2', _c_A1(11) ) .
180             _c_M14Pa('$K2', _c_A1(12) ) . _c_M15Pa('$K2', _c_A1(13) ) .
181             _c_M11Pa('$K2', _c_A1(14) ) . _c_M12Pa('$K2', _c_A1(15) ) .
182             _c_M13Pa('$K2', _c_A1( 0) ) . _c_M14Pa('$K2', _c_A1( 1) ) .
183             _c_M15Pa('$K2', _c_A1( 2) ) . _c_M11Pa('$K2', _c_A1( 3) ) .
184             _c_M12Pa('$K2', _c_A1( 4) ) . _c_M13Pa('$K2', _c_A1( 5) ) .
185             _c_M14Pa('$K2', _c_A1( 6) ) . _c_M15Pa('$K2', _c_A1( 7) ) .
186             _c_M11Ma('$K3', _c_A1( 8) ) . _c_M12Ma('$K3', _c_A1( 9) ) .
187             _c_M13Ma('$K3', _c_A1(10) ) . _c_M14Ma('$K3', _c_A1(11) ) .
188             _c_M15Ma('$K3', _c_A1(12) ) . _c_M11Ma('$K3', _c_A1(13) ) .
189             _c_M12Ma('$K3', _c_A1(14) ) . _c_M13Ma('$K3', _c_A1(15) ) .
190             _c_M14Ma('$K3', _c_A1( 0) ) . _c_M15Ma('$K3', _c_A1( 1) ) .
191             _c_M11Ma('$K3', _c_A1( 2) ) . _c_M12Ma('$K3', _c_A1( 3) ) .
192             _c_M13Ma('$K3', _c_A1( 4) ) . _c_M14Ma('$K3', _c_A1( 5) ) .
193             _c_M15Ma('$K3', _c_A1( 6) ) . _c_M11Ma('$K3', _c_A1( 7) ) .
194             _c_M12Ma('$K3', _c_A1( 8) ) . _c_M13Ma('$K3', _c_A1( 9) ) .
195             _c_M14Ma('$K3', _c_A1(10) ) . _c_M15Ma('$K3', _c_A1(11) ) .
196             _c_M11Pa('$K4', _c_A1(12) ) . _c_M12Pa('$K4', _c_A1(13) ) .
197             _c_M13Pa('$K4', _c_A1(14) ) . _c_M14Pa('$K4', _c_A1(15) ) .
198             _c_M15Pa('$K4', _c_A1( 0) ) . _c_M11Pa('$K4', _c_A1( 1) ) .
199             _c_M12Pa('$K4', _c_A1( 2) ) . _c_M13Pa('$K4', _c_A1( 3) ) .
200             _c_M14Pa('$K4', _c_A1( 4) ) . _c_M15Pa('$K4', _c_A1( 5) ) .
201             _c_M11Pa('$K4', _c_A1( 6) ) . _c_M12Pa('$K4', _c_A1( 7) ) .
202             _c_M13Pa('$K4', _c_A1( 8) ) . _c_M14Pa('$K4', _c_A1( 9) ) .
203             _c_M15Pa('$K4', _c_A1(10) ) . _c_M11Pa('$K4', _c_A1(11) ) .
204             _c_M12Pa('$K4', _c_A1(12) ) . _c_M13Pa('$K4', _c_A1(13) ) .
205             _c_M14Pa('$K4', _c_A1(14) ) . _c_M15Pa('$K4', _c_A1(15) ) .
206              
207             ' $self->{H}->[0] += $a; $self->{H}->[1] += $b; $self->{H}->[2] += $c;
208             $self->{H}->[3] += $d; $self->{H}->[4] += $e;
209             }
210             ';
211              
212 921     921   2735 eval($sha1_code);
  921         1431  
  921         2418  
  921         1258  
  921         1814  
  921         2091  
  921         1436  
  921         1503  
  921         1704  
  921         1531  
  921         1254  
  921         1429  
  921         1330  
  921         1519  
  921         1319  
  921         1489  
  921         1286  
  921         1463  
  921         1266  
  921         1474  
  921         1281  
  921         1517  
  921         1256  
  921         1453  
  921         1411  
  921         1457  
  921         1215  
  921         1455  
  921         1264  
  921         1453  
  921         1279  
  921         1343  
  921         1209  
  921         1465  
  921         1328  
  921         1529  
  921         1253  
  921         1988  
  921         1374  
  921         1933  
  921         1304  
  921         1855  
  921         1284  
  921         1849  
  921         1387  
  921         1941  
  921         1312  
  921         1886  
  921         1289  
  921         1937  
  921         1310  
  921         1930  
  921         1285  
  921         1907  
  921         1296  
  921         1886  
  921         1324  
  921         1865  
  921         1295  
  921         1824  
  921         1318  
  921         1979  
  921         1339  
  921         1842  
  921         1355  
  921         1825  
  921         1345  
  921         1772  
  921         1332  
  921         1838  
  921         1353  
  921         1828  
  921         1292  
  921         1934  
  921         1279  
  921         1895  
  921         1289  
  921         1744  
  921         1300  
  921         1821  
  921         1405  
  921         1918  
  921         1283  
  921         1837  
  921         1357  
  921         1951  
  921         1329  
  921         1940  
  921         1299  
  921         1958  
  921         1264  
  921         1907  
  921         1339  
  921         1868  
  921         1295  
  921         1935  
  921         1276  
  921         1948  
  921         1293  
  921         2002  
  921         1232  
  921         2061  
  921         1264  
  921         1994  
  921         1313  
  921         2000  
  921         1317  
  921         1812  
  921         1307  
  921         1962  
  921         1332  
  921         1907  
  921         1377  
  921         1960  
  921         1267  
  921         1871  
  921         1292  
  921         2033  
  921         1290  
  921         1975  
  921         1342  
  921         1892  
  921         1323  
  921         1886  
  921         1304  
  921         1838  
  921         1384  
  921         1858  
  921         1380  
  921         1883  
  921         1284  
  921         1745  
  921         1387  
  921         1937  
  921         1280  
  921         1869  
  921         1391  
  921         1865  
  921         1277  
  921         1840  
  921         1338  
  921         1846  
  921         1350  
  921         1887  
  921         1343  
  921         1890  
  921         1275  
  921         1848  
  921         1368  
  921         1853  
  921         1240  
  921         1932  
  921         1405  
  921         1842  
  921         1298  
  921         1766  
  921         1290  
  921         1848  
  921         1345  
  921         1910  
  921         1419  
  921         1886  
  921         1257  
  921         1828  
  921         1303  
  921         1503  
  921         1178  
  921         1277  
  921         1208  
  921         2912  
213              
214             sub _c_M2 { # ref. Digest::SHA sha.c (sha256 routine)
215 1536     1536   4172 my($a, $b, $c, $d, $e, $f, $g, $h, $w) = @_;
216 1536         2384 "\$T1 = $h + " . _c_SIGMA1($e) . " + " . _c_Ch($e, $f, $g) .
217             " + \$K256[\$i++] + $w; $h = \$T1 + " . _c_SIGMA0($a) .
218             " + " . _c_Ma($a, $b, $c) . "; $d += \$T1;\n";
219             }
220              
221 192     192   3305 sub _c_M21 { _c_M2('$a', '$b', '$c', '$d', '$e', '$f', '$g', '$h', $_[0]) }
222 192     192   382 sub _c_M22 { _c_M2('$h', '$a', '$b', '$c', '$d', '$e', '$f', '$g', $_[0]) }
223 192     192   386 sub _c_M23 { _c_M2('$g', '$h', '$a', '$b', '$c', '$d', '$e', '$f', $_[0]) }
224 192     192   374 sub _c_M24 { _c_M2('$f', '$g', '$h', '$a', '$b', '$c', '$d', '$e', $_[0]) }
225 192     192   375 sub _c_M25 { _c_M2('$e', '$f', '$g', '$h', '$a', '$b', '$c', '$d', $_[0]) }
226 192     192   382 sub _c_M26 { _c_M2('$d', '$e', '$f', '$g', '$h', '$a', '$b', '$c', $_[0]) }
227 192     192   389 sub _c_M27 { _c_M2('$c', '$d', '$e', '$f', '$g', '$h', '$a', '$b', $_[0]) }
228 192     192   369 sub _c_M28 { _c_M2('$b', '$c', '$d', '$e', '$f', '$g', '$h', '$a', $_[0]) }
229              
230 1152     1152   1416 sub _c_W21 { my($s) = @_; '$W[' . (($s + 0) & 0xf) . ']' }
  1152         2581  
231 1152     1152   1525 sub _c_W22 { my($s) = @_; '$W[' . (($s + 14) & 0xf) . ']' }
  1152         2073  
232 1152     1152   1622 sub _c_W23 { my($s) = @_; '$W[' . (($s + 9) & 0xf) . ']' }
  1152         2279  
233 1152     1152   1542 sub _c_W24 { my($s) = @_; '$W[' . (($s + 1) & 0xf) . ']' }
  1152         2086  
234              
235             sub _c_A2 {
236 1152     1152   1688 my($s) = @_;
237 1152         1539 "(" . _c_W21($s) . " += " . _c_sigma1(_c_W22($s)) . " + " .
238             _c_W23($s) . " + " . _c_sigma0(_c_W24($s)) . ")";
239             }
240              
241             # The following code emulates the "sha256" routine from Digest::SHA sha.c
242              
243             my $sha256_code = '
244              
245             my @K256 = ( # SHA-224/256 constants
246             0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
247             0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
248             0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
249             0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
250             0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
251             0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
252             0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
253             0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
254             0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
255             0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
256             0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
257             0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
258             0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
259             0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
260             0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
261             0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
262             );
263              
264             sub _sha256 {
265             my($self, $block) = @_;
266             my(@W, $a, $b, $c, $d, $e, $f, $g, $h, $i, $T1);
267              
268             @W = unpack("N16", $block);
269             ($a, $b, $c, $d, $e, $f, $g, $h) = @{$self->{H}};
270             ' .
271             _c_M21('$W[ 0]' ) . _c_M22('$W[ 1]' ) . _c_M23('$W[ 2]' ) .
272             _c_M24('$W[ 3]' ) . _c_M25('$W[ 4]' ) . _c_M26('$W[ 5]' ) .
273             _c_M27('$W[ 6]' ) . _c_M28('$W[ 7]' ) . _c_M21('$W[ 8]' ) .
274             _c_M22('$W[ 9]' ) . _c_M23('$W[10]' ) . _c_M24('$W[11]' ) .
275             _c_M25('$W[12]' ) . _c_M26('$W[13]' ) . _c_M27('$W[14]' ) .
276             _c_M28('$W[15]' ) .
277             _c_M21(_c_A2( 0)) . _c_M22(_c_A2( 1)) . _c_M23(_c_A2( 2)) .
278             _c_M24(_c_A2( 3)) . _c_M25(_c_A2( 4)) . _c_M26(_c_A2( 5)) .
279             _c_M27(_c_A2( 6)) . _c_M28(_c_A2( 7)) . _c_M21(_c_A2( 8)) .
280             _c_M22(_c_A2( 9)) . _c_M23(_c_A2(10)) . _c_M24(_c_A2(11)) .
281             _c_M25(_c_A2(12)) . _c_M26(_c_A2(13)) . _c_M27(_c_A2(14)) .
282             _c_M28(_c_A2(15)) . _c_M21(_c_A2( 0)) . _c_M22(_c_A2( 1)) .
283             _c_M23(_c_A2( 2)) . _c_M24(_c_A2( 3)) . _c_M25(_c_A2( 4)) .
284             _c_M26(_c_A2( 5)) . _c_M27(_c_A2( 6)) . _c_M28(_c_A2( 7)) .
285             _c_M21(_c_A2( 8)) . _c_M22(_c_A2( 9)) . _c_M23(_c_A2(10)) .
286             _c_M24(_c_A2(11)) . _c_M25(_c_A2(12)) . _c_M26(_c_A2(13)) .
287             _c_M27(_c_A2(14)) . _c_M28(_c_A2(15)) . _c_M21(_c_A2( 0)) .
288             _c_M22(_c_A2( 1)) . _c_M23(_c_A2( 2)) . _c_M24(_c_A2( 3)) .
289             _c_M25(_c_A2( 4)) . _c_M26(_c_A2( 5)) . _c_M27(_c_A2( 6)) .
290             _c_M28(_c_A2( 7)) . _c_M21(_c_A2( 8)) . _c_M22(_c_A2( 9)) .
291             _c_M23(_c_A2(10)) . _c_M24(_c_A2(11)) . _c_M25(_c_A2(12)) .
292             _c_M26(_c_A2(13)) . _c_M27(_c_A2(14)) . _c_M28(_c_A2(15)) .
293              
294             ' $self->{H}->[0] += $a; $self->{H}->[1] += $b; $self->{H}->[2] += $c;
295             $self->{H}->[3] += $d; $self->{H}->[4] += $e; $self->{H}->[5] += $f;
296             $self->{H}->[6] += $g; $self->{H}->[7] += $h;
297             }
298             ';
299              
300 257     257   930 eval($sha256_code);
  257         507  
  257         808  
  257         416  
  257         685  
  257         966  
  257         1013  
  257         348  
  257         665  
  257         632  
  257         346  
  257         591  
  257         598  
  257         360  
  257         670  
  257         584  
  257         349  
  257         652  
  257         553  
  257         329  
  257         687  
  257         637  
  257         350  
  257         618  
  257         555  
  257         336  
  257         619  
  257         591  
  257         330  
  257         577  
  257         592  
  257         313  
  257         651  
  257         615  
  257         335  
  257         704  
  257         591  
  257         369  
  257         601  
  257         571  
  257         323  
  257         587  
  257         587  
  257         371  
  257         633  
  257         558  
  257         364  
  257         623  
  257         695  
  257         318  
  257         670  
  257         609  
  257         323  
  257         847  
  257         656  
  257         326  
  257         842  
  257         565  
  257         317  
  257         983  
  257         602  
  257         327  
  257         902  
  257         573  
  257         333  
  257         898  
  257         582  
  257         348  
  257         886  
  257         849  
  257         343  
  257         996  
  257         564  
  257         347  
  257         887  
  257         565  
  257         341  
  257         851  
  257         543  
  257         324  
  257         932  
  257         611  
  257         339  
  257         900  
  257         608  
  257         338  
  257         814  
  257         562  
  257         325  
  257         949  
  257         568  
  257         324  
  257         946  
  257         625  
  257         318  
  257         918  
  257         574  
  257         328  
  257         859  
  257         564  
  257         331  
  257         955  
  257         588  
  257         310  
  257         906  
  257         538  
  257         297  
  257         836  
  257         568  
  257         310  
  257         882  
  257         590  
  257         315  
  257         810  
  257         572  
  257         339  
  257         869  
  257         550  
  257         329  
  257         857  
  257         605  
  257         310  
  257         888  
  257         577  
  257         322  
  257         880  
  257         572  
  257         313  
  257         899  
  257         630  
  257         327  
  257         953  
  257         588  
  257         321  
  257         855  
  257         576  
  257         320  
  257         873  
  257         562  
  257         329  
  257         916  
  257         660  
  257         338  
  257         804  
  257         4654  
  257         314  
  257         914  
  257         582  
  257         311  
  257         909  
  257         573  
  257         322  
  257         881  
  257         572  
  257         328  
  257         954  
  257         565  
  257         319  
  257         810  
  257         531  
  257         338  
  257         1037  
  257         598  
  257         307  
  257         887  
  257         544  
  257         327  
  257         837  
  257         573  
  257         325  
  257         904  
  257         511  
  257         339  
  257         862  
  257         627  
  257         303  
  257         777  
  257         561  
  257         319  
  257         852  
  257         579  
  257         308  
  257         1003  
  257         606  
  257         311  
  257         834  
  257         490  
  257         349  
  257         895  
  257         604  
  257         336  
  257         872  
  257         582  
  257         324  
  257         862  
  257         554  
  257         338  
  257         448  
  257         356  
  257         359  
  257         345  
  257         380  
  257         343  
  257         331  
  257         1453  
301              
302 0     0   0 sub _sha512_placeholder { return }
303             my $sha512 = \&_sha512_placeholder;
304              
305             my $_64bit_code = '
306              
307             no warnings qw(portable);
308              
309             my @K512 = (
310             0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
311             0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
312             0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
313             0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
314             0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
315             0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
316             0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
317             0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
318             0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
319             0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
320             0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
321             0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
322             0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
323             0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
324             0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
325             0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
326             0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
327             0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
328             0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
329             0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
330             0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
331             0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
332             0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
333             0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
334             0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
335             0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
336             0x5fcb6fab3ad6faec, 0x6c44198c4a475817);
337              
338             @H0384 = (
339             0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17,
340             0x152fecd8f70e5939, 0x67332667ffc00b31, 0x8eb44a8768581511,
341             0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4);
342              
343             @H0512 = (
344             0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b,
345             0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f,
346             0x1f83d9abfb41bd6b, 0x5be0cd19137e2179);
347              
348             @H0512224 = (
349             0x8c3d37c819544da2, 0x73e1996689dcd4d6, 0x1dfab7ae32ff9c82,
350             0x679dd514582f9fcf, 0x0f6d2b697bd44da8, 0x77e36f7304c48942,
351             0x3f9d85a86a1d36c8, 0x1112e6ad91d692a1);
352              
353             @H0512256 = (
354             0x22312194fc2bf72c, 0x9f555fa3c84c64c2, 0x2393b86b6f53b151,
355             0x963877195940eabd, 0x96283ee2a88effe3, 0xbe5e1e2553863992,
356             0x2b0199fc2c85b8aa, 0x0eb72ddc81c52ca2);
357              
358             use warnings;
359              
360             sub _c_SL64 { my($x, $n) = @_; "($x << $n)" }
361              
362             sub _c_SR64 {
363             my($x, $n) = @_;
364             my $mask = (1 << (64 - $n)) - 1;
365             "(($x >> $n) & $mask)";
366             }
367              
368             sub _c_ROTRQ {
369             my($x, $n) = @_;
370             "(" . _c_SR64($x, $n) . " | " . _c_SL64($x, 64 - $n) . ")";
371             }
372              
373             sub _c_SIGMAQ0 {
374             my($x) = @_;
375             "(" . _c_ROTRQ($x, 28) . " ^ " . _c_ROTRQ($x, 34) . " ^ " .
376             _c_ROTRQ($x, 39) . ")";
377             }
378              
379             sub _c_SIGMAQ1 {
380             my($x) = @_;
381             "(" . _c_ROTRQ($x, 14) . " ^ " . _c_ROTRQ($x, 18) . " ^ " .
382             _c_ROTRQ($x, 41) . ")";
383             }
384              
385             sub _c_sigmaQ0 {
386             my($x) = @_;
387             "(" . _c_ROTRQ($x, 1) . " ^ " . _c_ROTRQ($x, 8) . " ^ " .
388             _c_SR64($x, 7) . ")";
389             }
390              
391             sub _c_sigmaQ1 {
392             my($x) = @_;
393             "(" . _c_ROTRQ($x, 19) . " ^ " . _c_ROTRQ($x, 61) . " ^ " .
394             _c_SR64($x, 6) . ")";
395             }
396              
397             my $sha512_code = q/
398             sub _sha512 {
399             my($self, $block) = @_;
400             my(@N, @W, $a, $b, $c, $d, $e, $f, $g, $h, $T1, $T2);
401              
402             @N = unpack("N32", $block);
403             ($a, $b, $c, $d, $e, $f, $g, $h) = @{$self->{H}};
404             for ( 0 .. 15) { $W[$_] = (($N[2*$_] << 16) << 16) | $N[2*$_+1] }
405             for (16 .. 79) { $W[$_] = / .
406             _c_sigmaQ1(q/$W[$_- 2]/) . q/ + $W[$_- 7] + / .
407             _c_sigmaQ0(q/$W[$_-15]/) . q/ + $W[$_-16] }
408             for ( 0 .. 79) {
409             $T1 = $h + / . _c_SIGMAQ1(q/$e/) .
410             q/ + (($g) ^ (($e) & (($f) ^ ($g)))) +
411             $K512[$_] + $W[$_];
412             $T2 = / . _c_SIGMAQ0(q/$a/) .
413             q/ + ((($a) & ($b)) | (($c) & (($a) | ($b))));
414             $h = $g; $g = $f; $f = $e; $e = $d + $T1;
415             $d = $c; $c = $b; $b = $a; $a = $T1 + $T2;
416             }
417             $self->{H}->[0] += $a; $self->{H}->[1] += $b; $self->{H}->[2] += $c;
418             $self->{H}->[3] += $d; $self->{H}->[4] += $e; $self->{H}->[5] += $f;
419             $self->{H}->[6] += $g; $self->{H}->[7] += $h;
420             }
421             /;
422              
423             eval($sha512_code);
424             $sha512 = \&_sha512;
425              
426             ';
427              
428 24     24   190 eval($_64bit_code) if $uses64bit;
  24     24   46  
  24     240   2810  
  24     24   124  
  24     24   52  
  24     240   7674  
  240     288   370  
  240     24   357  
  24     24   47  
  24     249   70  
  24         50  
  24         59  
  240         371  
  240         904  
  288         409  
  288         392  
  288         901  
  24         52  
  24         59  
  24         57  
  24         63  
  249         964  
  249         542  
  249         962  
  249         405  
  249         670  
  249         647  
  3984         6323  
  249         458  
  15936         38273  
  249         500  
  19920         36472  
  19920         33263  
  19920         23535  
  19920         23166  
  19920         22954  
  19920         23466  
  19920         23126  
  19920         23260  
  19920         22766  
  19920         25238  
  249         458  
  249         398  
  249         355  
  249         370  
  249         364  
  249         385  
  249         390  
  249         2006  
429              
430             sub _SETBIT {
431 190     190   416 my($self, $pos) = @_;
432 190         906 my @c = unpack("C*", $self->{block});
433 190 100       660 $c[$pos >> 3] = 0x00 unless defined $c[$pos >> 3];
434 190         493 $c[$pos >> 3] |= (0x01 << (7 - $pos % 8));
435 190         801 $self->{block} = pack("C*", @c);
436             }
437              
438             sub _CLRBIT {
439 80088     80088   104762 my($self, $pos) = @_;
440 80088         208778 my @c = unpack("C*", $self->{block});
441 80088 100       137825 $c[$pos >> 3] = 0x00 unless defined $c[$pos >> 3];
442 80088         101425 $c[$pos >> 3] &= ~(0x01 << (7 - $pos % 8));
443 80088         264419 $self->{block} = pack("C*", @c);
444             }
445              
446             sub _BYTECNT {
447 1806     1806   2270 my($bitcnt) = @_;
448 1806 100       8067 $bitcnt > 0 ? 1 + (($bitcnt - 1) >> 3) : 0;
449             }
450              
451             sub _digcpy {
452 190     190   363 my($self) = @_;
453 190         279 my @dig;
454 190         318 for (@{$self->{H}}) {
  190         562  
455 1520 100       2529 push(@dig, (($_>>16)>>16) & $MAX32) if $self->{alg} >= 384;
456 1520         2022 push(@dig, $_ & $MAX32);
457             }
458 190         1156 $self->{digest} = pack("N" . ($self->{digestlen}>>2), @dig);
459             }
460              
461             sub _sharewind {
462 217     217   411 my($self) = @_;
463 217         410 my $alg = $self->{alg};
464 217         405 $self->{block} = ""; $self->{blockcnt} = 0;
  217         344  
465 217 100       640 $self->{blocksize} = $alg <= 256 ? 512 : 1024;
466 217         446 for (qw(lenll lenlh lenhl lenhh)) { $self->{$_} = 0 }
  868         1447  
467 217 100       570 $self->{digestlen} = $alg == 1 ? 20 : ($alg % 1000)/8;
468 217 100       733 if ($alg == 1) { $self->{sha} = \&_sha1; $self->{H} = [@H01] }
  103 100       215  
  103 100       282  
    100          
    100          
    100          
    50          
469 4         11 elsif ($alg == 224) { $self->{sha} = \&_sha256; $self->{H} = [@H0224] }
  4         13  
470 53         120 elsif ($alg == 256) { $self->{sha} = \&_sha256; $self->{H} = [@H0256] }
  53         139  
471 27         58 elsif ($alg == 384) { $self->{sha} = $sha512; $self->{H} = [@H0384] }
  27         82  
472 26         48 elsif ($alg == 512) { $self->{sha} = $sha512; $self->{H} = [@H0512] }
  26         73  
473 2         4 elsif ($alg == 512224) { $self->{sha}=$sha512; $self->{H}=[@H0512224] }
  2         7  
474 2         5 elsif ($alg == 512256) { $self->{sha}=$sha512; $self->{H}=[@H0512256] }
  2         6  
475 217         323 push(@{$self->{H}}, 0) while scalar(@{$self->{H}}) < 8;
  526         1013  
  309         504  
476 217         1172 $self;
477             }
478              
479             sub _shaopen {
480 154     154   307 my($alg) = @_;
481 154         221 my($self);
482 154 100       338 return unless grep { $alg == $_ } (1,224,256,384,512,512224,512256);
  1078         1849  
483 153 50 66     590 return if ($alg >= 384 && !$uses64bit);
484 153         348 $self->{alg} = $alg;
485 153         377 _sharewind($self);
486             }
487              
488             sub _shadirect {
489 623     623   1108 my($bitstr, $bitcnt, $self) = @_;
490 623         828 my $savecnt = $bitcnt;
491 623         860 my $offset = 0;
492 623         1015 my $blockbytes = $self->{blocksize} >> 3;
493 623         1285 while ($bitcnt >= $self->{blocksize}) {
494 833         1723 &{$self->{sha}}($self, substr($bitstr, $offset, $blockbytes));
  833         19243  
495 833         1793 $offset += $blockbytes;
496 833         2131 $bitcnt -= $self->{blocksize};
497             }
498 623 100       1118 if ($bitcnt > 0) {
499 532         1051 $self->{block} = substr($bitstr, $offset, _BYTECNT($bitcnt));
500 532         799 $self->{blockcnt} = $bitcnt;
501             }
502 623         2181 $savecnt;
503             }
504              
505             sub _shabytes {
506 670     670   963 my($bitstr, $bitcnt, $self) = @_;
507 670         689 my($numbits);
508 670         699 my $savecnt = $bitcnt;
509 670 100       1065 if ($self->{blockcnt} + $bitcnt >= $self->{blocksize}) {
510 376         464 $numbits = $self->{blocksize} - $self->{blockcnt};
511 376         625 $self->{block} .= substr($bitstr, 0, $numbits >> 3);
512 376         423 $bitcnt -= $numbits;
513 376         495 $bitstr = substr($bitstr, $numbits >> 3, _BYTECNT($bitcnt));
514 376         488 &{$self->{sha}}($self, $self->{block});
  376         7577  
515 376         625 $self->{block} = "";
516 376         455 $self->{blockcnt} = 0;
517 376         683 _shadirect($bitstr, $bitcnt, $self);
518             }
519             else {
520 294         425 $self->{block} .= substr($bitstr, 0, _BYTECNT($bitcnt));
521 294         377 $self->{blockcnt} += $bitcnt;
522             }
523 670         857 $savecnt;
524             }
525              
526             sub _shabits {
527 593     593   794 my($bitstr, $bitcnt, $self) = @_;
528 593         655 my($i, @buf);
529 593         762 my $numbytes = _BYTECNT($bitcnt);
530 593         815 my $savecnt = $bitcnt;
531 593         756 my $gap = 8 - $self->{blockcnt} % 8;
532 593         1584 my @c = unpack("C*", $self->{block});
533 593         1700 my @b = unpack("C" . $numbytes, $bitstr);
534 593         946 $c[$self->{blockcnt}>>3] &= (~0 << $gap);
535 593         799 $c[$self->{blockcnt}>>3] |= $b[0] >> (8 - $gap);
536 593         1281 $self->{block} = pack("C*", @c);
537 593 100       933 $self->{blockcnt} += ($bitcnt < $gap) ? $bitcnt : $gap;
538 593 100       863 return($savecnt) if $bitcnt < $gap;
539 583 100       869 if ($self->{blockcnt} == $self->{blocksize}) {
540 7         17 &{$self->{sha}}($self, $self->{block});
  7         156  
541 7         15 $self->{block} = "";
542 7         15 $self->{blockcnt} = 0;
543             }
544 583 100       871 return($savecnt) if ($bitcnt -= $gap) == 0;
545 580         948 for ($i = 0; $i < $numbytes - 1; $i++) {
546 26847         39673 $buf[$i] = (($b[$i] << $gap) & 0xff) | ($b[$i+1] >> (8 - $gap));
547             }
548 580         797 $buf[$numbytes-1] = ($b[$numbytes-1] << $gap) & 0xff;
549 580         1681 _shabytes(pack("C*", @buf), $bitcnt, $self);
550 580         1885 $savecnt;
551             }
552              
553             sub _shawrite {
554 931     931   1441 my($bitstr, $bitcnt, $self) = @_;
555 931 100       1671 return(0) unless $bitcnt > 0;
556 24     24   256 no integer;
  24         62  
  24         128  
557 930         1114 my $TWO32 = 4294967296;
558 930 100       1805 if (($self->{lenll} += $bitcnt) >= $TWO32) {
559 5         11 $self->{lenll} -= $TWO32;
560 5 50       29 if (++$self->{lenlh} >= $TWO32) {
561 0         0 $self->{lenlh} -= $TWO32;
562 0 0       0 if (++$self->{lenhl} >= $TWO32) {
563 0         0 $self->{lenhl} -= $TWO32;
564 0 0       0 if (++$self->{lenhh} >= $TWO32) {
565 0         0 $self->{lenhh} -= $TWO32;
566             }
567             }
568             }
569             }
570 24     24   2069 use integer;
  24         51  
  24         99  
571 930         1267 my $blockcnt = $self->{blockcnt};
572 930 100       1825 return(_shadirect($bitstr, $bitcnt, $self)) if $blockcnt == 0;
573 683 100       1053 return(_shabytes ($bitstr, $bitcnt, $self)) if $blockcnt % 8 == 0;
574 593         923 return(_shabits ($bitstr, $bitcnt, $self));
575             }
576              
577             my $no_downgrade = 'sub utf8::downgrade { 1 }';
578              
579             my $pp_downgrade = q {
580             sub utf8::downgrade {
581              
582             # No need to downgrade if character and byte
583             # semantics are equivalent. But this might
584             # leave the UTF-8 flag set, harmlessly.
585              
586             require bytes;
587             return 1 if length($_[0]) == bytes::length($_[0]);
588              
589             use utf8;
590             return 0 if $_[0] =~ /[^\x00-\xff]/;
591             $_[0] = pack('C*', unpack('U*', $_[0]));
592             return 1;
593             }
594             };
595              
596             {
597 24     24   2813 no integer;
  24         52  
  24         81  
598              
599             if ($] < 5.006) { eval $no_downgrade }
600             elsif ($] < 5.008) { eval $pp_downgrade }
601             }
602              
603             my $WSE = 'Wide character in subroutine entry';
604             my $MWS = 16384;
605              
606             sub _shaWrite {
607 98     98   236 my($bytestr_r, $bytecnt, $self) = @_;
608 98 100       472 return(0) unless $bytecnt > 0;
609 86 100       513 croak $WSE unless utf8::downgrade($$bytestr_r, 1);
610 85 50       340 return(_shawrite($$bytestr_r, $bytecnt<<3, $self)) if $bytecnt <= $MWS;
611 0         0 my $offset = 0;
612 0         0 while ($bytecnt > $MWS) {
613 0         0 _shawrite(substr($$bytestr_r, $offset, $MWS), $MWS<<3, $self);
614 0         0 $offset += $MWS;
615 0         0 $bytecnt -= $MWS;
616             }
617 0         0 _shawrite(substr($$bytestr_r, $offset, $bytecnt), $bytecnt<<3, $self);
618             }
619              
620             sub _shafinish {
621 190     190   382 my($self) = @_;
622 190 100       553 my $LENPOS = $self->{alg} <= 256 ? 448 : 896;
623 190         724 _SETBIT($self, $self->{blockcnt}++);
624 190         545 while ($self->{blockcnt} > $LENPOS) {
625 1223 100       1808 if ($self->{blockcnt} < $self->{blocksize}) {
626 1202         1710 _CLRBIT($self, $self->{blockcnt}++);
627             }
628             else {
629 21         36 &{$self->{sha}}($self, $self->{block});
  21         640  
630 21         59 $self->{block} = "";
631 21         79 $self->{blockcnt} = 0;
632             }
633             }
634 190         453 while ($self->{blockcnt} < $LENPOS) {
635 78886         114176 _CLRBIT($self, $self->{blockcnt}++);
636             }
637 190 100       524 if ($self->{blocksize} > 512) {
638 53         243 $self->{block} .= pack("N", $self->{lenhh} & $MAX32);
639 53         195 $self->{block} .= pack("N", $self->{lenhl} & $MAX32);
640             }
641 190         562 $self->{block} .= pack("N", $self->{lenlh} & $MAX32);
642 190         466 $self->{block} .= pack("N", $self->{lenll} & $MAX32);
643 190         335 &{$self->{sha}}($self, $self->{block});
  190         7029  
644             }
645              
646 79     79   159 sub _shadigest { my($self) = @_; _digcpy($self); $self->{digest} }
  79         247  
  79         588  
647              
648             sub _shahex {
649 100     100   214 my($self) = @_;
650 100         278 _digcpy($self);
651 100         646 join("", unpack("H*", $self->{digest}));
652             }
653              
654             sub _shabase64 {
655 11     11   30 my($self) = @_;
656 11         45 _digcpy($self);
657 11         48 my $b64 = pack("u", $self->{digest});
658 11         58 $b64 =~ s/^.//mg;
659 11         46 $b64 =~ s/\n//g;
660 11         33 $b64 =~ tr|` -_|AA-Za-z0-9+/|;
661 11         31 my $numpads = (3 - length($self->{digest}) % 3) % 3;
662 11 100       153 $b64 =~ s/.{$numpads}$// if $numpads;
663 11         76 $b64;
664             }
665              
666 0     0   0 sub _shadsize { my($self) = @_; $self->{digestlen} }
  0         0  
667              
668             sub _shacpy {
669 17     17   37 my($to, $from) = @_;
670 17         54 $to->{alg} = $from->{alg};
671 17         36 $to->{sha} = $from->{sha};
672 17         27 $to->{H} = [@{$from->{H}}];
  17         45  
673 17         40 $to->{block} = $from->{block};
674 17         44 $to->{blockcnt} = $from->{blockcnt};
675 17         33 $to->{blocksize} = $from->{blocksize};
676 17         39 for (qw(lenhh lenhl lenlh lenll)) { $to->{$_} = $from->{$_} }
  68         126  
677 17         30 $to->{digestlen} = $from->{digestlen};
678 17         77 $to;
679             }
680              
681 11     11   21 sub _shadup { my($self) = @_; my($copy); _shacpy($copy, $self) }
  11         17  
  11         30  
682              
683             sub _shadump {
684 4     4   8 my $self = shift;
685 4         13 for (qw(alg H block blockcnt lenhh lenhl lenlh lenll)) {
686 32 50       60 return unless defined $self->{$_};
687             }
688              
689 4         7 my @state = ();
690 4 100       16 my $fmt = ($self->{alg} <= 256 ? "%08x" : "%016x");
691              
692 4         22 push(@state, "alg:" . $self->{alg});
693              
694 4 100       9 my @H = map { $self->{alg} <= 256 ? $_ & $MAX32 : $_ } @{$self->{H}};
  32         66  
  4         10  
695 4         12 push(@state, "H:" . join(":", map { sprintf($fmt, $_) } @H));
  32         75  
696              
697 4         23 my @c = unpack("C*", $self->{block});
698 4         78 push(@c, 0x00) while scalar(@c) < ($self->{blocksize} >> 3);
699 4         9 push(@state, "block:" . join(":", map {sprintf("%02x", $_)} @c));
  384         582  
700 4         24 push(@state, "blockcnt:" . $self->{blockcnt});
701              
702 4         11 push(@state, "lenhh:" . $self->{lenhh});
703 4         8 push(@state, "lenhl:" . $self->{lenhl});
704 4         9 push(@state, "lenlh:" . $self->{lenlh});
705 4         9 push(@state, "lenll:" . $self->{lenll});
706 4         45 join("\n", @state) . "\n";
707             }
708              
709             sub _shaload {
710 11     11   43 my $state = shift;
711              
712 11         27 my %s = ();
713 11         70 for (split(/\n/, $state)) {
714 96         192 s/^\s+//;
715 96         172 s/\s+$//;
716 96 100       211 next if (/^(#|$)/);
717 88         587 my @f = split(/[:\s]+/);
718 88         147 my $tag = shift(@f);
719 88         331 $s{$tag} = join('', @f);
720             }
721              
722             # H and block may contain arbitrary values, but check everything else
723 11 50       39 grep { $_ == $s{alg} } (1,224,256,384,512,512224,512256) or return;
  77         160  
724 11 100       58 length($s{H}) == ($s{alg} <= 256 ? 64 : 128) or return;
    50          
725 11 100       50 length($s{block}) == ($s{alg} <= 256 ? 128 : 256) or return;
    50          
726             {
727 24     24   35879 no integer;
  24         52  
  24         122  
  11         15  
728 11         31 for (qw(blockcnt lenhh lenhl lenlh lenll)) {
729 55 50       121 0 <= $s{$_} or return;
730 55 50       120 $s{$_} <= 4294967295 or return;
731             }
732 11 100       38 $s{blockcnt} < ($s{alg} <= 256 ? 512 : 1024) or return;
    50          
733             }
734              
735 11 50       37 my $self = _shaopen($s{alg}) or return;
736              
737 11         109 my @h = $s{H} =~ /(.{8})/g;
738 11         27 for (@{$self->{H}}) {
  11         33  
739 88         127 $_ = hex(shift @h);
740 88 100       193 if ($self->{alg} > 256) {
741 32         48 $_ = (($_ << 16) << 16) | hex(shift @h);
742             }
743             }
744              
745 11         31 $self->{blockcnt} = $s{blockcnt};
746 11         67 $self->{block} = pack("H*", $s{block});
747 11         40 $self->{block} = substr($self->{block},0,_BYTECNT($self->{blockcnt}));
748              
749 11         30 $self->{lenhh} = $s{lenhh};
750 11         23 $self->{lenhl} = $s{lenhl};
751 11         23 $self->{lenlh} = $s{lenlh};
752 11         21 $self->{lenll} = $s{lenll};
753              
754 11         58 $self;
755             }
756              
757             # ref. src/hmac.c from Digest::SHA
758              
759             sub _hmacopen {
760 43     43   155 my($alg, $key) = @_;
761 43         80 my($self);
762 43 50       144 $self->{isha} = _shaopen($alg) or return;
763 43 50       107 $self->{osha} = _shaopen($alg) or return;
764 43 50       177 croak $WSE unless utf8::downgrade($key, 1);
765 43 100       144 if (length($key) > $self->{osha}->{blocksize} >> 3) {
766 11 50       29 $self->{ksha} = _shaopen($alg) or return;
767 11         48 _shawrite($key, length($key) << 3, $self->{ksha});
768 11         54 _shafinish($self->{ksha});
769 11         50 $key = _shadigest($self->{ksha});
770             }
771             $key .= chr(0x00)
772 43         5531 while length($key) < $self->{osha}->{blocksize} >> 3;
773 43         338 my @k = unpack("C*", $key);
774 43         129 for (@k) { $_ ^= 0x5c }
  3712         4350  
775 43         310 _shawrite(pack("C*", @k), $self->{osha}->{blocksize}, $self->{osha});
776 43         124 for (@k) { $_ ^= (0x5c ^ 0x36) }
  3712         4554  
777 43         334 _shawrite(pack("C*", @k), $self->{isha}->{blocksize}, $self->{isha});
778 43         1261 $self;
779             }
780              
781             sub _hmacWrite {
782 45     45   143 my($bytestr_r, $bytecnt, $self) = @_;
783 45         292 _shaWrite($bytestr_r, $bytecnt, $self->{isha});
784             }
785              
786             sub _hmacfinish {
787 43     43   89 my($self) = @_;
788 43         137 _shafinish($self->{isha});
789             _shawrite(_shadigest($self->{isha}),
790 43         166 $self->{isha}->{digestlen} << 3, $self->{osha});
791 43         108 _shafinish($self->{osha});
792             }
793              
794 23     23   64 sub _hmacdigest { my($self) = @_; _shadigest($self->{osha}) }
  23         73  
795 20     20   39 sub _hmachex { my($self) = @_; _shahex($self->{osha}) }
  20         62  
796 0     0   0 sub _hmacbase64 { my($self) = @_; _shabase64($self->{osha}) }
  0         0  
797              
798             # SHA and HMAC-SHA functions
799              
800             my @suffix_extern = ("", "_hex", "_base64");
801             my @suffix_intern = ("digest", "hex", "base64");
802              
803             my($i, $alg);
804             for $alg (1, 224, 256, 384, 512, 512224, 512256) {
805             for $i (0 .. 2) {
806             my $fcn = 'sub sha' . $alg . $suffix_extern[$i] . ' {
807             my $state = _shaopen(' . $alg . ') or return;
808             for (@_) { _shaWrite(\$_, length($_), $state) }
809             _shafinish($state);
810             _sha' . $suffix_intern[$i] . '($state);
811             }';
812 1 50   1 1 5 eval($fcn);
  1 50   2 1 3  
  1 50   5 1 4  
  1 0   0 1 4  
  1 50   2 1 7  
  2 50   2 1 208  
  2 0   0 1 6  
  2 50   2 1 10  
  2 50   2 1 10  
  2 0   0 1 11  
  5 50   2 1 295  
  5 50   4 1 13  
  5 0   0 1 21  
  4 0   0 1 16  
  4 0   0 1 15  
  0 50   2 1 0  
  0 0   0 1 0  
  0 0   0 1 0  
  0 50   2 1 0  
  0 50   2 1 0  
  2 50   5 1 61  
  2         5  
  2         9  
  2         7  
  2         10  
  2         229  
  2         6  
  2         7  
  2         9  
  2         9  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  2         61  
  2         5  
  2         9  
  2         7  
  2         11  
  2         190  
  2         6  
  2         7  
  2         8  
  2         7  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  2         65  
  2         22  
  2         11  
  2         9  
  2         11  
  4         250  
  4         12  
  4         15  
  4         16  
  4         19  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  2         77  
  2         9  
  2         9  
  2         8  
  2         12  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  2         86  
  2         7  
  2         9  
  2         9  
  2         12  
  2         63  
  2         7  
  2         9  
  2         9  
  2         12  
  5         489  
  5         14  
  5         19  
  5         19  
  5         26  
813             push(@EXPORT_OK, 'sha' . $alg . $suffix_extern[$i]);
814             $fcn = 'sub hmac_sha' . $alg . $suffix_extern[$i] . ' {
815             my $state = _hmacopen(' . $alg . ', pop(@_)) or return;
816             for (@_) { _hmacWrite(\$_, length($_), $state) }
817             _hmacfinish($state);
818             _hmac' . $suffix_intern[$i] . '($state);
819             }';
820 0 0   0 1 0 eval($fcn);
  0 0   0 1 0  
  0 50   11 1 0  
  0 0   0 1 0  
  0 0   0 1 0  
  0 0   0 1 0  
  0 50   8 1 0  
  0 0   0 1 0  
  0 50   9 1 0  
  0 50   8 1 0  
  11 0   0 1 701  
  11 0   0 1 28  
  11 50   7 1 32  
  11 0   0 1 35  
  11 0   0 1 40  
  0 0   0 1 0  
  0 0   0 1 0  
  0 0   0 1 0  
  0 0   0 1 0  
  0 0   0 1 0  
  0 0   0 1 0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  8         3433  
  8         29  
  10         39  
  8         32  
  8         34  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  9         337  
  9         35  
  9         70  
  9         35  
  9         50  
  8         344  
  8         37  
  8         46  
  8         43  
  8         49  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  7         295  
  7         30  
  7         37  
  7         32  
  7         36  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
821             push(@EXPORT_OK, 'hmac_sha' . $alg . $suffix_extern[$i]);
822             }
823             }
824              
825             # OOP methods
826              
827 0     0 1 0 sub hashsize { my $self = shift; _shadsize($self) << 3 }
  0         0  
828 4     4 1 7 sub algorithm { my $self = shift; $self->{alg} }
  4         26  
829              
830             sub add {
831 19     19 1 466 my $self = shift;
832 19         34 for (@_) { _shaWrite(\$_, length($_), $self) }
  20         46  
833 19         52 $self;
834             }
835              
836             sub digest {
837 1     1 1 2 my $self = shift;
838 1         11 _shafinish($self);
839 1         5 my $rsp = _shadigest($self);
840 1         4 _sharewind($self);
841 1         28 $rsp;
842             }
843              
844             sub hexdigest {
845 59     59 1 135 my $self = shift;
846 59         143 _shafinish($self);
847 59         219 my $rsp = _shahex($self);
848 59         167 _sharewind($self);
849 59         178 $rsp;
850             }
851              
852             sub b64digest {
853 1     1 1 3 my $self = shift;
854 1         2 _shafinish($self);
855 1         4 my $rsp = _shabase64($self);
856 1         4 _sharewind($self);
857 1         2 $rsp;
858             }
859              
860             sub new {
861 16     16 1 1161 my($class, $alg) = @_;
862 16 100       73 $alg =~ s/\D+//g if defined $alg;
863 16 100       42 if (ref($class)) { # instance method
864 5 100 100     21 if (!defined($alg) || ($alg == $class->algorithm)) {
865 3         9 _sharewind($class);
866 3         11 return($class);
867             }
868 2 50       7 my $self = _shaopen($alg) or return;
869 2         8 return(_shacpy($class, $self));
870             }
871 11 100       31 $alg = 1 unless defined $alg;
872 11 100       33 my $self = _shaopen($alg) or return;
873 10         23 bless($self, $class);
874 10         35 $self;
875             }
876              
877             sub clone {
878 11     11 1 326 my $self = shift;
879 11 50       32 my $copy = _shadup($self) or return;
880 11         44 bless($copy, ref($self));
881             }
882              
883 24     24   51172 BEGIN { *reset = \&new }
884              
885             sub add_bits {
886 706     706 1 2894 my($self, $data, $nbits) = @_;
887 706 100       1136 unless (defined $nbits) {
888 38         50 $nbits = length($data);
889 38         141 $data = pack("B*", $data);
890             }
891 706 50       1151 $nbits = length($data) * 8 if $nbits > length($data) * 8;
892 706         1291 _shawrite($data, $nbits, $self);
893 706         1112 return($self);
894             }
895              
896             sub _bail {
897 0     0   0 my $msg = shift;
898              
899 0         0 $errmsg = $!;
900 0         0 $msg .= ": $!";
901 0         0 croak $msg;
902             }
903              
904             sub _addfile {
905 3     3   7 my ($self, $handle) = @_;
906              
907 3         4 my $n;
908 3         4 my $buf = "";
909              
910 3         55 while (($n = read($handle, $buf, 4096))) {
911 3         11 $self->add($buf);
912             }
913 3 50       7 _bail("Read failed") unless defined $n;
914              
915 3         9 $self;
916             }
917              
918             {
919             my $_can_T_filehandle;
920              
921             sub _istext {
922 1     1   2 local *FH = shift;
923 1         3 my $file = shift;
924              
925 1 50       4 if (! defined $_can_T_filehandle) {
926 1         5 local $^W = 0;
927 1         2 my $istext = eval { -T FH };
  1         15  
928 1 50       5 $_can_T_filehandle = $@ ? 0 : 1;
929 1 50       7 return $_can_T_filehandle ? $istext : -T $file;
930             }
931 0 0       0 return $_can_T_filehandle ? -T FH : -T $file;
932             }
933             }
934              
935             sub addfile {
936 6     6 1 52 my ($self, $file, $mode) = @_;
937              
938 6 100       23 return(_addfile($self, $file)) unless ref(\$file) eq 'SCALAR';
939              
940 4 50       9 $mode = defined($mode) ? $mode : "";
941             my ($binary, $UNIVERSAL, $BITS) =
942 4         9 map { $_ eq $mode } ("b", "U", "0");
  12         24  
943              
944             ## Always interpret "-" to mean STDIN; otherwise use
945             ## sysopen to handle full range of POSIX file names.
946             ## If $file is a directory, force an EISDIR error
947             ## by attempting to open with mode O_RDWR
948              
949 4         9 local *FH;
950 4 50 33     156 $file eq '-' and open(FH, '< -')
    50 33        
951             or sysopen(FH, $file, -d $file ? O_RDWR : O_RDONLY)
952             or _bail('Open failed');
953              
954 4 100       16 if ($BITS) {
955 2         5 my ($n, $buf) = (0, "");
956 2         29 while (($n = read(FH, $buf, 4096))) {
957 2         6 $buf =~ tr/01//cd;
958 2         11 $self->add_bits($buf);
959             }
960 2 50       5 _bail("Read failed") unless defined $n;
961 2         15 close(FH);
962 2         12 return($self);
963             }
964              
965 2 50 66     10 binmode(FH) if $binary || $UNIVERSAL;
966 2 100 66     8 if ($UNIVERSAL && _istext(*FH, $file)) {
967 1         5 while () {
968 3         9 s/\015\012/\012/g; # DOS/Windows
969 3         7 s/\015/\012/g; # early MacOS
970 3         6 $self->add($_);
971             }
972             }
973 1         3 else { $self->_addfile(*FH) }
974 2         17 close(FH);
975              
976 2         11 $self;
977             }
978              
979             sub getstate {
980 4     4 1 8 my $self = shift;
981              
982 4         13 return _shadump($self);
983             }
984              
985             sub putstate {
986 11     11 1 1243 my $class = shift;
987 11         21 my $state = shift;
988              
989 11 100       41 if (ref($class)) { # instance method
990 4 50       15 my $self = _shaload($state) or return;
991 4         16 return(_shacpy($class, $self));
992             }
993 7 50       25 my $self = _shaload($state) or return;
994 7         18 bless($self, $class);
995 7         22 return($self);
996             }
997              
998             sub dump {
999 0     0 1   my $self = shift;
1000 0           my $file = shift;
1001              
1002 0 0         my $state = $self->getstate or return;
1003 0 0 0       $file = "-" if (!defined($file) || $file eq "");
1004              
1005 0           local *FH;
1006 0 0         open(FH, "> $file") or return;
1007 0           print FH $state;
1008 0           close(FH);
1009              
1010 0           return($self);
1011             }
1012              
1013             sub load {
1014 0     0 1   my $class = shift;
1015 0           my $file = shift;
1016              
1017 0 0 0       $file = "-" if (!defined($file) || $file eq "");
1018            
1019 0           local *FH;
1020 0 0         open(FH, "< $file") or return;
1021 0           my $str = join('', );
1022 0           close(FH);
1023              
1024 0           $class->putstate($str);
1025             }
1026              
1027             1;
1028             __END__