Пример #1
0
bool_t pfokTestStdParams()
{
	pfok_params params[1];
	pfok_params params1[1];
	pfok_seed seed[1];
	// тест PFOK.GENP.1
	if (pfokStdParams(params, seed, "test") != ERR_OK ||
		pfokGenParams(params1, seed, _on_q) != ERR_OK ||
		pfokValParams(params1) != ERR_OK ||
		!memEq(params->p, params1->p, O_OF_B(params->l)) ||
		params->l != params1->l || params->r != params1->r)
		return FALSE;
	// тест PFOK.GENP.2
	if (pfokStdParams(params, seed, "1.2.112.0.2.0.1176.2.3.3.2") != ERR_OK ||
		pfokValParams(params1) != ERR_OK ||
		pfokGenParams(params1, seed, _on_q) != ERR_OK ||
		!memEq(params->p, params1->p, O_OF_B(params->l)) ||
		params->l != params1->l || params->r != params1->r)
		return FALSE;
	// тест PFOK.GENP.3
	if (pfokStdParams(params, seed, "1.2.112.0.2.0.1176.2.3.6.2") != ERR_OK ||
		pfokGenParams(params1, seed, _on_q) != ERR_OK ||
		!memEq(params->p, params1->p, O_OF_B(params->l)) ||
		params->l != params1->l || params->r != params1->r)
		return FALSE;
	// тест PFOK.GENP.4
	if (pfokStdParams(params, seed, "1.2.112.0.2.0.1176.2.3.10.2") != ERR_OK ||
		pfokGenParams(params1, seed, _on_q) != ERR_OK ||
		!memEq(params->p, params1->p, O_OF_B(params->l)) ||
		params->l != params1->l || params->r != params1->r)
		return FALSE;
	// все нормально
	return TRUE;
}
Пример #2
0
static err_t beePrintBuildInfo(blob_t* str)
{
	// прочитать контрольную характеристику
	octet stampRead[STAMP_SIZE], stampCalc[STAMP_SIZE];
	err_t code = beeReadAndCalcStamp(stampRead, stampCalc);
	octet stamp[2 * STAMP_SIZE + STAMP_SIZE * 4 / 16 + 1], pos, *ptr;
	// ошибка чтения?
	if (code != ERR_OK)
		return beeSprintf(str, 
			"Platform: Win%d\r\n"
			"Version: %s\r\n"
			"Stamp: read error", 
			sizeof(size_t) == 4 ? 32 : 64, 
			BEE2_VERSION);
	// напечатать контрольную характеристику
	for (pos = 0, ptr = stamp; pos < STAMP_SIZE; ++pos)
	{
		if (pos % 16 == 0)
			*ptr++ = '\r', *ptr++ = '\n', *ptr++ = ' ', *ptr++ = ' ';
		sprintf(ptr, "%02X", (unsigned)stampRead[pos]);
		++ptr, ++ptr;
	}
	return beeSprintf(str, 
		"Platform: Win%d\r\n"
		"Version: %s\r\n"
		"Stamp: %s [%s]", 
		sizeof(size_t) == 4 ? 32 : 64,
		BEE2_VERSION, 
		stamp, 
		memEq(stampRead, stampCalc, STAMP_SIZE) ? "OK" : "error");
}
Пример #3
0
static err_t beeSelfCheck()
{
	// характеристики
	octet stampRead[STAMP_SIZE], stampCalc[STAMP_SIZE];
	err_t code = beeReadAndCalcStamp(stampRead, stampCalc);
	ERR_CALL_CHECK(code);
	// сравнить
	return memEq(stampRead, stampCalc, STAMP_SIZE) ? ERR_OK : ERR_BAD_HASH;
}
Пример #4
0
static err_t fileWrite(size_t* written, const void* buf, size_t count,
	void* file)
{
	file_st* f = (file_st*)file;
	u16 len;
	// pre
	ASSERT(memIsValid(f, sizeof(file_st)));
	ASSERT(memIsValid(buf, count));
	ASSERT(memIsValid(written, sizeof(size_t)));
	// конец файла?
	// запись не с начала пакета?
	// отличаются длины пакета и сообщения?
	// отличается содержимое?
	if (f->frame == 0 ||
		f->frame_offset != 0 ||
		f->frame_len != count ||
		!memEq(f->frame, buf, count))
		return ERR_FILE_WRITE;
	// к следующему пакету
	f->frame += f->frame_len;
	if (f->frame + 2 >= f->data + f->data_len)
	{
		f->frame = 0;
		f->frame_len = f->frame_offset = 0;
	}
	else
	{
		u16From(&len, f->frame, 2);
		f->frame_len = (size_t)len;
		f->frame += 2;
		f->frame_offset = 0;
		// выход за границы?
		if (f->frame + f->frame_len > f->data + f->data_len)
			return ERR_BAD_FORMAT;
	}
	// все нормально
	*written = count;
	return ERR_OK;
}
Пример #5
0
bool_t beltTest()
{
	octet buf[48];
	octet buf1[48];
	octet mac[8];
	octet mac1[8];
	octet hash[32];
	octet hash1[32];
	u32 key[8];
	octet level[12];
	octet state[1024];
	// создать стек
	ASSERT(sizeof(state) >= beltECB_keep());
	ASSERT(sizeof(state) >= beltCBC_keep());
	ASSERT(sizeof(state) >= beltCFB_keep());
	ASSERT(sizeof(state) >= beltCTR_keep());
	ASSERT(sizeof(state) >= beltMAC_keep());
	ASSERT(sizeof(state) >= beltDWP_keep());
	ASSERT(sizeof(state) >= beltKWP_keep());
	ASSERT(sizeof(state) >= beltHash_keep());
	ASSERT(sizeof(state) >= beltKRP_keep());
	ASSERT(sizeof(state) >= beltHMAC_keep());
	// тест A.1
	memCopy(buf, beltH(), 16);
	beltKeyExpand2(key, beltH() + 128, 32);
	beltBlockEncr(buf, key);
	if (!hexEq(buf,
		"69CCA1C93557C9E3D66BC3E0FA88FA6E"))
		return FALSE;
	// тест A.4
	memCopy(buf, beltH() + 64, 16);
	beltKeyExpand2(key, beltH() + 128 + 32, 32);
	beltBlockDecr(buf, key);
	if (!hexEq(buf,
		"0DC5300600CAB840B38448E5E993F421"))
		return FALSE;
	// тест A.6
	memCopy(buf, beltH(), 48);
	beltECBStart(state, beltH() + 128, 32);
	beltECBStepE(buf, 32, state);
	beltECBStepE(buf + 32, 48 - 32, state);
	if (!hexEq(buf,
		"69CCA1C93557C9E3D66BC3E0FA88FA6E"
		"5F23102EF109710775017F73806DA9DC"
		"46FB2ED2CE771F26DCB5E5D1569F9AB0"))
		return FALSE;
	beltECBEncr(buf1, beltH(), 48, beltH() + 128, 32);
	if (!memEq(buf, buf1, 48))
		return FALSE;
	// тест A.7
	memCopy(buf, beltH(), 47);
	beltECBStart(state, beltH() + 128, 32);
	beltECBStepE(buf, 16, state);
	beltECBStepE(buf + 16, 47 - 16, state);
	if (!hexEq(buf,
		"69CCA1C93557C9E3D66BC3E0FA88FA"
		"6E36F00CFED6D1CA1498C12798F4BE"
		"B2075F23102EF109710775017F7380"
		"6DA9"))
		return FALSE;
	beltECBEncr(buf1, beltH(), 47, beltH() + 128, 32);
	if (!memEq(buf, buf1, 47))
		return FALSE;
	// тест A.8
	memCopy(buf, beltH() + 64, 48);
	beltECBStart(state, beltH() + 128 + 32, 32);
	beltECBStepD(buf, 16, state);
	beltECBStepD(buf + 16, 48 - 16, state);
	if (!hexEq(buf,
		"0DC5300600CAB840B38448E5E993F421"
		"E55A239F2AB5C5D5FDB6E81B40938E2A"
		"54120CA3E6E19C7AD750FC3531DAEAB7"))
		return FALSE;
	beltECBDecr(buf1, beltH() + 64, 48, beltH() + 128 + 32, 32);
	if (!memEq(buf, buf1, 48))
		return FALSE;
	// тест A.9
	memCopy(buf, beltH() + 64, 36);
	beltECBStart(state, beltH() + 128 + 32, 32);
	beltECBStepD(buf, 36, state);
	if (!hexEq(buf,
		"0DC5300600CAB840B38448E5E993F421"
		"5780A6E2B69EAFBB258726D7B6718523"
		"E55A239F"))
		return FALSE;
	beltECBDecr(buf1, beltH() + 64, 36, beltH() + 128 + 32, 32);
	if (!memEq(buf, buf1, 36))
		return FALSE;
	// тест A.10
	memCopy(buf, beltH(), 48);
	beltCBCStart(state, beltH() + 128, 32, beltH() + 192);
	beltCBCStepE(buf, 32, state);
	beltCBCStepE(buf + 32, 48 - 32, state);
	if (!hexEq(buf,
		"10116EFAE6AD58EE14852E11DA1B8A74"
		"5CF2480E8D03F1C19492E53ED3A70F60"
		"657C1EE8C0E0AE5B58388BF8A68E3309"))
		return FALSE;
	beltCBCEncr(buf1, beltH(), 48, beltH() + 128, 32, beltH() + 192);
	if (!memEq(buf, buf1, 48))
		return FALSE;
	// тест A.11
	memCopy(buf, beltH(), 36);
	beltCBCStart(state, beltH() + 128, 32, beltH() + 192);
	beltCBCStepE(buf, 16, state);
	beltCBCStepE(buf + 16, 36 - 16, state);
	if (!hexEq(buf,
		"10116EFAE6AD58EE14852E11DA1B8A74"
		"6A9BBADCAF73F968F875DEDC0A44F6B1"
		"5CF2480E"))
		return FALSE;
	beltCBCEncr(buf1, beltH(), 36, beltH() + 128, 32, beltH() + 192);
	if (!memEq(buf, buf1, 36))
		return FALSE;
	// тест A.12
	memCopy(buf, beltH() + 64, 48);
	beltCBCStart(state, beltH() + 128 + 32, 32, beltH() + 192 + 16);
	beltCBCStepD(buf, 16, state);
	beltCBCStepD(buf + 16, 48 - 16, state);
	if (!hexEq(buf,
		"730894D6158E17CC1600185A8F411CAB"
		"0471FF85C83792398D8924EBD57D03DB"
		"95B97A9B7907E4B020960455E46176F8"))
		return FALSE;
	beltCBCDecr(buf1, beltH() + 64, 48, beltH() + 128 + 32, 32,
		beltH() + 192 + 16);
	if (!memEq(buf, buf1, 48))
		return FALSE;
	// тест A.13
	memCopy(buf, beltH() + 64, 36);
	beltCBCStart(state, beltH() + 128 + 32, 32, beltH() + 192 + 16);
	beltCBCStepD(buf, 16, state);
	beltCBCStepD(buf + 16, 36 - 16, state);
	if (!hexEq(buf,
		"730894D6158E17CC1600185A8F411CAB"
		"B6AB7AF8541CF85755B8EA27239F08D2"
		"166646E4"))
		return FALSE;
	beltCBCDecr(buf1, beltH() + 64, 36, beltH() + 128 + 32, 32,
		beltH() + 192 + 16);
	if (!memEq(buf, buf1, 36))
		return FALSE;
	// тест A.14
	memCopy(buf, beltH(), 48);
	beltCFBStart(state, beltH() + 128, 32, beltH() + 192);
	beltCFBStepE(buf, 16, state);
	beltCFBStepE(buf + 16, 3, state);
	beltCFBStepE(buf + 16 + 3, 48 - 16 - 3, state);
	if (!hexEq(buf,
		"C31E490A90EFA374626CC99E4B7B8540"
		"A6E48685464A5A06849C9CA769A1B0AE"
		"55C2CC5939303EC832DD2FE16C8E5A1B"))
		return FALSE;
	beltCFBEncr(buf1, beltH(), 48, beltH() + 128, 32, beltH() + 192);
	if (!memEq(buf, buf1, 48))
		return FALSE;
	// тест A.15
	memCopy(buf, beltH() + 64, 48);
	beltCFBStart(state, beltH() + 128 + 32, 32, beltH() + 192 + 16);
	beltCFBStepD(buf, 15, state);
	beltCFBStepD(buf + 15, 7, state);
	beltCFBStepD(buf + 15 + 7, 48 - 15 - 7, state);
	if (!hexEq(buf,
		"FA9D107A86F375EE65CD1DB881224BD0"
		"16AFF814938ED39B3361ABB0BF0851B6"
		"52244EB06842DD4C94AA4500774E40BB"))
		return FALSE;
	beltCFBDecr(buf1, beltH() + 64, 48, beltH() + 128 + 32, 32,
		beltH() + 192 + 16);
	if (!memEq(buf, buf1, 48))
		return FALSE;
	// тест A.16
	memCopy(buf, beltH(), 48);
	beltCTRStart(state, beltH() + 128, 32, beltH() + 192);
	beltCTRStepE(buf, 15, state);
	beltCTRStepE(buf + 15, 7, state);
	beltCTRStepE(buf + 15 + 7, 48 - 15 - 7, state);
	if (!hexEq(buf,
		"52C9AF96FF50F64435FC43DEF56BD797"
		"D5B5B1FF79FB41257AB9CDF6E63E81F8"
		"F00341473EAE409833622DE05213773A"))
		return FALSE;
	beltCTR(buf1, beltH(), 48, beltH() + 128, 32, beltH() + 192);
	if (!memEq(buf, buf1, 48))
		return FALSE;
	// тест A.17
	beltMACStart(state, beltH() + 128, 32);
	beltMACStepA(beltH(), 13, state);
	hexTo(buf, "7260DA60138F96C9");
	if (!beltMACStepV(buf, state))
		return FALSE;
	beltMAC(buf1, beltH(), 13, beltH() + 128, 32);
	if (!memEq(buf, buf1, 8))
		return FALSE;
	// тест A.18 [+ инкрементальность]
	beltMACStart(state, beltH() + 128, 32);
	beltMACStepA(beltH(), 27, state);
	beltMACStepG(buf, state);
	beltMACStepA(beltH() + 27, 48 - 27, state);
	beltMACStepG2(buf, 4, state);
	hexTo(buf, "2DAB59771B4B16D0");
	if (!beltMACStepV(buf, state) || !beltMACStepV2(buf, 3, state))
		return FALSE;
	beltMAC(buf1, beltH(), 48, beltH() + 128, 32);
	if (!memEq(buf, buf1, 8))
		return FALSE;
	// тест A.20
	beltDWPStart(state, beltH() + 128, 32, beltH() + 192);
	memCopy(buf, beltH(), 16);
	beltDWPStepE(buf, 16, state);
	beltDWPStepI(beltH() + 16, 32, state);
	beltDWPStepA(buf, 16, state);
	beltDWPStepG(mac, state);
	if (!hexEq(buf, 
		"52C9AF96FF50F64435FC43DEF56BD797"))
		return FALSE;
	if (!hexEq(mac, 
		"3B2E0AEB2B91854B"))
		return FALSE;
	beltDWPWrap(buf1, mac1, beltH(), 16, beltH() + 16, 32,
		beltH() + 128, 32, beltH() + 192);
	if (!memEq(buf, buf1, 16) || !memEq(mac, mac1, 8))
		return FALSE;
	// тест A.21
	beltDWPStart(state, beltH() + 128 + 32, 32, beltH() + 192 + 16);
	memCopy(buf, beltH() + 64, 16);
	beltDWPStepI(beltH() + 64 + 16, 32, state);
	beltDWPStepA(buf, 16, state);
	beltDWPStepD(buf, 16, state);
	beltDWPStepG(mac, state);
	if (!hexEq(buf, 
		"DF181ED008A20F43DCBBB93650DAD34B"))
		return FALSE;
	if (!hexEq(mac, 
		"6A2C2C94C4150DC0"))
		return FALSE;
	if (beltDWPUnwrap(buf1, beltH() + 64, 16, beltH() + 64 + 16, 32,
		mac, beltH() + 128 + 32, 32, beltH() + 192 + 16) != ERR_OK ||
		!memEq(buf, buf1, 16))
		return FALSE;
	// тест A.22
	beltKWPStart(state, beltH() + 128, 32);
	memCopy(buf, beltH(), 32);
	memCopy(buf + 32, beltH() + 32, 16);
	beltKWPStepE(buf, 48, state);
	if (!hexEq(buf,
		"49A38EE108D6C742E52B774F00A6EF98"
		"B106CBD13EA4FB0680323051BC04DF76"
		"E487B055C69BCF541176169F1DC9F6C8"))
		return FALSE;
	beltKWPWrap(buf1, beltH(), 32, beltH() + 32, beltH() + 128, 32);
	if (!memEq(buf, buf1, 48))
		return FALSE;
	// тест A.23
	beltKWPStart(state, beltH() + 128 + 32, 32);
	memCopy(buf, beltH() + 64, 48);
	beltKWPStepD(buf, 48, state);
	if (!hexEq(buf,
		"92632EE0C21AD9E09A39343E5C07DAA4"
		"889B03F2E6847EB152EC99F7A4D9F154"))
		return FALSE;
	if (!hexEq(buf + 32, 
		"B5EF68D8E4A39E567153DE13D72254EE"))
		return FALSE;
	if (beltKWPUnwrap(buf1, beltH() + 64, 48, (octet*)buf + 32,
		beltH() + 128 + 32, 32) != ERR_OK ||
		!memEq(buf, buf1, 32))
		return FALSE;
	// тест A.24
	beltHashStart(state);
	beltHashStepH(beltH(), 13, state);
	beltHashStepG(hash, state);
	if (!hexEq(hash,
		"ABEF9725D4C5A83597A367D14494CC25"
		"42F20F659DDFECC961A3EC550CBA8C75"))
		return FALSE;
	beltHash(hash1, beltH(), 13);
	if (!memEq(hash, hash1, 32))
		return FALSE;
	// тест A.25
	beltHashStart(state);
	beltHashStepH(beltH(), 32, state);
	hexTo(hash, 
		"749E4C3653AECE5E48DB4761227742EB"
		"6DBE13F4A80F7BEFF1A9CF8D10EE7786");
	if (!beltHashStepV(hash, state) || !beltHashStepV2(hash, 13, state))
		return FALSE;
	beltHash(hash1, beltH(), 32);
	if (!memEq(hash, hash1, 32))
		return FALSE;
	// тест A.26 [+ инкрементальность]
	beltHashStart(state);
	beltHashStepH(beltH(), 11, state);
	beltHashStepG2(hash, 32, state);
	beltHashStepH(beltH() + 11, 48 - 11, state);
	hexTo(hash, 
		"9D02EE446FB6A29FE5C982D4B13AF9D3"
		"E90861BC4CEF27CF306BFB0B174A154A");
	if (!beltHashStepV2(hash, 32, state))
		return FALSE;
	beltHash(hash1, beltH(), 48);
	if (!memEq(hash, hash1, 32))
		return FALSE;
	// тест A.29
	memSetZero(level, 12);
	level[0] = 1;
	beltKRPStart(state, beltH() + 128, 32, level);
	beltKRPStepG(buf, 16, beltH() + 32, state);
	if (!hexEq(buf, 
		"6BBBC2336670D31AB83DAA90D52C0541"))
		return FALSE;
	beltKRP(buf1, 16, beltH() + 128, 32, level, beltH() + 32);
	if (!memEq(buf, buf1, 16))
		return FALSE;
	// тест A.30
	beltKRPStepG(buf, 24, beltH() + 32, state);
	if (!hexEq(buf,
		"9A2532A18CBAF145398D5A95FEEA6C82"
		"5B9C197156A00275"))
		return FALSE;
	beltKRP(buf1, 24, beltH() + 128, 32, level, beltH() + 32);
	if (!memEq(buf, buf1, 24))
		return FALSE;
	// тест A.31
	beltKRPStepG(buf, 32, beltH() + 32, state);
	if (!hexEq(buf,
		"76E166E6AB21256B6739397B672B8796"
		"14B81CF05955FC3AB09343A745C48F77"))
		return FALSE;
	beltKRP(buf1, 32, beltH() + 128, 32, level, beltH() + 32);
	if (!memEq(buf, buf1, 32))
		return FALSE;
	// тест Б.1-1
	beltHMACStart(state, beltH() + 128, 29);
	beltHMACStepA(beltH() + 128 + 64, 32, state);
	beltHMACStepG(hash, state);
	if (!hexEq(hash,
		"D4828E6312B08BB83C9FA6535A463554"
		"9E411FD11C0D8289359A1130E930676B"))
		return FALSE;
	beltHMAC(hash1, beltH() + 128 + 64, 32, beltH() + 128, 29);
	if (!memEq(hash, hash1, 32))
		return FALSE;
	// тест Б.1-2
	beltHMACStart(state, beltH() + 128, 32);
	beltHMACStepA(beltH() + 128 + 64, 32, state);
	hexTo(hash, 
		"41FFE8645AEC0612E952D2CDF8DD508F"
		"3E4A1D9B53F6A1DB293B19FE76B1879F");
	if (!beltHMACStepV(hash, state))
		return FALSE;
	beltHMAC(hash1, beltH() + 128 + 64, 32, beltH() + 128, 32);
	if (!memEq(hash, hash1, 32))
		return FALSE;
	// тест Б.1-3 [+ икрементальность]
	beltHMACStart(state, beltH() + 128, 42);
	beltHMACStepA(beltH() + 128 + 64, 17, state);
	beltHMACStepG(hash, state);
	beltHMACStepG2(hash, 17, state);
	beltHMACStepA(beltH() + 128 + 64 + 17, 32 - 17, state);
	hexTo(hash, 
		"7D01B84D2315C332277B3653D7EC6470"
		"7EBA7CDFF7FF70077B1DECBD68F2A144");
	if (!beltHMACStepV(hash, state) || !beltHMACStepV2(hash, 23, state))
		return FALSE;
	beltHMAC(hash1, beltH() + 128 + 64, 32, beltH() + 128, 42);
	if (!memEq(hash, hash1, 32))
		return FALSE;
	// все нормально
	return TRUE;
}
Пример #6
0
bool_t pfokTest()
{
	pfok_params params[1];
	octet combo_state[128];
	octet ua[O_OF_B(130)];
	octet xa[O_OF_B(130)];
	octet vb[O_OF_B(638)];
	octet yb[O_OF_B(638)];
	octet key[32];
	// тест PFOK.GENG.1
	if (pfokStdParams(params, 0, "test") != ERR_OK ||
		pfokValParams(params) != ERR_OK ||
		(params->g[0] += 2) == 0 ||
		pfokValParams(params) == ERR_OK)
		return FALSE;
	// тест PFOK.GENG.2
	if (pfokStdParams(params, 0, "1.2.112.0.2.0.1176.2.3.3.2") != ERR_OK ||
		pfokValParams(params) != ERR_OK ||
		(params->g[0] += 3) == 0 ||
		pfokValParams(params) == ERR_OK)
		return FALSE;
	// тест PFOK.GENG.3
	if (pfokStdParams(params, 0, "1.2.112.0.2.0.1176.2.3.6.2") != ERR_OK ||
		pfokValParams(params) != ERR_OK ||
		(params->g[0] += 1) == 0 ||
		pfokValParams(params) == ERR_OK)
		return FALSE;
	// тест PFOK.GENG.4
	if (pfokStdParams(params, 0, "1.2.112.0.2.0.1176.2.3.10.2") != ERR_OK ||
		pfokValParams(params) != ERR_OK ||
		(params->g[0] += 1) == 0 ||
		pfokValParams(params) == ERR_OK)
		return FALSE;
	// загрузить параметры "test"
	if (pfokStdParams(params, 0, "test") != ERR_OK)
		return FALSE;
	// сгенерировать ключи
	ASSERT(prngCOMBO_keep() <= sizeof(combo_state));
	prngCOMBOStart(combo_state, utilNonce32());
	if (pfokGenKeypair(ua, vb, params, prngCOMBOStepG, combo_state) != ERR_OK ||
		pfokValPubkey(params, vb) != ERR_OK ||
		pfokCalcPubkey(yb, params, ua) != ERR_OK ||
		!memEq(vb, yb, O_OF_B(params->l)))
		return FALSE;
	// тест PFOK.ANON.1
	hexToRev(ua, 
		"01"
		"1D4665B357DB361D106E32E353CD534B");
	hexToRev(vb, 
		"0739539C2AE25B53A05C8D16A14351D8"
		"EA86A1DD1893E08EE4A266F970E0243F"
		"8DF27F738F64E99E262E337792E5DD84"
		"7CF2A83362C6EC3C024E47313AA49A1E"
		"0A2E637AD35E31EB5F034D889B666701");
	if (pfokValPubkey(params, vb) != ERR_OK ||
		pfokDH(key, params, ua, vb) != ERR_OK ||
		!hexEqRev(key, 
			"777BB35E950D3080C1E896BE4172DBD0" 
			"61423D3BFEF78F15E3F7A7F2FF7A242B"))
		return FALSE;
	// тест PFOK.ANON.2
	hexToRev(ua, 
		"00"
		"0530110167E1443819A8662A0FAB7AC0");
	hexToRev(vb, 
		"1590312CBACB7B21FC0B173DC100AC5D"
		"8692E04813CA2F87A5763E3F4940B10C"
		"DF3F2B3ECDF28BE4BEA9363B07A8A8A3"
		"BFDDE074DCF36D669A56931D083FC3BE"
		"46D02CC8EF719EF66AE47F57BEAE8E02");
	if (pfokValPubkey(params, vb) != ERR_OK ||
		pfokDH(key, params, ua, vb) != ERR_OK ||
		!hexEqRev(key, 
			"46FA834B28D5E5D4183E28646AFFE806"
			"803E4C865CB99B1C423B0F1C78DE758D"))
		return FALSE;
	// тест PFOK.AUTH.1
	hexToRev(xa, 
		"00"
		"78E7101B4A8F421D2AF5740D6ED27680");
	hexToRev(yb, 
		"193E5E1E0839091BC7ABBDD09E8D2298"
		"8812D37EDEB39E077130A244888BE1A7"
		"53337AB5743C898D1CFC947430813448"
		"16AF5189A4E84D5B6EA310F72534D2E5"
		"E531B579CEA862EAB0251A3C20F0EC1D");
	hexToRev(ua, 
		"01"
		"27E33C0D7595566570936FEF0AA53A24");
	hexToRev(vb, 
		"0947264BEFA107E99616F347B6A05C62"
		"D7F5F26804D848FC4A7D81915F4546DD"
		"22949C07131D84F8B5A73A60ED61BC6E"
		"158E9B83F38C1EE6AD97F2BF771AA4FF"
		"B10A38298498D943995697FD0F65284C");
	if (pfokValPubkey(params, yb) != ERR_OK ||
		pfokValPubkey(params, vb) != ERR_OK ||
		pfokMTI(key, params, xa, ua, yb, vb) != ERR_OK ||
		!hexEqRev(key, 
			"EA92D5BCEC18BB44514E096748DB3E21"
			"D6E7B9C97D604699BEA7D3B96C87E18B"))
		return FALSE;
	// тест PFOK.AUTH.2
	hexToRev(xa, 
		"00"
		"05773C812D6F2A002D4E3EAC643C2CF3");
	hexToRev(yb, 
		"221CBFEB62F4AA3204D349B3D57E45E4"
		"C9BA601483CF9DDE4DD1AE1CC2694149"
		"F08765C5CCAEBD44B7B7D0F1783F9FDD"
		"2929523E1CEF2A46FBD419C5E5E2E712"
		"4099B405E0B90A5FB15A56F439DA47D1");
	hexToRev(ua, 
		"01"
		"3BB0377B3C0E55577A0D4A43627C6EC2");
	hexToRev(vb, 
		"2740ECD0631257DD8124DC38CFAC3DEF"
		"7162503B7F7C8DEC6478408B225D4C05"
		"56E566AF50661CE2F46662FC66DC429A"
		"CCF65D95E4F90BDCD08A11957C898EE2"
		"C2B77231929ACE9649B2C184CC9D8104");
	if (pfokValPubkey(params, yb) != ERR_OK ||
		pfokValPubkey(params, vb) != ERR_OK ||
		pfokMTI(key, params, xa, ua, yb, vb) != ERR_OK ||
		!hexEqRev(key, 
			"5A4C323604206C8898BF6C234F75A537"
			"DF75E9A249D87F1E55CBD7B40C4FDAFA"))
		return FALSE;
	// все нормально
	return TRUE;
}
Пример #7
0
bool_t bakeTest()
{
	err_t codea;
	err_t codeb;
	bign_params params[1];
	octet randa[48];
	octet randb[48];
	octet echoa[64];
	octet echob[64];
	bake_settings settingsa[1];
	bake_settings settingsb[1];
	octet da[32];
	octet db[32];
	octet certdataa[5 /* Alice */ + 64 + 3 /* align */];
	octet certdatab[3 /* Bob */ + 64 + 5 /* align */];
	bake_cert certa[1];
	bake_cert certb[1];
	file_msg_st filea[1];
	file_msg_st fileb[1];
	const char pwd[] = "8086";
	octet keya[32];
	octet keyb[32];
	octet secret[32];
	octet iv[64];
	// загрузить долговременные параметры
	if (bignStdParams(params, "1.2.112.0.2.0.34.101.45.3.1") != ERR_OK)
		return FALSE;
	// настроить генераторы
	ASSERT(prngEcho_keep() <= sizeof(echoa));
	// задать настройки
	memSetZero(settingsa, sizeof(bake_settings));
	memSetZero(settingsb, sizeof(bake_settings));
	settingsa->kca = settingsa->kcb = TRUE;
	settingsb->kca = settingsb->kcb = TRUE;
	settingsa->rng = settingsb->rng = prngEchoStepR;
	settingsa->rng_state = echoa;
	settingsb->rng_state = echob;
	// загрузить личные ключи
	hexTo(da, _da);
	hexTo(db, _db);
	// загрузить сертификаты
	hexTo(certdataa, _certa);
	hexTo(certdatab, _certb);
	certa->data = certdataa;
	certa->len = strLen(_certa) / 2;
	certb->data = certdatab;
	certb->len = strLen(_certb) / 2;
	certa->val = certb->val = bakeTestCertVal;
	// тест Б.2
	hexTo(randa, _bmqv_randa);
	hexTo(randb, _bmqv_randb);
	fileMsgFlash();
	do
	{
		filea->i = filea->offset = 0;
		fileb->i = fileb->offset = 0;
		prngEchoStart(echoa, randa, strLen(_bmqv_randb) / 2);
		prngEchoStart(echob, randb, strLen(_bmqv_randb) / 2);
		codeb = bakeBMQVRunB(keyb, params, settingsb, db, certb, certa,
			fileMsgRead, fileMsgWrite, fileb);
		if (codeb != ERR_OK && codeb != ERR_FILE_NOT_FOUND)
			return FALSE;
		codea = bakeBMQVRunA(keya, params, settingsa, da, certa, certb,
			fileMsgRead, fileMsgWrite, filea);
		if (codea != ERR_OK && codea != ERR_FILE_NOT_FOUND)
			return FALSE;
	}
	while (codea == ERR_FILE_NOT_FOUND || codeb == ERR_FILE_NOT_FOUND);
	if (!memEq(keya, keyb, 32) ||
		!hexEq(keya,
			"C6F86D0E468D5EF1A9955B2EE0CF0581"
			"050C81D1B47727092408E863C7EEB48C"))
		return FALSE;
	// тест Б.3
	hexTo(randa, _bsts_randa);
	hexTo(randb, _bsts_randb);
	fileMsgFlash();
	do
	{
		filea->i = filea->offset = 0;
		fileb->i = fileb->offset = 0;
		prngEchoStart(echoa, randa, strLen(_bsts_randb) / 2);
		prngEchoStart(echob, randb, strLen(_bsts_randb) / 2);
		codeb = bakeBSTSRunB(keyb, params, settingsb, db, certb,
			bakeTestCertVal, fileMsgRead, fileMsgWrite, fileb);
		if (codeb != ERR_OK && codeb != ERR_FILE_NOT_FOUND)
			return FALSE;
		codea = bakeBSTSRunA(keya, params, settingsa, da, certa,
			bakeTestCertVal, fileMsgRead, fileMsgWrite, filea);
		if (codea != ERR_OK && codea != ERR_FILE_NOT_FOUND)
			return FALSE;
	}
	while (codea == ERR_FILE_NOT_FOUND || codeb == ERR_FILE_NOT_FOUND);
	if (!memEq(keya, keyb, 32) ||
		!hexEq(keya,
			"78EF2C56BD6DA2116BB5BEE80CEE5C05"
			"394E7609183CF7F76DF0C2DCFB25C4AD"))
		return FALSE;
	// тест Б.4
	hexTo(randa, _bpace_randa);
	hexTo(randb, _bpace_randb);
	fileMsgFlash();
	do
	{
		filea->i = filea->offset = 0;
		fileb->i = fileb->offset = 0;
		prngEchoStart(echoa, randa, strLen(_bpace_randb) / 2);
		prngEchoStart(echob, randb, strLen(_bpace_randb) / 2);
		codeb = bakeBPACERunB(keyb, params, settingsb, (const octet*)pwd,
            strLen(pwd), fileMsgRead, fileMsgWrite, fileb);
		if (codeb != ERR_OK && codeb != ERR_FILE_NOT_FOUND)
			return FALSE;
		codea = bakeBPACERunA(keya, params, settingsa, (const octet*)pwd,
            strLen(pwd), fileMsgRead, fileMsgWrite, filea);
		if (codea != ERR_OK && codea != ERR_FILE_NOT_FOUND)
			return FALSE;
	}
	while (codea == ERR_FILE_NOT_FOUND || codeb == ERR_FILE_NOT_FOUND);
	if (!memEq(keya, keyb, 32) ||
		!hexEq(keya,
			"DAC4D8F411F9C523D28BBAAB32A5270E"
			"4DFA1F0F757EF8E0F30AF08FBDE1E7F4"))
		return FALSE;
	// тест bakeKDF (по данным из теста Б.4)
	hexTo(secret, 
		"723356E335ED70620FFB1842752092C3"
		"2603EB666040920587D800575BECFC42");
	hexTo(iv, 
		"6B13ACBB086FB87618BCC2EF20A3FA89"
		"475654CB367E670A2441730B24B8AB31"
		"CD3D6487DC4EEB23456978186A069C71"
		"375D75C2DF198BAD1E61EEA0DBBFF737");
	if (bakeKDF(keya, secret, 32, iv, 64, 0) != ERR_OK ||
		bakeKDF(keyb, secret, 32, iv, 64, 1) != ERR_OK ||
		!hexEq(keya,
			"DAC4D8F411F9C523D28BBAAB32A5270E"
			"4DFA1F0F757EF8E0F30AF08FBDE1E7F4") ||
		!hexEq(keyb,
			"54AC058284D679CF4C47D3D72651F3E4"
			"EF0D61D1D0ED5BAF8FF30B8924E599D8"))
		return FALSE;
	// тест bakeSWU (по данным из теста Б.4)
	hexTo(secret, 
		"AD1362A8F9A3D42FBE1B8E6F1C88AAD5"
		"0F51D91347617C20BD4AB07AEF4F26A1");
	if (bakeSWU(iv, params, secret) != ERR_OK ||
		!hexEq(iv,
			"014417D3355557317D2E2AB6D0875487"
			"8D19E8D97B71FDC95DBB2A9B894D16D7"
			"7704A0B5CAA9CDA10791E4760671E105"
			"0DDEAB7083A7458447866ADB01473810"))
		return FALSE;
	// все нормально
	return TRUE;
}
Пример #8
0
// проверить характеристику
void stampCheck(const char* name)
{
	HANDLE hFile;
	DWORD size;
	HANDLE hMapping;
	octet* image;
	DWORD offset;
	octet stamp[STAMP_SIZE];
	void* hash_state;
	bool_t success;
	// открыть файл
	hFile = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 
		FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		printf("File \"%s\" was not found or could not be open.\n", name);
		return;
	}
	// длина файла
	size = SetFilePointer(hFile, 0, NULL, FILE_END);
	if (size == INVALID_SET_FILE_POINTER)
	{
		CloseHandle(hFile);
		printf("Error processing the file \"%s\".\n", name);
		return;
	}
	// проецировать файл в память
	hMapping = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
	if (hMapping == NULL)
	{
		CloseHandle(hFile);
		printf("Error processing the file \"%s\".\n", name);
		return;
	}
	// отобразить файл в память
	image = (octet*)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
	if (image == NULL)
	{
		CloseHandle(hMapping);
		CloseHandle(hFile);
		printf("Error processing the file \"%s\".\n", name);
		return;
	}
	// найти смещение контрольной характеристики
	offset = stampFindOffset(image, size);
	if (offset == (DWORD)-1)
	{
		UnmapViewOfFile(image);
		CloseHandle(hMapping);
		CloseHandle(hFile);
		printf("Control stamp of \"%s\" was not found or corrupted.\n", name);
		return;
	}
	// подготовить место для контрольной характеристики
	CASSERT(STAMP_SIZE >= 32);
	memSet(stamp, 0, STAMP_SIZE);
	// состояние хэширования
	hash_state = blobCreate(beltHash_keep());
	if (hash_state)
	{
		// хэшировать
		beltHashStart(hash_state);
		beltHashStepH(image, offset, hash_state);
		beltHashStepH(image + offset + STAMP_SIZE, 
			size - offset - STAMP_SIZE, hash_state);
		beltHashStepG(stamp, hash_state);
		blobClose(hash_state);
		// сравнить
		success = memEq(image + offset, stamp, STAMP_SIZE);
		printf("Integrity of \"%s\"... %s\n", name, success ? "OK" : "Failed");
		if (success)
			stampPrint(image + offset, "stamp");
		else
			stampPrint(image + offset, "read_stamp"),
			stampPrint(stamp, "calc_stamp");
	}
	else
		printf("Insufficient memory.\n");
	// очистка
	UnmapViewOfFile(image);
	CloseHandle(hMapping);
	CloseHandle(hFile);
}
Пример #9
0
bool_t bakeDemo()
{
	bign_params params[1];
	octet randa[48];
	octet randb[48];
	octet echoa[64];
	octet echob[64];
	bake_settings settingsa[1];
	bake_settings settingsb[1];
	octet da[32];
	octet db[32];
	octet certdataa[5 + 64];
	octet certdatab[3 + 64];
	bake_cert certa[1];
	bake_cert certb[1];
	octet file_data[1024];
	file_st filea[1];
	file_st fileb[1];
	const char pwd[] = "8086";
	octet keya[32];
	octet keyb[32];
	// загрузить долговременные параметры
	if (bignStdParams(params, "1.2.112.0.2.0.34.101.45.3.1") != ERR_OK)
	 return FALSE;
	// настроить генераторы
	ASSERT(prngEcho_keep() <= sizeof(echoa));
	// задать настройки
	memSetZero(settingsa, sizeof(bake_settings));
	memSetZero(settingsb, sizeof(bake_settings));
	settingsa->kca = settingsa->kcb = TRUE;
	settingsb->kca = settingsb->kcb = TRUE;
	settingsa->rng = settingsb->rng = prngEchoStepR;
	settingsa->rng_state = echoa;
	settingsb->rng_state = echob;
	// загрузить личные ключи
	hexTo(da, _da);
	hexTo(db, _db);
	// загрузить сертификаты
	hexTo(certdataa, _certa);
	hexTo(certdatab, _certb);
	certa->data = certdataa;
	certa->len = strLen(_certa) / 2;
	certb->data = certdatab;
	certb->len = strLen(_certb) / 2;
	certa->val = certb->val = certVal;
	// тест Б.2
	hexTo(randa, _bmqv_randa);
	hexTo(randb, _bmqv_randb);
	ASSERT(sizeof(file_data) >= sizeof(_bmqv_data) / 2);
	hexTo(file_data, _bmqv_data);
	if (fileCreate(filea, file_data, strlen(_bmqv_data) / 2) != ERR_OK ||
		fileCreate(fileb, file_data, strlen(_bmqv_data) / 2) != ERR_OK)
		return FALSE;
	prngEchoStart(echoa, randa, strLen(_bmqv_randb) / 2);
	prngEchoStart(echob, randb, strLen(_bmqv_randb) / 2);
	if (bakeBMQVRunB(keyb, params, settingsb, db, certb, certa,
			fileRead, fileWrite, fileb) != ERR_OK ||
		bakeBMQVRunA(keya, params, settingsa, da, certa, certb,
			fileRead, fileWrite, filea))
			return FALSE;
	if (!memEq(keya, keyb, 32) ||
		!hexEq(keya,
			"C6F86D0E468D5EF1A9955B2EE0CF0581"
			"050C81D1B47727092408E863C7EEB48C"))
		return FALSE;
	// тест Б.3
	hexTo(randa, _bsts_randa);
	hexTo(randb, _bsts_randb);
	ASSERT(sizeof(file_data) >= strlen(_bsts_data) / 2);
	hexTo(file_data, _bsts_data);
	if (fileCreate(filea, file_data, strlen(_bsts_data) / 2) != ERR_OK ||
		fileCreate(fileb, file_data, strlen(_bsts_data) / 2) != ERR_OK)
		return FALSE;
	prngEchoStart(echoa, randa, strLen(_bsts_randb) / 2);
	prngEchoStart(echob, randb, strLen(_bsts_randb) / 2);
	if (bakeBSTSRunB(keyb, params, settingsb, db, certb, certVal,
			fileRead, fileWrite, fileb) != ERR_OK ||
		bakeBSTSRunA(keya, params, settingsa, da, certa, certVal,
			fileRead, fileWrite, filea))
			return FALSE;
	if (!memEq(keya, keyb, 32) ||
		!hexEq(keya,
			"78EF2C56BD6DA2116BB5BEE80CEE5C05"
			"394E7609183CF7F76DF0C2DCFB25C4AD"))
		return FALSE;
	// тест Б.4
	hexTo(randa, _bpace_randa);
	hexTo(randb, _bpace_randb);
	ASSERT(sizeof(file_data) >= strlen(_bsts_data) / 2);
	hexTo(file_data, _bpace_data);
	if (fileCreate(filea, file_data, strlen(_bpace_data) / 2) != ERR_OK ||
		fileCreate(fileb, file_data, strlen(_bpace_data) / 2) != ERR_OK)
		return FALSE;
	prngEchoStart(echoa, randa, strLen(_bpace_randb) / 2);
	prngEchoStart(echob, randb, strLen(_bpace_randb) / 2);
	if (bakeBPACERunB(keyb, params, settingsb, (octet*)pwd, strLen(pwd),
			fileRead, fileWrite, fileb) != ERR_OK ||
		bakeBPACERunA(keya, params, settingsa, (octet*)pwd, strLen(pwd),
			fileRead, fileWrite, filea))
			return FALSE;
	if (!memEq(keya, keyb, 32) ||
		!hexEq(keya,
			"DAC4D8F411F9C523D28BBAAB32A5270E"
			"4DFA1F0F757EF8E0F30AF08FBDE1E7F4"))
		return FALSE;
	// все нормально
	return TRUE;
}
Пример #10
0
bool_t belsTest()
{
	size_t len, num;
	octet m0[32];
	octet mi[32 * 5];
	octet s[32];
	octet si[32 * 5];
	char id[] = "Alice";
	octet echo_state[64];
	octet combo_state[512];
	// проверить состояния
	ASSERT(sizeof(echo_state) >= prngEcho_keep());
	ASSERT(sizeof(combo_state) >= prngCOMBO_keep());
	// проверить таблицы A.1 -- A.4
	for (len = 16; len <= 32; len += 8)
	for (num = 0; num <= 16; ++num)
	{
		if (belsStdM(mi, len, num) != ERR_OK)
			return FALSE;
		if (belsValM(mi, len) != ERR_OK)
			return FALSE;
	}
	// сгенерировать общие ключи
	prngCOMBOStart(combo_state, utilNonce32());
	if (belsGenM0(m0, 16, prngCOMBOStepG, combo_state) != ERR_OK ||
		belsValM(m0, 16) != ERR_OK)
		return FALSE;
	if (belsGenM0(m0, 24, prngCOMBOStepG, combo_state) != ERR_OK ||
		belsValM(m0, 24) != ERR_OK)
		return FALSE;
	if (belsGenM0(m0, 32, prngCOMBOStepG, combo_state) != ERR_OK ||
		belsValM(m0, 32) != ERR_OK)
		return FALSE;
	// тест Б.1
	belsStdM(m0, 16, 0);
	if (belsGenMid(mi, 16, m0, (const octet*)id, strLen(id)) != ERR_OK ||
		belsValM(mi, 16) != ERR_OK ||
		!hexEq(mi, 
		"F9D6F31B5DB0BB61F00E17EEF2E6007F"))
		return FALSE;
	belsStdM(m0, 24, 0);
	if (belsGenMid(mi, 24, m0, (const octet*)id, strLen(id)) != ERR_OK ||
		belsValM(mi, 24) != ERR_OK ||
		!hexEq(mi, 
		"09EA79297F94A3E43A3885FC0D1BB8FD"
		"D0DF86FD313CEF46"))
		return FALSE;
	belsStdM(m0, 32, 0);
	if (belsGenMid(mi, 32, m0, (const octet*)id, strLen(id)) != ERR_OK ||
		belsValM(mi, 32) != ERR_OK ||
		!hexEq(mi,
		"D53CC51BE1F976F1032A00D9CD0E190E"
		"62C37FFD233E8A9DF14C85F85C51A045"))
		return FALSE;
	// проверка belsGenMi
	for (len = 16; len <= 32; len += 8)
	{
		belsStdM(m0, len, 0);
		if (belsGenMi(mi, len, m0, prngCOMBOStepG, combo_state) != ERR_OK || 
			belsValM(mi, len) != ERR_OK)
			return FALSE;
	}
	// проверка belsShare
	for (len = 16; len <= 32; len += 8)
	{
		// загрузить открытые ключи
		belsStdM(m0, len, 0);
		belsStdM(mi + 0 * len, len, 1);
		belsStdM(mi + 1 * len, len, 2);
		belsStdM(mi + 2 * len, len, 3);
		belsStdM(mi + 3 * len, len, 4);
		belsStdM(mi + 4 * len, len, 5);
		// инициализировать эхо-генератор
		prngEchoStart(echo_state, beltH() + 128, 128);
		// разделить секрет (тесты Б.2 -- Б.4)
		if (belsShare(si, 5, 3, len, beltH(), m0, mi, prngEchoStepG, 
			echo_state) != ERR_OK)
			return FALSE;
		if (len == 16 && !hexEq(si,
			"E27D0CFD31C557BC37C3897DCFF2C7FC"
			"50BB9EECBAEF52DDB811BCDE1495441D"
			"A92473F6796683534AD115812A3F9950"
			"9A8331FD945D58E6D8723E4744FB1DA9"
			"51913D18C8625C5AB0812133FB643D66"))
			return FALSE;
		if (len == 24 && !hexEq(si,
			"8D0EBB0C67A315C214B34A5D68E9712A"
			"12F7B43287E3138A"
			"2506EB8283D8555318479D278A752B04"
			"E9B5E6CC43543403"
			"E5B885E65E69ADD330D08268EC3D0A44"
			"B04B8E142CDDDD5C"
			"E85B368A66489AFE0E73D3D0EEB6A210"
			"CF0629C275AB1E94"
			"ED6CD8B56C37C03EE4FF04AE2A975AAA"
			"748AA0E97AA0DE20"))
			return FALSE;
		if (len == 32 && !hexEq(si,
			"27EC2268C7A06E7CC54F66FC3D357298"
			"4D4D4EF69916EB8D1EAFDFA420217ADC"
			"20E06235E355CC433E2AF2F4100C636F"
			"3BFAB861A4390614E42BC17577BCBE42"
			"1E14B1E795CED216AAC5BB526EFC786C"
			"5BCE1F1865D3886ED4DD7D9EFEF77F39"
			"62EFAD2544718293262E2CB74A396B50"
			"B6D8843DF5E2F0EEFFFE6CD18722765E"
			"71ADE959FC88CCBB1C521FA9A1168C184"
			"619832AB66265E08A65DD48EE406418"))
			return FALSE;
		// восстановить секрет
		if (belsRecover(s, 1, len, si, m0, mi) != ERR_OK ||
			memEq(s, beltH(), len))
			return FALSE;
		if (belsRecover(s, 2, len, si, m0, mi) != ERR_OK ||
			memEq(s, beltH(), len))
			return FALSE;
		if (belsRecover(s, 3, len, si, m0, mi) != ERR_OK ||
			!memEq(s, beltH(), len))
			return FALSE;
		if (belsRecover(s, 4, len, si, m0, mi) != ERR_OK ||
			!memEq(s, beltH(), len))
			return FALSE;
		if (belsRecover(s, 5, len, si, m0, mi) != ERR_OK ||
			!memEq(s, beltH(), len))
			return FALSE;
		// восстановить секрет (тесты Б.5 -- Б.7, строка 1)
		if (belsRecover(s, 2, len, si, m0, mi) != ERR_OK ||
			len == 16 && !hexEq(s, 
			"6380669CA508058FA9AADF986C77C175") ||
			len == 24 && !hexEq(s, 
			"1E9811BD520C56E12B5B0E517756FA1A"
			"EE3CACC13B6313E9") ||
			len == 32 && !hexEq(s, 
			"C39C8FA8590A7855914AED9B05940D9E"
			"8A119B130D939B8799889C938D1E078D"))
			return FALSE;
		// восстановить секрет (тесты Б.5 -- Б.7, строка 5)
		if (belsRecover(s, 2, len, si + len, m0, mi + len) != ERR_OK ||
			len == 16 && !hexEq(s, 
			"E8BA837676967C5C939DBF5172C9AB4F") ||
			len == 24 && !hexEq(s, 
			"AF8AB8304FEBD5CF89D643A850C77165"
			"7310CA0E8EDF9C60") ||
			len == 32 && !hexEq(s, 
			"31C06C2BF7AF38C2A6870A7F1B7BA9CC"
			"1A741DD96374A4D17A1F701666C9A777"))
			return FALSE;
		// восстановить секрет (тесты Б.5 -- Б.7, строка 8)
		if (belsRecover(s, 2, len, si + 2 * len, m0, mi + 2 * len) != ERR_OK ||
			len == 16 && !hexEq(s, 
			"81C498D55DC506E858DE632A079C2C31") ||
			len == 24 && !hexEq(s, 
			"21B6A467511CD2CE6AE671E1D0992538"
			"BFB4EAE927F70991") ||
			len == 32 && !hexEq(s, 
			"3ACC00A6DF80BC314A708A19D467F954"
			"40B214356D4666B4075E384B87BEB86C"))
			return FALSE;
		// восстановить секрет (тесты Б.5 -- Б.7, строка 10)
		if (belsRecover(s, 2, len, si + 3 * len, m0, mi + 3 * len) != ERR_OK ||
			len == 16 && !hexEq(s, 
			"40F629F9A4487DBCBF53192EA4A49EAA") ||
			len == 24 && !hexEq(s, 
			"1C0E2B99D81134E0EB9AD40279D09786"
			"CA3CDA79B2E5D385") ||
			len == 32 && !hexEq(s, 
			"3F5F33C778D77A4FADC0BB51BE9F0153"
			"2627D1E83D023DA72255CC826B05213B"))
			return FALSE;
		// изменить порядок открытых ключей / частичных секретов: 13245
		memSwap(mi + len, mi + 2 * len, len);
		memSwap(si + len, si + 2 * len, len);
		// восстановить секрет (тесты Б.5 -- Б.7, строка 2)
		if (belsRecover(s, 2, len, si, m0, mi) != ERR_OK ||
			len == 16 && !hexEq(s, 
			"ABD72A835739A358DD954BEF7A923AEC") ||
			len == 24 && !hexEq(s, 
			"A2E3B51AFBD7AFD552048DD6444416E0"
			"7F2D9FA92D726920") ||
			len == 32 && !hexEq(s, 
			"70EDE256F46BDC35EEE39361921EE8A3"
			"94E8E67F3F56ABFBA65329D146DA185B"))
			return FALSE;
		// восстановить секрет (тесты Б.5 -- Б.7, строка 6)
		if (belsRecover(s, 2, len, si + 2 * len, m0, mi + 2 * len) != ERR_OK ||
			len == 16 && !hexEq(s, 
			"6CB93B8CF600A746F8520860901E36FA") ||
			len == 24 && !hexEq(s, 
			"6D542544073C04C1C417ABDC292755A2"
			"861B4EB590B65841") ||
			len == 32 && !hexEq(s, 
			"44FC1DE684980BE2660BB7BCE50728A1"
			"25A81D3B71B8D4ACD74E03190ADA473B"))
			return FALSE;
		// изменить порядок открытых ключей / частичных секретов: 53241
		memSwap(mi, mi + 4 * len, len);
		memSwap(si, si + 4 * len, len);
		// восстановить секрет (тесты Б.5 -- Б.7, строка 9)
		if (belsRecover(s, 2, len, si, m0, mi) != ERR_OK ||
			len == 16 && !hexEq(s, 
			"E685CC725DDE29E60927563912CBBEA4") ||
			len == 24 && !hexEq(s, 
			"F2E193958DB1D3391D54C410244C151D"
			"BC267D6F5182DEC4") ||
			len == 32 && !hexEq(s, 
			"B3C2EDAD484A5A864575721D10B9D0C0"
			"9AE32C972C74857BA423D04502EE0066"))
			return FALSE;
		// восстановить секрет (тесты Б.5 -- Б.7, строка 3)
		if (belsRecover(s, 2, len, si + 3 * len, m0, mi + 3 * len) != ERR_OK ||
			len == 16 && !hexEq(s, 
			"225E2DF0E4AE6532D5A741981410A83C") ||
			len == 24 && !hexEq(s, 
			"2B65B8D1BEF2EA079F6C45DF5877EAA1"
			"8F1188539B0AEF32") ||
			len == 32 && !hexEq(s, 
			"7C2D5033F0F10CC69065B13BB53BE7D1"
			"9D61CF864CF1578E8325F10564F995A3"))
			return FALSE;
		// изменить порядок открытых ключей / частичных секретов: 43251
		memSwap(mi, mi + 3 * len, len);
		memSwap(si, si + 3 * len, len);
		// восстановить секрет (тесты Б.5 -- Б.7, строка 7)
		if (belsRecover(s, 2, len, si + 2 * len, m0, mi + 2 * len) != ERR_OK ||
			len == 16 && !hexEq(s, 
			"E4FCC7E24E448324367F400326954776") ||
			len == 24 && !hexEq(s, 
			"EF5CE43C8AE6F4E441CE1C2D16ACC662"
			"D6CC1D8BAF937320") ||
			len == 32 && !hexEq(s, 
			"264FD3BE9298495758B2446363616A38"
			"75D15EB96F95A122332597A87B2CCCBC"))
			return FALSE;
		// восстановить секрет (тесты Б.5 -- Б.7, строка 4)
		if (belsRecover(s, 2, len, si + 3 * len, m0, mi + 3 * len) != ERR_OK ||
			len == 16 && !hexEq(s, 
			"E0C4268AC9C5FE35C15334E4D01417BE") ||
			len == 24 && !hexEq(s, 
			"7E880E3E89CE5FD4E8452256BD66E42D"
			"18D88C0CF85FDC26") ||
			len == 32 && !hexEq(s, 
			"00DD41CD32684FE7564F67FC51B0AD87"
			"003EEBDF90E803BA37CBA4FF8D9A724F"))
			return FALSE;
	}
	// все нормально
	return TRUE;
}