File Coverage

blib/lib/Digest/SHA/PurePerl.pm
Criterion Covered Total %
statement 982 1145 85.7
branch 143 262 54.5
condition 9 18 50.0
subroutine 127 158 80.3
pod 56 56 100.0
total 1317 1639 80.3


line stmt bran cond sub pod time code
1             package Digest::SHA::PurePerl;
2              
3             require 5.003000;
4              
5 24     24   20962 use strict;
  24         155  
  24         581  
6 24     24   103 use warnings;
  24         47  
  24         809  
7 24     24   145 use vars qw($VERSION @ISA @EXPORT_OK $errmsg);
  24         45  
  24         1917  
8 24     24   128 use Fcntl qw(O_RDONLY O_RDWR);
  24         39  
  24         1349  
9 24     24   128 use Cwd qw(getcwd);
  24         40  
  24         1125  
10 24     24   10297 use integer;
  24         313  
  24         109  
11 24     24   685 use Carp qw(croak);
  24         45  
  24         94041  
12              
13             $VERSION = '6.03';
14              
15             require Exporter;
16             @ISA = qw(Exporter);
17             @EXPORT_OK = ('$errmsg'); # see "SHA and HMAC-SHA functions" below
18              
19             # Inherit from Digest::base if possible
20              
21             eval {
22             require Digest::base;
23             push(@ISA, 'Digest::base');
24             };
25              
26             # ref. src/sha.c and sha/sha64bit.c from Digest::SHA
27              
28             my $MAX32 = 0xffffffff;
29              
30             my $uses64bit = (((1 << 16) << 16) << 16) << 15;
31              
32             my @H01 = ( # SHA-1 initial hash value
33             0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476,
34             0xc3d2e1f0
35             );
36              
37             my @H0224 = ( # SHA-224 initial hash value
38             0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
39             0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
40             );
41              
42             my @H0256 = ( # SHA-256 initial hash value
43             0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
44             0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
45             );
46              
47             my(@H0384, @H0512, @H0512224, @H0512256); # filled in later if $uses64bit
48              
49             # Routines with a "_c_" prefix return Perl code-fragments which are
50             # eval'ed at initialization. This technique emulates the behavior
51             # of the C preprocessor, allowing the optimized transform code from
52             # Digest::SHA to be more easily translated into Perl.
53              
54             sub _c_SL32 { # code to shift $x left by $n bits
55 19200     19200   24276 my($x, $n) = @_;
56 19200         42652 "($x << $n)"; # even works for 64-bit integers
57             # since the upper 32 bits are
58             # eventually discarded in _digcpy
59             }
60              
61             sub _c_SR32 { # code to shift $x right by $n bits
62 21504     21504   25879 my($x, $n) = @_;
63 21504         24556 my $mask = (1 << (32 - $n)) - 1;
64 21504         84924 "(($x >> $n) & $mask)"; # "use integer" does arithmetic
65             # shift, so clear upper bits
66             }
67              
68 2016     2016   2834 sub _c_Ch { my($x, $y, $z) = @_; "($z ^ ($x & ($y ^ $z)))" }
  2016         5416  
69 960     960   1375 sub _c_Pa { my($x, $y, $z) = @_; "($x ^ $y ^ $z)" }
  960         2427  
70 2016     2016   2828 sub _c_Ma { my($x, $y, $z) = @_; "(($x & $y) | ($z & ($x | $y)))" }
  2016         9834  
71              
72             sub _c_ROTR { # code to rotate $x right by $n bits
73 13824     13824   17098 my($x, $n) = @_;
74 13824         16980 "(" . _c_SR32($x, $n) . " | " . _c_SL32($x, 32 - $n) . ")";
75             }
76              
77             sub _c_ROTL { # code to rotate $x left by $n bits
78 5376     5376   7149 my($x, $n) = @_;
79 5376         6726 "(" . _c_SL32($x, $n) . " | " . _c_SR32($x, 32 - $n) . ")";
80             }
81              
82             sub _c_SIGMA0 { # ref. NIST SHA standard
83 1536     1536   1938 my($x) = @_;
84 1536         1898 "(" . _c_ROTR($x, 2) . " ^ " . _c_ROTR($x, 13) . " ^ " .
85             _c_ROTR($x, 22) . ")";
86             }
87              
88             sub _c_SIGMA1 {
89 1536     1536   1933 my($x) = @_;
90 1536         1933 "(" . _c_ROTR($x, 6) . " ^ " . _c_ROTR($x, 11) . " ^ " .
91             _c_ROTR($x, 25) . ")";
92             }
93              
94             sub _c_sigma0 {
95 1152     1152   1489 my($x) = @_;
96 1152         1446 "(" . _c_ROTR($x, 7) . " ^ " . _c_ROTR($x, 18) . " ^ " .
97             _c_SR32($x, 3) . ")";
98             }
99              
100             sub _c_sigma1 {
101 1152     1152   1467 my($x) = @_;
102 1152         1510 "(" . _c_ROTR($x, 17) . " ^ " . _c_ROTR($x, 19) . " ^ " .
103             _c_SR32($x, 10) . ")";
104             }
105              
106             sub _c_M1Ch { # ref. Digest::SHA sha.c (sha1 routine)
107 480     480   770 my($a, $b, $c, $d, $e, $k, $w) = @_;
108 480         697 "$e += " . _c_ROTL($a, 5) . " + " . _c_Ch($b, $c, $d) .
109             " + $k + $w; $b = " . _c_ROTL($b, 30) . ";\n";
110             }
111              
112             sub _c_M1Pa {
113 960     960   1414 my($a, $b, $c, $d, $e, $k, $w) = @_;
114 960         1294 "$e += " . _c_ROTL($a, 5) . " + " . _c_Pa($b, $c, $d) .
115             " + $k + $w; $b = " . _c_ROTL($b, 30) . ";\n";
116             }
117              
118             sub _c_M1Ma {
119 480     480   750 my($a, $b, $c, $d, $e, $k, $w) = @_;
120 480         693 "$e += " . _c_ROTL($a, 5) . " + " . _c_Ma($b, $c, $d) .
121             " + $k + $w; $b = " . _c_ROTL($b, 30) . ";\n";
122             }
123              
124 96     96   176 sub _c_M11Ch { my($k, $w) = @_; _c_M1Ch('$a', '$b', '$c', '$d', '$e', $k, $w) }
  96         162  
125 192     192   313 sub _c_M11Pa { my($k, $w) = @_; _c_M1Pa('$a', '$b', '$c', '$d', '$e', $k, $w) }
  192         314  
126 96     96   163 sub _c_M11Ma { my($k, $w) = @_; _c_M1Ma('$a', '$b', '$c', '$d', '$e', $k, $w) }
  96         175  
127 96     96   164 sub _c_M12Ch { my($k, $w) = @_; _c_M1Ch('$e', '$a', '$b', '$c', '$d', $k, $w) }
  96         159  
128 192     192   312 sub _c_M12Pa { my($k, $w) = @_; _c_M1Pa('$e', '$a', '$b', '$c', '$d', $k, $w) }
  192         333  
129 96     96   154 sub _c_M12Ma { my($k, $w) = @_; _c_M1Ma('$e', '$a', '$b', '$c', '$d', $k, $w) }
  96         168  
130 96     96   162 sub _c_M13Ch { my($k, $w) = @_; _c_M1Ch('$d', '$e', '$a', '$b', '$c', $k, $w) }
  96         482  
131 192     192   296 sub _c_M13Pa { my($k, $w) = @_; _c_M1Pa('$d', '$e', '$a', '$b', '$c', $k, $w) }
  192         311  
132 96     96   181 sub _c_M13Ma { my($k, $w) = @_; _c_M1Ma('$d', '$e', '$a', '$b', '$c', $k, $w) }
  96         326  
133 96     96   149 sub _c_M14Ch { my($k, $w) = @_; _c_M1Ch('$c', '$d', '$e', '$a', '$b', $k, $w) }
  96         148  
