Имплементация алгоритма Keccak на языке 1С

Публикация № 1233190

Разработка - Защита и шифрование

SHA3-128 SHA3-224 SHA3-256 SHA3-384 SHA3-512 Keccak-256 Keccak-512 SHAKE128 SHAKE256 cSHAKE128 cSHAKE256 HMAC-SHA3

Имплементация алгоритма Keccak на 1С версии 8.3.11, примеры функций SHA3-512, Keccak-512, HMAC-3, SHAKE256, cSHAKE256 и другие варианты параметров Keccak без внешних компонент.

Во встроенном языке текущей версии платформы 1С:Предприятие нет реализации алгоритма Keccak и основанных на нём SHA-3.
В статье приведен текст алгоритма расчёта Хеша по стандартам:

  • SHA3-128
  • SHA3-224
  • SHA3-256
  • SHA3-384
  • SHA3-512
  • Keccak-256
  • Keccak-512
  • SHAKE128
  • SHAKE256
  • cSHAKE128
  • cSHAKE256

Приложенная обработка содержит в себе реализацию представленного алгоритма с возможностью запуска функции со стандартными значениями параметров, а также с произвольными значениями параметров. Проверки на корректность произвольных значений параметров нет.

В обработке также реализован алгоритм расчета HMAC

Указанные стандарты получаются выполнением алгоритма Keccak с различными параметрами

Так, для SHA3-512 размер блока 1024 бита, размер выходной строки 512 бит, первая часть дополнения входных данных 0x06, вторая часть дополнения входных данных 0x80. Между первой и второй частью добавляются нулевые байты, с таким расчётом, чтобы длина входных данных стала кратной (1600 - размер блока) - 576 бит.
 

Описание алгоритма SHA-3 можно найти в википедии.
 

В приведённом примере функция SHA3 предназначена для расчета хеша по алгоритму Keccak с параметрами, указанными в стандарте, соответствие варианты стандартов и параметров формируются в функции ПолучитьСоответствияСтандартов3

Функция HMACSHA3 производит расчет хеша с ключом.

Функция ПодготовитьИВыполнитьКечак выполняет расчёт хеша с указанными параметрами, в неё передается входное сообщение в виде двоичных данных, размер блока, длина выходной строки, первый и второй суффиксы. Функция вызывает подготовку входных данных, подготавливает переменные и запускает функцию хеширования Кечак.

Текст кода имплементации:


#Область ВспомогательныеФункции

Функция ПолучитьСоответствияСтандартов3()
	лСоответствиеСтандартаИАлгоритма = Новый Соответствие;
	лСоответствиеСтандартаИАлгоритма.Вставить("SHA3-128",Новый Структура("Битность,Суффикс,Размер",256,"06",128));
	лСоответствиеСтандартаИАлгоритма.Вставить("SHA3-224",Новый Структура("Битность,Суффикс,Размер",448,"06",224));
	лСоответствиеСтандартаИАлгоритма.Вставить("SHA3-256",Новый Структура("Битность,Суффикс,Размер",512,"06",256));
	лСоответствиеСтандартаИАлгоритма.Вставить("SHA3-384",Новый Структура("Битность,Суффикс,Размер",768,"06",384));
	лСоответствиеСтандартаИАлгоритма.Вставить("SHA3-512",Новый Структура("Битность,Суффикс,Размер",1024,"06",512));
	лСоответствиеСтандартаИАлгоритма.Вставить("Keccak-256",Новый Структура("Битность,Суффикс,Размер",512,"01",256));
	лСоответствиеСтандартаИАлгоритма.Вставить("Keccak-512",Новый Структура("Битность,Суффикс,Размер",1024,"01",512));
	лСоответствиеСтандартаИАлгоритма.Вставить("SHAKE128",Новый Структура("Битность,Суффикс,Размер",256,"1f","256"));
	лСоответствиеСтандартаИАлгоритма.Вставить("SHAKE256",Новый Структура("Битность,Суффикс,Размер",512,"1f","512"));
	лСоответствиеСтандартаИАлгоритма.Вставить("cSHAKE128",Новый Структура("Битность,Суффикс,Размер",256,"00","256"));
	лСоответствиеСтандартаИАлгоритма.Вставить("cSHAKE256",Новый Структура("Битность,Суффикс,Размер",512,"00","512"));
	Возврат лСоответствиеСтандартаИАлгоритма;
