1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Base Portability Library
3e5c31af7Sopenharmony_ci * -------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2015 The Android Open Source Project
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief SHA1 hash functions.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "deSha1.h"
25e5c31af7Sopenharmony_ci
26e5c31af7Sopenharmony_ci#include "deMemory.h"
27e5c31af7Sopenharmony_ci
28e5c31af7Sopenharmony_ciDE_BEGIN_EXTERN_C
29e5c31af7Sopenharmony_ci
30e5c31af7Sopenharmony_cienum
31e5c31af7Sopenharmony_ci{
32e5c31af7Sopenharmony_ci	CHUNK_BIT_SIZE	= 512,
33e5c31af7Sopenharmony_ci	CHUNK_BYTE_SIZE	= CHUNK_BIT_SIZE / 8
34e5c31af7Sopenharmony_ci};
35e5c31af7Sopenharmony_ci
36e5c31af7Sopenharmony_cistatic deUint32 leftRotate (deUint32 val, deUint32 count)
37e5c31af7Sopenharmony_ci{
38e5c31af7Sopenharmony_ci	DE_ASSERT(count < 32);
39e5c31af7Sopenharmony_ci
40e5c31af7Sopenharmony_ci	return (val << count) | (val >> (32 - count));
41e5c31af7Sopenharmony_ci}
42e5c31af7Sopenharmony_ci
43e5c31af7Sopenharmony_civoid deSha1Stream_init (deSha1Stream* stream)
44e5c31af7Sopenharmony_ci{
45e5c31af7Sopenharmony_ci	stream->size = 0;
46e5c31af7Sopenharmony_ci
47e5c31af7Sopenharmony_ci	/* Set the initial 16 deUint32s that contain real data to zeros. */
48e5c31af7Sopenharmony_ci	deMemset(stream->data, 0, 16 * sizeof(deUint32));
49e5c31af7Sopenharmony_ci
50e5c31af7Sopenharmony_ci	stream->hash[0] = 0x67452301u;
51e5c31af7Sopenharmony_ci	stream->hash[1] = 0xEFCDAB89u;
52e5c31af7Sopenharmony_ci	stream->hash[2] = 0x98BADCFEu;
53e5c31af7Sopenharmony_ci	stream->hash[3] = 0x10325476u;
54e5c31af7Sopenharmony_ci	stream->hash[4] = 0xC3D2E1F0u;
55e5c31af7Sopenharmony_ci}
56e5c31af7Sopenharmony_ci
57e5c31af7Sopenharmony_cistatic void deSha1Stream_flushChunk (deSha1Stream* stream)
58e5c31af7Sopenharmony_ci{
59e5c31af7Sopenharmony_ci	DE_ASSERT(stream->size % CHUNK_BYTE_SIZE == 0 && stream->size > 0);
60e5c31af7Sopenharmony_ci
61e5c31af7Sopenharmony_ci	{
62e5c31af7Sopenharmony_ci		size_t ndx;
63e5c31af7Sopenharmony_ci
64e5c31af7Sopenharmony_ci		/* Expand the 16 uint32s that contain the data to 80. */
65e5c31af7Sopenharmony_ci		for (ndx = 16; ndx < DE_LENGTH_OF_ARRAY(stream->data); ndx++)
66e5c31af7Sopenharmony_ci		{
67e5c31af7Sopenharmony_ci			stream->data[ndx] = leftRotate(stream->data[ndx - 3]
68e5c31af7Sopenharmony_ci										   ^ stream->data[ndx - 8]
69e5c31af7Sopenharmony_ci										   ^ stream->data[ndx - 14]
70e5c31af7Sopenharmony_ci										   ^ stream->data[ndx - 16], 1);
71e5c31af7Sopenharmony_ci		}
72e5c31af7Sopenharmony_ci	}
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_ci	{
75e5c31af7Sopenharmony_ci		deUint32	a = stream->hash[0];
76e5c31af7Sopenharmony_ci		deUint32	b = stream->hash[1];
77e5c31af7Sopenharmony_ci		deUint32	c = stream->hash[2];
78e5c31af7Sopenharmony_ci		deUint32	d = stream->hash[3];
79e5c31af7Sopenharmony_ci		deUint32	e = stream->hash[4];
80e5c31af7Sopenharmony_ci		size_t		ndx;
81e5c31af7Sopenharmony_ci
82e5c31af7Sopenharmony_ci		for (ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stream->data); ndx++)
83e5c31af7Sopenharmony_ci		{
84e5c31af7Sopenharmony_ci			deUint32 f;
85e5c31af7Sopenharmony_ci			deUint32 k;
86e5c31af7Sopenharmony_ci
87e5c31af7Sopenharmony_ci			if (ndx < 20)
88e5c31af7Sopenharmony_ci			{
89e5c31af7Sopenharmony_ci				f = (b & c) | ((~b) & d);
90e5c31af7Sopenharmony_ci				k = 0x5A827999u;
91e5c31af7Sopenharmony_ci			}
92e5c31af7Sopenharmony_ci			else if (ndx < 40)
93e5c31af7Sopenharmony_ci			{
94e5c31af7Sopenharmony_ci				f = b ^ c ^ d;
95e5c31af7Sopenharmony_ci				k = 0x6ED9EBA1u;
96e5c31af7Sopenharmony_ci			}
97e5c31af7Sopenharmony_ci			else if (ndx < 60)
98e5c31af7Sopenharmony_ci			{
99e5c31af7Sopenharmony_ci				f = (b & c) | (b & d) | (c & d);
100e5c31af7Sopenharmony_ci				k = 0x8F1BBCDCu;
101e5c31af7Sopenharmony_ci			}
102e5c31af7Sopenharmony_ci			else
103e5c31af7Sopenharmony_ci			{
104e5c31af7Sopenharmony_ci				f = b ^ c ^ d;
105e5c31af7Sopenharmony_ci				k = 0xCA62C1D6u;
106e5c31af7Sopenharmony_ci			}
107e5c31af7Sopenharmony_ci
108e5c31af7Sopenharmony_ci			{
109e5c31af7Sopenharmony_ci				const deUint32 tmp = leftRotate(a, 5) + f + e + k + stream->data[ndx];
110e5c31af7Sopenharmony_ci
111e5c31af7Sopenharmony_ci				e = d;
112e5c31af7Sopenharmony_ci				d = c;
113e5c31af7Sopenharmony_ci				c = leftRotate(b, 30);
114e5c31af7Sopenharmony_ci				b = a;
115e5c31af7Sopenharmony_ci				a = tmp;
116e5c31af7Sopenharmony_ci			}
117e5c31af7Sopenharmony_ci		}
118e5c31af7Sopenharmony_ci
119e5c31af7Sopenharmony_ci		stream->hash[0] += a;
120e5c31af7Sopenharmony_ci		stream->hash[1] += b;
121e5c31af7Sopenharmony_ci		stream->hash[2] += c;
122e5c31af7Sopenharmony_ci		stream->hash[3] += d;
123e5c31af7Sopenharmony_ci		stream->hash[4] += e;
124e5c31af7Sopenharmony_ci
125e5c31af7Sopenharmony_ci		/* Set the initial 16 deUint32s that contain the real data to zeros. */
126e5c31af7Sopenharmony_ci		deMemset(stream->data, 0, 16 * sizeof(deUint32));
127e5c31af7Sopenharmony_ci	}
128e5c31af7Sopenharmony_ci}
129e5c31af7Sopenharmony_ci
130e5c31af7Sopenharmony_civoid deSha1Stream_process (deSha1Stream* stream, size_t size, const void* data_)
131e5c31af7Sopenharmony_ci{
132e5c31af7Sopenharmony_ci	const deUint8* const	data			= (const deUint8*)data_;
133e5c31af7Sopenharmony_ci	size_t					bytesProcessed	= 0;
134e5c31af7Sopenharmony_ci
135e5c31af7Sopenharmony_ci	while (bytesProcessed < size)
136e5c31af7Sopenharmony_ci	{
137e5c31af7Sopenharmony_ci		do
138e5c31af7Sopenharmony_ci		{
139e5c31af7Sopenharmony_ci			const size_t bitOffset = (size_t)(8 * (4 - (1 + (stream->size % 4))));
140e5c31af7Sopenharmony_ci
141e5c31af7Sopenharmony_ci			stream->data[(stream->size / 4) % 16] |= ((deUint32)data[bytesProcessed]) << (deUint32)bitOffset;
142e5c31af7Sopenharmony_ci
143e5c31af7Sopenharmony_ci			stream->size++;
144e5c31af7Sopenharmony_ci			bytesProcessed++;
145e5c31af7Sopenharmony_ci		}
146e5c31af7Sopenharmony_ci		while (stream->size % CHUNK_BYTE_SIZE != 0 && bytesProcessed < size);
147e5c31af7Sopenharmony_ci
148e5c31af7Sopenharmony_ci		if (stream->size % CHUNK_BYTE_SIZE == 0)
149e5c31af7Sopenharmony_ci			deSha1Stream_flushChunk(stream);
150e5c31af7Sopenharmony_ci	}
151e5c31af7Sopenharmony_ci
152e5c31af7Sopenharmony_ci	DE_ASSERT(bytesProcessed == size);
153e5c31af7Sopenharmony_ci}
154e5c31af7Sopenharmony_ci
155e5c31af7Sopenharmony_civoid deSha1Stream_finalize (deSha1Stream* stream, deSha1* hash)
156e5c31af7Sopenharmony_ci{
157e5c31af7Sopenharmony_ci	/* \note First element is initialized to 0x80u and rest to 0x0. */
158e5c31af7Sopenharmony_ci	static const deUint8	padding[CHUNK_BYTE_SIZE]	= { 0x80u };
159e5c31af7Sopenharmony_ci	const deUint64			length						= stream->size * 8;
160e5c31af7Sopenharmony_ci	deUint8					lengthData[sizeof(deUint64)];
161e5c31af7Sopenharmony_ci	size_t					ndx;
162e5c31af7Sopenharmony_ci
163e5c31af7Sopenharmony_ci	DE_ASSERT(padding[0] == 0x80u);
164e5c31af7Sopenharmony_ci	DE_ASSERT(padding[1] == 0x0u);
165e5c31af7Sopenharmony_ci
166e5c31af7Sopenharmony_ci	for (ndx = 0; ndx < sizeof(deUint64); ndx++)
167e5c31af7Sopenharmony_ci		lengthData[ndx] = (deUint8)(0xffu & (length >> (8 * (sizeof(deUint64) - 1 - ndx))));
168e5c31af7Sopenharmony_ci
169e5c31af7Sopenharmony_ci	{
170e5c31af7Sopenharmony_ci		const deUint64 spaceLeftInChunk = CHUNK_BYTE_SIZE - (stream->size % CHUNK_BYTE_SIZE);
171e5c31af7Sopenharmony_ci
172e5c31af7Sopenharmony_ci		/* The stream must be a multiple of 512 bits (CHUNK_BYTE_SIZE) and is terminated by a single bit set to 1,
173e5c31af7Sopenharmony_ci		 * then 7 or more 0 bits, then finally the last 64 bits are the message length. */
174e5c31af7Sopenharmony_ci
175e5c31af7Sopenharmony_ci		if (spaceLeftInChunk >= 1 + sizeof(lengthData))
176e5c31af7Sopenharmony_ci		{
177e5c31af7Sopenharmony_ci			/* There's room for a 0x80 byte and zero or more 0x0 padding bytes. */
178e5c31af7Sopenharmony_ci			deSha1Stream_process(stream, (size_t)(spaceLeftInChunk - sizeof(lengthData)), padding);
179e5c31af7Sopenharmony_ci		}
180e5c31af7Sopenharmony_ci		else
181e5c31af7Sopenharmony_ci		{
182e5c31af7Sopenharmony_ci			/* 0x80 and the message length won't fit in this chunk, we need to add a whole new chunk of zero padding,
183e5c31af7Sopenharmony_ci			 * which will include the message length at the end. */
184e5c31af7Sopenharmony_ci			deSha1Stream_process(stream, (size_t)(spaceLeftInChunk), padding);
185e5c31af7Sopenharmony_ci			deSha1Stream_process(stream, (size_t)(CHUNK_BYTE_SIZE - sizeof(lengthData)), padding + spaceLeftInChunk);
186e5c31af7Sopenharmony_ci		}
187e5c31af7Sopenharmony_ci	}
188e5c31af7Sopenharmony_ci
189e5c31af7Sopenharmony_ci	deSha1Stream_process(stream, sizeof(lengthData), lengthData);
190e5c31af7Sopenharmony_ci	DE_ASSERT(stream->size % CHUNK_BYTE_SIZE == 0);
191e5c31af7Sopenharmony_ci
192e5c31af7Sopenharmony_ci	deMemcpy(hash->hash, stream->hash, sizeof(hash->hash));
193e5c31af7Sopenharmony_ci}
194e5c31af7Sopenharmony_ci
195e5c31af7Sopenharmony_civoid deSha1_compute (deSha1* hash, size_t size, const void* data)
196e5c31af7Sopenharmony_ci{
197e5c31af7Sopenharmony_ci	deSha1Stream stream;
198e5c31af7Sopenharmony_ci
199e5c31af7Sopenharmony_ci	deSha1Stream_init(&stream);
200e5c31af7Sopenharmony_ci	deSha1Stream_process(&stream, size, data);
201e5c31af7Sopenharmony_ci	deSha1Stream_finalize(&stream, hash);
202e5c31af7Sopenharmony_ci}
203e5c31af7Sopenharmony_ci
204e5c31af7Sopenharmony_civoid deSha1_render (const deSha1* hash, char* buffer)
205e5c31af7Sopenharmony_ci{
206e5c31af7Sopenharmony_ci	size_t charNdx;
207e5c31af7Sopenharmony_ci
208e5c31af7Sopenharmony_ci	for (charNdx = 0; charNdx < 40; charNdx++)
209e5c31af7Sopenharmony_ci	{
210e5c31af7Sopenharmony_ci		const deUint32	val32	= hash->hash[charNdx / 8];
211e5c31af7Sopenharmony_ci		const deUint8	val8	= (deUint8)(0x0fu & (val32 >> (4 * (8 - 1 - (charNdx % 8)))));
212e5c31af7Sopenharmony_ci
213e5c31af7Sopenharmony_ci		if (val8 < 10)
214e5c31af7Sopenharmony_ci			buffer[charNdx] = (char)('0' + val8);
215e5c31af7Sopenharmony_ci		else
216e5c31af7Sopenharmony_ci			buffer[charNdx] = (char)('a' + val8 - 10);
217e5c31af7Sopenharmony_ci	}
218e5c31af7Sopenharmony_ci}
219e5c31af7Sopenharmony_ci
220e5c31af7Sopenharmony_cideBool deSha1_parse (deSha1* hash, const char* buffer)
221e5c31af7Sopenharmony_ci{
222e5c31af7Sopenharmony_ci	size_t charNdx;
223e5c31af7Sopenharmony_ci
224e5c31af7Sopenharmony_ci	deMemset(hash->hash, 0, sizeof(hash->hash));
225e5c31af7Sopenharmony_ci
226e5c31af7Sopenharmony_ci	for (charNdx = 0; charNdx < 40; charNdx++)
227e5c31af7Sopenharmony_ci	{
228e5c31af7Sopenharmony_ci		deUint8 val4;
229e5c31af7Sopenharmony_ci
230e5c31af7Sopenharmony_ci		if (buffer[charNdx] >= '0' && buffer[charNdx] <= '9')
231e5c31af7Sopenharmony_ci			val4 = (deUint8)(buffer[charNdx] - '0');
232e5c31af7Sopenharmony_ci		else if (buffer[charNdx] >= 'a' && buffer[charNdx] <= 'f')
233e5c31af7Sopenharmony_ci			val4 = (deUint8)(10 + (buffer[charNdx] - 'a'));
234e5c31af7Sopenharmony_ci		else if (buffer[charNdx] >= 'A' && buffer[charNdx] <= 'F')
235e5c31af7Sopenharmony_ci			val4 = (deUint8)(10 + (buffer[charNdx] - 'A'));
236e5c31af7Sopenharmony_ci		else
237e5c31af7Sopenharmony_ci			return DE_FALSE;
238e5c31af7Sopenharmony_ci
239e5c31af7Sopenharmony_ci		hash->hash[charNdx / 8] |= ((deUint32)val4) << (4 * (8u - 1u - (charNdx % 8u)));
240e5c31af7Sopenharmony_ci	}
241e5c31af7Sopenharmony_ci
242e5c31af7Sopenharmony_ci	return DE_TRUE;
243e5c31af7Sopenharmony_ci}
244e5c31af7Sopenharmony_ci
245e5c31af7Sopenharmony_cideBool deSha1_equal (const deSha1* a, const deSha1* b)
246e5c31af7Sopenharmony_ci{
247e5c31af7Sopenharmony_ci	/* \note deMemcmp() can only be used for equality. It doesn't provide correct ordering between hashes. */
248e5c31af7Sopenharmony_ci	return deMemCmp(a->hash, b->hash, sizeof(b->hash)) == 0;
249e5c31af7Sopenharmony_ci}
250e5c31af7Sopenharmony_ci
251e5c31af7Sopenharmony_civoid deSha1_selfTest (void)
252e5c31af7Sopenharmony_ci{
253e5c31af7Sopenharmony_ci	const char* const validHashStrings[] =
254e5c31af7Sopenharmony_ci	{
255e5c31af7Sopenharmony_ci		"ac890cfca05717c05dc831996b2289251da2984e",
256e5c31af7Sopenharmony_ci		"0f87ba807acb3e6effe617249f30453a524a2ea3",
257e5c31af7Sopenharmony_ci		"6f483cc3fa820e58ed9f83c83bdf8d213293b3ad"
258e5c31af7Sopenharmony_ci	};
259e5c31af7Sopenharmony_ci
260e5c31af7Sopenharmony_ci	const char* const invalidHashStrings[] =
261e5c31af7Sopenharmony_ci	{
262e5c31af7Sopenharmony_ci		" c890cfca05717c05dc831996b2289251da2984e",
263e5c31af7Sopenharmony_ci		"0f87ba807acb3e6 ffe617249f30453a524a2ea3",
264e5c31af7Sopenharmony_ci		"6f483cc3fa820e58ed9f83c83bdf8d213293b3a ",
265e5c31af7Sopenharmony_ci
266e5c31af7Sopenharmony_ci		"mc890cfca05717c05dc831996b2289251da2984e",
267e5c31af7Sopenharmony_ci		"0f87ba807acb3e6effe617249fm0453a524a2ea3",
268e5c31af7Sopenharmony_ci		"6f483cc3fa820e58ed9f83c83bdf8d213293b3an",
269e5c31af7Sopenharmony_ci
270e5c31af7Sopenharmony_ci		"ac890cfca05717c05dc83\n996b2289251da2984e",
271e5c31af7Sopenharmony_ci		"0f87ba807acb3e6effe617\t49f30453a524a2ea3",
272e5c31af7Sopenharmony_ci		"ac890cfca05717c05dc831\096b2289251da2984e",
273e5c31af7Sopenharmony_ci		"6f483cc3fa{20e58ed9f83c83bdf8d213293b3ad"
274e5c31af7Sopenharmony_ci	};
275e5c31af7Sopenharmony_ci
276e5c31af7Sopenharmony_ci	const struct
277e5c31af7Sopenharmony_ci	{
278e5c31af7Sopenharmony_ci		const char* const hash;
279e5c31af7Sopenharmony_ci		const char* const data;
280e5c31af7Sopenharmony_ci	} stringHashPairs[] =
281e5c31af7Sopenharmony_ci	{
282e5c31af7Sopenharmony_ci		/* Generated using sha1sum. */
283e5c31af7Sopenharmony_ci		{ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "" },
284e5c31af7Sopenharmony_ci		{ "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d", "hello" },
285e5c31af7Sopenharmony_ci		{ "ec1919e856540f42bd0e6f6c1ffe2fbd73419975",
286e5c31af7Sopenharmony_ci			"Cherry is a browser-based GUI for controlling deqp test runs and analysing the test results."
287e5c31af7Sopenharmony_ci		},
288e5c31af7Sopenharmony_ci		{ "27a4485e4fe6dff5bcc1cc3093639e27c65c55c0",
289e5c31af7Sopenharmony_ci			"This message has exactly 56 characters and that's tricky"
290e5c31af7Sopenharmony_ci		}
291e5c31af7Sopenharmony_ci	};
292e5c31af7Sopenharmony_ci
293e5c31af7Sopenharmony_ci	const int garbage = 0xde;
294e5c31af7Sopenharmony_ci
295e5c31af7Sopenharmony_ci	/* Test parsing valid sha1 strings. */
296e5c31af7Sopenharmony_ci	{
297e5c31af7Sopenharmony_ci		size_t stringNdx;
298e5c31af7Sopenharmony_ci
299e5c31af7Sopenharmony_ci		for (stringNdx = 0; stringNdx < DE_LENGTH_OF_ARRAY(validHashStrings); stringNdx++)
300e5c31af7Sopenharmony_ci		{
301e5c31af7Sopenharmony_ci			deSha1 hash;
302e5c31af7Sopenharmony_ci			deMemset(&hash, garbage, sizeof(deSha1));
303e5c31af7Sopenharmony_ci			DE_TEST_ASSERT(deSha1_parse(&hash, validHashStrings[stringNdx]));
304e5c31af7Sopenharmony_ci		}
305e5c31af7Sopenharmony_ci	}
306e5c31af7Sopenharmony_ci
307e5c31af7Sopenharmony_ci	/* Test parsing invalid sha1 strings. */
308e5c31af7Sopenharmony_ci	{
309e5c31af7Sopenharmony_ci		size_t stringNdx;
310e5c31af7Sopenharmony_ci
311e5c31af7Sopenharmony_ci		for (stringNdx = 0; stringNdx < DE_LENGTH_OF_ARRAY(invalidHashStrings); stringNdx++)
312e5c31af7Sopenharmony_ci		{
313e5c31af7Sopenharmony_ci			deSha1 hash;
314e5c31af7Sopenharmony_ci			deMemset(&hash, garbage, sizeof(deSha1));
315e5c31af7Sopenharmony_ci			DE_TEST_ASSERT(!deSha1_parse(&hash, invalidHashStrings[stringNdx]));
316e5c31af7Sopenharmony_ci		}
317e5c31af7Sopenharmony_ci	}
318e5c31af7Sopenharmony_ci
319e5c31af7Sopenharmony_ci	/* Compare valid hash strings for equality. */
320e5c31af7Sopenharmony_ci	{
321e5c31af7Sopenharmony_ci		size_t stringNdx;
322e5c31af7Sopenharmony_ci
323e5c31af7Sopenharmony_ci		for (stringNdx = 0; stringNdx < DE_LENGTH_OF_ARRAY(validHashStrings); stringNdx++)
324e5c31af7Sopenharmony_ci		{
325e5c31af7Sopenharmony_ci			deSha1 hashA;
326e5c31af7Sopenharmony_ci			deSha1 hashB;
327e5c31af7Sopenharmony_ci
328e5c31af7Sopenharmony_ci			deMemset(&hashA, garbage, sizeof(deSha1));
329e5c31af7Sopenharmony_ci			deMemset(&hashB, garbage, sizeof(deSha1));
330e5c31af7Sopenharmony_ci
331e5c31af7Sopenharmony_ci			DE_TEST_ASSERT(deSha1_parse(&hashA, validHashStrings[stringNdx]));
332e5c31af7Sopenharmony_ci			DE_TEST_ASSERT(deSha1_parse(&hashB, validHashStrings[stringNdx]));
333e5c31af7Sopenharmony_ci
334e5c31af7Sopenharmony_ci			DE_TEST_ASSERT(deSha1_equal(&hashA, &hashA));
335e5c31af7Sopenharmony_ci			DE_TEST_ASSERT(deSha1_equal(&hashA, &hashB));
336e5c31af7Sopenharmony_ci			DE_TEST_ASSERT(deSha1_equal(&hashB, &hashA));
337e5c31af7Sopenharmony_ci		}
338e5c31af7Sopenharmony_ci	}
339e5c31af7Sopenharmony_ci
340e5c31af7Sopenharmony_ci	/* Compare valid different hash strings for equality. */
341e5c31af7Sopenharmony_ci	{
342e5c31af7Sopenharmony_ci		size_t stringANdx;
343e5c31af7Sopenharmony_ci		size_t stringBNdx;
344e5c31af7Sopenharmony_ci
345e5c31af7Sopenharmony_ci		for (stringANdx = 0; stringANdx < DE_LENGTH_OF_ARRAY(validHashStrings); stringANdx++)
346e5c31af7Sopenharmony_ci		for (stringBNdx = 0; stringBNdx < DE_LENGTH_OF_ARRAY(validHashStrings); stringBNdx++)
347e5c31af7Sopenharmony_ci		{
348e5c31af7Sopenharmony_ci			deSha1 hashA;
349e5c31af7Sopenharmony_ci			deSha1 hashB;
350e5c31af7Sopenharmony_ci
351e5c31af7Sopenharmony_ci			if (stringANdx == stringBNdx)
352e5c31af7Sopenharmony_ci				continue;
353e5c31af7Sopenharmony_ci
354e5c31af7Sopenharmony_ci			deMemset(&hashA, garbage, sizeof(deSha1));
355e5c31af7Sopenharmony_ci			deMemset(&hashB, garbage, sizeof(deSha1));
356e5c31af7Sopenharmony_ci
357e5c31af7Sopenharmony_ci			DE_TEST_ASSERT(deSha1_parse(&hashA, validHashStrings[stringANdx]));
358e5c31af7Sopenharmony_ci			DE_TEST_ASSERT(deSha1_parse(&hashB, validHashStrings[stringBNdx]));
359e5c31af7Sopenharmony_ci
360e5c31af7Sopenharmony_ci			DE_TEST_ASSERT(!deSha1_equal(&hashA, &hashB));
361e5c31af7Sopenharmony_ci			DE_TEST_ASSERT(!deSha1_equal(&hashB, &hashA));
362e5c31af7Sopenharmony_ci		}
363e5c31af7Sopenharmony_ci	}
364e5c31af7Sopenharmony_ci
365e5c31af7Sopenharmony_ci	/* Test rendering hash as string. */
366e5c31af7Sopenharmony_ci	{
367e5c31af7Sopenharmony_ci		size_t stringNdx;
368e5c31af7Sopenharmony_ci
369e5c31af7Sopenharmony_ci		for (stringNdx = 0; stringNdx < DE_LENGTH_OF_ARRAY(validHashStrings); stringNdx++)
370e5c31af7Sopenharmony_ci		{
371e5c31af7Sopenharmony_ci			char	result[40];
372e5c31af7Sopenharmony_ci			deSha1	hash;
373e5c31af7Sopenharmony_ci
374e5c31af7Sopenharmony_ci			deMemset(&hash, garbage, sizeof(hash));
375e5c31af7Sopenharmony_ci			deMemset(&result, garbage, sizeof(result));
376e5c31af7Sopenharmony_ci
377e5c31af7Sopenharmony_ci			DE_TEST_ASSERT(deSha1_parse(&hash, validHashStrings[stringNdx]));
378e5c31af7Sopenharmony_ci			deSha1_render(&hash, result);
379e5c31af7Sopenharmony_ci
380e5c31af7Sopenharmony_ci			DE_TEST_ASSERT(strncmp(result, validHashStrings[stringNdx], 40) == 0);
381e5c31af7Sopenharmony_ci		}
382e5c31af7Sopenharmony_ci	}
383e5c31af7Sopenharmony_ci
384e5c31af7Sopenharmony_ci	/* Test hash against few pre-computed cases. */
385e5c31af7Sopenharmony_ci	{
386e5c31af7Sopenharmony_ci		size_t ndx;
387e5c31af7Sopenharmony_ci
388e5c31af7Sopenharmony_ci		for (ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stringHashPairs); ndx++)
389e5c31af7Sopenharmony_ci		{
390e5c31af7Sopenharmony_ci			deSha1 result;
391e5c31af7Sopenharmony_ci			deSha1 reference;
392e5c31af7Sopenharmony_ci
393e5c31af7Sopenharmony_ci			deSha1_compute(&result, strlen(stringHashPairs[ndx].data),  stringHashPairs[ndx].data);
394e5c31af7Sopenharmony_ci			DE_TEST_ASSERT(deSha1_parse(&reference, stringHashPairs[ndx].hash));
395e5c31af7Sopenharmony_ci
396e5c31af7Sopenharmony_ci			DE_TEST_ASSERT(deSha1_equal(&reference, &result));
397e5c31af7Sopenharmony_ci		}
398e5c31af7Sopenharmony_ci	}
399e5c31af7Sopenharmony_ci
400e5c31af7Sopenharmony_ci	/* Test hash stream against few pre-computed cases. */
401e5c31af7Sopenharmony_ci	{
402e5c31af7Sopenharmony_ci		size_t ndx;
403e5c31af7Sopenharmony_ci
404e5c31af7Sopenharmony_ci		for (ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stringHashPairs); ndx++)
405e5c31af7Sopenharmony_ci		{
406e5c31af7Sopenharmony_ci			const char* const	data	= stringHashPairs[ndx].data;
407e5c31af7Sopenharmony_ci			const size_t		size	= strlen(data);
408e5c31af7Sopenharmony_ci
409e5c31af7Sopenharmony_ci			deSha1Stream		stream;
410e5c31af7Sopenharmony_ci			deSha1				result;
411e5c31af7Sopenharmony_ci			deSha1				reference;
412e5c31af7Sopenharmony_ci
413e5c31af7Sopenharmony_ci			deSha1Stream_init(&stream);
414e5c31af7Sopenharmony_ci
415e5c31af7Sopenharmony_ci			deSha1Stream_process(&stream, size/2, data);
416e5c31af7Sopenharmony_ci			deSha1Stream_process(&stream, size - (size/2), data + size/2);
417e5c31af7Sopenharmony_ci
418e5c31af7Sopenharmony_ci			deSha1Stream_finalize(&stream, &result);
419e5c31af7Sopenharmony_ci
420e5c31af7Sopenharmony_ci			deSha1_compute(&result, strlen(stringHashPairs[ndx].data),  stringHashPairs[ndx].data);
421e5c31af7Sopenharmony_ci			DE_TEST_ASSERT(deSha1_parse(&reference, stringHashPairs[ndx].hash));
422e5c31af7Sopenharmony_ci
423e5c31af7Sopenharmony_ci			DE_TEST_ASSERT(deSha1_equal(&reference, &result));
424e5c31af7Sopenharmony_ci		}
425e5c31af7Sopenharmony_ci	}
426e5c31af7Sopenharmony_ci}
427e5c31af7Sopenharmony_ci
428e5c31af7Sopenharmony_ciDE_END_EXTERN_C
429