134 192     192   318 sub _c_M14Pa { my($k, $w) = @_; _c_M1Pa('$c', '$d', '$e', '$a', '$b', $k, $w) }
  192         282  
135 96     96   153 sub _c_M14Ma { my($k, $w) = @_; _c_M1Ma('$c', '$d', '$e', '$a', '$b', $k, $w) }
  96         180  
136 96     96   169 sub _c_M15Ch { my($k, $w) = @_; _c_M1Ch('$b', '$c', '$d', '$e', '$a', $k, $w) }
  96         150  
137 192     192   285 sub _c_M15Pa { my($k, $w) = @_; _c_M1Pa('$b', '$c', '$d', '$e', '$a', $k, $w) }
  192         287  
138 96     96   1478 sub _c_M15Ma { my($k, $w) = @_; _c_M1Ma('$b', '$c', '$d', '$e', '$a', $k, $w) }
  96         2868  
139              
140 3072     3072   3743 sub _c_W11 { my($s) = @_; '$W[' . (($s + 0) & 0xf) . ']' }
  3072         5906  
141 1536     1536   1925 sub _c_W12 { my($s) = @_; '$W[' . (($s + 13) & 0xf) . ']' }
  1536         2648  
142 1536     1536   1868 sub _c_W13 { my($s) = @_; '$W[' . (($s + 8) & 0xf) . ']' }
  1536         2633  
143 1536     1536   1875 sub _c_W14 { my($s) = @_; '$W[' . (($s + 2) & 0xf) . ']' }
  1536         2446  
144              
145             sub _c_A1 {
146 1536     1536   2245 my($s) = @_;
147 1536         1967 my $tmp = _c_W11($s) . " ^ " . _c_W12($s) . " ^ " .
148             _c_W13($s) . " ^ " . _c_W14($s);
149 1536         2596 "((\$tmp = $tmp), (" . _c_W11($s) . " = " . _c_ROTL('$tmp', 1) . "))";
150             }
151              
152             # The following code emulates the "sha1" routine from Digest::SHA sha.c
153              
154             my $sha1_code = '
155              
156             my($K1, $K2, $K3, $K4) = ( # SHA-1 constants
157             0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
158             );
159              
160             sub _sha1 {
161             my($self, $block) = @_;
162             my(@W, $a, $b, $c, $d, $e, $tmp);
163              
164             @W = unpack("N16", $block);
165             ($a, $b, $c, $d, $e) = @{$self->{H}};
166             ' .
167             _c_M11Ch('$K1', '$W[ 0]' ) . _c_M12Ch('$K1', '$W[ 1]' ) .
168             _c_M13Ch('$K1', '$W[ 2]' ) . _c_M14Ch('$K1', '$W[ 3]' ) .
169             _c_M15Ch('$K1', '$W[ 4]' ) . _c_M11Ch('$K1', '$W[ 5]' ) .
170             _c_M12Ch('$K1', '$W[ 6]' ) . _c_M13Ch('$K1', '$W[ 7]' ) .
171             _c_M14Ch('$K1', '$W[ 8]' ) . _c_M15Ch('$K1', '$W[ 9]' ) .
172             _c_M11Ch('$K1', '$W[10]' ) . _c_M12Ch('$K1', '$W[11]' ) .
173             _c_M13Ch('$K1', '$W[12]' ) . _c_M14Ch('$K1', '$W[13]' ) .
174             _c_M15Ch('$K1', '$W[14]' ) . _c_M11Ch('$K1', '$W[15]' ) .
175             _c_M12Ch('$K1', _c_A1( 0) ) . _c_M13Ch('$K1', _c_A1( 1) ) .
176             _c_M14Ch('$K1', _c_A1( 2) ) . _c_M15Ch('$K1', _c_A1( 3) ) .
177             _c_M11Pa('$K2', _c_A1( 4) ) . _c_M12Pa('$K2', _c_A1( 5) ) .
178             _c_M13Pa('$K2', _c_A1( 6) ) . _c_M14Pa('$K2', _c_A1( 7) ) .
179             _c_M15Pa('$K2', _c_A1( 8) ) . _c_M11Pa('$K2', _c_A1( 9) ) .
180             _c_M12Pa('$K2', _c_A1(10) ) . _c_M13Pa('$K2', _c_A1(11) ) .
181             _c_M14Pa('$K2', _c_A1(12) ) . _c_M15Pa('$K2', _c_A1(13) ) .
182             _c_M11Pa('$K2', _c_A1(14) ) . _c_M12Pa('$K2', _c_A1(15) ) .
183             _c_M13Pa('$K2', _c_A1( 0) ) . _c_M14Pa('$K2', _c_A1( 1) ) .
184             _c_M15Pa('$K2', _c_A1( 2) ) . _c_M11Pa('$K2', _c_A1( 3) ) .
185             _c_M12Pa('$K2', _c_A1( 4) ) . _c_M13Pa('$K2', _c_A1( 5) ) .
186             _c_M14Pa('$K2', _c_A1( 6) ) . _c_M15Pa('$K2', _c_A1( 7) ) .
187             _c_M11Ma('$K3', _c_A1( 8) ) . _c_M12Ma('$K3', _c_A1( 9) ) .
188             _c_M13Ma('$K3', _c_A1(10) ) . _c_M14Ma('$K3', _c_A1(11) ) .
189             _c_M15Ma('$K3', _c_A1(12) ) . _c_M11Ma('$K3', _c_A1(13) ) .
190             _c_M12Ma('$K3', _c_A1(14) ) . _c_M13Ma('$K3', _c_A1(15) ) .
191             _c_M14Ma('$K3', _c_A1( 0) ) . _c_M15Ma('$K3', _c_A1( 1) ) .
192             _c_M11Ma('$K3', _c_A1( 2) ) . _c_M12Ma('$K3', _c_A1( 3) ) .
193             _c_M13Ma('$K3', _c_A1( 4) ) . _c_M14Ma('$K3', _c_A1( 5) ) .
194             _c_M15Ma('$K3', _c_A1( 6) ) . _c_M11Ma('$K3', _c_A1( 7) ) .
195             _c_M12Ma('$K3', _c_A1( 8) ) . _c_M13Ma('$K3', _c_A1( 9) ) .
196             _c_M14Ma('$K3', _c_A1(10) ) . _c_M15Ma('$K3', _c_A1(11) ) .
197             _c_M11Pa('$K4', _c_A1(12) ) . _c_M12Pa('$K4', _c_A1(13) ) .
198             _c_M13Pa('$K4', _c_A1(14) ) . _c_M14Pa('$K4', _c_A1(15) ) .
199             _c_M15Pa('$K4', _c_A1( 0) ) . _c_M11Pa('$K4', _c_A1( 1) ) .
200             _c_M12Pa('$K4', _c_A1( 2) ) . _c_M13Pa('$K4', _c_A1( 3) ) .
201             _c_M14Pa('$K4', _c_A1( 4) ) . _c_M15Pa('$K4', _c_A1( 5) ) .
202             _c_M11Pa('$K4', _c_A1( 6) ) . _c_M12Pa('$K4', _c_A1( 7) ) .
203             _c_M13Pa('$K4', _c_A1( 8) ) . _c_M14Pa('$K4', _c_A1( 9) ) .
204             _c_M15Pa('$K4', _c_A1(10) ) . _c_M11Pa('$K4', _c_A1(11) ) .
205             _c_M12Pa('$K4', _c_A1(12) ) . _c_M13Pa('$K4', _c_A1(13) ) .
206             _c_M14Pa('$K4', _c_A1(14) ) . _c_M15Pa('$K4', _c_A1(15) ) .
207              
208             ' $self->{H}->[0] += $a; $self->{H}->[1] += $b; $self->{H}->[2] += $c;
209             $self->{H}->[3] += $d; $self->{H}->[4] += $e;
210             }
211             ';
212              
213 921     921   2496 eval($sha1_code);
  921         1425  
  921         2245  
  921         1164  
  921         1762  
  921         1961  
  921         1282  
  921         1496  
  921         1234  
  921         1524  
  921         1270  
  921         1517  
  921         1227  
  921         1439  
  921         1381  
  921         1376  
  921         1299  
  921         1329  
  921         1213  
  921         1362  
  921         1219  
  921         1469  
  921         1200  
  921         1429  
  921         1190  
  921         1403  
  921         1255  
  921         1500  
  921         1186  
  921         1415  
  921         1264  
  921         1369  
  921         1267  
  921         1319  
  921         1199  
  921         1320  
  921         1161  
  921         1821  
  921         1311  
  921         1851  
  921         1209  
  921         1851  
  921         1261  
  921         1801  
  921         1174  
  921         1796  
  921         1216  
  921         1815  
  921         1283  
  921         1812  
  921         1235  
  921         1730  
  921         1278  
  921         1796  
  921         1242  
  921         1769  
  921         1243  
  921         1786  
  921         1230  
  921         1737  
  921         1207  
  921         1773  
  921         1280  
  921         1738  
  921         1260  
  921         1772  
  921         1238  
  921         1667  
  921         1233  
  921         1813  
  921         1230  
  921         1758  
  921         1202  
  921         1730  
  921         1242  
  921         1648  
  921         1354  
  921         1705  
  921         1286  
  921         1718  
  921         1159  
  921         1702  
  921         1285  
  921         1687  
  921         1239  
  921         1901  
  921         1303  
  921         1839  
  921         1277  
  921         1983  
  921         1243  
  921         1818  
  921         1306  
  921         2215  
  921         1222  
  921         1934  
  921         1216  
  921         1881  
  921         1331  
  921         1917  
  921         1205  
  921         1834  
  921         1234  
  921         1921  
  921         1138  
  921         1864  
  921         1238  
  921         1917  
  921         1198  
  921         1890  
  921         1279  
  921         1790  
  921         1222  
  921         1851  
  921         1252  
  921         1934  
  921         1215  
  921         1739  
  921         1247  
  921         1870  
  921         1235  
  921         1804  
  921         1261  
  921         1886  
  921         1257  
  921         1774  
  921         1246  
  921         1784  
  921         1264  
  921         1800  
  921         1266  
  921         1715  
  921         1220  
  921         1803  
  921         1337  
  921         1746  
  921         1173  
  921         1782  
  921         1221  
  921         1864  
  921         1251  
  921         1748  
  921         1315  
  921         1791  
  921         1213  
  921         1731  
  921         1190  
  921         1747  
  921         1374  
  921         1942  
  921         1253  
  921         1761  
  921         1258  
  921         1709  
  921         1212  
  921         1681  
  921         1207  
  921         1957  
  921         1284  
  921         1747  
  921         1213  
  921         1856  
  921         1306  
  921         1717  
  921         1301  
  921         1396  
  921         1175  
  921         1198  
  921         1098  
  921         2926  
