File Coverage

SHA3.xs
Criterion Covered Total %
statement 35 95 36.8
branch 20 70 28.5
condition n/a
subroutine n/a
pod n/a
total 55 165 33.3


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2             #include "EXTERN.h"
3             #include "perl.h"
4             #include "XSUB.h"
5              
6             #ifdef SvPVbyte
7             #if PERL_REVISION == 5 && PERL_VERSION < 8
8             #undef SvPVbyte
9             #define SvPVbyte(sv, lp) \
10             (sv_utf8_downgrade((sv), 0), SvPV((sv), (lp)))
11             #endif
12             #else
13             #define SvPVbyte SvPV
14             #endif
15              
16             #ifndef dTHX
17             #define pTHX_
18             #define aTHX_
19             #endif
20              
21             #ifndef PerlIO
22             #define PerlIO FILE
23             #define PerlIO_read(f, buf, count) fread(buf, 1, count, f)
24             #endif
25              
26             #ifndef sv_derived_from
27             #include "src/sdf.c"
28             #endif
29              
30             #ifndef Newx
31             #define Newx(ptr, num, type) New(0, ptr, num, type)
32             #define Newxz(ptr, num, type) Newz(0, ptr, num, type)
33             #endif
34              
35             #include "src/sha3.c"
36              
37             static const int ix2alg[] =
38             {224,224,224,256,256,256,384,384,384,512,512,512,
39             128000,128000,128000,256000,256000,256000};
40              
41             #ifndef INT2PTR
42             #define INT2PTR(p, i) (p) (i)
43             #endif
44              
45             #define MAX_WRITE_SIZE 16384
46             #define IO_BUFFER_SIZE 4096
47              
48 74           static SHA3 *getSHA3(pTHX_ SV *self)
49             {
50 74 50         if (!sv_isobject(self) || !sv_derived_from(self, "Digest::SHA3"))
    50          
51 0           return(NULL);
52 74 50         return INT2PTR(SHA3 *, SvIV(SvRV(self)));
53             }
54              
55             MODULE = Digest::SHA3 PACKAGE = Digest::SHA3
56              
57             PROTOTYPES: ENABLE
58              
59             int
60             shainit(s, alg)
61             SHA3 * s
62             int alg
63              
64             void
65             sharewind(s)
66             SHA3 * s
67              
68             unsigned long
69             shawrite(bitstr, bitcnt, s)
70             unsigned char * bitstr
71             unsigned long bitcnt
72             SHA3 * s
73              
74             SV *
75             newSHA3(classname, alg)
76             char * classname
77             int alg
78             PREINIT:
79             SHA3 *state;
80             CODE:
81 18           Newxz(state, 1, SHA3);
82 18 50         if (!shainit(state, alg)) {
83 0           Safefree(state);
84 0           XSRETURN_UNDEF;
85             }
86 18           RETVAL = newSV(0);
87 18           sv_setref_pv(RETVAL, classname, (void *) state);
88 18           SvREADONLY_on(SvRV(RETVAL));
89             OUTPUT:
90             RETVAL
91              
92             SV *
93             clone(self)
94             SV * self
95             PREINIT:
96             SHA3 *state;
97             SHA3 *clone;
98             CODE:
99 0 0         if ((state = getSHA3(aTHX_ self)) == NULL)
100 0           XSRETURN_UNDEF;
101 0           Newx(clone, 1, SHA3);
102 0           RETVAL = newSV(0);
103 0           sv_setref_pv(RETVAL, sv_reftype(SvRV(self), 1), (void *) clone);
104 0           SvREADONLY_on(SvRV(RETVAL));
105 0           Copy(state, clone, 1, SHA3);
106             OUTPUT:
107             RETVAL
108              
109             void
110             DESTROY(s)
111             SHA3 * s
112             CODE:
113 18           Safefree(s);
114              
115             SV *
116             sha3_224(...)
117             ALIAS:
118             Digest::SHA3::sha3_224 = 0
119             Digest::SHA3::sha3_224_hex = 1
120             Digest::SHA3::sha3_224_base64 = 2
121             Digest::SHA3::sha3_256 = 3
122             Digest::SHA3::sha3_256_hex = 4
123             Digest::SHA3::sha3_256_base64 = 5
124             Digest::SHA3::sha3_384 = 6
125             Digest::SHA3::sha3_384_hex = 7
126             Digest::SHA3::sha3_384_base64 = 8
127             Digest::SHA3::sha3_512 = 9
128             Digest::SHA3::sha3_512_hex = 10
129             Digest::SHA3::sha3_512_base64 = 11
130             Digest::SHA3::shake128 = 12
131             Digest::SHA3::shake128_hex = 13
132             Digest::SHA3::shake128_base64 = 14
133             Digest::SHA3::shake256 = 15
134             Digest::SHA3::shake256_hex = 16
135             Digest::SHA3::shake256_base64 = 17
136             PREINIT:
137             int i;
138             UCHR *data;
139             STRLEN len;
140             SHA3 sha3;
141             char *result;
142             CODE:
143 12 50         if (!shainit(&sha3, ix2alg[ix]))
144 0           XSRETURN_UNDEF;
145 24 100         for (i = 0; i < items; i++) {
146 12 50         data = (UCHR *) (SvPVbyte(ST(i), len));
147 256 100         while (len > MAX_WRITE_SIZE) {
148 244           shawrite(data, MAX_WRITE_SIZE << 3, &sha3);
149 244           data += MAX_WRITE_SIZE;
150 244           len -= MAX_WRITE_SIZE;
151             }
152 12           shawrite(data, len << 3, &sha3);
153             }
154 12           shafinish(&sha3);
155 12           len = 0;
156 12 50         if (ix % 3 == 0) {
157 0           result = (char *) shadigest(&sha3);
158 0           len = (STRLEN) sha3.digestlen;
159             }
160 12 50         else if (ix % 3 == 1)
161 12           result = shahex(&sha3);
162             else
163 0           result = shabase64(&sha3);
164 12           RETVAL = newSVpv(result, len);
165             OUTPUT:
166             RETVAL
167              
168             int
169             hashsize(self)
170             SV * self
171             ALIAS:
172             Digest::SHA3::hashsize = 0
173             Digest::SHA3::algorithm = 1
174             PREINIT:
175             SHA3 *state;
176             CODE:
177 0 0         if ((state = getSHA3(aTHX_ self)) == NULL)
178 0           XSRETURN_UNDEF;
179 0 0         RETVAL = ix ? state->alg : state->digestlen << 3;
180             OUTPUT:
181             RETVAL
182              
183             void
184             add(self, ...)
185             SV * self
186             PREINIT:
187             int i;
188             UCHR *data;
189             STRLEN len;
190             SHA3 *state;
191             PPCODE:
192 0 0         if ((state = getSHA3(aTHX_ self)) == NULL)
193 0           XSRETURN_UNDEF;
194 0 0         for (i = 1; i < items; i++) {
195 0 0         data = (UCHR *) (SvPVbyte(ST(i), len));
196 0 0         while (len > MAX_WRITE_SIZE) {
197 0           shawrite(data, MAX_WRITE_SIZE << 3, state);
198 0           data += MAX_WRITE_SIZE;
199 0           len -= MAX_WRITE_SIZE;
200             }
201 0           shawrite(data, len << 3, state);
202             }
203 0           XSRETURN(1);
204              
205             SV *
206             digest(self)
207             SV * self
208             ALIAS:
209             Digest::SHA3::digest = 0
210             Digest::SHA3::hexdigest = 1
211             Digest::SHA3::b64digest = 2
212             Digest::SHA3::squeeze = 3
213             PREINIT:
214             STRLEN len;
215             SHA3 *state;
216             char *result;
217             CODE:
218 33 50         if ((state = getSHA3(aTHX_ self)) == NULL)
219 0           XSRETURN_UNDEF;
220 33           shafinish(state);
221 33           len = 0;
222 33 50         if (ix == 0) {
223 0           result = (char *) shadigest(state);
224 0           len = (STRLEN) state->digestlen;
225             }
226 33 100         else if (ix == 1)
227 17           result = shahex(state);
228 16 50         else if (ix == 2)
229 0           result = shabase64(state);
230             else {
231 16 50         if ((result = (char *) shasqueeze(state)) == NULL)
232 0           XSRETURN_UNDEF;
233 16           len = (STRLEN) state->digestlen;
234             }
235 33           RETVAL = newSVpv(result, len);
236 33 100         if (ix != 3)
237 17           sharewind(state);
238             OUTPUT:
239             RETVAL
240              
241             void
242             _addfilebin(self, f)
243             SV * self
244             PerlIO * f
245             PREINIT:
246             SHA3 *state;
247             int n;
248             UCHR in[IO_BUFFER_SIZE];
249             PPCODE:
250 0 0         if (!f || (state = getSHA3(aTHX_ self)) == NULL)
    0          