КонецФункции // ПолучитьСоответствияСтандартов3(пКлюч)

#КонецОбласти

#Область ПобитовыеОперации

Функция ПовторитьСтроку(пСтрока, пКоличество)
	лЧасти = Новый Массив;
	Для к = 1 По пКоличество Цикл
		лЧасти.Добавить(пСтрока);
	КонецЦикла;
	Возврат СтрСоединить(лЧасти, "");
КонецФункции // ПовторитьСтроку(пСтрока, пКоличество)

Функция СклеитьДвоичныеДанные(пДвоичныеДанные1, пДвоичныеДанные2)
	лМассивДвоичныхДанных = Новый Массив;
	лМассивДвоичныхДанных.Добавить(пДвоичныеДанные1);
	лМассивДвоичныхДанных.Добавить(пДвоичныеДанные2);
	Возврат СоединитьДвоичныеДанные(лМассивДвоичныхДанных);
КонецФункции // СклеитьДвоичныеДанные(пДвоичныеДанные1, пДвоичныеДанные2)

Функция ПолучитьМассивЧиселИзHexСтроки(Знач пСтрока)
	лПоз = Найти(пСтрока,",");
	лМассив = Новый Массив;
	Пока лПоз>1 Цикл
		лПодстрока = Сред(пСтрока,1,лПоз-1);
		пСтрока = Сред(пСтрока,лПоз+1);
		лПоз = Найти(пСтрока,",");
		лМассив.Добавить(ПолучитьБуферДвоичныхДанныхИзHexСтроки(лПодстрока).ПрочитатьЦелое64(0,ПорядокБайтов.BigEndian));
	КонецЦикла;
	лМассив.Добавить(ПолучитьБуферДвоичныхДанныхИзHexСтроки(пСтрока).ПрочитатьЦелое64(0,ПорядокБайтов.BigEndian));
	Возврат лМассив;
КонецФункции // ПолучитьМассивБДДИзHexСтроки(Знач пСтрока)

Функция ПобитовыйСдвигВлево64(пЧисло, пСмещение)
	лЧисло0 = Цел(пЧисло/4294967296);
	лЧисло1 = пЧисло%4294967296;
	Если пСмещение<32 Тогда
		Возврат (ПобитовыйСдвигВлево(лЧисло0, пСмещение)+ПобитовыйСдвигВправо(лЧисло1, 32-пСмещение))*4294967296+
		ПобитовыйСдвигВлево(лЧисло1, пСмещение);
	ИНаче
		Возврат ПобитовыйСдвигВлево(лЧисло1, пСмещение - 32)*4294967296;
	КонецЕсли;
КонецФункции // ПобитовыйСдвигВлево64(пЧисло, пСмещение)

Функция ПобитовыйСдвигВправо64(пЧисло, пСмещение)
	лЧисло0 = Цел(пЧисло/4294967296);
	лЧисло1 = пЧисло%4294967296;
	Если пСмещение<32 Тогда
		Возврат (ПобитовыйСдвигВправо(лЧисло0, пСмещение))*4294967296+
		ПобитовыйСдвигВправо(лЧисло1, пСмещение)+ПобитовыйСдвигВлево(лЧисло0, 32-пСмещение);
	ИНаче
		Возврат ПобитовыйСдвигВправо(лЧисло0, пСмещение - 32);
	КонецЕсли;
КонецФункции // ПобитовыйСдвигВправо64(пЧисло, пСмещение)

// функция осуществляет циклический сдвиг влево
//
Функция ЦиклическийСдвигВлево64(пЧисло, пСмещение)
	Возврат(ПобитовыйСдвигВправо64(пЧисло, 64-пСмещение) + ПобитовыйСдвигВлево64(пЧисло, пСмещение));