214              
215             sub _c_M2 { # ref. Digest::SHA sha.c (sha256 routine)
216 1536     1536   2598 my($a, $b, $c, $d, $e, $f, $g, $h, $w) = @_;
217 1536         2368 "\$T1 = $h + " . _c_SIGMA1($e) . " + " . _c_Ch($e, $f, $g) .
218             " + \$K256[\$i++] + $w; $h = \$T1 + " . _c_SIGMA0($a) .
219             " + " . _c_Ma($a, $b, $c) . "; $d += \$T1;\n";
220             }
221              
222 192     192   358 sub _c_M21 { _c_M2('$a', '$b', '$c', '$d', '$e', '$f', '$g', '$h', $_[0]) }
223 192     192   357 sub _c_M22 { _c_M2('$h', '$a', '$b', '$c', '$d', '$e', '$f', '$g', $_[0]) }
224 192     192   358 sub _c_M23 { _c_M2('$g', '$h', '$a', '$b', '$c', '$d', '$e', '$f', $_[0]) }
225 192     192   403 sub _c_M24 { _c_M2('$f', '$g', '$h', '$a', '$b', '$c', '$d', '$e', $_[0]) }
226 192     192   346 sub _c_M25 { _c_M2('$e', '$f', '$g', '$h', '$a', '$b', '$c', '$d', $_[0]) }
227 192     192   350 sub _c_M26 { _c_M2('$d', '$e', '$f', '$g', '$h', '$a', '$b', '$c', $_[0]) }
228 192     192   345 sub _c_M27 { _c_M2('$c', '$d', '$e', '$f', '$g', '$h', '$a', '$b', $_[0]) }
229 192     192   359 sub _c_M28 { _c_M2('$b', '$c', '$d', '$e', '$f', '$g', '$h', '$a', $_[0]) }
230              
231 1152     1152   1484 sub _c_W21 { my($s) = @_; '$W[' . (($s + 0) & 0xf) . ']' }
  1152         2547  
232 1152     1152   1473 sub _c_W22 { my($s) = @_; '$W[' . (($s + 14) & 0xf) . ']' }
  1152         2075  
233 1152     1152   1523 sub _c_W23 { my($s) = @_; '$W[' . (($s + 9) & 0xf) . ']' }
  1152         2222  
234 1152     1152   1494 sub _c_W24 { my($s) = @_; '$W[' . (($s + 1) & 0xf) . ']' }
  1152         2071  
