agievich / bee2
1
/*
2
*******************************************************************************
3
\file bash_hash.c
4
\brief STB 34.101.77 (bash): hashing algorithms
5
\project bee2 [cryptographic library]
6
\author (C) Sergey Agievich [agievich@{bsu.by|gmail.com}]
7
\author (C) Vlad Semenov [semenov.vlad.by@gmail.com]
8
\created 2014.07.15
9
\version 2019.07.09
10
\license This program is released under the GNU General Public License 
11
version 3. See Copyright Notices in bee2/info.h.
12
*******************************************************************************
13
*/
14

15
#include "bee2/core/blob.h"
16
#include "bee2/core/err.h"
17
#include "bee2/core/mem.h"
18
#include "bee2/core/u64.h"
19
#include "bee2/core/util.h"
20
#include "bee2/crypto/bash.h"
21

22
/*
23
*******************************************************************************
24
Хэширование
25
*******************************************************************************
26
*/
27

28
typedef struct {
29
	octet s[192];		/*< состояние */
30
	octet s1[192];		/*< копия s */
31
	size_t block_len;	/*< длина блока */
32
	size_t filled;		/*< накоплено октетов в блоке */
33
	octet stack[];		/*< [[bashF_deep()] стек bashF */
34
} bash_hash_st;
35

36 1
size_t bashHash_keep()
37
{
38 1
	return sizeof(bash_hash_st) + bashF_deep();
39
}
40

41 1
void bashHashStart(void* state, size_t l)
42
{
43 1
	bash_hash_st* s = (bash_hash_st*)state;
44 1
	ASSERT(l > 0 && l % 16 == 0 && l <= 256);
45 1
	ASSERT(memIsValid(s, bashHash_keep()));
46
	// s <- 0^{1536 - 64} || <l / 4>_{64}
47 1
	memSetZero(s->s, sizeof(s->s));
48 1
	s->s[192 - 8] = (octet)(l / 4);
49
	// длина блока
50 1
	s->block_len = 192 - l / 2;
51
	// нет накопленнных данных
52 1
	s->filled = 0;
53
}
54

55 1
void bashHashStepH(const void* buf, size_t count, void* state)
56
{
57 1
	bash_hash_st* s = (bash_hash_st*)state;
58 1
	ASSERT(memIsDisjoint2(buf, count, s, bashHash_keep()));
59
	// есть накопленные данные?
60 1
	if (s->filled)
61
	{
62 1
		if (count < s->block_len - s->filled)
63
		{
64 0
			memCopy(s->s + s->filled, buf, count);
65 0
			s->filled += count;
66 0
			return;
67
		}
68 1
		memCopy(s->s + s->filled, buf, s->block_len - s->filled);
69 1
		count -= s->block_len - s->filled;
70 1
		buf = (const octet*)buf + s->block_len - s->filled;
71 1
		bashF(s->s, s->stack);
72 1
		s->filled = 0;
73
	}
74
	// цикл по полным блокам
75 1
	while (count >= s->block_len)
76
	{
77 1
		memCopy(s->s, buf, s->block_len);
78 1
		bashF(s->s, s->stack);
79 1
		buf = (const octet*)buf + s->block_len;
80 1
		count -= s->block_len;
81
	}
82
	// неполный блок?
83 1
	if (count)
84 1
		memCopy(s->s, buf, s->filled = count);
85
}
86

87 1
static void bashHashStepG_internal(size_t hash_len, void* state)
88
{
89 1
	bash_hash_st* s = (bash_hash_st*)state;
90
	// pre
91 1
	ASSERT(memIsValid(s, bashHash_keep()));
92 1
	ASSERT(s->block_len + hash_len * 2 <= 192);
93
	// создать копию s->s
94 1
	memCopy(s->s1, s->s, sizeof(s->s));
95
	// есть необработанные данные?
96 1
	if (s->filled)
97
	{
98 1
		memSetZero(s->s1 + s->filled, s->block_len - s->filled);
99 1
		s->s1[s->filled] = 0x40;
100
	}
101
	// дополнительный блок
102
	else
103
	{
104 1
		memSetZero(s->s1, s->block_len);
105 1
		s->s1[0] = 0x40;
106
	}
107
	// последний шаг
108 1
	bashF(s->s1, s->stack);
109
}
110

111 1
void bashHashStepG(octet hash[], size_t hash_len, void* state)
112
{
113 1
	bash_hash_st* s = (bash_hash_st*)state;
114 1
	bashHashStepG_internal(hash_len, state);
115 1
	memMove(hash, s->s1, hash_len);
116
}
117

118 0
bool_t bashHashStepV(const octet hash[], size_t hash_len, void* state)
119
{
120 0
	bash_hash_st* s = (bash_hash_st*)state;
121 0
	bashHashStepG_internal(hash_len, state);
122 0
	return memEq(hash, s->s1, hash_len);
123
}
124

125 1
err_t bashHash(octet hash[], size_t l, const void* src, size_t count)
126
{
127
	void* state;
128
	// проверить входные данные
129 1
	if (l == 0 || l % 16 != 0 || l > 256)
130 0
		return ERR_BAD_PARAMS;
131 1
	if (!memIsValid(src, count) || !memIsValid(hash, l / 4))
132 0
		return ERR_BAD_INPUT;
133
	// создать состояние
134 1
	state = blobCreate(bashHash_keep());
135 1
	if (state == 0)
136 0
		return ERR_OUTOFMEMORY;
137
	// вычислить хэш-значение
138 1
	bashHashStart(state, l);
139 1
	bashHashStepH(src, count, state);
140 1
	bashHashStepG(hash, l / 4, state);
141
	// завершить
142 1
	blobClose(state);
143 1
	return ERR_OK;
144
}

Read our documentation on viewing source code .

Loading