КонецФункции // ЦиклическийСдвигВлево64(пЧисло, пСмещение)

Функция ПобитовоеИсключительноеИли64(пЧисло1, пЧисло2)
	лЧисло10 = Цел(пЧисло1/4294967296);
	лЧисло11 = пЧисло1%4294967296;
	лЧисло20 = Цел(пЧисло2/4294967296);
	лЧисло21 = пЧисло2%4294967296;
	Возврат (ПобитовоеИсключительноеИли(лЧисло10,лЧисло20)*4294967296+ПобитовоеИсключительноеИли(лЧисло11,лЧисло21));
КонецФункции // ПобитовоеИсключительноеИли64(пЧисло1, пЧисло2)

Функция ПобитовоеИ64(пЧисло1, пЧисло2)
	лЧисло10 = Цел(пЧисло1/4294967296);
	лЧисло11 = пЧисло1%4294967296;
	лЧисло20 = Цел(пЧисло2/4294967296);
	лЧисло21 = пЧисло2%4294967296;
	Возврат (ПобитовоеИ(лЧисло10,лЧисло20)*4294967296+ПобитовоеИ(лЧисло11,лЧисло21));
КонецФункции // ПобитовоеИ64(пЧисло1, пЧисло2)

Функция ПобитовоеНе64(пЧисло1)
	лЧисло10 = Цел(пЧисло1/4294967296);
	лЧисло11 = пЧисло1%4294967296;
	Возврат (ПобитовоеНе(лЧисло10)*4294967296+ПобитовоеНе(лЧисло11));
КонецФункции // ПобитовоеНе64(пЧисло1)

Функция СложитьHex(Знач пСуффикс1, Знач пСуффикс2)
	лСтрокаHex = "0123456789abcdef";
	пСуффикс1 = нРег(пСуффикс1);
	пСуффикс2 = НРег(пСуффикс2);
	н1=0;
	н2=0;
	Колво1 = СтрДлина(пСуффикс1);
	Колво2 = СтрДлина(пСуффикс2);
	лВыхСтрока = "";
	лПереносРазряда = 0;
	лФл = Истина;
	Пока лФл Цикл
		лФл = Ложь;
		лЧисло1 = 0;
		лЧисло2 = 0;
		Если н1<Колво1 Тогда
			лСимв1 = Сред(пСуффикс1,Колво1-н1,1);
			лЧисло1 = СтрНайти(лСтрокаHex,лСимв1)-1;
			лФл = Истина;
		КонецЕсли;
		Если н2<Колво2 Тогда
			лСимв2 = Сред(пСуффикс2,Колво2-н2,1);
			лЧисло2 = СтрНайти(лСтрокаHex,лСимв2)-1;
			лФл = Истина;
		КонецЕсли;
		лЧисло3 = лЧисло1+лЧисло2+лПереносРазряда;
		лПереносРазряда = 0;
		Если лЧисло3>15 Тогда
			лЧисло3 = 0;
			лПереносРазряда = 1;
		КонецЕсли;
		Если лФл Тогда
			лВыхСтрока = Сред(лСтрокаHex,лЧисло3+1,1) + лВыхСтрока;
		КонецЕсли;
		н1 = н1 + 1;
		н2 = н2 + 1;
	КонецЦикла;
	Если лПереносРазряда>0 Тогда
		лВыхСтрока = Сред(лСтрокаHex,лПереносРазряда+1,1) + лВыхСтрока;
	КонецЕсли;
	Если СтрДлина(лВыхСтрока)%2<>0 Тогда
		лВыхСтрока = "0" + лВыхСтрока;
	КонецЕсли;
	Возврат лВыхСтрока;
КонецФункции

#КонецОбласти

#Область SHA3