235              
236             sub _c_A2 {
237 1152     1152   1728 my($s) = @_;
238 1152         1530 "(" . _c_W21($s) . " += " . _c_sigma1(_c_W22($s)) . " + " .
239             _c_W23($s) . " + " . _c_sigma0(_c_W24($s)) . ")";
240             }
241              
242             # The following code emulates the "sha256" routine from Digest::SHA sha.c
243              
244             my $sha256_code = '
245              
246             my @K256 = ( # SHA-224/256 constants
247             0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
248             0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
249             0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
250             0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
251             0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
252             0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
253             0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
254             0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
255             0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
256             0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
257             0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
258             0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
259             0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
260             0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
261             0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
262             0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
263             );
264              
265             sub _sha256 {
266             my($self, $block) = @_;
267             my(@W, $a, $b, $c, $d, $e, $f, $g, $h, $i, $T1);
268              
269             @W = unpack("N16", $block);
270             ($a, $b, $c, $d, $e, $f, $g, $h) = @{$self->{H}};
271             ' .
272             _c_M21('$W[ 0]' ) . _c_M22('$W[ 1]' ) . _c_M23('$W[ 2]' ) .
273             _c_M24('$W[ 3]' ) . _c_M25('$W[ 4]' ) . _c_M26('$W[ 5]' ) .
274             _c_M27('$W[ 6]' ) . _c_M28('$W[ 7]' ) . _c_M21('$W[ 8]' ) .
275             _c_M22('$W[ 9]' ) . _c_M23('$W[10]' ) . _c_M24('$W[11]' ) .
276             _c_M25('$W[12]' ) . _c_M26('$W[13]' ) . _c_M27('$W[14]' ) .
277             _c_M28('$W[15]' ) .
278             _c_M21(_c_A2( 0)) . _c_M22(_c_A2( 1)) . _c_M23(_c_A2( 2)) .
279             _c_M24(_c_A2( 3)) . _c_M25(_c_A2( 4)) . _c_M26(_c_A2( 5)) .
280             _c_M27(_c_A2( 6)) . _c_M28(_c_A2( 7)) . _c_M21(_c_A2( 8)) .
281             _c_M22(_c_A2( 9)) . _c_M23(_c_A2(10)) . _c_M24(_c_A2(11)) .
282             _c_M25(_c_A2(12)) . _c_M26(_c_A2(13)) . _c_M27(_c_A2(14)) .
283             _c_M28(_c_A2(15)) . _c_M21(_c_A2( 0)) . _c_M22(_c_A2( 1)) .
284             _c_M23(_c_A2( 2)) . _c_M24(_c_A2( 3)) . _c_M25(_c_A2( 4)) .
285             _c_M26(_c_A2( 5)) . _c_M27(_c_A2( 6)) . _c_M28(_c_A2( 7)) .
286             _c_M21(_c_A2( 8)) . _c_M22(_c_A2( 9)) . _c_M23(_c_A2(10)) .
287             _c_M24(_c_A2(11)) . _c_M25(_c_A2(12)) . _c_M26(_c_A2(13)) .
288             _c_M27(_c_A2(14)) . _c_M28(_c_A2(15)) . _c_M21(_c_A2( 0)) .
289             _c_M22(_c_A2( 1)) . _c_M23(_c_A2( 2)) . _c_M24(_c_A2( 3)) .
290             _c_M25(_c_A2( 4)) . _c_M26(_c_A2( 5)) . _c_M27(_c_A2( 6)) .
291             _c_M28(_c_A2( 7)) . _c_M21(_c_A2( 8)) . _c_M22(_c_A2( 9)) .
292             _c_M23(_c_A2(10)) . _c_M24(_c_A2(11)) . _c_M25(_c_A2(12)) .
293             _c_M26(_c_A2(13)) . _c_M27(_c_A2(14)) . _c_M28(_c_A2(15)) .
294              
295             ' $self->{H}->[0] += $a; $self->{H}->[1] += $b; $self->{H}->[2] += $c;
296             $self->{H}->[3] += $d; $self->{H}->[4] += $e; $self->{H}->[5] += $f;
297             $self->{H}->[6] += $g; $self->{H}->[7] += $h;
298             }
299             ';
300              
301 257     257   1091 eval($sha256_code);
  257         415  
  257         694  
  257         365  
  257         521  
  257         815  
  257         564  
  257         320  
  257         572  
  257         519  
  257         293  
  257         526  
  257         517  
  257         290  
  257         516  
  257         484  
  257         326  
  257         538  
  257         515  
  257         296  
  257         551  
  257         524  
  257         309  
  257         508  
  257         492  
  257         300  
  257         547  
  257         498  
  257         342  
  257         526  
  257         499  
  257         314  
  257         516  
  257         526  
  257         305  
  257         545  
  257         500  
  257         294  
  257         526  
  257         514  
  257         314  
  257         519  
  257         516  
  257         333  
  257         552  
  257         517  
  257         290  
  257         536  
  257         532  
  257         287  
  257         531  
  257         513  
  257         295  
  257         776  
  257         497  
  257         332  
  257         829  
  257         534  
  257         351  
  257         757  
  257         492  
  257         312  
  257         816  
  257         499  
  257         294  
  257         763  
  257         491  
  257         306  
  257         762  
  257         505  
  257         313  
  257         821  
  257         512  
  257         314  
  257         732  
  257         502  
  257         348  
  257         799  
  257         513  
  257         301  
  257         823  
  257         512  
  257         333  
  257         783  
  257         535  
  257         331  
  257         733  
  257         530  
  257         294  
  257         810  
  257         501  
  257         303  
  257         776  
  257         507  
  257         306  
  257         808  
  257         480  
  257         318  
  257         764  
  257         496  
  257         316  
  257         800  
  257         492  
  257         308  
  257         734  
  257         499  
  257         300  
  257         796  
  257         532  
  257         313  
  257         757  
  257         532  
  257         301  
  257         723  
  257         509  
  257         308  
  257         781  
  257         531  
  257         314  
  257         789  
  257         493  
  257         304  
  257         812  
  257         504  
  257         313  
  257         755  
  257         498  
  257         306  
  257         748  
  257         495  
  257         309  
  257         798  
  257         506  
  257         336  
  257         751  
  257         476  
  257         319  
  257         760  
  257         554  
  257         294  
  257         794  
  257         519  
  257         302  
  257         742  
  257         524  
  257         293  
  257         741  
  257         491  
  257         307  
  257         835  
  257         510  
  257         317  
  257         751  
  257         503  
  257         322  
  257         781  
  257         492  
  257         325  
  257         914  
  257         499  
  257         298  
  257         799  
  257         505  
  257         295  
  257         736  
  257         497  
  257         302  
  257         701  
  257         532  
  257         306  
  257         813  
  257         491  
  257         303  
  257         765  
  257         531  
  257         299  
  257         783  
  257         561  
  257         340  
  257         889  
  257         512  
  257         301  
  257         770  
  257         514  
  257         312  
  257         765  
  257         468  
  257         300  
  257         848  
  257         504  
  257         340  
  257         797  
  257         505  
  257         309  
  257         735  
  257         490  
  257         296  
  257         399  
  257         339  
  257         324  
  257         321  
  257         340  
  257         310  
  257         318  
  257         1245  
302              
303 0     0   0 sub _sha512_placeholder { return }
304             my $sha512 = \&_sha512_placeholder;
305              
306             my $_64bit_code = '
307              
308             no warnings qw(portable);
309              
310             my @K512 = (
311             0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
312             0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
313             0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
314             0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
315             0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
316             0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
317             0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
318             0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
319             0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
320             0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
321             0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
322             0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
323             0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
324             0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
325             0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
326             0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
327             0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
328             0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
329             0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
330             0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
331             0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
332             0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
333             0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
334             0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
335             0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
336             0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
337             0x5fcb6fab3ad6faec, 0x6c44198c4a475817);
338              
339             @H0384 = (
340             0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17,
341             0x152fecd8f70e5939, 0x67332667ffc00b31, 0x8eb44a8768581511,
342             0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4);
343              
344             @H0512 = (
345             0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b,
346             0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f,
347             0x1f83d9abfb41bd6b, 0x5be0cd19137e2179);
348              
349             @H0512224 = (
350             0x8c3d37c819544da2, 0x73e1996689dcd4d6, 0x1dfab7ae32ff9c82,
351             0x679dd514582f9fcf, 0x0f6d2b697bd44da8, 0x77e36f7304c48942,
352             0x3f9d85a86a1d36c8, 0x1112e6ad91d692a1);
353              
354             @H0512256 = (
355             0x22312194fc2bf72c, 0x9f555fa3c84c64c2, 0x2393b86b6f53b151,
356             0x963877195940eabd, 0x96283ee2a88effe3, 0xbe5e1e2553863992,
357             0x2b0199fc2c85b8aa, 0x0eb72ddc81c52ca2);
358              
359             use warnings;
360              
361             sub _c_SL64 { my($x, $n) = @_; "($x << $n)" }
362              
363             sub _c_SR64 {
364             my($x, $n) = @_;
365             my $mask = (1 << (64 - $n)) - 1;
366             "(($x >> $n) & $mask)";
367             }
368              
369             sub _c_ROTRQ {
370             my($x, $n) = @_;
371             "(" . _c_SR64($x, $n) . " | " . _c_SL64($x, 64 - $n) . ")";
372             }
373              
374             sub _c_SIGMAQ0 {
375             my($x) = @_;
376             "(" . _c_ROTRQ($x, 28) . " ^ " . _c_ROTRQ($x, 34) . " ^ " .
377             _c_ROTRQ($x, 39) . ")";
378             }
379              
380             sub _c_SIGMAQ1 {
381             my($x) = @_;
382             "(" . _c_ROTRQ($x, 14) . " ^ " . _c_ROTRQ($x, 18) . " ^ " .
383             _c_ROTRQ($x, 41) . ")";
384             }
385              
386             sub _c_sigmaQ0 {
387             my($x) = @_;
388             "(" . _c_ROTRQ($x, 1) . " ^ " . _c_ROTRQ($x, 8) . " ^ " .
389             _c_SR64($x, 7) . ")";
390             }
391              
392             sub _c_sigmaQ1 {
393             my($x) = @_;
394             "(" . _c_ROTRQ($x, 19) . " ^ " . _c_ROTRQ($x, 61) . " ^ " .
395             _c_SR64($x, 6) . ")";
396             }
397              
398             my $sha512_code = q/
399             sub _sha512 {
400             my($self, $block) = @_;
401             my(@N, @W, $a, $b, $c, $d, $e, $f, $g, $h, $T1, $T2);
402              
403             @N = unpack("N32", $block);
404             ($a, $b, $c, $d, $e, $f, $g, $h) = @{$self->{H}};
405             for ( 0 .. 15) { $W[$_] = (($N[2*$_] << 16) << 16) | $N[2*$_+1] }
406             for (16 .. 79) { $W[$_] = / .
407             _c_sigmaQ1(q/$W[$_- 2]/) . q/ + $W[$_- 7] + / .
408             _c_sigmaQ0(q/$W[$_-15]/) . q/ + $W[$_-16] }
409             for ( 0 .. 79) {
410             $T1 = $h + / . _c_SIGMAQ1(q/$e/) .
411             q/ + (($g) ^ (($e) & (($f) ^ ($g)))) +
412             $K512[$_] + $W[$_];
413             $T2 = / . _c_SIGMAQ0(q/$a/) .
414             q/ + ((($a) & ($b)) | (($c) & (($a) | ($b))));
415             $h = $g; $g = $f; $f = $e; $e = $d + $T1;
416             $d = $c; $c = $b; $b = $a; $a = $T1 + $T2;
417             }
418             $self->{H}->[0] += $a; $self->{H}->[1] += $b; $self->{H}->[2] += $c;
419             $self->{H}->[3] += $d; $self->{H}->[4] += $e; $self->{H}->[5] += $f;
420             $self->{H}->[6] += $g; $self->{H}->[7] += $h;
421             }
422             /;
423              
424             eval($sha512_code);
425             $sha512 = \&_sha512;
426              
427             ';
428              
429 24     24   164 eval($_64bit_code) if $uses64bit;
  24     24   42  
  24     240   2552  
  24     24   120  
  24     24   45  
  24     240   7452  
  240     288   358  
  240     24   330  
  24     24   45  
  24     249   47  
  24         46  
  24         47  
  240         333  
  240         835  
  288         383  
  288         360  
  288         877  
  24         45  
  24         50  
  24         57  
  24         53  
  249         773  
  249         414  
  249         751  
  249         368  
  249         518  
  249         552  
  3984         6192  
  249         420  
  15936         36855  
  249         395  
  19920         35184  
  19920         33029  
  19920         23005  
  19920         22345  
  19920         22427  
  19920         22821  
  19920         23285  
  19920         22225  
  19920         22815  
  19920         24837  
  249         392  
  249         316  
  249         340  
  249         361  
  249         335  
  249         335  
  249         320  
  249         1930  
