Пошагово объясняем, как работает алгоритм хеширования SHA-2 (SHA-256)
Пошагово разбираемся в алгоритме хеширования SHA-2 (SHA-256) и показываем, как он работает, на реальном примере.
Автор Мария Багулина
SHA-2 (Secure Hash Algorithm 2) — одно из самых популярных семейств алгоритмов хеширования. В этой статье мы разберём каждый шаг алгоритма SHA-256, принадлежащего к SHA-2, и покажем, как он работает на реальном примере.
Что такое хеш-функция?
Если вы хотите узнать больше о хеш-функциях, можете почитать Википедию. Но чтобы понять, о чём пойдёт речь, давайте вспомним три основные цели хеш-функции:
- обеспечить проверку целостности (неизменности) данных;
- принимать ввод любой длины и выводить результат фиксированной длины;
- необратимо изменить данные (ввод не может быть получен из вывода).
SHA-2 и SHA-256
SHA-2 — это семейство алгоритмов с общей идеей хеширования данных. SHA-256 устанавливает дополнительные константы, которые определяют поведение алгоритма SHA-2. Одной из таких констант является размер вывода. «256» и «512» относятся к соответствующим размерам выходных данных в битах.
Мы рассмотрим пример работы SHA-256.
SHA-256 «hello world». Шаг 1. Предварительная обработка
1. Преобразуем «hello world» в двоичный вид:
01101000 01100101 01101100 01101100 01101111 00100000 01110111 01101111 01110010 01101100 01100100
2. Добавим одну единицу:
01101000 01100101 01101100 01101100 01101111 00100000 01110111 01101111 01110010 01101100 01100100 1
3. Заполняем нулями до тех пор, пока данные не станут кратны 512 без последних 64 бит (в нашем случае 448 бит):
01101000 01100101 01101100 01101100 01101111 00100000 01110111 01101111 01110010 01101100 01100100 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
4. Добавим 64 бита в конец, где 64 бита — целое число с порядком байтов big-endian, обозначающее длину входных данных в двоичном виде. В нашем случае 88, в двоичном виде — «1011000».
01101000 01100101 01101100 01101100 01101111 00100000 01110111 01101111 01110010 01101100 01100100 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 01011000
Теперь у нас есть ввод, который всегда будет без остатка делиться на 512.
Шаг 2. Инициализация значений хеша (h)
Создадим 8 значений хеша. Это константы, представляющие первые 32 бита дробных частей квадратных корней первых 8 простых чисел: 2, 3, 5, 7, 11, 13, 17, 19.
h0 := 0x6a09e667 h1 := 0xbb67ae85 h2 := 0x3c6ef372 h3 := 0xa54ff53a h4 := 0x510e527f h5 := 0x9b05688c h6 := 0x1f83d9ab h7 := 0x5be0cd19
Шаг 3. Инициализация округлённых констант (k)
Создадим ещё немного констант, на этот раз их 64. Каждое значение — это первые 32 бита дробных частей кубических корней первых 64 простых чисел (2–311).
0x428a2f98 0x71374491 0xb5c0fbcf 0xe9b5dba5 0x3956c25b 0x59f111f1 0x923f82a4 0xab1c5ed5 0xd807aa98 0x12835b01 0x243185be 0x550c7dc3 0x72be5d74 0x80deb1fe 0x9bdc06a7 0xc19bf174 0xe49b69c1 0xefbe4786 0x0fc19dc6 0x240ca1cc 0x2de92c6f 0x4a7484aa 0x5cb0a9dc 0x76f988da 0x983e5152 0xa831c66d 0xb00327c8 0xbf597fc7 0xc6e00bf3 0xd5a79147 0x06ca6351 0x14292967 0x27b70a85 0x2e1b2138 0x4d2c6dfc 0x53380d13 0x650a7354 0x766a0abb 0x81c2c92e 0x92722c85 0xa2bfe8a1 0xa81a664b 0xc24b8b70 0xc76c51a3 0xd192e819 0xd6990624 0xf40e3585 0x106aa070 0x19a4c116 0x1e376c08 0x2748774c 0x34b0bcb5 0x391c0cb3 0x4ed8aa4a 0x5b9cca4f 0x682e6ff3 0x748f82ee 0x78a5636f 0x84c87814 0x8cc70208 0x90befffa 0xa4506ceb 0xbef9a3f7 0xc67178f2
Шаг 4. Основной цикл
Следующие шаги будут выполняться для каждого 512-битного «куска» входных данных. Наша тестовая фраза «hello world» довольно короткая, поэтому «кусок» всего один. На каждой итерации цикла мы будем изменять значения хеш-функций h0 – h7 , чтобы получить окончательный результат.
Шаг 5. Создаём очередь сообщений (w)
1. Копируем входные данные из шага 1 в новый массив, где каждая запись является 32-битным словом:
01101000011001010110110001101100 01101111001000000111011101101111 01110010011011000110010010000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000001011000
2. Добавляем ещё 48 слов, инициализированных нулями, чтобы получить массив w[0…63] :
01101000011001010110110001101100 01101111001000000111011101101111 01110010011011000110010010000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000001011000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 . . 00000000000000000000000000000000 00000000000000000000000000000000
3. Изменяем нулевые индексы в конце массива, используя следующий алгоритм:
- For i from w[16…63] :s0 = (w[i-15] rightrotate 7) xor (w[i-15] rightrotate 18) xor (w[i-15] righthift 3)s1 = (w[i-2] rightrotate 17) xor (w[i-2] rightrotate 19) xor (w[i-2] righthift 10)w [i] = w[i-16] + s0 + w[i-7] + s1
Давайте посмотрим, как это работает для w[16] :
w[1] rightrotate 7: 01101111001000000111011101101111 -> 11011110110111100100000011101110 w[1] rightrotate 18: 01101111001000000111011101101111 -> 00011101110110111101101111001000 w[1] rightshift 3: 01101111001000000111011101101111 -> 00001101111001000000111011101101 s0 = 11011110110111100100000011101110 XOR 00011101110110111101101111001000 XOR 00001101111001000000111011101101 s0 = 11001110111000011001010111001011 w[14] rightrotate 17: 00000000000000000000000000000000 -> 00000000000000000000000000000000 w[14] rightrotate19: 00000000000000000000000000000000 -> 00000000000000000000000000000000 w[14] rightshift 10: 00000000000000000000000000000000 -> 00000000000000000000000000000000 s1 = 00000000000000000000000000000000 XOR 00000000000000000000000000000000 XOR 00000000000000000000000000000000 s1 = 00000000000000000000000000000000 w[16] = w[0] + s0 + w[9] + s1 w[16] = 01101000011001010110110001101100 + 11001110111000011001010111001011 + 00000000000000000000000000000000 + 00000000000000000000000000000000 // сложение рассчитывается по модулю 2^32 w[16] = 00110111010001110000001000110111
Это оставляет нам 64 слова в нашей очереди сообщений ( w ):
01101000011001010110110001101100 01101111001000000111011101101111 01110010011011000110010010000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000001011000 00110111010001110000001000110111 10000110110100001100000000110001 11010011101111010001000100001011 01111000001111110100011110000010 00101010100100000111110011101101 01001011001011110111110011001001 00110001111000011001010001011101 10001001001101100100100101100100 01111111011110100000011011011010 11000001011110011010100100111010 10111011111010001111011001010101 00001100000110101110001111100110 10110000111111100000110101111101 01011111011011100101010110010011 00000000100010011001101101010010 00000111111100011100101010010100 00111011010111111110010111010110 01101000011001010110001011100110 11001000010011100000101010011110 00000110101011111001101100100101 10010010111011110110010011010111 01100011111110010101111001011010 11100011000101100110011111010111 10000100001110111101111000010110 11101110111011001010100001011011 10100000010011111111001000100001 11111001000110001010110110111000 00010100101010001001001000011001 00010000100001000101001100011101 01100000100100111110000011001101 10000011000000110101111111101001 11010101101011100111100100111000 00111001001111110000010110101101 11111011010010110001101111101111 11101011011101011111111100101001 01101010001101101001010100110100 00100010111111001001110011011000 10101001011101000000110100101011 01100000110011110011100010000101 11000100101011001001100000111010 00010001010000101111110110101101 10110000101100000001110111011001 10011000111100001100001101101111 01110010000101111011100000011110 10100010110101000110011110011010 00000001000011111001100101111011 11111100000101110100111100001010 11000010110000101110101100010110
Шаг 6. Цикл сжатия
- Инициализируем переменные a, b, c, d, e, f, g, h и установим их равными текущим значениям хеша соответственно. h0, h1, h2, h3, h4, h5, h6, h7 .
- Запустим цикл сжатия, который будет изменять значения a…h . Цикл выглядит следующим образом:
- for i from 0 to 63 S1 = (e rightrotate 6) xor (e rightrotate 11) xor (e rightrotate 25)ch = (e and f) xor ((not e) and g)temp1 = h + S1 + ch + k[i] + w[i]S0 = (a rightrotate 2) xor (a rightrotate 13) xor (a rightrotate 22)maj = (a and b) xor (a and c) xor (b and c)temp2 := S0 + majh = gg = ff = ee = d + temp1d = cc = bb = aa = temp1 + temp2
Давайте пройдём первую итерацию. Сложение рассчитывается по модулю 2^32:
a = 0x6a09e667 = 01101010000010011110011001100111 b = 0xbb67ae85 = 10111011011001111010111010000101 c = 0x3c6ef372 = 00111100011011101111001101110010 d = 0xa54ff53a = 10100101010011111111010100111010 e = 0x510e527f = 01010001000011100101001001111111 f = 0x9b05688c = 10011011000001010110100010001100 g = 0x1f83d9ab = 00011111100000111101100110101011 h = 0x5be0cd19 = 01011011111000001100110100011001 e rightrotate 6: 01010001000011100101001001111111 -> 11111101010001000011100101001001 e rightrotate 11: 01010001000011100101001001111111 -> 01001111111010100010000111001010 e rightrotate 25: 01010001000011100101001001111111 -> 10000111001010010011111110101000 S1 = 11111101010001000011100101001001 XOR 01001111111010100010000111001010 XOR 10000111001010010011111110101000 S1 = 00110101100001110010011100101011 e and f: 01010001000011100101001001111111 & 10011011000001010110100010001100 = 00010001000001000100000000001100 not e: 01010001000011100101001001111111 -> 10101110111100011010110110000000 (not e) and g: 10101110111100011010110110000000 & 00011111100000111101100110101011 = 00001110100000011000100110000000 ch = (e and f) xor ((not e) and g) = 00010001000001000100000000001100 xor 00001110100000011000100110000000 = 00011111100001011100100110001100 // k[i] is the round constant // w[i] is the batch temp1 = h + S1 + ch + k[i] + w[i] temp1 = 01011011111000001100110100011001 + 00110101100001110010011100101011 + 00011111100001011100100110001100 + 1000010100010100010111110011000 + 01101000011001010110110001101100 temp1 = 01011011110111010101100111010100 a rightrotate 2: 01101010000010011110011001100111 -> 11011010100000100111100110011001 a rightrotate 13: 01101010000010011110011001100111 -> 00110011001110110101000001001111 a rightrotate 22: 01101010000010011110011001100111 -> 00100111100110011001110110101000 S0 = 11011010100000100111100110011001 XOR 00110011001110110101000001001111 XOR 00100111100110011001110110101000 S0 = 11001110001000001011010001111110 a and b: 01101010000010011110011001100111 & 10111011011001111010111010000101 = 00101010000000011010011000000101 a and c: 01101010000010011110011001100111 & 00111100011011101111001101110010 = 00101000000010001110001001100010 b and c: 10111011011001111010111010000101 & 00111100011011101111001101110010 = 00111000011001101010001000000000 maj = (a and b) xor (a and c) xor (b and c) = 00101010000000011010011000000101 xor 00101000000010001110001001100010 xor 00111000011001101010001000000000 = 00111010011011111110011001100111 temp2 = S0 + maj = 11001110001000001011010001111110 + 00111010011011111110011001100111 = 00001000100100001001101011100101 h = 00011111100000111101100110101011 g = 10011011000001010110100010001100 f = 01010001000011100101001001111111 e = 10100101010011111111010100111010 + 01011011110111010101100111010100 = 00000001001011010100111100001110 d = 00111100011011101111001101110010 c = 10111011011001111010111010000101 b = 01101010000010011110011001100111 a = 01011011110111010101100111010100 + 00001000100100001001101011100101 = 01100100011011011111010010111001
Все расчёты выполняются ещё 63 раза, изменяя переменные а … h . В итоге мы должны получить следующее:
h0 = 6A09E667 = 01101010000010011110011001100111 h1 = BB67AE85 = 10111011011001111010111010000101 h2 = 3C6EF372 = 00111100011011101111001101110010 h3 = A54FF53A = 10100101010011111111010100111010 h4 = 510E527F = 01010001000011100101001001111111 h5 = 9B05688C = 10011011000001010110100010001100 h6 = 1F83D9AB = 00011111100000111101100110101011 h7 = 5BE0CD19 = 01011011111000001100110100011001 a = 4F434152 = 001001111010000110100000101010010 b = D7E58F83 = 011010111111001011000111110000011 c = 68BF5F65 = 001101000101111110101111101100101 d = 352DB6C0 = 000110101001011011011011011000000 e = 73769D64 = 001110011011101101001110101100100 f = DF4E1862 = 011011111010011100001100001100010 g = 71051E01 = 001110001000001010001111000000001 h = 870F00D0 = 010000111000011110000000011010000
Шаг 7. Изменяем окончательные значения
После цикла сжатия, но ещё внутри основного цикла, мы модифицируем значения хеша, добавляя к ним соответствующие переменные a … h . Как обычно, всё сложение происходит по модулю 2^32.
h0 = h0 + a = 10111001010011010010011110111001 h1 = h1 + b = 10010011010011010011111000001000 h2 = h2 + c = 10100101001011100101001011010111 h3 = h3 + d = 11011010011111011010101111111010 h4 = h4 + e = 11000100100001001110111111100011 h5 = h5 + f = 01111010010100111000000011101110 h6 = h6 + g = 10010000100010001111011110101100 h7 = h7 + h = 11100010111011111100110111101001
Шаг 8. Получаем финальный хеш
И последний важный шаг — собираем всё вместе.
digest = h0 append h1 append h2 append h3 append h4 append h5 append h6 append h7 = B94D27B9934D3E08A52E52D7DA7DABFAC484EFE37A5380EE9088F7ACE2EFCDE9
Готово! Мы выполнили каждый шаг SHA-2 (SHA-256) (без некоторых итераций).
Алгоритм SHA-2 в виде псевдокода
Если вы хотите посмотреть на все шаги, которые мы только что сделали, в виде псевдокода, то вот пример:
Пояснения: Все переменные беззнаковые, имеют размер 32 бита и при вычислениях суммируются по модулю 232 message — исходное двоичное сообщение m — преобразованное сообщение Инициализация переменных (первые 32 бита дробных частей квадратных корней первых восьми простых чисел [от 2 до 19]): h0 := 0x6a09e667 h1 := 0xbb67ae85 h2 := 0x3c6ef372 h3 := 0xa54ff53a h4 := 0x510e527f h5 := 0x9b05688c h6 := 0x1f83d9ab h7 := 0x5be0cd19 Таблица констант (первые 32 бита дробных частей кубических корней первых 64 простых чисел [от 2 до 311]): k[ 0..63 ] := 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 Предварительная обработка: m := message ǁ [единичный бит] m := m ǁ [k нулевых бит], где k — наименьшее неотрицательное число, такое что (L + 1 + K) mod 512 = 448, где L — число бит в сообщении (сравнима по модулю 512 c 448) m := m ǁ Длина(message) — длина исходного сообщения в битах в виде 64-битного числа с порядком байтов от старшего к младшему Далее сообщение обрабатывается последовательными порциями по 512 бит: разбить сообщение на куски по 512 бит для каждого куска разбить кусок на 16 слов длиной 32 бита (с порядком байтов от старшего к младшему внутри слова): w[ 0..15 ] Сгенерировать дополнительные 48 слов: для i от 16 до 63 s0 := (w[i-15] rightrotate 7) xor (w[i-15] rightrotate 18) xor (w[i-15] rightshift 3) s1 := (w[i- 2] rightrotate 17) xor (w[i- 2] rightrotate 19) xor (w[i- 2] rightshift 10) w[i] := w[i-16] + s0 + w[i-7] + s1 Инициализация вспомогательных переменных: a := h0 b := h1 c := h2 d := h3 e := h4 f := h5 g := h6 h := h7 Основной цикл: для i от 0 до 63 S1 := (e rightrotate 6) xor (e rightrotate 11) xor (e rightrotate 25) ch := (e and f) xor ((not e) and g) temp1 := h + S1 + ch + k[i] + w[i] S0 := (a rightrotate 2) xor (a rightrotate 13) xor (a rightrotate 22) maj := (a and b) xor (a and c) xor (b and c) temp2 := S0 + maj h := g g := f f := e e := d + temp1 d := c c := b b := a a := temp1 + temp2 Добавить полученные значения к ранее вычисленному результату: h0 := h0 + a h1 := h1 + b h2 := h2 + c h3 := h3 + d h4 := h4 + e h5 := h5 + f h6 := h6 + g h7 := h7 + h Получить итоговое значение хеша SHA-2: digest := hash := h0 append h1 append h2 append h3 append h4 append h5 append h6 append h7
Алгоритм хеширования SHA-256 — что это такое простыми словами и как работает, функции и примеры?
SHA-256 – алгоритм шифрования хэш-функции из семейства SHA-2 (Secure Hash Algorithm, с англ. – Алгоритм безопасного хэширования). Приставка 256 обозначает размер вывода – 256 бит. Существуют и другие форматы: 224, 384, 512.
Разработана для Агентства Национальной Безопасности США (АНБ) в 2001 году. Запатентована под номером 6829355 в США и распространяется свободно по бесплатной лицензии (RF).
Метод хэширования SHA-256 используется правительством и гражданскими учреждениями США согласно Федеральным стандартам обработки информации, для обеспечения защиты данных. А ещё с его помощью генерируются хеши в сети Биткоин.
Предшественник (SHA-1) был успешно атакован. В 2011 году Марк Стивенс доказал возможность коллизионной атаки, а в 2017 Google опубликовал отчёт об успешном её проведении. С тех пор браузеры отказались от SSL-сертификатов на SHA-1, и Windows прекратил поддержку закодированных алгоритмом подписей в 2020 году.
В SHA-256 атаки с нахождением прообраза могут вычислить 52, а при коллизионной атаке пока что удаётся раскрыть 46 раундов из 64.
Что такое алгоритм хэширования и шифрования sha256 (sha 256 algorithm)?