// Функция расчета Хеша по алгоритму SHA3 с ключом
// Возвращает hex строку
// Входные параметры:
// пКлюч - строка с ключом, неограниченная, приводится к длине блока - 128
// пДанные - строка с данными, неограниченная
// пСтандарт - строка с описанием стандарта, варианты: "SHA3-128", "SHA3-224", "SHA3-256", "SHA3-384", "SHA3-512", "Keccak-256", "Keccak-512", "SHAKE128", "SHAKE256", "cSHAKE128", "cSHAKE256" 
// Возвращаяет Hex строку с хешем
//
Функция HMACSHA3(пДанные, пКлюч="", пСтандарт="SHA3-512") Экспорт
	
	ДанныеДв = ПолучитьДвоичныеДанныеИзСтроки(пДанные);
	КлючДв = ПолучитьДвоичныеДанныеИзСтроки(пКлюч);
	
	СоответствиеСтандартаИАлгоритма = ПолучитьСоответствияСтандартов3();
	лСтандарт = СоответствиеСтандартаИАлгоритма[пСтандарт];
	
	РазмерБлока = (1600-лСтандарт.Битность)/8; // Размер блока для HMAC512 - 128
	
	Если КлючДв.Размер() > РазмерБлока Тогда
		КлючHex = SHA3(КлючДв, пСтандарт);
	ИНаче
		КлючHex = ПолучитьHexСтрокуИзДвоичныхДанных(КлючДв);
	КонецЕсли;
	Если СтрДлина(КлючHex)/2 < РазмерБлока Тогда
		КлючHex = Лев(КлючHex + ПовторитьСтроку("00", РазмерБлока-СтрДлина(КлючHex)/2), РазмерБлока);
	КонецЕсли;
	
	КлючБуфер = ПолучитьБуферДвоичныхДанныхИзHexСтроки(КлючHex);
	
	opad = ПолучитьБуферДвоичныхДанныхИзHexСтроки(ПовторитьСтроку("5c", РазмерБлока));
	ipad = ПолучитьБуферДвоичныхДанныхИзHexСтроки(ПовторитьСтроку("36", РазмерБлока));

	ipad.ЗаписатьПобитовоеИсключительноеИли(0, КлючБуфер);
	ikeypad = ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(ipad);
	
	opad.ЗаписатьПобитовоеИсключительноеИли(0, КлючБуфер);
	okeypad = ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(opad);
	
	Возврат SHA3(СклеитьДвоичныеДанные(okeypad, ПолучитьДвоичныеДанныеИзHexСтроки(SHA3(СклеитьДвоичныеДанные(ikeypad, ДанныеДв),пСтандарт))),пСтандарт);
	
КонецФункции

// Функция расчёта хеша по алгоритму SHA3, Keccak (кечак)
// Возвращает Hex строку
// Параметры:
// Данные - дв.данные с данными
// пСтандарт - стандрат по которому производится расчёт.
//  Варианты: "SHA3-128", "SHA3-224", "SHA3-256", "SHA3-384", "SHA3-512", "Keccak-256", "Keccak-512", "SHAKE128", "SHAKE256", "cSHAKE128", "cSHAKE256"
//
Функция SHA3(пДанные, пСтандарт="SHA3-512") Экспорт
	СоответствиеСтандартаИАлгоритма = ПолучитьСоответствияСтандартов3();
	лСтандарт = СоответствиеСтандартаИАлгоритма[пСтандарт];
	Возврат ПодготовитьИВыполнитьКечак(пДанные, лСтандарт.Битность, лСтандарт.Размер, лСтандарт.Суффикс, "80");
КонецФункции // SHA3(пДанные, пСтандарт="SHA3-512") Экспорт

