1 unit SHA3_256;
2
3 {SHA3-256 - 256 bit Secure Hash Function}
4
5
6 interface
7
8 (*************************************************************************
9
10 DESCRIPTION : SHA3-256 - 256 bit Secure Hash Function
11
12 REQUIREMENTS : TP5-7, D1-D7/D9-D10/D12/D17-D18/D25S, FPC, VP
13
14 EXTERNAL DATA : ---
15
16 MEMORY USAGE : ---
17
18 DISPLAY MODE : ---
19
20 REFERENCES : - FIPS 202 SHA-3 Standard: 'Permutation-Based Hash and
21 Extendable-Output Functions' available from
22 http://csrc.nist.gov/publications/PubsFIPS.html or
23 http://dx.doi.org/10.6028/NIST.FIPS.202 or
24 http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
25 - Test vectors and intermediate values:
26 http://csrc.nist.gov/groups/ST/toolkit/examples.html
27
28 Version Date Author Modification
29 ------- -------- ------- ------------------------------------------
30 0.10 08.08.15 W.Ehrhardt Initial BP version using SHA5-256 layout
31 0.11 09.08.15 we SHA3_256FinalBits_LSB
32 0.12 17.08.15 we Updated references
33 0.13 15.05.17 we adjust OID to new MaxOIDLen
34 0.14 29.11.17 we SHA3_256File - fname: string
35
36 **************************************************************************)
37
38 (*-------------------------------------------------------------------------
39 (C) Copyright 2015-2017 Wolfgang Ehrhardt
40
41 This software is provided 'as-is', without any express or implied warranty.
42 In no event will the authors be held liable for any damages arising from
43 the use of this software.
44
45 Permission is granted to anyone to use this software for any purpose,
46 including commercial applications, and to alter it and redistribute it
47 freely, subject to the following restrictions:
48
49 1. The origin of this software must not be misrepresented; you must not
50 claim that you wrote the original software. If you use this software in
51 a product, an acknowledgment in the product documentation would be
52 appreciated but is not required.
53
54 2. Altered source versions must be plainly marked as such, and must not be
55 misrepresented as being the original software.
56
57 3. This notice may not be removed or altered from any source distribution.
58 ----------------------------------------------------------------------------*)
59
60
61 {$i STD.INC}
62
63 uses
64 BTypes,Hash,SHA3;
65
66
67 procedure SHA3_256Init(var Context: THashContext);
68 {-initialize context}
69
70 procedure SHA3_256Update(var Context: THashContext; Msg: pointer; Len: word);
71 {-update context with Msg data}
72
73 procedure SHA3_256UpdateXL(var Context: THashContext; Msg: pointer; Len: longint);
74 {-update context with Msg data}
75
76 procedure SHA3_256Final(var Context: THashContext; var Digest: TSHA3_256Digest);
77 {-finalize SHA3-256 calculation, clear context}
78
79 procedure SHA3_256FinalEx(var Context: THashContext; var Digest: THashDigest);
80 {-finalize SHA3-256 calculation, clear context}
81
82 procedure SHA3_256FinalBitsEx(var Context: THashContext; var Digest: THashDigest; BData: byte; bitlen: integer);
83 {-finalize SHA3-256 calculation with bitlen bits from BData (big-endian), clear context}
84
85 procedure SHA3_256FinalBits(var Context: THashContext; var Digest: TSHA3_256Digest; BData: byte; bitlen: integer);
86 {-finalize SHA3-256 calculation with bitlen bits from BData (big-endian), clear context}
87
88 procedure SHA3_256FinalBits_LSB(var Context: THashContext; var Digest: TSHA3_256Digest; BData: byte; bitlen: integer);
89 {-finalize SHA3-256 calculation with bitlen bits from BData (LSB format), clear context}
90
SHA3_256SelfTestnull91 function SHA3_256SelfTest: boolean;
92 {-self test for string from SHA3-256 documents}
93
94 procedure SHA3_256Full(var Digest: TSHA3_256Digest; Msg: pointer; Len: word);
95 {-SHA3-256 of Msg with init/update/final}
96
97 procedure SHA3_256FullXL(var Digest: TSHA3_256Digest; Msg: pointer; Len: longint);
98 {-SHA3-256 of Msg with init/update/final}
99
100 procedure SHA3_256File({$ifdef CONST} const {$endif} fname: string;
101 var Digest: TSHA3_256Digest; var buf; bsize: word; var Err: word);
102 {-SHA3-256 of file, buf: buffer with at least bsize bytes}
103
104
105 implementation
106
107
108 const
109 SHA3_256_BlockLen = 136; {Rate / 8, used only for HMAC} {FIPS202, Tab.3}
110
111 {http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html}
112 {2.16.840.1.101.3.4.2.8}
113 {joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) SHA3-256(8)}
114
115 const
116 SHA3_256_OID : TOID_Vec = (2,16,840,1,101,3,4,2,8,-1,-1); {Len=9}
117
118
119 {$ifndef VER5X}
120 const
121 SHA3_256_Desc: THashDesc = (
122 HSig : C_HashSig;
123 HDSize : sizeof(THashDesc);
124 HDVersion : C_HashVers;
125 HBlockLen : SHA3_256_BlockLen;
126 HDigestlen: sizeof(TSHA3_256Digest);
127 {$ifdef FPC_ProcVar}
128 HInit : @SHA3_256Init;
129 HFinal : @SHA3_256FinalEx;
130 HUpdateXL : @SHA3_256UpdateXL;
131 {$else}
132 HInit : SHA3_256Init;
133 HFinal : SHA3_256FinalEx;
134 HUpdateXL : SHA3_256UpdateXL;
135 {$endif}
136 HAlgNum : longint(_SHA3_256);
137 HName : 'SHA3-256';
138 HPtrOID : @SHA3_256_OID;
139 HLenOID : 9;
140 HFill : 0;
141 {$ifdef FPC_ProcVar}
142 HFinalBit : @SHA3_256FinalBitsEx;
143 {$else}
144 HFinalBit : SHA3_256FinalBitsEx;
145 {$endif}
146 HReserved : (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
147 );
148 {$else}
149 var
150 SHA3_256_Desc: THashDesc;
151 {$endif}
152
153
154 {$ifdef BIT16}
155 {$F-}
156 {$endif}
157
158
159 {---------------------------------------------------------------------------}
160 procedure SHA3_256Init(var Context: THashContext);
161 {-initialize context}
162 begin
163 {Clear context}
164 SHA3_LastError := SHA3_Init(TSHA3State(Context),__SHA3_256);
165 end;
166
167
168 {---------------------------------------------------------------------------}
169 procedure SHA3_256UpdateXL(var Context: THashContext; Msg: pointer; Len: longint);
170 {-update context with Msg data}
171 begin
172 SHA3_LastError := SHA3_UpdateXL(TSHA3State(Context), Msg, Len);
173 end;
174
175
176 {---------------------------------------------------------------------------}
177 procedure SHA3_256Update(var Context: THashContext; Msg: pointer; Len: word);
178 {-update context with Msg data}
179 begin
180 SHA3_LastError := SHA3_UpdateXL(TSHA3State(Context), Msg, Len);
181 end;
182
183
184 {---------------------------------------------------------------------------}
185 procedure SHA3_256FinalBitsEx(var Context: THashContext; var Digest: THashDigest; BData: byte; bitlen: integer);
186 {-finalize SHA3-256 calculation with bitlen bits from BData (big-endian), clear context}
187 begin
188 SHA3_LastError := SHA3_FinalBit(TSHA3State(Context), BData, bitlen, @Digest[0], 8*sizeof(Digest));
189 end;
190
191
192 {---------------------------------------------------------------------------}
193 procedure SHA3_256FinalBits(var Context: THashContext; var Digest: TSHA3_256Digest; BData: byte; bitlen: integer);
194 {-finalize SHA3-256 calculation with bitlen bits from BData (big-endian), clear context}
195 begin
196 SHA3_LastError := SHA3_FinalBit(TSHA3State(Context), BData, bitlen, @Digest[0], 8*sizeof(Digest));
197 end;
198
199
200 {---------------------------------------------------------------------------}
201 procedure SHA3_256FinalBits_LSB(var Context: THashContext; var Digest: TSHA3_256Digest; BData: byte; bitlen: integer);
202 {-finalize SHA3-256 calculation with bitlen bits from BData (LSB format), clear context}
203 begin
204 SHA3_LastError := SHA3_FinalBit_LSB(TSHA3State(Context), BData, bitlen, @Digest[0], 8*sizeof(Digest));
205 end;
206
207
208 {---------------------------------------------------------------------------}
209 procedure SHA3_256FinalEx(var Context: THashContext; var Digest: THashDigest);
210 {-finalize SHA3-256 calculation, clear context}
211 begin
212 SHA3_LastError := SHA3_FinalHash(TSHA3State(Context), @Digest[0]);
213 end;
214
215
216 {---------------------------------------------------------------------------}
217 procedure SHA3_256Final(var Context: THashContext; var Digest: TSHA3_256Digest);
218 {-finalize SHA3-256 calculation, clear context}
219 begin
220 SHA3_LastError := SHA3_FinalHash(TSHA3State(Context), @Digest[0]);
221 end;
222
223
224 {---------------------------------------------------------------------------}
SHA3_256SelfTestnull225 function SHA3_256SelfTest: boolean;
226 {-self test for string from SHA3-256 documents}
227 const
228 Bl1 = 0;
229 dig1: TSHA3_256Digest = ($A7,$FF,$C6,$F8,$BF,$1E,$D7,$66,
230 $51,$C1,$47,$56,$A0,$61,$D6,$62,
231 $F5,$80,$FF,$4D,$E4,$3B,$49,$FA,
232 $82,$D8,$0A,$4B,$80,$F8,$43,$4A);
233 BL2 = 5;
234 msg2: array[0..0] of byte = ($13);
235 dig2: TSHA3_256Digest = ($7B,$00,$47,$CF,$5A,$45,$68,$82,
236 $36,$3C,$BF,$0F,$B0,$53,$22,$CF,
237 $65,$F4,$B7,$05,$9A,$46,$36,$5E,
238 $83,$01,$32,$E3,$B5,$D9,$57,$AF);
239 BL3 = 30;
240 msg3: array[0..3] of byte = ($53,$58,$7B,$19);
241 dig3: TSHA3_256Digest = ($C8,$24,$2F,$EF,$40,$9E,$5A,$E9,
242 $D1,$F1,$C8,$57,$AE,$4D,$C6,$24,
243 $B9,$2B,$19,$80,$9F,$62,$AA,$8C,
244 $07,$41,$1C,$54,$A0,$78,$B1,$D0);
245
246 {https://github.com/gvanas/KeccakCodePackage, SKat len=200}
247 BL4 = 200;
248 msg4: array[0..24] of byte = ($aa,$fd,$c9,$24,$3d,$3d,$4a,$09,
249 $65,$58,$a3,$60,$cc,$27,$c8,$d8,
250 $62,$f0,$be,$73,$db,$5e,$88,$aa,$55);
251 dig4: TSHA3_256Digest = ($c6,$4b,$ec,$f7,$b7,$5f,$c8,$85,
252 $d5,$85,$39,$24,$f2,$b7,$d3,$7a,
253 $bc,$ef,$d3,$da,$12,$6b,$b8,$17,
254 $69,$7e,$1a,$09,$15,$2b,$1e,$be);
255 var
256 Context: THashContext;
257 Digest : TSHA3_256Digest;
258
SingleTestnull259 function SingleTest(Msg: pointer; BL: word; TDig: TSHA3_256Digest): boolean;
260 var
261 bytes: word;
262 begin
263 SingleTest := false;
264 SHA3_256Init(Context);
265 if SHA3_LastError<>0 then exit;
266 if BL=0 then SHA3_256Final(Context,Digest)
267 else begin
268 if BL>7 then begin
269 bytes := BL shr 3;
270 SHA3_256Update(Context, Msg, BL shr 3);
271 if SHA3_LastError<>0 then exit;
272 inc(Ptr2Inc(Msg), bytes);
273 end;
274 SHA3_256FinalBits_LSB(Context, Digest, pByte(Msg)^, BL and 7);
275 end;
276 if SHA3_LastError<>0 then exit;
277 SingleTest := HashSameDigest(@SHA3_256_Desc, PHashDigest(@TDig), PHashDigest(@Digest));
278 end;
279
280 begin
281 SHA3_256SelfTest := SingleTest(nil, BL1, dig1) and
282 SingleTest(@msg2, BL2, dig2) and
283 SingleTest(@msg3, BL3, dig3) and
284 SingleTest(@msg4, BL4, dig4);
285 end;
286
287
288 {---------------------------------------------------------------------------}
289 procedure SHA3_256FullXL(var Digest: TSHA3_256Digest; Msg: pointer; Len: longint);
290 {-SHA3-256 of Msg with init/update/final}
291 var
292 Context: THashContext;
293 begin
294 SHA3_256Init(Context);
295 if SHA3_LastError=0 then SHA3_256UpdateXL(Context, Msg, Len);
296 SHA3_256Final(Context, Digest);
297 end;
298
299
300 {---------------------------------------------------------------------------}
301 procedure SHA3_256Full(var Digest: TSHA3_256Digest; Msg: pointer; Len: word);
302 {-SHA3-256 of Msg with init/update/final}
303 begin
304 SHA3_256FullXL(Digest, Msg, Len);
305 end;
306
307
308 {---------------------------------------------------------------------------}
309 procedure SHA3_256File({$ifdef CONST} const {$endif} fname: string;
310 var Digest: TSHA3_256Digest; var buf; bsize: word; var Err: word);
311 {-SHA3-256 of file, buf: buffer with at least bsize bytes}
312 var
313 tmp: THashDigest;
314 begin
315 HashFile(fname, @SHA3_256_Desc, tmp, buf, bsize, Err);
316 move(tmp, Digest, sizeof(Digest));
317 end;
318
319
320 begin
321 {$ifdef VER5X}
322 fillchar(SHA3_256_Desc, sizeof(SHA3_256_Desc), 0);
323 with SHA3_256_Desc do begin
324 HSig := C_HashSig;
325 HDSize := sizeof(THashDesc);
326 HDVersion := C_HashVers;
327 HBlockLen := SHA3_256_BlockLen;
328 HDigestlen:= sizeof(TSHA3_256Digest);
329 HInit := SHA3_256Init;
330 HFinal := SHA3_256FinalEx;
331 HUpdateXL := SHA3_256UpdateXL;
332 HAlgNum := longint(_SHA3_256);
333 HName := 'SHA3-256';
334 HPtrOID := @SHA3_256_OID;
335 HLenOID := 9;
336 HFinalBit := SHA3_256FinalBitsEx;
337 end;
338 {$endif}
339 RegisterHash(_SHA3_256, @SHA3_256_Desc);
340 end.
341