251 0           XSRETURN_UNDEF;
252 0 0         while ((n = PerlIO_read(f, in, sizeof(in))) > 0)
253 0           shawrite(in, (ULNG) n << 3, state);
254 0           XSRETURN(1);
255              
256             void
257             _addfileuniv(self, f)
258             SV * self
259             PerlIO * f
260             PREINIT:
261             UCHR c;
262             int n;
263 0           int cr = 0;
264             UCHR *src, *dst;
265             UCHR in[IO_BUFFER_SIZE+1];
266             SHA3 *state;
267             PPCODE:
268 0 0         if (!f || (state = getSHA3(aTHX_ self)) == NULL)
    0          
269 0           XSRETURN_UNDEF;
270 0 0         while ((n = PerlIO_read(f, in+1, IO_BUFFER_SIZE)) > 0) {
271 0 0         for (dst = in, src = in + 1; n; n--) {
272 0           c = *src++;
273 0 0         if (!cr) {
274 0 0         if (c == '\015')
275 0           cr = 1;
276             else
277 0           *dst++ = c;
278             }
279             else {
280 0 0         if (c == '\015')
281 0           *dst++ = '\012';
282 0 0         else if (c == '\012') {
283 0           *dst++ = '\012';
284 0           cr = 0;
285             }
286             else {
287 0           *dst++ = '\012';
288 0           *dst++ = c;
289 0           cr = 0;
290             }
291             }
292             }
293 0           shawrite(in, (ULNG) (dst - in) << 3, state);
294             }
295 0 0         if (cr) {
296 0           in[0] = '\012';
297 0           shawrite(in, 1UL << 3, state);
298             }
299 0           XSRETURN(1);