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 2020.06.23
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 buf_len;		/*< длина буфера */
32
	size_t pos;		/*< позиция в буфере (накоплено октетов) */
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* st = (bash_hash_st*)state;
44 1
	ASSERT(l > 0 && l % 16 == 0 && l <= 256);
45 1
	ASSERT(memIsValid(st, bashHash_keep()));
46
	// s <- 0^{1536 - 64} || <l / 4>_{64}
47 1
	memSetZero(st->s, sizeof(st->s));
48 1
	st->s[192 - 8] = (octet)(l / 4);
49
	// длина блока
50 1
	st->buf_len = 192 - l / 2;
51
	// нет накопленнных октетов
52 1
	st->pos = 0;
53
}
54

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

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

107 1
void bashHashStepG(octet hash[], size_t hash_len, void* state)
108
{
109 1
	bash_hash_st* st = (bash_hash_st*)state;
110 1
	bashHashStepG_internal(hash_len, state);
111 1
	memMove(hash, st->s1, hash_len);
112
}
113

114 0
bool_t bashHashStepV(const octet hash[], size_t hash_len, void* state)
115
{
116 0
	bash_hash_st* st = (bash_hash_st*)state;
117 0
	bashHashStepG_internal(hash_len, state);
118 0
	return memEq(hash, st->s1, hash_len);
119
}
120

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

Read our documentation on viewing source code .

Loading