SHA-3 основан на алгоритме Keccak, разработанном Гвидо Бертоне, Жоаном Даменом, Михаэлем Пеетерсом и Жилем Ван Ассхе. В отличие от предыдущих стандартов семейства SHA (SHA-1, SHA-2), использующих конструкцию Меркла–Дамгарда, Keccak построен на принципиально иной модели — sponge construction (губчатая конструкция).
Губчатая конструкция оперирует внутренним состоянием фиксированного размера и выполняет две фазы:
Внутреннее состояние Keccak представлено как трёхмерный массив битов, обычно обозначаемый как:
A[x][y][z]
где:
x, y — координаты в плоскости 5×5z — глубина (битовая длина слова)Общий размер состояния обозначается как b (например,
1600 бит для SHA-3).
Ключевыми параметрами являются:
Связь:
b = r + c
Для SHA-3:
| Алгоритм | r | c | Выход |
|---|---|---|---|
| SHA3-224 | 1152 | 448 | 224 |
| SHA3-256 | 1088 | 512 | 256 |
| SHA3-384 | 832 | 768 | 384 |
| SHA3-512 | 576 | 1024 | 512 |
Чем больше c, тем выше устойчивость к атакам, но ниже
производительность.
Основой алгоритма является перестановка Keccak-f[b],
состоящая из последовательности раундов. Для b = 1600
используется 24 раунда.
Каждый раунд включает 5 шагов:
Диффузия между столбцами:
Побитовые циклические сдвиги:
Перестановка координат:
Нелинейное преобразование:
Добавление раундовой константы:
Перед обработкой данные дополняются до кратности r.
Используется схема:
pad10*1
Это означает:
11Для SHA-3 добавляется также доменный разделитель:
0x060x01Это отличие делает SHA-3 несовместимым с «чистым» Keccak.
| Характеристика | SHA-2 | SHA-3 (Keccak) |
|---|---|---|
| Конструкция | Меркл–Дамгард | Sponge |
| Уязвимость к length extension | Да | Нет |
| Параллелизм | Ограниченный | Лучше масштабируется |
| Гибкость выхода | Фиксированный | Произвольный |
Библиотека crypto-js предоставляет поддержку SHA-3, но
важно учитывать: реализация соответствует Keccak, а не
финальному стандарту NIST SHA-3.
import CryptoJS from "crypto-js";
или
const CryptoJS = require("crypto-js");
const hash = CryptoJS.SHA3("Hello, world!");
console.log(hash.toString());
По умолчанию используется длина 512 бит.
const hash224 = CryptoJS.SHA3("data", { outputLength: 224 });
const hash256 = CryptoJS.SHA3("data", { outputLength: 256 });
const hash384 = CryptoJS.SHA3("data", { outputLength: 384 });
const hash512 = CryptoJS.SHA3("data", { outputLength: 512 });
Параметр outputLength управляет размером результата.
CryptoJS.SHA3("text").toString();
const wordArray = CryptoJS.enc.Utf8.parse("text");
const hash = CryptoJS.SHA3(wordArray);
hash.toString(CryptoJS.enc.Hex);
Позволяет обрабатывать данные частями:
const sha3 = CryptoJS.algo.SHA3.create();
sha3.update("Hello");
sha3.update(", ");
sha3.update("world");
const hash = sha3.finalize();
Полезно при работе с потоками или большими файлами.
const hmac = CryptoJS.HmacSHA3("message", "secret");
console.log(hmac.toString());
С параметрами:
const hmac = CryptoJS.HmacSHA3("message", "secret", {
outputLength: 256
});
CryptoJS использует структуру WordArray:
sigBytes)Пример:
const data = CryptoJS.enc.Hex.parse("deadbeef");
Keccak также поддерживает SHAKE:
В CryptoJS напрямую не реализованы, но концептуально:
CryptoJS.SHA3(password).toString();
Лучше использовать:
const fileHash = CryptoJS.SHA3(fileContent).toString();
const signature = CryptoJS.HmacSHA3(message, key);
CryptoJS.SHA3("abc").toString();
Результат будет отличаться от:
SHA3-256("abc") по стандарту NIST
Причина — различный padding (доменный разделитель).
outputLength явноСостояние делится на:
Во время absorbing:
state[0:r] ^= input_block
Затем применяется permutation.
Во время squeezing:
output = state[0:r]
При необходимости — повтор permutation.
Уровень безопасности определяется c:
security ≈ c / 2
Например:
const hash = CryptoJS.SHA3("Hello", {
outputLength: 256
});
console.log(hash.toString(CryptoJS.enc.Hex));
const hmac = CryptoJS.HmacSHA3("Important message", "key123", {
outputLength: 512
});
console.log(hmac.toString());
console.log(CryptoJS.SHA3("abc", { outputLength: 256 }).toString());
Сравнение с эталонными SHA-3 значениями выявит несовпадение из-за Keccak-паддинга.
for each round:
θ → ρ → π → χ → ι
Эта последовательность обеспечивает:
В Ethereum используется:
Keccak-256 (не SHA3-256!)
Это совпадает с реализацией CryptoJS, что делает библиотеку полезной для Web3-разработки.