430              
431             sub _SETBIT {
432 190     190   306 my($self, $pos) = @_;
433 190         679 my @c = unpack("C*", $self->{block});
434 190 100       565 $c[$pos >> 3] = 0x00 unless defined $c[$pos >> 3];
435 190         373 $c[$pos >> 3] |= (0x01 << (7 - $pos % 8));
436 190         636 $self->{block} = pack("C*", @c);
437             }
438              
439             sub _CLRBIT {
440 80088     80088   95724 my($self, $pos) = @_;
441 80088         192808 my @c = unpack("C*", $self->{block});
442 80088 100       126606 $c[$pos >> 3] = 0x00 unless defined $c[$pos >> 3];
443 80088         97332 $c[$pos >> 3] &= ~(0x01 << (7 - $pos % 8));
444 80088         250998 $self->{block} = pack("C*", @c);
445             }
446              
447             sub _BYTECNT {
448 1827     1827   2288 my($bitcnt) = @_;
449 1827 100       4072 $bitcnt > 0 ? 1 + (($bitcnt - 1) >> 3) : 0;
450             }
451              
452             sub _digcpy {
453 190     190   272 my($self) = @_;
454 190         236 my @dig;
455 190         253 for (@{$self->{H}}) {
  190         499  
456 1520 100       2330 push(@dig, (($_>>16)>>16) & $MAX32) if $self->{alg} >= 384;
457 1520         1941 push(@dig, $_ & $MAX32);
458             }
459 190         867 $self->{digest} = pack("N" . ($self->{digestlen}>>2), @dig);
460             }
461              
462             sub _sharewind {
463 217     217   316 my($self) = @_;
464 217         326 my $alg = $self->{alg};
465 217         356 $self->{block} = ""; $self->{blockcnt} = 0;
  217         299  
466 217 100       462 $self->{blocksize} = $alg <= 256 ? 512 : 1024;
467 217         363 for (qw(lenll lenlh lenhl lenhh)) { $self->{$_} = 0 }
  868         1318  
468 217 100       473 $self->{digestlen} = $alg == 1 ? 20 : ($alg % 1000)/8;
469 217 100       524 if ($alg == 1) { $self->{sha} = \&_sha1; $self->{H} = [@H01] }
  103 100       191  
  103 100       260  
    100          
    100          
    100          
    50          
470 4         9 elsif ($alg == 224) { $self->{sha} = \&_sha256; $self->{H} = [@H0224] }
  4         11  
471 53         96 elsif ($alg == 256) { $self->{sha} = \&_sha256; $self->{H} = [@H0256] }
  53         121  
472 27         39 elsif ($alg == 384) { $self->{sha} = $sha512; $self->{H} = [@H0384] }
  27         54  
473 26         38 elsif ($alg == 512) { $self->{sha} = $sha512; $self->{H} = [@H0512] }
  26         70  
474 2         4 elsif ($alg == 512224) { $self->{sha}=$sha512; $self->{H}=[@H0512224] }
  2         5  
475 2         4 elsif ($alg == 512256) { $self->{sha}=$sha512; $self->{H}=[@H0512256] }
  2         5  
476 217         302 push(@{$self->{H}}, 0) while scalar(@{$self->{H}}) < 8;
  526         937  
  309         491  
477 217         1180 $self;
478             }
479              
480             sub _shaopen {
481 154     154   267 my($alg) = @_;
482 154         190 my($self);
483 154 100       265 return unless grep { $alg == $_ } (1,224,256,384,512,512224,512256);
  1078         1657  
484 153 50 66     452 return if ($alg >= 384 && !$uses64bit);
485 153         322 $self->{alg} = $alg;
486 153         302 _sharewind($self);
487             }
488              
489             sub _shadirect {
490 627     627   1122 my($bitstr, $bitcnt, $self) = @_;
491 627         751 my $savecnt = $bitcnt;
492 627         719 my $offset = 0;
493 627         849 my $blockbytes = $self->{blocksize} >> 3;
494 627         1248 while ($bitcnt >= $self->{blocksize}) {
495 826         1661 &{$self->{sha}}($self, substr($bitstr, $offset, $blockbytes));
  826         17686  
496 826         1597 $offset += $blockbytes;
497 826         1857 $bitcnt -= $self->{blocksize};
498             }
499 627 100       1085 if ($bitcnt > 0) {
500 536         912 $self->{block} = substr($bitstr, $offset, _BYTECNT($bitcnt));
501 536         811 $self->{blockcnt} = $bitcnt;
502             }
503 627         2038 $savecnt;
504             }
505              
506             sub _shabytes {
507 678     678   981 my($bitstr, $bitcnt, $self) = @_;
508 678         729 my($numbits);
509 678         731 my $savecnt = $bitcnt;
510 678 100       1080 if ($self->{blockcnt} + $bitcnt >= $self->{blocksize}) {
511 380         441 $numbits = $self->{blocksize} - $self->{blockcnt};
512 380         665 $self->{block} .= substr($bitstr, 0, $numbits >> 3);
513 380         408 $bitcnt -= $numbits;
514 380         539 $bitstr = substr($bitstr, $numbits >> 3, _BYTECNT($bitcnt));
515 380         560 &{$self->{sha}}($self, $self->{block});
  380         7952  
516 380         671 $self->{block} = "";
517 380         451 $self->{blockcnt} = 0;
518 380         702 _shadirect($bitstr, $bitcnt, $self);
519             }
520             else {
521 298         784 $self->{block} .= substr($bitstr, 0, _BYTECNT($bitcnt));
522 298         431 $self->{blockcnt} += $bitcnt;
523             }
524 678         892 $savecnt;
525             }
526              
527             sub _shabits {
528 602     602   776 my($bitstr, $bitcnt, $self) = @_;
529 602         660 my($i, @buf);
530 602         773 my $numbytes = _BYTECNT($bitcnt);
531 602         737 my $savecnt = $bitcnt;
532 602         754 my $gap = 8 - $self->{blockcnt} % 8;
533 602         1682 my @c = unpack("C*", $self->{block});
534 602         1815 my @b = unpack("C" . $numbytes, $bitstr);
535 602         1012 $c[$self->{blockcnt}>>3] &= (~0 << $gap);
536 602         816 $c[$self->{blockcnt}>>3] |= $b[0] >> (8 - $gap);
537 602         1462 $self->{block} = pack("C*", @c);
538 602 100       951 $self->{blockcnt} += ($bitcnt < $gap) ? $bitcnt : $gap;
539 602 100       890 return($savecnt) if $bitcnt < $gap;
540 593 100       884 if ($self->{blockcnt} == $self->{blocksize}) {
541 10         13 &{$self->{sha}}($self, $self->{block});
  10         216  
542 10         15 $self->{block} = "";
543 10         18 $self->{blockcnt} = 0;
544             }
545 593 100       825 return($savecnt) if ($bitcnt -= $gap) == 0;
546 590         1039 for ($i = 0; $i < $numbytes - 1; $i++) {
547 26957         41642 $buf[$i] = (($b[$i] << $gap) & 0xff) | ($b[$i+1] >> (8 - $gap));
548             }
549 590         800 $buf[$numbytes-1] = ($b[$numbytes-1] << $gap) & 0xff;
550 590         1727 _shabytes(pack("C*", @buf), $bitcnt, $self);
551 590         1998 $savecnt;
552             }
553              
554             sub _shawrite {
555 938     938   1329 my($bitstr, $bitcnt, $self) = @_;
556 938 100       1561 return(0) unless $bitcnt > 0;
557 24     24   207 no integer;
  24         65  
  24         102  
558 937         1106 my $TWO32 = 4294967296;
559 937 100       1753 if (($self->{lenll} += $bitcnt) >= $TWO32) {
560 5         8 $self->{lenll} -= $TWO32;
561 5 50       15 if (++$self->{lenlh} >= $TWO32) {
562 0         0 $self->{lenlh} -= $TWO32;
563 0 0       0 if (++$self->{lenhl} >= $TWO32) {
564 0         0 $self->{lenhl} -= $TWO32;
565 0 0       0 if (++$self->{lenhh} >= $TWO32) {
566 0         0 $self->{lenhh} -= $TWO32;
567             }
568             }
569             }
570             }
571 24     24   1926 use integer;
  24         51  
  24         83  
572 937         1105 my $blockcnt = $self->{blockcnt};
573 937 100       1582 return(_shadirect($bitstr, $bitcnt, $self)) if $blockcnt == 0;
574 690 100       1064 return(_shabytes ($bitstr, $bitcnt, $self)) if $blockcnt % 8 == 0;
575 602         826 return(_shabits ($bitstr, $bitcnt, $self));
576             }
577              
578             my $no_downgrade = 'sub utf8::downgrade { 1 }';
579              
580             my $pp_downgrade = q {
581             sub utf8::downgrade {
582              
583             # No need to downgrade if character and byte
584             # semantics are equivalent. But this might
585             # leave the UTF-8 flag set, harmlessly.
586              
587             require bytes;
588             return 1 if length($_[0]) == bytes::length($_[0]);
589              
590             use utf8;
591             return 0 if $_[0] =~ /[^\x00-\xff]/;
592             $_[0] = pack('C*', unpack('U*', $_[0]));
593             return 1;
594             }
595             };
596              
597             {
598 24     24   2664 no integer;
  24         44  
  24         78  
599              
600             if ($] < 5.006) { eval $no_downgrade }
601             elsif ($] < 5.008) { eval $pp_downgrade }
602             }
603              
604             my $WSE = 'Wide character in subroutine entry';
605             my $MWS = 16384;
606              
607             sub _shaWrite {
608 98     98   172 my($bytestr_r, $bytecnt, $self) = @_;
609 98 100       393 return(0) unless $bytecnt > 0;
610 86 100       506 croak $WSE unless utf8::downgrade($$bytestr_r, 1);
611 85 50       297 return(_shawrite($$bytestr_r, $bytecnt<<3, $self)) if $bytecnt <= $MWS;
612 0         0 my $offset = 0;
613 0         0 while ($bytecnt > $MWS) {
614 0         0 _shawrite(substr($$bytestr_r, $offset, $MWS), $MWS<<3, $self);
615 0         0 $offset += $MWS;
616 0         0 $bytecnt -= $MWS;
617             }
618 0         0 _shawrite(substr($$bytestr_r, $offset, $bytecnt), $bytecnt<<3, $self);
619             }
620              
621             sub _shafinish {
622 190     190   287 my($self) = @_;
623 190 100       392 my $LENPOS = $self->{alg} <= 256 ? 448 : 896;
624 190         489 _SETBIT($self, $self->{blockcnt}++);
625 190         415 while ($self->{blockcnt} > $LENPOS) {
626 1223 100       1757 if ($self->{blockcnt} < $self->{blocksize}) {
627 1202         1571 _CLRBIT($self, $self->{blockcnt}++);
628             }
629             else {
630 21         43 &{$self->{sha}}($self, $self->{block});
  21         534  
631 21         42 $self->{block} = "";
632 21         71 $self->{blockcnt} = 0;
633             }
634             }
635 190         371 while ($self->{blockcnt} < $LENPOS) {
636 78886         108490 _CLRBIT($self, $self->{blockcnt}++);
637             }
638 190 100       436 if ($self->{blocksize} > 512) {
639 53         125 $self->{block} .= pack("N", $self->{lenhh} & $MAX32);
640 53         113 $self->{block} .= pack("N", $self->{lenhl} & $MAX32);
641             }
642 190         395 $self->{block} .= pack("N", $self->{lenlh} & $MAX32);
643 190         349 $self->{block} .= pack("N", $self->{lenll} & $MAX32);
644 190         318 &{$self->{sha}}($self, $self->{block});
  190         5157  
645             }
646              
647 79     79   124 sub _shadigest { my($self) = @_; _digcpy($self); $self->{digest} }
  79         170  
  79         340  