// Функция подготавливает данные, дополняя их суффиксами между которыми нулевые байты, возвращает двоичные данные
// Возвращает двоичные данные
//  Параметры:
//   пДанные - Двоичные данные, которые нужно подготовить
//   пБитность - Количество бит, кратно которому должен получиться результат
//   пСуффикс1 - Hex строка с суффиксом 1 по умолчанию "06" для SHA3
//   пСуффикс2 - Hex строка с суффиксом 2 по уиолчанию "80"
//   
Функция ПодготовитьДанные(пДанные, пБитность, пСуффикс1="06", пСуффикс2="80")
	лРазмер = пДанные.Размер();
	лКолвБайт = пБитность/8;
	лРазница = лРазмер%лКолвБайт;
	лКолВоКДобавке = (лКолвБайт - лРазница);
	Если лКолВоКДобавке = 1 Тогда
		лСтрокаДополнения = СложитьHex(пСуффикс1,пСуффикс2);// "9f";//"86"; //пСуффикс1 + ПовторитьСтроку("00", лКолвБайт-1) + пСуффикс2;;

	Иначе
		лСтрокаДополнения = пСуффикс1 + ПовторитьСтроку("00", лКолВоКДобавке-2) + пСуффикс2;
		//лСтрокаДополнения = "01" + ПовторитьСтроку("00", лКолВоКДобавке-2) + "80"; // keccak
		//лСтрокаДополнения = "06" + ПовторитьСтроку("00", лКолВоКДобавке-2) + "80"; // sha3
	КонецЕсли;
	Возврат СклеитьДвоичныеДанные(пДанные, ПолучитьДвоичныеДанныеИзHexСтроки(лСтрокаДополнения));
КонецФункции // ПодготовитьДанные(пДанные, пБитность, пСуффикс1, пСуффикс2)

// Функция подготавливает данные и выполняет расчет хеша
// Возвращаяет hex строку
// Параметры:
//  пДанные - двоичные данные
//  пБитность - размер блока алгоритма в битах
//  пДлинаВыхода - размер выхода функции в битах
//  пСуффикс1 - суффикс добавляемый к входным данным, hex строка
//  пСуффикс2 - суффикс добавляемый к выходным данным дополненным первым суффиксом и нулевыми данными, hex строка
// заданы значения по умолчанию для стандарта SHA3-512
//
Функция ПодготовитьИВыполнитьКечак(пДанные, пБитность=1024, пДлинаВыхода=512, пСуффикс1="06", пСуффикс2="80") Экспорт
	
	b = 1600; // размер буфера бит
	c = пБитность;
	
	d = пДлинаВыхода;
	
	l = 6; // в SHA-3 приняты такие параметры Keccak
	
	r = b - c; // (200-(c/8))*8; // 576 для sha3-512
		
	пДанные2 = ПодготовитьДанные(пДанные,r, пСуффикс1, пСуффикс2);

	msg = ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(пДанные2); // Message
	
	Возврат Кечак(l,r,msg,d);
КонецФункции // ПодготовитьИВыполнитьКечак(пДанные, пБитность, пДлинаВыхода=0, пСуффикс1, пСуффикс2) Экспорт

// Собственно сам алгоритм
// Возвращает hex строку указанной длины d
// Параметры:
// l - задаёт длину обрабатываемого слова в битах, реализован алгоритм для l=6
// r - размер обрабатываемого блока в битах
// msg - данные в виде буфера двоичных данных
// d - длина выхода в битах
//
Функция Кечак(l,r,msg,d)
	
	w = Pow(2,l); // 64 бита слово  	лДлинаСлова = 64; // Бит
	m_blockSize = r / w * 8;  	// 72 = 200-2*(лРазмер/8);
	wb = w/8;
	// Инициализация массива 5 х 5 х w
	state = Новый Массив;
	Для x = 0 по 4 Цикл
		state.Добавить(Новый Массив);
		Для y = 0 по 4 Цикл
			state[x].Добавить(0); // Число будет обрабатываться как 64-х разрядное 2^_l
		КонецЦикла;
	КонецЦикла;
	
	// фаза впитывания
	
	i = 0;
	Пока i<msg.Размер Цикл
		j = 0;
		Пока j < r/w Цикл
            лТекБлок = msg.ПрочитатьЦелое64(i+j*wb,ПорядокБайтов.LittleEndian);
            x = j % 5;
            y = Цел(j / 5);
            state[x][y] = ПобитовоеИсключительноеИли64(state[x][y],лТекБлок);
			j = j + 1;
		КонецЦикла;
		ФункцияПерестановокКечак(state,l,w);
		i = i + m_blockSize;
	КонецЦикла;
	
	// Фаза выжимки
	Z0 = "";
	лБуферZ = Новый БуферДвоичныхДанных(25*wb); // 200
	лДлинаВыхСтр = d/4; //  d/8*2   d/8 - байт и * 2 - символа hex на байт
	Пока СтрДлина(Z0) < лДлинаВыхСтр Цикл // для кечак и sha3 цикл проходит один раз
		k = 0;
		Для i=0 По 4 Цикл
			Для j=0 По 4 Цикл
				лБуферZ.ЗаписатьЦелое64(k,state[j][i],ПорядокБайтов.LittleEndian);
				k = k + 8;
			КонецЦикла;
		КонецЦикла;
		ФункцияПерестановокКечак(state,l,w);
		Z0 = Z0 + ПолучитьHexСтрокуИзБуфераДвоичныхДанных(лБуферZ);
	КонецЦикла;
	Z = Лев(Z0,лДлинаВыхСтр);
	Возврат Нрег(Z);
