Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2018-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.4//5// Based on https://github.com/noloader/SHA-Intrinsics/blob/master/sha256-x86.c,6// Written and placed in public domain by Jeffrey Walton.7// Based on code from Intel, and by Sean Gulley for the miTLS project.9#if defined(ENABLE_SSE41) && defined(ENABLE_X86_SHANI)11#include <cstddef>12#include <cstdint>13#include <immintrin.h>15#include <attributes.h>17namespace {19alignas(__m128i) const uint8_t MASK[16] = {0x03, 0x02, 0x01, 0x00, 0x07, 0x06, 0x05, 0x04, 0x0b, 0x0a, 0x09, 0x08, 0x0f, 0x0e, 0x0d, 0x0c};20alignas(__m128i) const uint8_t INIT0[16] = {0x8c, 0x68, 0x05, 0x9b, 0x7f, 0x52, 0x0e, 0x51, 0x85, 0xae, 0x67, 0xbb, 0x67, 0xe6, 0x09, 0x6a};21alignas(__m128i) const uint8_t INIT1[16] = {0x19, 0xcd, 0xe0, 0x5b, 0xab, 0xd9, 0x83, 0x1f, 0x3a, 0xf5, 0x4f, 0xa5, 0x72, 0xf3, 0x6e, 0x3c};23void ALWAYS_INLINE QuadRound(__m128i& state0, __m128i& state1, uint64_t k1, uint64_t k0)24{25const __m128i msg = _mm_set_epi64x(k1, k0);26state1 = _mm_sha256rnds2_epu32(state1, state0, msg);27state0 = _mm_sha256rnds2_epu32(state0, state1, _mm_shuffle_epi32(msg, 0x0e));28}30void ALWAYS_INLINE QuadRound(__m128i& state0, __m128i& state1, __m128i m, uint64_t k1, uint64_t k0)31{32const __m128i msg = _mm_add_epi32(m, _mm_set_epi64x(k1, k0));33state1 = _mm_sha256rnds2_epu32(state1, state0, msg);34state0 = _mm_sha256rnds2_epu32(state0, state1, _mm_shuffle_epi32(msg, 0x0e));35}37void ALWAYS_INLINE ShiftMessageA(__m128i& m0, __m128i m1)38{39m0 = _mm_sha256msg1_epu32(m0, m1);40}42void ALWAYS_INLINE ShiftMessageC(__m128i& m0, __m128i m1, __m128i& m2)43{44m2 = _mm_sha256msg2_epu32(_mm_add_epi32(m2, _mm_alignr_epi8(m1, m0, 4)), m1);45}47void ALWAYS_INLINE ShiftMessageB(__m128i& m0, __m128i m1, __m128i& m2)48{49ShiftMessageC(m0, m1, m2);50ShiftMessageA(m0, m1);51}53void ALWAYS_INLINE Shuffle(__m128i& s0, __m128i& s1)54{55const __m128i t1 = _mm_shuffle_epi32(s0, 0xB1);56const __m128i t2 = _mm_shuffle_epi32(s1, 0x1B);57s0 = _mm_alignr_epi8(t1, t2, 0x08);58s1 = _mm_blend_epi16(t2, t1, 0xF0);59}61void ALWAYS_INLINE Unshuffle(__m128i& s0, __m128i& s1)62{63const __m128i t1 = _mm_shuffle_epi32(s0, 0x1B);64const __m128i t2 = _mm_shuffle_epi32(s1, 0xB1);65s0 = _mm_blend_epi16(t1, t2, 0xF0);66s1 = _mm_alignr_epi8(t2, t1, 0x08);67}69__m128i ALWAYS_INLINE Load(const unsigned char* in)70{71return _mm_shuffle_epi8(_mm_loadu_si128((const __m128i*)in), _mm_load_si128((const __m128i*)MASK));72}74void ALWAYS_INLINE Save(unsigned char* out, __m128i s)75{76_mm_storeu_si128((__m128i*)out, _mm_shuffle_epi8(s, _mm_load_si128((const __m128i*)MASK)));77}78}80namespace sha256_x86_shani {81void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks)82{83__m128i m0, m1, m2, m3, s0, s1, so0, so1;85/* Load state */86s0 = _mm_loadu_si128((const __m128i*)s);87s1 = _mm_loadu_si128((const __m128i*)(s + 4));88Shuffle(s0, s1);90while (blocks--) {91/* Remember old state */92so0 = s0;93so1 = s1;95/* Load data and transform */96m0 = Load(chunk);97QuadRound(s0, s1, m0, 0xe9b5dba5b5c0fbcfull, 0x71374491428a2f98ull);98m1 = Load(chunk + 16);99QuadRound(s0, s1, m1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull);100ShiftMessageA(m0, m1);101m2 = Load(chunk + 32);102QuadRound(s0, s1, m2, 0x550c7dc3243185beull, 0x12835b01d807aa98ull);103ShiftMessageA(m1, m2);104m3 = Load(chunk + 48);105QuadRound(s0, s1, m3, 0xc19bf1749bdc06a7ull, 0x80deb1fe72be5d74ull);106ShiftMessageB(m2, m3, m0);107QuadRound(s0, s1, m0, 0x240ca1cc0fc19dc6ull, 0xefbe4786E49b69c1ull);108ShiftMessageB(m3, m0, m1);109QuadRound(s0, s1, m1, 0x76f988da5cb0a9dcull, 0x4a7484aa2de92c6full);110ShiftMessageB(m0, m1, m2);111QuadRound(s0, s1, m2, 0xbf597fc7b00327c8ull, 0xa831c66d983e5152ull);112ShiftMessageB(m1, m2, m3);113QuadRound(s0, s1, m3, 0x1429296706ca6351ull, 0xd5a79147c6e00bf3ull);114ShiftMessageB(m2, m3, m0);115QuadRound(s0, s1, m0, 0x53380d134d2c6dfcull, 0x2e1b213827b70a85ull);116ShiftMessageB(m3, m0, m1);117QuadRound(s0, s1, m1, 0x92722c8581c2c92eull, 0x766a0abb650a7354ull);118ShiftMessageB(m0, m1, m2);119QuadRound(s0, s1, m2, 0xc76c51A3c24b8b70ull, 0xa81a664ba2bfe8a1ull);120ShiftMessageB(m1, m2, m3);121QuadRound(s0, s1, m3, 0x106aa070f40e3585ull, 0xd6990624d192e819ull);122ShiftMessageB(m2, m3, m0);123QuadRound(s0, s1, m0, 0x34b0bcb52748774cull, 0x1e376c0819a4c116ull);124ShiftMessageB(m3, m0, m1);125QuadRound(s0, s1, m1, 0x682e6ff35b9cca4full, 0x4ed8aa4a391c0cb3ull);126ShiftMessageC(m0, m1, m2);127QuadRound(s0, s1, m2, 0x8cc7020884c87814ull, 0x78a5636f748f82eeull);128ShiftMessageC(m1, m2, m3);129QuadRound(s0, s1, m3, 0xc67178f2bef9A3f7ull, 0xa4506ceb90befffaull);131/* Combine with old state */132s0 = _mm_add_epi32(s0, so0);133s1 = _mm_add_epi32(s1, so1);135/* Advance */136chunk += 64;137}139Unshuffle(s0, s1);140_mm_storeu_si128((__m128i*)s, s0);141_mm_storeu_si128((__m128i*)(s + 4), s1);142}143}145namespace sha256d64_x86_shani {147void Transform_2way(unsigned char* out, const unsigned char* in)148{149__m128i am0, am1, am2, am3, as0, as1, aso0, aso1;150__m128i bm0, bm1, bm2, bm3, bs0, bs1, bso0, bso1;152/* Transform 1 */153bs0 = as0 = _mm_load_si128((const __m128i*)INIT0);154bs1 = as1 = _mm_load_si128((const __m128i*)INIT1);155am0 = Load(in);156bm0 = Load(in + 64);157QuadRound(as0, as1, am0, 0xe9b5dba5b5c0fbcfull, 0x71374491428a2f98ull);158QuadRound(bs0, bs1, bm0, 0xe9b5dba5b5c0fbcfull, 0x71374491428a2f98ull);159am1 = Load(in + 16);160bm1 = Load(in + 80);161QuadRound(as0, as1, am1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull);162QuadRound(bs0, bs1, bm1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull);163ShiftMessageA(am0, am1);164ShiftMessageA(bm0, bm1);165am2 = Load(in + 32);166bm2 = Load(in + 96);167QuadRound(as0, as1, am2, 0x550c7dc3243185beull, 0x12835b01d807aa98ull);168QuadRound(bs0, bs1, bm2, 0x550c7dc3243185beull, 0x12835b01d807aa98ull);169ShiftMessageA(am1, am2);170ShiftMessageA(bm1, bm2);171am3 = Load(in + 48);172bm3 = Load(in + 112);173QuadRound(as0, as1, am3, 0xc19bf1749bdc06a7ull, 0x80deb1fe72be5d74ull);174QuadRound(bs0, bs1, bm3, 0xc19bf1749bdc06a7ull, 0x80deb1fe72be5d74ull);175ShiftMessageB(am2, am3, am0);176ShiftMessageB(bm2, bm3, bm0);177QuadRound(as0, as1, am0, 0x240ca1cc0fc19dc6ull, 0xefbe4786E49b69c1ull);178QuadRound(bs0, bs1, bm0, 0x240ca1cc0fc19dc6ull, 0xefbe4786E49b69c1ull);179ShiftMessageB(am3, am0, am1);180ShiftMessageB(bm3, bm0, bm1);181QuadRound(as0, as1, am1, 0x76f988da5cb0a9dcull, 0x4a7484aa2de92c6full);182QuadRound(bs0, bs1, bm1, 0x76f988da5cb0a9dcull, 0x4a7484aa2de92c6full);183ShiftMessageB(am0, am1, am2);184ShiftMessageB(bm0, bm1, bm2);185QuadRound(as0, as1, am2, 0xbf597fc7b00327c8ull, 0xa831c66d983e5152ull);186QuadRound(bs0, bs1, bm2, 0xbf597fc7b00327c8ull, 0xa831c66d983e5152ull);187ShiftMessageB(am1, am2, am3);188ShiftMessageB(bm1, bm2, bm3);189QuadRound(as0, as1, am3, 0x1429296706ca6351ull, 0xd5a79147c6e00bf3ull);190QuadRound(bs0, bs1, bm3, 0x1429296706ca6351ull, 0xd5a79147c6e00bf3ull);191ShiftMessageB(am2, am3, am0);192ShiftMessageB(bm2, bm3, bm0);193QuadRound(as0, as1, am0, 0x53380d134d2c6dfcull, 0x2e1b213827b70a85ull);194QuadRound(bs0, bs1, bm0, 0x53380d134d2c6dfcull, 0x2e1b213827b70a85ull);195ShiftMessageB(am3, am0, am1);196ShiftMessageB(bm3, bm0, bm1);197QuadRound(as0, as1, am1, 0x92722c8581c2c92eull, 0x766a0abb650a7354ull);198QuadRound(bs0, bs1, bm1, 0x92722c8581c2c92eull, 0x766a0abb650a7354ull);199ShiftMessageB(am0, am1, am2);200ShiftMessageB(bm0, bm1, bm2);201QuadRound(as0, as1, am2, 0xc76c51A3c24b8b70ull, 0xa81a664ba2bfe8a1ull);202QuadRound(bs0, bs1, bm2, 0xc76c51A3c24b8b70ull, 0xa81a664ba2bfe8a1ull);203ShiftMessageB(am1, am2, am3);204ShiftMessageB(bm1, bm2, bm3);205QuadRound(as0, as1, am3, 0x106aa070f40e3585ull, 0xd6990624d192e819ull);206QuadRound(bs0, bs1, bm3, 0x106aa070f40e3585ull, 0xd6990624d192e819ull);207ShiftMessageB(am2, am3, am0);208ShiftMessageB(bm2, bm3, bm0);209QuadRound(as0, as1, am0, 0x34b0bcb52748774cull, 0x1e376c0819a4c116ull);210QuadRound(bs0, bs1, bm0, 0x34b0bcb52748774cull, 0x1e376c0819a4c116ull);211ShiftMessageB(am3, am0, am1);212ShiftMessageB(bm3, bm0, bm1);213QuadRound(as0, as1, am1, 0x682e6ff35b9cca4full, 0x4ed8aa4a391c0cb3ull);214QuadRound(bs0, bs1, bm1, 0x682e6ff35b9cca4full, 0x4ed8aa4a391c0cb3ull);215ShiftMessageC(am0, am1, am2);216ShiftMessageC(bm0, bm1, bm2);217QuadRound(as0, as1, am2, 0x8cc7020884c87814ull, 0x78a5636f748f82eeull);218QuadRound(bs0, bs1, bm2, 0x8cc7020884c87814ull, 0x78a5636f748f82eeull);219ShiftMessageC(am1, am2, am3);220ShiftMessageC(bm1, bm2, bm3);221QuadRound(as0, as1, am3, 0xc67178f2bef9A3f7ull, 0xa4506ceb90befffaull);222QuadRound(bs0, bs1, bm3, 0xc67178f2bef9A3f7ull, 0xa4506ceb90befffaull);223as0 = _mm_add_epi32(as0, _mm_load_si128((const __m128i*)INIT0));224bs0 = _mm_add_epi32(bs0, _mm_load_si128((const __m128i*)INIT0));225as1 = _mm_add_epi32(as1, _mm_load_si128((const __m128i*)INIT1));226bs1 = _mm_add_epi32(bs1, _mm_load_si128((const __m128i*)INIT1));228/* Transform 2 */229aso0 = as0;230bso0 = bs0;231aso1 = as1;232bso1 = bs1;233QuadRound(as0, as1, 0xe9b5dba5b5c0fbcfull, 0x71374491c28a2f98ull);234QuadRound(bs0, bs1, 0xe9b5dba5b5c0fbcfull, 0x71374491c28a2f98ull);235QuadRound(as0, as1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull);236QuadRound(bs0, bs1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull);237QuadRound(as0, as1, 0x550c7dc3243185beull, 0x12835b01d807aa98ull);238QuadRound(bs0, bs1, 0x550c7dc3243185beull, 0x12835b01d807aa98ull);239QuadRound(as0, as1, 0xc19bf3749bdc06a7ull, 0x80deb1fe72be5d74ull);240QuadRound(bs0, bs1, 0xc19bf3749bdc06a7ull, 0x80deb1fe72be5d74ull);241QuadRound(as0, as1, 0x240cf2540fe1edc6ull, 0xf0fe4786649b69c1ull);242QuadRound(bs0, bs1, 0x240cf2540fe1edc6ull, 0xf0fe4786649b69c1ull);243QuadRound(as0, as1, 0x16f988fa61b9411eull, 0x6cc984be4fe9346full);244QuadRound(bs0, bs1, 0x16f988fa61b9411eull, 0x6cc984be4fe9346full);245QuadRound(as0, as1, 0xb9d99ec7b019fc65ull, 0xa88e5a6df2c65152ull);246QuadRound(bs0, bs1, 0xb9d99ec7b019fc65ull, 0xa88e5a6df2c65152ull);247QuadRound(as0, as1, 0xc7353eb0fdb1232bull, 0xe70eeaa09a1231c3ull);248QuadRound(bs0, bs1, 0xc7353eb0fdb1232bull, 0xe70eeaa09a1231c3ull);249QuadRound(as0, as1, 0xdc1eeefd5a0f118full, 0xcb976d5f3069bad5ull);250QuadRound(bs0, bs1, 0xdc1eeefd5a0f118full, 0xcb976d5f3069bad5ull);
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.