648              
649             sub _shahex {
650 100     100   232 my($self) = @_;
651 100         245 _digcpy($self);
652 100         592 join("", unpack("H*", $self->{digest}));
653             }
654              
655             sub _shabase64 {
656 11     11   20 my($self) = @_;
657 11         31 _digcpy($self);
658 11         31 my $b64 = pack("u", $self->{digest});
659 11         46 $b64 =~ s/^.//mg;
660 11         33 $b64 =~ s/\n//g;
661 11         24 $b64 =~ tr|` -_|AA-Za-z0-9+/|;
662 11         21 my $numpads = (3 - length($self->{digest}) % 3) % 3;
663 11 100       82 $b64 =~ s/.{$numpads}$// if $numpads;
664 11         47 $b64;
665             }
666              
667 0     0   0 sub _shadsize { my($self) = @_; $self->{digestlen} }
  0         0  
668              
669             sub _shacpy {
670 17     17   32 my($to, $from) = @_;
671 17         48 $to->{alg} = $from->{alg};
672 17         27 $to->{sha} = $from->{sha};
673 17         33 $to->{H} = [@{$from->{H}}];
  17         40  
674 17         30 $to->{block} = $from->{block};
675 17         33 $to->{blockcnt} = $from->{blockcnt};
676 17         27 $to->{blocksize} = $from->{blocksize};
677 17         27 for (qw(lenhh lenhl lenlh lenll)) { $to->{$_} = $from->{$_} }
  68         114  
678 17         28 $to->{digestlen} = $from->{digestlen};
679 17         82 $to;
680             }
681              
682 11     11   17 sub _shadup { my($self) = @_; my($copy); _shacpy($copy, $self) }
  11         13  
  11         19  
683              
684             sub _shadump {
685 4     4   11 my $self = shift;
686 4         11 for (qw(alg H block blockcnt lenhh lenhl lenlh lenll)) {
687 32 50       61 return unless defined $self->{$_};
688             }
689              
690 4         9 my @state = ();
691 4 100       13 my $fmt = ($self->{alg} <= 256 ? "%08x" : "%016x");
692              
693 4         14 push(@state, "alg:" . $self->{alg});
694              
695 4 100       8 my @H = map { $self->{alg} <= 256 ? $_ & $MAX32 : $_ } @{$self->{H}};
  32         77  
  4         15  
696 4         11 push(@state, "H:" . join(":", map { sprintf($fmt, $_) } @H));
  32         86  
697              
698 4         23 my @c = unpack("C*", $self->{block});
699 4         75 push(@c, 0x00) while scalar(@c) < ($self->{blocksize} >> 3);
700 4         11 push(@state, "block:" . join(":", map {sprintf("%02x", $_)} @c));
  384         583  
701 4         24 push(@state, "blockcnt:" . $self->{blockcnt});
702              
703 4         9 push(@state, "lenhh:" . $self->{lenhh});
704 4         5 push(@state, "lenhl:" . $self->{lenhl});
705 4         11 push(@state, "lenlh:" . $self->{lenlh});
706 4         8 push(@state, "lenll:" . $self->{lenll});
707 4         66 join("\n", @state) . "\n";
708             }
709              
710             sub _shaload {
711 11     11   17 my $state = shift;
712              
713 11         20 my %s = ();
714 11         57 for (split(/\n/, $state)) {
715 96         163 s/^\s+//;
716 96         146 s/\s+$//;
717 96 100       189 next if (/^(#|$)/);
718 88         513 my @f = split(/[:\s]+/);
719 88         120 my $tag = shift(@f);
720 88         288 $s{$tag} = join('', @f);
721             }
722              
723             # H and block may contain arbitrary values, but check everything else
724 11 50       30 grep { $_ == $s{alg} } (1,224,256,384,512,512224,512256) or return;
  77         143  
725 11 100       51 length($s{H}) == ($s{alg} <= 256 ? 64 : 128) or return;
    50          
726 11 100       42 length($s{block}) == ($s{alg} <= 256 ? 128 : 256) or return;
    50          
727             {
728 24     24   27423 no integer;
  24         51  
  24         91  
  11         15  
729 11         23 for (qw(blockcnt lenhh lenhl lenlh lenll)) {
730 55 50       130 0 <= $s{$_} or return;
731 55 50       100 $s{$_} <= 4294967295 or return;
732             }
733 11 100       48 $s{blockcnt} < ($s{alg} <= 256 ? 512 : 1024) or return;
    50          
734             }
735              
736 11 50       32 my $self = _shaopen($s{alg}) or return;
737              
738 11         95 my @h = $s{H} =~ /(.{8})/g;
739 11         19 for (@{$self->{H}}) {
  11         26  
740 88         122 $_ = hex(shift @h);
741 88 100       147 if ($self->{alg} > 256) {
742 32         88 $_ = (($_ << 16) << 16) | hex(shift @h);
743             }
744             }
745              
746 11         24 $self->{blockcnt} = $s{blockcnt};
747 11         70 $self->{block} = pack("H*", $s{block});
748 11         33 $self->{block} = substr($self->{block},0,_BYTECNT($self->{blockcnt}));
749              
750 11         23 $self->{lenhh} = $s{lenhh};
751 11         20 $self->{lenhl} = $s{lenhl};
752 11         28 $self->{lenlh} = $s{lenlh};
753 11         17 $self->{lenll} = $s{lenll};
754              
755 11         49 $self;
756             }
757              
758             # ref. src/hmac.c from Digest::SHA
759              
760             sub _hmacopen {
761 43     43   92 my($alg, $key) = @_;
762 43         51 my($self);
763 43 50       83 $self->{isha} = _shaopen($alg) or return;
764 43 50       80 $self->{osha} = _shaopen($alg) or return;
765 43 50       123 croak $WSE unless utf8::downgrade($key, 1);
766 43 100       108 if (length($key) > $self->{osha}->{blocksize} >> 3) {
767 11 50       23 $self->{ksha} = _shaopen($alg) or return;
768 11         37 _shawrite($key, length($key) << 3, $self->{ksha});
769 11         29 _shafinish($self->{ksha});
770 11         33 $key = _shadigest($self->{ksha});
771             }
772             $key .= chr(0x00)
773 43         1167 while length($key) < $self->{osha}->{blocksize} >> 3;
774 43         202 my @k = unpack("C*", $key);
775 43         80 for (@k) { $_ ^= 0x5c }
  3712         3972  
776 43         203 _shawrite(pack("C*", @k), $self->{osha}->{blocksize}, $self->{osha});
777 43         86 for (@k) { $_ ^= (0x5c ^ 0x36) }
  3712         3928  
778 43         222 _shawrite(pack("C*", @k), $self->{isha}->{blocksize}, $self->{isha});
779 43         1002 $self;
780             }
781              
782             sub _hmacWrite {
783 45     45   89 my($bytestr_r, $bytecnt, $self) = @_;
784 45         99 _shaWrite($bytestr_r, $bytecnt, $self->{isha});
785             }
786              
787             sub _hmacfinish {
788 43     43   67 my($self) = @_;
789 43         90 _shafinish($self->{isha});
790             _shawrite(_shadigest($self->{isha}),
791 43         106 $self->{isha}->{digestlen} << 3, $self->{osha});
792 43         77 _shafinish($self->{osha});
793             }
794              
795 23     23   38 sub _hmacdigest { my($self) = @_; _shadigest($self->{osha}) }
  23         39  
796 20     20   35 sub _hmachex { my($self) = @_; _shahex($self->{osha}) }
  20         40  
797 0     0   0 sub _hmacbase64 { my($self) = @_; _shabase64($self->{osha}) }
  0         0  
798              
799             # SHA and HMAC-SHA functions
800              
801             my @suffix_extern = ("", "_hex", "_base64");
802             my @suffix_intern = ("digest", "hex", "base64");
803              
804             my($i, $alg);
805             for $alg (1, 224, 256, 384, 512, 512224, 512256) {
806             for $i (0 .. 2) {
807             my $fcn = 'sub sha' . $alg . $suffix_extern[$i] . ' {
808             my $state = _shaopen(' . $alg . ') or return;
809             for (@_) { _shaWrite(\$_, length($_), $state) }
810             _shafinish($state);
811             _sha' . $suffix_intern[$i] . '($state);
812             }';
813 1 50   1 1 4 eval($fcn);
  1 50   2 1 3  
  1 50   5 1 4  
  1 0   0 1 4  
  1 50   2 1 4  
  2 50   2 1 219  
  2 0   0 1 6  
  2 50   2 1 7  
  2 50   2 1 7  
  2 0   0 1 7  
  5 50   2 1 315  
  5 50   4 1 13  
  5 0   0 1 22  
  4 0   0 1 14  
  4 0   0 1 17  
  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 52  
  2         8  
  2         6  
  2         5  
  2         8  
  2         188  
  2         6  
  2         7  
  2         8  
  2         9  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  2         50  
  2         7  
  2         10  
  2         9  
  2         9  
  2         200  
  2         5  
  2         8  
  2         7  
  2         8  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  2         50  
  2         6  
  2         6  
  2         7  
  2         8  
  4         258  
  4         12  
  4         14  
  4         14  
  4         14  
  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         64  
  2         6  
  2         6  
  2         8  
  2         8  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  2         61  
  2         5  
  2         6  
  2         17  
  2         10  
  2         56  
  2         7  
  2         6  
  2         8  
  2         7  
  5         563  
  5         23  
  5         28  
  5         24  
  5         32  
814             push(@EXPORT_OK, 'sha' . $alg . $suffix_extern[$i]);
815             $fcn = 'sub hmac_sha' . $alg . $suffix_extern[$i] . ' {
816             my $state = _hmacopen(' . $alg . ', pop(@_)) or return;
817             for (@_) { _hmacWrite(\$_, length($_), $state) }
818             _hmacfinish($state);
819             _hmac' . $suffix_intern[$i] . '($state);
820             }';
821 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 737  
  11 0   0 1 142  
  11 50   7 1 37  
  11 0   0 1 32  
  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         2194  
  8         26  
  10         28  
  8         26  
  8         29  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  9         263  
  9         28  
  9         26  
  9         30  
  9         40  
  8         207  
  8         22  
  8         20  
  8         23  
  8         21  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  7         187  
  7         41  
  7         22  
  7         22  
  7         24  
  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  
822             push(@EXPORT_OK, 'hmac_sha' . $alg . $suffix_extern[$i]);
823             }
824             }
825              
826             # OOP methods
827              
828 0     0 1 0 sub hashsize { my $self = shift; _shadsize($self) << 3 }
  0         0  
829 4     4 1 8 sub algorithm { my $self = shift; $self->{alg} }
  4         22  
830              
831             sub add {
832 19     19 1 437 my $self = shift;
833 19         43 for (@_) { _shaWrite(\$_, length($_), $self) }
  20         51  
834 19         52 $self;
835             }
836              
837             sub digest {
838 1     1 1 2 my $self = shift;
839 1         3 _shafinish($self);
840 1         3 my $rsp = _shadigest($self);
841 1         4 _sharewind($self);
842 1         26 $rsp;
843             }
844              
845             sub hexdigest {
846 59     59 1 237 my $self = shift;
847 59         146 _shafinish($self);
848 59         157 my $rsp = _shahex($self);
849 59         157 _sharewind($self);
850 59         161 $rsp;
851             }
852              
853             sub b64digest {
854 1     1 1 2 my $self = shift;
855 1         3 _shafinish($self);
856 1         4 my $rsp = _shabase64($self);
857 1         3 _sharewind($self);
858 1         3 $rsp;
859             }
860              
861             sub new {
862 16     16 1 1244 my($class, $alg) = @_;
863 16 100       84 $alg =~ s/\D+//g if defined $alg;
864 16 100       46 if (ref($class)) { # instance method
865 5 100 100     17 if (!defined($alg) || ($alg == $class->algorithm)) {
866 3         7 _sharewind($class);
867 3         10 return($class);
868             }
869 2 50       5 my $self = _shaopen($alg) or return;
870 2         4 return(_shacpy($class, $self));
871             }
872 11 100       32 $alg = 1 unless defined $alg;
873 11 100       33 my $self = _shaopen($alg) or return;
874 10         22 bless($self, $class);
875 10         43 $self;
876             }
877              
878             sub clone {
879 11     11 1 237 my $self = shift;
880 11 50       19 my $copy = _shadup($self) or return;
881 11         31 bless($copy, ref($self));
882             }
883              
884 24     24   50870 BEGIN { *reset = \&new }
885              
886             sub add_bits {
887 713     713 1 3338 my($self, $data, $nbits) = @_;
888 713 100       1118 unless (defined $nbits) {
889 38         63 $nbits = length($data);
890 38         131 $data = pack("B*", $data);
891             }
892 713 50       1149 $nbits = length($data) * 8 if $nbits > length($data) * 8;
893 713         1304 _shawrite($data, $nbits, $self);
894 713         1179 return($self);
895             }
896              
897             sub _bail {
898 0     0   0 my $msg = shift;
899              
900 0         0 $errmsg = $!;
901 0         0 $msg .= ": $!";
902 0         0 croak $msg;
903             }
904              
905             sub _addfile {
906 3     3   8 my ($self, $handle) = @_;
907              
908 3         5 my $n;
909 3         3 my $buf = "";
910              
911 3         84 while (($n = read($handle, $buf, 4096))) {
912 3         11 $self->add($buf);
913             }
914 3 50       7 _bail("Read failed") unless defined $n;
915              
916 3         34 $self;
917             }
918              
919             {
920             my $_can_T_filehandle;
921              
922             sub _istext {
923 1     1   3 local *FH = shift;
924 1         3 my $file = shift;
925              
926 1 50       3 if (! defined $_can_T_filehandle) {
927 1         5 local $^W = 0;
928 1         2 my $istext = eval { -T FH };
  1         20  
929 1 50       7 $_can_T_filehandle = $@ ? 0 : 1;
930 1 50       7 return $_can_T_filehandle ? $istext : -T $file;
931             }
932 0 0       0 return $_can_T_filehandle ? -T FH : -T $file;
933             }
934             }
935              
936             sub addfile {
937 6     6 1 43 my ($self, $file, $mode) = @_;
938              
939 6 100       25 return(_addfile($self, $file)) unless ref(\$file) eq 'SCALAR';
940              
941 4 50       9 $mode = defined($mode) ? $mode : "";
942             my ($binary, $UNIVERSAL, $BITS) =
943 4         10 map { $_ eq $mode } ("b", "U", "0");
  12         25  
944              
945             ## Always interpret "-" to mean STDIN; otherwise use
946             ## sysopen to handle full range of POSIX file names.
947             ## If $file is a directory, force an EISDIR error
948             ## by attempting to open with mode O_RDWR
949              
950 4         9 local *FH;
951 4 50       9 if ($file eq '-') {
952 0 0       0 if (-d STDIN) {
953 0 0       0 sysopen(FH, getcwd(), O_RDWR)
954             or _bail('Open failed');
955             }
956 0 0       0 open(FH, '< -')
957             or _bail('Open failed');
958             }
959             else {
960 4 50       140 sysopen(FH, $file, -d $file ? O_RDWR : O_RDONLY)
    50          
961             or _bail('Open failed');
962             }
963              
964 4 100       14 if ($BITS) {
965 2         6 my ($n, $buf) = (0, "");
966 2         40 while (($n = read(FH, $buf, 4096))) {
967 2         7 $buf =~ tr/01//cd;
968 2         5 $self->add_bits($buf);
969             }
970 2 50       5 _bail("Read failed") unless defined $n;
971 2         17 close(FH);
972 2         12 return($self);
973             }
974              
975 2 50 66     11 binmode(FH) if $binary || $UNIVERSAL;
976 2 100 66     7 if ($UNIVERSAL && _istext(*FH, $file)) {
977 1         5 while () {
978 3         8 s/\015\012/\012/g; # DOS/Windows
979 3         8 s/\015/\012/g; # early MacOS
980 3         5 $self->add($_);
981             }
982             }
983 1         3 else { $self->_addfile(*FH) }
984 2         19 close(FH);
985              
986 2         12 $self;
987             }
988              
989             sub getstate {
990 4     4 1 12 my $self = shift;
991              
992 4         33 return _shadump($self);
993             }
994              
995             sub putstate {
996 11     11 1 1203 my $class = shift;
997 11         22 my $state = shift;
998              
999 11 100       28 if (ref($class)) { # instance method
1000 4 50       9 my $self = _shaload($state) or return;
1001 4         15 return(_shacpy($class, $self));
1002             }
1003 7 50       21 my $self = _shaload($state) or return;
1004 7         19 bless($self, $class);
1005 7         19 return($self);
1006             }
1007              
1008             sub dump {
1009 0     0 1   my $self = shift;
1010 0           my $file = shift;
1011              
1012 0 0         my $state = $self->getstate or return;
1013 0 0 0       $file = "-" if (!defined($file) || $file eq "");
1014              
1015 0           local *FH;
1016 0 0         open(FH, "> $file") or return;
1017 0           print FH $state;
1018 0           close(FH);
1019              
1020 0           return($self);
1021             }
1022              
1023             sub load {
1024 0     0 1   my $class = shift;
1025 0           my $file = shift;
1026              
1027 0 0 0       $file = "-" if (!defined($file) || $file eq "");
1028            
1029 0           local *FH;
1030 0 0         open(FH, "< $file") or return;
1031 0           my $str = join('', );
1032 0           close(FH);
1033              
1034 0           $class->putstate($str);
1035             }
1036              
1037             1;
1038             __END__