КонецФункции // Кечак(l,r,msg,d)

Функция ФункцияПерестановокКечак(a,l,w)
	nRounds = 12 + 2*l;
	
	лСтрока = "
	|0000000000000001,0000000000008082,800000000000808a,8000000080008000,
	|000000000000808b,0000000080000001,8000000080008081,8000000000008009,
	|000000000000008a,0000000000000088,0000000080008009,000000008000000a,
	|000000008000808b,800000000000008b,8000000000008089,8000000000008003,
	|8000000000008002,8000000000000080,000000000000800a,800000008000000a,
	|8000000080008081,8000000000008080,0000000080000001,8000000080008008";
	RC = ПолучитьМассивЧиселИзHexСтроки(лСтрока);
	
	Для r=0 По nRounds-1 Цикл
		
		// _2; [Keccak §2.3.2]
		C = Новый Массив(5);
		D = Новый Массив(5);
		Для x=0 По 4 Цикл
			C[x] = a[x][0];
			Для y=1 По 4 Цикл
				C[x] = ПобитовоеИсключительноеИли64(C[x], a[x][y]);
			КонецЦикла;
		КонецЦикла;
		Для x=0 По 4 Цикл
			D[x] = ПобитовоеИсключительноеИли64(C[((x+4)%5)],ЦиклическийСдвигВлево64(C[((x+1)%5)], 1));
			// a[x,y] = a[x,y] X53; D[x]
			Для y=0 По 4 Цикл
				a[x][y] = ПобитовоеИсключительноеИли64(a[x][y], D[x]);
			КонецЦикла;
		КонецЦикла;
		
		// `1; + `0; [Keccak §2.3.4]
		x = 1;
		y = 0;
		current = a[x][y];
		Для t=0 По nRounds-1 Цикл
			X1 = y;
			Y1 = (2*x + 3*y)%5;
			
			tmp = a[X1][Y1];
			a[X1][Y1] = ЦиклическийСдвигВлево64(current, ((t+1)*(t+2)/2) % w);
			current = tmp;
			x = X1;
			y = Y1;
		КонецЦикла;
        // `7; [Keccak §2.3.1]
        Для y=0 По 4 Цикл
            C = Новый Массив;
			Для x=0 По 4 Цикл
				C.Добавить(a[x][y]);
			КонецЦикла;
            Для x=0 По 4 Цикл
                a[x][y] = ПобитовоеИсключительноеИли64(C[x], ПобитовоеИ64(ПобитовоеНе64(C[(x+1)%5]),  C[(x+2)%5]));
            КонецЦикла;
        КонецЦикла;

        // _3; [Keccak §2.3.5]
        a[0][0] = ПобитовоеИсключительноеИли64(a[0][0], RC[r]);
	КонецЦикла;
	Возврат Неопределено;