Задача хэширования – превратить информацию в строку. Функция может принять данные неограниченного размера, даже 10 мегабайт текста из 1000 книг. Процесс хеширования происходит раундами (кругами) – так можно уместить в строку любой объем. Но расшифровать обратно уже не получится. Если кому-то удастся это сделать, то алгоритм автоматически потеряет смысл.
Задача шифрования – превратить информацию в условно хаотичный набор символов, расшифровать которые можно только с помощью ключа. Зашифрованный файл размером в 10 мегабайт будет занимать как минимум столько же места, что и является главным отличием его от хэширования: оно превращает любой объем данных в строку одинаковой длины.
Биткоин не использует шифрование. Приставка «крипто» (crypto – encrypt – шифровать) в его обозначении «криптовалюта», была присвоена ему только потому, что его алгоритм цифровой подписи использует методы, основанные на эллиптических кривых, что применяются в шифровании.
Вместо этого пользователь генерирует пару – открытый и закрытый ключ. Они связаны математически, и мы можем утверждать, что получить закрытый ключ из открытого – невозможно, что и подтверждает право владения BTC.
В блокчейне у всех транзакций есть неизрасходованные выходы (UTXO), а проще говоря – балансы. Они связаны с биткоин-адресами и мы можем просматривать их в сети публично. Имея на балансе 1 BTC, у вас есть закрытый ключ от открытого ключа с этим UTXO, а значит вы сможете подписать транзакцию и будет создан новый UTXO с передачей права на открытый ключ получателя.
SHA-256 генерирует строки максимально надёжно на сегодняшний день. Достаточно, чтобы их нельзя было расшифровать, получив закрытые данные из открытого ключа.
Алгоритм удовлетворяет 4 ключевым требованиям:
- Детерминированный (для любого ввода вывод будет одинаковым)
- Уникальный (невозможно, чтобы 2 ввода привели к одинаковому выводу)
- Быстрый (в протоколе Bitcoin скорость примерно 140 Мбит/сек)
- Необратимый (исходное значение не может быть получено из полученного хэша)
Как работает майнинг на кодировке SHA-256?
В интернете есть сайты с конвертацией любого текста с помощью функции SHA-256. Можно попробовать сделать это самому.
Например, слово «Hello»: 185f8db32271fe25f561a. a518007d1764826381969.
Выходная строка неизменна, это отличает хэширование от шифрования. Если другой человек с другого устройства введёт «Hello», он получит ту же строку.
Bitcoin использует двойное хеширование. Полученный хэш, он пропускает повторно через SHA-256. Это нужно во избежание атаки «дней рождения», хотя вероятность её невелика.
Например, вводим полученный хэш от «Hello»: 185f8db32271fe25f561a. da518007d1764826381969 = 52c87cd40ccfbd78. d4c3684ed60f6513e8d16077e5b8e.
По такому принципу собирается и обрабатывается целый ряд данных. Результат – блокчейн. Цепочка блоков, образно растущая вверх. Нижние блоки невозможно достать и подменить, не разрушив при этом всё строение сети.
Древо Меркла
У каждой транзакции есть хэш. Он представляет такую же строку, выводимую с помощью функции SHA-256. Иерархическая принадлежность транзакций образовывает древо вида родитель-ребёнок. Подобно семейному древу, древо Меркла хранит данные обо всех предыдущих транзакциях. Эти данные хранятся у тысяч узлов (нод), и если кто-то попытается подсунуть в сеть ложный баланс или перевод, несоответствие историческому наследию будет обнаружено и отвергнуто сетью.
Корень Меркла добавляется в функцию наоборот. Например: b7a0c5014ae6ecb. 707a42516e94899073 вместо 37099849e61524. 019efbce6ea4105c0a7b.
Версия клиента
Актуальная версия, одобренная сетью. Например: 02000000.
Часть строк принимается в формате 4-byte «little-endian», и это одна из них.
Хэш предыдущего блока
Скрепляет блокчейн, гарантируя, что следующий блок будет ссылаться на прежде подтверждённый.
Вводится наоборот. Например: 05c2ddc616d1b90. 0000000000000000 вместо оригинального 000000000000000. 346f13a009b1d616cdd2c50.
Зеркальное отражение строки избавляет алгоритм от потери детализации. Чем больше значений, тем меньше вероятность того, что сложность окажется слишком трудной или слишком лёгкой.
Метка времени (Timestamp)
В формате системы Unix, количество секунд от начала эпохи (1 января 1970, 00:00).
Принимается сетью, только если число больше медианы временных штампов последних 11 блоков, и меньше медианы штампов, что возвращают подключённые ноды (скорректированное сетью время) + 2 часа.
Биткоин использует беззнаковое целое число для метки времени, поэтому «проблема 2038 года» откладывается еще на 68 лет.
Таргет (Target)
Сложность следующей цели. Пересчитывается каждые 2016 блоков (примерно 2 недели). Если хэшрейт в сети будет расти, увеличится и количество нулей в таргете искомого хеша, что потребует перебора большего количества хэшей при майнинге криптовалюты. И наоборот, уменьшение желающих участвовать в добыче BTC и валидации блоков, уменьшает сложность и «снижает» таргет. За 1 цикл не может быть изменён более чем в х4 раза.
Например таргет генезис блока был 00000000ffff00000000000000. 00000, в 2013 уже 0000000000000529b10000000. 00000, в 2018 – 00000000000000000049500d0. 00000, а в 2021 – 0000000000000000000cdf6f00. 00000. Судя по количеству нулей, можно легко наблюдать рост сложности.
Помещается в функцию тоже в компактном 4-байтном формате вида: f2c9749a.
Нонс (Nonce)
Аббревиатура от числа, используемого единожды, при переборе хэшей.
Мы взяли 5 известных значений, описанных выше и теперь можем начать подставлять nonce в функцию, покуда не будет найден хэш, меньше таргета.
1, 2, 3… 40348, 40349… 168437213, 168437214, 168437215…
Когда нонс подойдёт, и мы получим хэш-значение меньше таргета, установленного сетью, новый блок будет найден. Майнер может добавить в него избранные транзакции (не превышая допустимый размер блока: 1,5 МБ) забетонировать их в нём и получить за это комиссию.
Поиск следующего блока в сети произойдёт с участием этого же набора данных, что теперь изменились в связи с новыми транзакциями в древе Меркла, временем на планете, и т.д.
Особенности SHA-256
SHA-2 – это криптографическая хеш-функция и обычно является строительным блоком для других криптографических конструкций. Удовлетворяя требованиям криптографического хэширования, это односторонняя функция, которая детерминирована, быстро вычисляется, устойчива к атакам с предварительным и вторым прообразом, а также устойчива к коллизиям.
Далее её можно использовать в своих целях, наделяя особенностями. Например Bitcoin сделал двойное SHA-256.
Оборудование для майнинга
В сравнении с алгоритмом RandomX Monero (только CPU), SHA-256 майнинг не может быть устойчив к ASIC или GPU.
Для добычи BTC может использоваться любой процессор. В гонке за скоростью перебора хэшей выигрывают ASIC майнеры (интегральные схемы особого назначения), спроектированные специально под задачу добычи Bitcoin. Самые популярные производители: Bitmain, MicroBT.
SHA-256 – что можно майнить
Все форки Bitcoin пошли по простому пути и используют тот же алгоритм хэширования. Сюда входят известные «альткоины»: Bitcoin Cash, Namecoin, Peercoin, Emercoin и сотни других, менее популярных.
Ethereum разработал собственную функцию Ethash, чтобы допустить к добыче только видеокарты (до момента полного переключения на Ethereum 2.0). Litecoin – Scrypt (в попытках быть резистентным к асикам). Современные криптовалюты предпочитают алгоритм Proof-of-Stake, в которых добыча криптовалют называется стейкингом. Традиционные Proof-of-Work вычисления становятся инвесторам всё менее интересными.
Список криптовалют на SHA-256
Отсортированы по размеру капитализации.
- Bitcoin
- Bitcoin Cash
- Bitcoin SV
- Bitcoin Diamond
- BitcoinV
- Namecoin
- ILCoin
- EmerCoin
- Unobtanium
- Litecoin Cash
- Amoveo
- Freicoin
- Bean Cash
- I0Coin
- ADAMANT Messenger
- Internet Of People
- IXCoin
- Sakura Bloom
- Ultimate Secure Cash
- Qbao
- TerraCoin
- Swing
- PRISM
- Sprouts
- Neutron
- Incakoin
- ZetaCoin
- Nubits
- BitTokens
- TRBO
- И ещё сотни с капитализацией менее 100 тыс. $
Алгоритмы / Хэш-функция SHA-256
SHA-256 представляет собой однонаправленную функцию для создания цифровых отпечатков фиксированной длины (256 бит, 32 байт) из входных данных размером до 2,31 эксабайт (2⁶⁴ бит) и является частным случаем алгоритма из семейства криптографических алгоритмов SHA-2 (Secure Hash Algorithm Version 2) опубликованным АНБ США в 2002 году.
Хеш-функции семейства SHA-2 построены на основе структуры Меркла — Дамгарда.
Исходное сообщение после дополнения разбивается на блоки, каждый блок — на 16 слов. Алгоритм пропускает каждый блок сообщения через цикл с 64 итерациями. На каждой итерации 2 слова преобразуются, функцию преобразования задают остальные слова. Результаты обработки каждого блока складываются, сумма является значением хеш-функции. Так как инициализация внутреннего состояния производится результатом обработки предыдущего блока, то нет возможности обрабатывать блоки параллельно. Графическое представление одной итерации обработки блока данных:
На текущий момент известны методы для конструирования коллизий до 31 итерации. Ввиду алгоритмической схожести SHA-2 с SHA-1 и наличия у последней потенциальных уязвимостей принято решение, что SHA-3 будет базироваться на совершенно ином алгоритме. 2 октября 2012 года NIST утвердил в качестве SHA-3 алгоритм Keccak.
Алгоритм расчёта отпечатка в виде псевдокода:
Пояснения:
Все переменные беззнаковые, имеют размер 32 бита и при вычислениях суммируются по модулю 232
message — исходное двоичное сообщение
m — преобразованное сообщениеИнициализация переменных
(первые 32 бита дробных частей квадратных корней первых восьми простых чисел [от 2 до 19]):
h0 := 0x6A09E667
h1 := 0xBB67AE85
h2 := 0x3C6EF372
h3 := 0xA54FF53A
h4 := 0x510E527F
h5 := 0x9B05688C
h6 := 0x1F83D9AB
h7 := 0x5BE0CD19Таблица констант
(первые 32 бита дробных частей кубических корней первых 64 простых чисел [от 2 до 311]):
k[0..63] :=
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2Предварительная обработка:
m := message ǁ [единичный бит]
m := m ǁ [k нулевых бит], где k — наименьшее неотрицательное число, такое что
(L + 1 + K) mod 512 = 448, где L — число бит в сообщении (сравнима по модулю 512 c 448)
m := m ǁ Длина(message) — длина исходного сообщения в битах в виде 64-битного числа с порядком байтов от старшего к младшемуДалее сообщение обрабатывается последовательными порциями по 512 бит:
разбить сообщение на куски по 512 бит
для каждого куска разбить кусок на 16 слов длиной 32 бита (с порядком байтов от старшего к младшему внутри слова): w[0..15]Сгенерировать дополнительные 48 слов:
для i от 16 до 63
s0 := (w[i-15] rotr 7) xor (w[i-15] rotr 18) xor (w[i-15] shr 3)
s1 := (w[i-2] rotr 17) xor (w[i-2] rotr 19) xor (w[i-2] shr 10)
w[i] := w[i-16] + s0 + w[i-7] + s1
Инициализация вспомогательных переменных:
a := h0
b := h1
c := h2
d := h3
e := h4
f := h5
g := h6
h := h7Основной цикл:
для i от 0 до 63
Σ0 := (a rotr 2) xor (a rotr 13) xor (a rotr 22)
Ma := (a and b) xor (a and c) xor (b and c)
t2 := Σ0 + Ma
Σ1 := (e rotr 6) xor (e rotr 11) xor (e rotr 25)
Ch := (e and f) xor ((not e) and g)
t1 := h + Σ1 + Ch + k[i] + w[i]h := g
g := f
f := e
e := d + t1
d := c
c := b
b := a
a := t1 + t2Добавить полученные значения к ранее вычисленному результату:
h0 := h0 + a
h1 := h1 + b
h2 := h2 + c
h3 := h3 + d
h4 := h4 + e
h5 := h5 + f
h6 := h6 + g
h7 := h7 + hПолучить итоговое значения хеша:
digest = hash = h0 ǁ h1 ǁ h2 ǁ h3 ǁ h4 ǁ h5 ǁ h6 ǁ h7
Алгоритм используется:
- Bitcoin — эмиссия криптовалюты через поиск отпечатков с определёнными рамками значений
- DNSSEC — дайджесты DNSKEY
- DSA — используется для создания электронной цифровой подписи
- IPSec — в протоколах ESP и IKE
- OpenLDAP — хеши паролей
- PGP — используются для создания электронной цифровой подписи
- S/MIME — дайджесты сообщений
- SHACAL-2 — блочный алгоритм шифрования
- X.509 — используются для создания электронной цифровой подписи сертификата
SHA-256: что это и как работает алгоритм шифрования в 2022
![]()
Если вы хотя бы раз интересовались темой майнинга, то встречали такое понятие как «алгоритм хеширования SHA-256». Что это и почему имеет такую важность в теме криптовалюты? Кажется, что человек, далекий от программирования или цифровых систем, не сможет до конца разобраться в том, что это за «внутрянка» цифрового мира. Но это не так, и я собираюсь доказать свою теорию.
Итак, поговорим об алгоритме SHA-256 и о том, как он работает в мире цифровой валюты.
Что такое алгоритм SHA-256?
Начну с того, что мир криптовалюты построен на блокчейне. Это целая система разной информации, которая зашифрована в символы, цифры, знаки. Такая информация объемная и длинная, может содержать большие строки с данными. Чтобы уместить ее в четко отведенное количество символов и строк, была создана хеш-функция.
Она выполняется специальными алгоритмами (да, в цифровом мире очень многое завязано на вычислениях и программных действиях), и одним из таких является алгоритм SHA-256.
Он ― всего лишь небольшая (но самая известная) составляющая целого «семейства» криптографических алгоритмов под название SHA-2. Помимо 256 туда входят 224, 384 и другие. Грубо говоря, SHA-256 ― это артист агентства, в котором работают сотни других талантливых исполнителей, но именно его чаще требуют на бис и именно он приносит компании большую прибыль.
Постараюсь объяснить наглядно, что происходит в процессе хеширования. В цифровом мире любая информация переведена в набор символов, например, в «938db8c9f82c8». Для человека это непонятная околесица, для программ и блокчейна ― текст, аналогичный этой статье: из него можно получить или передать информацию.
Например, вам нужно перевести всю книгу «Маленький принц» Экзюпери в систему блокчейн. Получится, уникальный код, но очень длинный. Если воспользоваться хеш-функцией, его можно сократить до нужного количества символов, при этом суть информации не изменится.
Все, что касается темы хеширования (сокращения данных), напрямую связано с безопасностью и надежностью в цифровом мире. И все семейство SHA-2 в этом плане считается самыми надежными и популярными алгоритмами.
Любая хэш-функция выполняет как минимум 3 задачи:
- полностью изменить исходные данные на новые;
- принять данные любой длины, чтобы на выходе выдать данные четко заданной длины (сократить);
- обеспечить при сокращении данных их безопасность.
А теперь перейдем к насущному вопросу: при чем SHA-256 к теме майнинга? Неважно, интересуетесь ли вы майнинг-пулами или соло-майнингом, информация о хешировании понадобится в любом случае.
Майнинг на алгоритме SHA

