Позвольте мне ответить относительно sha 256, а также sha 512. Вкратце: сам алгоритм не зависит от порядка байтов.Чувствительные элементы к порядку байтов - это когда данные импортируются из байтового буфера в рабочие переменные алгоритма и когда они экспортируются обратно в результат дайджеста - также байтовый буфер.Если импорт / экспорт включает в себя кастинг, то порядок байтов имеет значение.
Где может произойти приведение: в ша 512 есть рабочий буфер 128 байт.В моем коде это определено так:
union
{
U64 w [80]; (see U64 example below)
byte buffer [128];
};
Входные данные копируются в этот байтовый буфер, а затем работа выполняется на W. Это означает, что данные были преобразованы в некоторый 64-битный тип.Эти данные нужно будет поменять местами.в моем случае он поменялся местами для машин с прямым порядком байтов.
Лучшим способом было бы подготовить макрос get, который берет каждый байт и помещает его на правильное место в типе u64.
КогдаАлгоритм завершен, дайджест-результат выводится из рабочих переменных в некоторый байтовый буфер, если это делается с помощью memcpy, его также нужно будет поменять местами.
При реализации sha 512 может произойти другое приведение типов, которое предназначено для64-битные машины - на 32-битных машинах.В моем случае у меня есть 64-битный тип, который определен:
typedef struct {
uint high;
uint low;
} U64;
Предположим, я также определил его для байтов с прямым порядком байтов, как показано ниже:
typedef struct {
uint low;
uint high;
} U64;
А затем алгоритм k initделается так:
static const SHA_U64 k[80] =
{
{0xD728AE22, 0x428A2F98}, {0x23EF65CD, 0x71374491}, ...
...
...
}
Но мне нужно, чтобы логическое значение k [0] .high было одинаковым на любой машине.Таким образом, в этом примере мне понадобится другой массив k с заменой верхнего и нижнего значений.
После сохранения данных в рабочих параметрах любое побитовое манипулирование будет иметь одинаковый результат на обеих машинах с большим и меньшим порядком байтов.
Хороший метод - избегать приведения: импортируйте байты из входного буфера в ваши рабочие параметры с помощью макроса.Работайте с логическими значениями, не думая об отображении памяти.Экспортируйте выходные данные, чтобы переварить результат с помощью макроса.
Макрос для получения 32 битов из байтового буфера в int32 (BE = big endian):
#define GET_BE_BYTES_FROM32(a)
((((NQ_UINT32) (a)[0]) << 24) |
(((NQ_UINT32) (a)[1]) << 16) |
(((NQ_UINT32) (a)[2]) << 8) |
((NQ_UINT32) (a)[3]))
#define GET_LE_BYTES_FROM32(a)
((((NQ_UINT32) (a)[3]) << 24) |
(((NQ_UINT32) (a)[2]) << 16) |
(((NQ_UINT32) (a)[1]) << 8) |
((NQ_UINT32) (a)[0]))