КонецФункции // ФункцияПерестановокКечак(a,l,w)  

#КонецОбласти

 

В обработке имеется поле для ввода входной строки, ключа и настроек алгоритма. Для расчёта хеша или HMAC по стандартам нужно выбрать стандарт в соответствующем поле ввода и нажать кнопку "Рассчитатьхеш3" или "Получитьхмак3". Для расчёта хеша по произвольным параметрам достаточно указать битность, префикс, суффикс и длину выхода и нажать кнопку "кечак по параметрам".

Скачать файлы

Наименование Файл Версия Размер
SHA3 и HMAC3 на 1с 8 без использования внешних компонент:

.epf 18,10Kb
9
.epf 1.1 18,10Kb 9 Скачать бесплатно

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
2. mrsmrv 78 08.05.20 16:10 Сейчас в теме
Исправлена ошибка в функции дополнения данных, в случае дополнения одним байтом добавлено сложение Hex значений суффикса1 и суффикса2. Длина суффиксов всё также однобайтовая. Проверок на другу длину суффиксов нет.
5. mrsmrv 78 08.05.20 18:02 Сейчас в теме
(2) ошибка проявлялась при длине входного сообщения таком, что требовалось к входным данным добавлять один байт и этот байт должен содержать оба суффикса. Исправлено в обработке и в статье.
3. mrsmrv 78 08.05.20 17:04 Сейчас в теме
Сервис с онлайн хешированием через http запросы: https://md5calc.com/hash/sha3-512
4. mrsmrv 78 08.05.20 17:50 Сейчас в теме
Интересная статистика по быстродействию: входная строка одна и та-же, в три символа.
Слева SHA3-512, справа SHA2-512
Прикрепленные файлы:
6. mrsmrv 78 14.05.20 12:18 Сейчас в теме
Анализ и улучшение быстродействия.
были выявлены строки кода, которые оказывают наиболее значительное влияние на скорость, Битовые сдвиги 64-х разрядных чисел, с вызовами функций сдвига 32-х разрядных чисел были сначала заменены на деление и умножения числа на степень двойки, прямо в в тексте была применена pow, что улучшило быстродействие, но незначительно. Было решено сформировать массив степеней 2 от 0 до 64-х и передавать его в функции битовых сдвигов. Удалось ускорить общее время выполнения с 5 секунд до 4-х (примерно) на 4-х килобайтной входной строке при вычислении 512 битной HASH3 суммы.
на скриншоте указано цифрами как было и как стало. Строки, которые ускорились помечены одним цветом.

функции битовых операций стали такими:
// функция осуществляет циклический сдвиг влево
//
Функция ЦиклическийСдвигВлево64(лМассивСтепеней2,пЧисло, пСмещение)
	Возврат ПривестиК64Битам(Цел(пЧисло/лМассивСтепеней2[64-пСмещение]) + пЧисло*лМассивСтепеней2[пСмещение]);
КонецФункции // ЦиклическийСдвигВлево64(пЧисло, пСмещение)

// функция осуществляет циклический сдвиг вправо
//
Функция ЦиклическийСдвигВправо64(лМассивСтепеней2,пЧисло, пСмещение)
	Возврат ПривестиК64Битам(Цел(пЧисло/лМассивСтепеней2[пСмещение]) + пЧисло*лМассивСтепеней2[64-пСмещение]);
КонецФункции // ЦиклическийСдвигВправо64(пЧисло, пСмещение)

Функция ПобитовыйСдвигВправо64(лМассивСтепеней2,пЧисло, пСмещение)
	Возврат Цел(пЧисло/лМассивСтепеней2[пСмещение])
КонецФункции // ПобитовыйСдвигВправо64(пЧисло, пСмещение)

Функция ПобитовыйСдвигВлево64(лМассивСтепеней2,пЧисло, пСмещение)
	ПривестиК64Битам(пЧисло*лМассивСтепеней2[пСмещение]);