Мы с вами ― потребители в мире криптовалюты точно так же, как, например, в фармацевтике. Для того чтобы купить себе таблетку от головной боли, мы не станем лезть в производство этого лекарства, искать лаборантов, а также воочию следить за процессом изготовления или исследованиями. Но состав на упаковке прочитаем обязательно.
То же самое происходит и с цифровым миром, когда становишься его частью. Да, в сложные процессы, которыми занимаются разработчики при создании алгоритмов, криптовалют вроде биткоина или лайткоина, мало кто станет вникать. Но суть всех процессов и то, на чем строится блокчейн, интересна любому пользователю, который стал частью криптомира. Как минимум, чтобы понимать с чем придется работать.
Потому поговорим о майнинге.
Здесь все относительно понятно: купил оборудование, выбрал крипту, настроил устройство для вычисления и начал работать и зарабатывать. Но внутри всегда лежит намного больше, чем на поверхности.
Алгоритм SHA-256 начинался с биткоина. Или наоборот. Дальше многие другие монеты присоединились именно к этому алгоритму хеширования:
- Bitcoin Cash (BCH);
- Syscoin (SYS);
- Peercoin (PPC);
- DigiByte (DGB);
- Namecoin (NMC).
У алгоритма можно выделить один самый большой плюс и один минус. Первое ― его востребованность (большая часть оборудования работает именно на нем, майнеры его очень любят). Второе ― его подконтрольность (из-за того, что SHA во многом зависит от вычислительной мощности оборудования, крупные майнеры пользуются большими привилегиями в нем, чем одиночки и новички).
В процессе майнинга пользователи с помощью специального оборудования и хеширования расшифровывают блок с информацией, а когда сделают это, смогут получить добыть новый блок и вознаграждение. Именно в этом процессе и участвует алгоритм хеширования SHA-256. Чем мощнее оборудование майнера, тем скорее он справится с этой задачей и первым заработает на своей работе. Удивительно, но алгоритм SHA-2 считается устаревшей моделью хеширования, хотя все еще самой популярной и важной для майнеров.
Что понадобится для майнинга?

При майнинге алгоритм SHA-256 используется на оборудовании:
- ASIC;
- GPU (или видеокарты).
Есть еще центральные процессоры, но добыча криптовалюты на них устарела. Выгоднее всего работать с первыми (ASIC), так как они приносят больше прибыли, хотя и более энергозатратны, что обусловлено их вычислительной мощностью. Асики способны справляться с задачами быстро и качественно, они стоят дороже другого оборудования, но и окупаются гораздо быстрее. Многие из них работают исключительно на алгоритме SHA-256 и добывают лояльную ему криптовалюту вроде биткоина.
Купить ASIC в России можно с помощью агентов и посредников, так как на рынке оборудования эти устройства не представлены, как те же смартфоны, например. Выбирая нужную модель, стоит обращать внимание не только на алгоритм хеширования, но обязательно на объем энергопотребления устройства (в конце концов, вам потом платить за электричество), его мощность и систему охлаждения.
А вы уже присмотрели для себя подходящий ASIC? Какую криптовалюту хотели бы добывать на нем?