КонецФункции // ПобитовыйСдвигВлево64(пЧисло, пСмещение)

Функция ПривестиК64Битам(пЧисло)
	Если пЧисло<18446744073709551616 Тогда
		Возврат пЧисло
	Иначе
		Возврат пЧисло%18446744073709551616;
	КонецЕсли;
КонецФункции // ПривестиК64Битам(пЧисло)
Показать


функция получения массива:
Функция ПолучитьМассивСтепеней2()
	лМассивСтепеней2 = Новый Массив;
	Для н=0 по 64 Цикл
		лМассивСтепеней2.Добавить(pow(2,н));
	КонецЦикла;
	Возврат лМассивСтепеней2;
КонецФункции
	
Показать
Прикрепленные файлы:
7. Darklight 27 18.05.20 15:03 Сейчас в теме
Эх... опередили меня с публикацией. Сам седлал всё это полтора года назад, только всё никак не публиковал. Ибо кое-что ещё хотел доделать - и так пока и не доделал. Ну а скорость хеширования средствами 1С - всё-равно низкая настолько, что смысла в этом большого нет (если только хешировать нужно не более 1-2 килобайт данных да и не в цикле)
8. mrsmrv 78 18.05.20 18:13 Сейчас в теме
(7) Да, хеш обычно применяется чтобы подписать сообщение какому-нибудь сервису. Естественно что средствами 1С никто не будет мегабайты данных подписывать. Но, публиковать всё равно надо. Вдруг ваша реализация окажется быстрее, или универсальнее, или экономичнее по памяти. Вот товарищ в решении: https://infostart.ru/public/1179411/ реализовал оказывается keccak, причем было это в январе, правда у него 7 секунд считается хеш, Но реализацию было интересно посмотреть. Правда походу я один скачал это творение.
Оставьте свое сообщение

См. также

Создаем шифрованные ярлыки.

Универсальные обработки Сервисные утилиты Защита и шифрование v8 1cv8.cf Бесплатно (free)

Покопавшись на сайте я нашел как создают ярлыки. Немного переделав под себя выкладываю данную обработку, не претендуя на Авторство. Просто сделал более удобным.

30.09.2009    14292    90    dj_tol    1    

Простой пример защиты конфигурации (1с8)

Информационная безопасность Защита и шифрование v8 1cv8.cf Россия Бесплатно (free)

Самый простой пример защиты конфигурации от несанкционированного использования. Базируется на привязке конфигурации к номеру тома флешки. Не претендует на особую новизну или оригинальность но антиламерскую защиту способна обеспечить. Использует WMI.

18.05.2009    27278    797    YVolohov    45    

Защита информации при обмене данными между информационными базами "Управление производственным предприятием"

Защита и шифрование Разработка внешних компонент Обмен через XML v8 УПП1 Бесплатно (free)

Защита информации при обмене с распределенной базой данных. В крупной фирме имеется одна центральная информационная база 1С:Предприятие 8.1 "Управление производственным предприятием" и несколько периферийных баз, обмен данными происходит через файлы XML. После выявления многочисленных случаев несанкционированного доступа к конфиденциальной информации, а именно кассовым и банковским документам при обмене данными, руководством было решено защитить данные при обмене информацией между центральной базой и периферийными базами. Перемещение данных между базами происходит через файлы XML, по нескольким каналам связи FTP, HTTP, POP, SMTP, а также на сменных носителях (типа USB Flash Drive). В связи с этим решено использовать внешнюю компоненту для шифрования файлов XML и небольшой доработки конфигурации баз данных.

25.11.2008    15899    143    astracrypt    13    

Пример шифрования данных.

Защита и шифрование v8 1cv8.cf Россия Бесплатно (free)

Обработка представляет собой простой пример шифровки/дешифровки произвольного текста, без использования внешних библиотек, средствами Windows (c помощью объекта «CAPICOM.EncryptedData»). Если capicom.dll всё же нет в Вашей версии Windows - то её можно скачать здесь же.

20.11.2008    37388    2356    coder1cv8    69