mirror of
				https://github.com/ton-blockchain/ton
				synced 2025-03-09 15:40:10 +00:00 
			
		
		
		
	* New TVM instructions * Remove PREVBLOCKS * Separate target ton_crypto into TVM-related and -unrelared code * Add fine for failed "send message"; rework SENDMSG * Fix include * Fix bugs, improve action fines * Disable fines for special accounts * Handle msg_balance_remaining.grams == null in transaction.cpp * Bugfixes in SENDMSG * Fix fee calculation in SENDMSG * Fix CellStorageStat and transaction.cpp after merge * SETBOUNCEONACTIONPHASEFAIL instruction * ADDDIVMOD instructions * RUNVM, RUNVMX instructions * Changes in RUNVM * Tests for adddiv and runvm * HASHEXT instruction * Improve opcode-timing More iterations Don't measure preliminary run Remove logs and other excessive operations Add "error" to output * Increase RUNVM gas price * Optimize HASHEXT, adjust gas price * Add "bounce of action fail" flag to actions * Stack operations with unlimited arguments * Ristretto255 instructions * Adjust gas consumption * Optional fixed number of return values in RUNVM, fix exception handling * Adjust gas consumption * Simplify gas consumption logic * Support of secp256k1 and sodium libraries in builds (#11) * add support of secp256k1 library to the builds (linux, win) * add support of secp256k1 library to the builds (linux, win) * install secp256k1 via brew * install libsodium via brew; change sodium to upper case in FindSodium.cmake * install libsodium via brew; change sodium to upper case in FindSodium.cmake * simplify FindSodium.cmake * bug fixing * bug fixing * bug fixing * add macro SODIUM_STATIC * adjust build command for windows * put back original FindSodium.cmake * put back original FindSodium.cmake * fix sodium unzipped path for windows; add ninja * fix sodium unzipped path for windows; add ninja * fix sodium unzipped path for windows; add ninja * Win32 github build for secp256k1 * x64 architecture github build for secp256k1 * fix sodium linking on linux * enable docker buildx arm64 builds from forked repos * enable docker buildx arm64 builds from forked repos * enable docker buildx arm64 builds from forked repos * adjust mac builds for secp2561k and sodium * fix tonlib jni generation * minor fix * sync fixes across platforms * add libsodium build script for android and precompiled static libraries * build tonlib for android (fails) * FindSodium uppercase * remove system libsodium for android, use precompiled instead; specify SECP256K1_INCLUDE_DIR fir mac 12.6 * uppercase sodium * simplify FindSodium * fix windows build sodium path; use ninja for windows * simplify sodium 2 * adjust windows sodium paths; add paths to android jni * add ninja build windows * add ninja build windows * add ninja build windows 2 * remove win ninja * fix 1 * fix 2 * fix win 3 * fix linux compile 3 * fix jni 1 * fix jni 2 and mac * fix jni 3 * fix jni 4 * fix jni 5 * fix mac 6 * fix mac 7 and jni paths * fix jni 8 * rework sodium for android * rework sodium for android * rework sodium for android 2 * fixed sodium for android 2 * fixed sodium for android 3 * static secp256k1 for android * add precompiled arm secp256k1 * add precompiled arm secp256k1 * build native-lib with secp256k1 x86-64 (non arm) * update precompiled with NDK libsecp256k1.a * update precompiled with NDK libsecp256k1.a * update precompiled with NDK libsecp256k1.a * refactor llvm-strip location * refactor llvm-strip location * add native-lib.so for armv7a, armv8a * add native-lib.so for armv7a, armv8a * test armv7a, armv8a * armv7a - fails linking on sodium, test -> armv8a * works x86-64, armv7a - fails linking on sodium, armv8a - fails linking secp256k1 (incompatible with aarch64linux) * update libpsec256k1, sodium static libs * test x86 android native-lib * test armv7 android native-lib * test armv8 android native-lib * x86_64 and arm64 android native-lib works * x86_64 and arm64 android native-lib works * x86_64 and arm64 android native-lib works * test armv7 android native-lib * test all android native-libs * test all android native-libs * test all android native-libs * test all android native-libs - without SodiumAndroid * test all android native-libs - with FindSodiumAndroid.cmake * win, with Sodium via SODIUM_DIR * win, with Sodium via SODIUM_DIR env * win, with Sodium via SODIUM_DIR env * win, with Sodium via SODIUM_DIR env and SODIUM_USE_STATIC_LIBS * win, with Sodium via SODIUM_DIR, SODIUM_USE_STATIC_LIBS and SODIUM_INCLUDE_DIR * android, with FindSodium * android, with FindSodium with SODIUM_USE_STATIC_LIBS * remove if not apple * target_link_libraries(ton_crypto_core PUBLIC secp256k1) * android SECP256K1_INCLUDE_DIRS * android SECP256K1_INCLUDE_DIR * add libsecp256k1.a/so pre-compiled with ubuntu 22 x86-64 * add libsecp256k1.a/so pre-compiled with ubuntu 22 x86-64 * sodium dirs * sodium dirs * sodium dirs * remove NOT APPLE and SodiumAndroid * add NOT APPLE and remove SodiumAndroid * add NOT APPLE and remove SodiumAndroid * remove build scripts for 18.04, reduce CMakeLists.txt * remove build scripts for 18.04, reduce CMakeLists.txt * Fix cas consumption during library load * Fix fetch_config_params after merge * Add all ADDDIVMOD ops to Asm.fif * Save unpaid storage fee to due_payment * Add "set prev blocks info" to emulator * Adjusted builds (#13) * Update flake.nix Add libsodium * add libsecp256k1-dev and libsodium-dev into wasm build * make back emulator a shared library; put emulator to artifacts; compile wasm artifacts with sodium and secp256k1. * add secp256k1 to nix * compile emulator statically with nix * compile emulator statically with nix * compile emulator lib statically with nix * compile emulator lib statically with nix * add libemulator to artifacts * add shared libemulator library to artifacts * minor release fix * update set-output commands; add recent_changelog.md * releases fixes * releases fixes, multiline * releases fixes, multiline * releases fixes, multiline * put back multiline changelog * put back multiline changelog * ConfigParam 19 (global-id) and GLOBALID instruction * Fix gas consumption in HASHEXT * Add blst library * Add bls instructions * Allow passing long code to opcode-timing * Add bls testcase * More BLS instructions * Fix tests, add bls tests * Add more bls tests * Improve some bls operations * Adjust some BLS gas prices * Adjust BLS gas prices * Enable __BLST_PORTABLE__ flag only if PORTABLE flag is set * Add tests for BLS_PAIRING * GASCONSUMED instruction * Fix compilation against docker with blst library; (#14) * fix compilation against docker with blst library; add precompiled libblst.a to android builds * minor fix * Adjust BLKSWX gas * Fix comparison with NAN * Allow arbitrary integers for scalars in ristretto multiplication, fix test * Adjust nix builds according to PR 694 (#15) * integrate and test PR-694 * integrate and test PR-694, test 2 * Add P256_CHKSIGN (secp256r1) --------- Co-authored-by: SpyCheese <mikle98@yandex.ru> Co-authored-by: neodiX42 <namlem@gmail.com>
		
			
				
	
	
		
			473 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			473 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * An implementation of the SHA3 (Keccak) hash function family.
 | |
|  *
 | |
|  * Algorithm specifications: http://keccak.noekeon.org/
 | |
|  * NIST Announcement:
 | |
|  * http://csrc.nist.gov/groups/ST/hash/sha-3/winner_sha-3.html
 | |
|  *
 | |
|  * Written in 2013 by Fabrizio Tarizzo <fabrizio@fabriziotarizzo.org>
 | |
|  *
 | |
|  * ===================================================================
 | |
|  * The contents of this file are dedicated to the public domain. To
 | |
|  * the extent that dedication to the public domain is not available,
 | |
|  * everyone is granted a worldwide, perpetual, royalty-free,
 | |
|  * non-exclusive license to exercise all rights associated with the
 | |
|  * contents of this file for any purpose whatsoever.
 | |
|  * No rights are reserved.
 | |
|  *
 | |
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | |
|  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | |
|  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | |
|  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | |
|  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | |
|  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | |
|  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | |
|  * SOFTWARE.
 | |
|  * ===================================================================
 | |
| */
 | |
| 
 | |
| #include <string.h>
 | |
| #include <assert.h>
 | |
| #include <stdint.h>
 | |
| #include <stdlib.h>
 | |
| 
 | |
| #define KECCAK_F1600_STATE 200
 | |
| #define MIN(x, y) ((x) < (y) ? (x) : (y))
 | |
| #define MAX(x, y) ((x) < (y) ? (x) : (y))
 | |
| 
 | |
| /** Standard errors common to all ciphers **/
 | |
| #define ERR_NULL                1
 | |
| #define ERR_MEMORY              2
 | |
| #define ERR_NOT_ENOUGH_DATA     3
 | |
| #define ERR_ENCRYPT             4
 | |
| #define ERR_DECRYPT             5
 | |
| #define ERR_KEY_SIZE            6
 | |
| #define ERR_NONCE_SIZE          7
 | |
| #define ERR_NR_ROUNDS           8
 | |
| #define ERR_DIGEST_SIZE         9
 | |
| #define ERR_MAX_DATA            10
 | |
| #define ERR_MAX_OFFSET          11
 | |
| #define ERR_BLOCK_SIZE          12
 | |
| #define ERR_TAG_SIZE            13
 | |
| #define ERR_VALUE               14
 | |
| #define ERR_EC_POINT            15
 | |
| #define ERR_EC_CURVE            16
 | |
| #define ERR_MODULUS             17
 | |
| #define ERR_UNKNOWN             32
 | |
| 
 | |
| typedef struct
 | |
| {
 | |
|     uint64_t state[25];
 | |
| 
 | |
|     /*  The buffer is as long as the state,
 | |
|      *  but only 'rate' bytes will be used.
 | |
|      */
 | |
|     uint8_t  buf[KECCAK_F1600_STATE];
 | |
| 
 | |
|     /*  When absorbing, this is the number of bytes in buf that
 | |
|      *  are coming from the message and outstanding.
 | |
|      *  When squeezing, this is the remaining number of bytes
 | |
|      *  that can be used as digest.
 | |
|      */
 | |
|     unsigned valid_bytes;
 | |
| 
 | |
|     /* All values in bytes */
 | |
|     unsigned capacity;
 | |
|     unsigned rate;
 | |
| 
 | |
|     uint8_t  squeezing;
 | |
|     uint8_t  rounds;
 | |
| } keccak_state;
 | |
| 
 | |
| #undef ROL64
 | |
| #define ROL64(x,y) ((((x) << (y)) | (x) >> (64-(y))) & 0xFFFFFFFFFFFFFFFFULL)
 | |
| 
 | |
| static void keccak_function (uint64_t *state, unsigned rounds);
 | |
| 
 | |
| int keccak_reset(keccak_state *state)
 | |
| {
 | |
|     if (NULL == state)
 | |
|         return ERR_NULL;
 | |
| 
 | |
|     memset(state->state, 0, sizeof(state->state));
 | |
|     memset(state->buf, 0, sizeof(state->buf));
 | |
|     state->valid_bytes = 0;
 | |
|     state->squeezing = 0;
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| static void keccak_absorb_internal (keccak_state *self)
 | |
| {
 | |
|     unsigned i,j;
 | |
|     uint64_t d;
 | |
| 
 | |
|     for (i=j=0; j < self->rate; ++i, j += 8) {
 | |
|         d = *(const uint64_t*)(self->buf + j);
 | |
|         self->state[i] ^= d;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void
 | |
| keccak_squeeze_internal (keccak_state *self)
 | |
| {
 | |
|     unsigned i, j;
 | |
| 
 | |
|     for (i=j=0; j < self->rate; ++i, j += 8) {
 | |
|         *(uint64_t*)(self->buf+j) = self->state[i];
 | |
|     }
 | |
| }
 | |
| 
 | |
| int keccak_init (keccak_state **state,
 | |
|                             size_t capacity_bytes,
 | |
|                             uint8_t rounds)
 | |
| {
 | |
|     keccak_state *ks;
 | |
| 
 | |
|     if (NULL == state) {
 | |
|         return ERR_NULL;
 | |
|     }
 | |
| 
 | |
|     *state = ks = (keccak_state*) calloc(1, sizeof(keccak_state));
 | |
|     if (NULL == ks)
 | |
|         return ERR_MEMORY;
 | |
| 
 | |
|     if (capacity_bytes >= KECCAK_F1600_STATE)
 | |
|         return ERR_DIGEST_SIZE;
 | |
| 
 | |
|     if ((rounds != 12) && (rounds != 24))
 | |
|         return ERR_NR_ROUNDS;
 | |
| 
 | |
|     ks->capacity  = (unsigned)capacity_bytes;
 | |
| 
 | |
|     ks->rate      = KECCAK_F1600_STATE - ks->capacity;
 | |
| 
 | |
|     ks->squeezing = 0;
 | |
|     ks->rounds    = rounds;
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| int keccak_destroy(keccak_state *state)
 | |
| {
 | |
|     free(state);
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| int keccak_absorb (keccak_state *self,
 | |
|                               const uint8_t *in,
 | |
|                               size_t length)
 | |
| {
 | |
|     if (NULL==self || NULL==in)
 | |
|         return ERR_NULL;
 | |
| 
 | |
|     if (self->squeezing != 0)
 | |
|         return ERR_UNKNOWN;
 | |
| 
 | |
|     while (length > 0) {
 | |
|         unsigned tc;
 | |
|         unsigned left;
 | |
| 
 | |
|         left = self->rate - self->valid_bytes;
 | |
|         tc = (unsigned) MIN(length, left);
 | |
|         memcpy(self->buf + self->valid_bytes, in, tc);
 | |
| 
 | |
|         self->valid_bytes += tc;
 | |
|         in                += tc;
 | |
|         length            -= tc;
 | |
| 
 | |
|         if (self->valid_bytes == self->rate) {
 | |
|             keccak_absorb_internal (self);
 | |
|             keccak_function(self->state, self->rounds);
 | |
|             self->valid_bytes = 0;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| static void keccak_finish (keccak_state *self, uint8_t padding)
 | |
| {
 | |
|     assert(self->squeezing == 0);
 | |
|     assert(self->valid_bytes < self->rate);
 | |
| 
 | |
|     /* Padding */
 | |
|     memset(self->buf + self->valid_bytes, 0, self->rate - self->valid_bytes);
 | |
|     self->buf[self->valid_bytes] = padding;
 | |
|     self->buf[self->rate-1] |= 0x80;
 | |
| 
 | |
|     /* Final absorb */
 | |
|     keccak_absorb_internal (self);
 | |
|     keccak_function (self->state, self->rounds);
 | |
| 
 | |
|     /* First squeeze */
 | |
|     self->squeezing = 1;
 | |
|     keccak_squeeze_internal (self);
 | |
|     self->valid_bytes = self->rate;
 | |
| }
 | |
| 
 | |
| int keccak_squeeze (keccak_state *self, uint8_t *out, size_t length, uint8_t padding)
 | |
| {
 | |
|     if ((NULL == self) || (NULL == out))
 | |
|         return ERR_NULL;
 | |
| 
 | |
|     if (self->squeezing == 0) {
 | |
|         keccak_finish (self, padding);
 | |
|     }
 | |
| 
 | |
|     assert(self->squeezing == 1);
 | |
|     assert(self->valid_bytes > 0);
 | |
|     assert(self->valid_bytes <= self->rate);
 | |
| 
 | |
|     while (length > 0) {
 | |
|         unsigned tc;
 | |
| 
 | |
|         tc = (unsigned)MIN(self->valid_bytes, length);
 | |
|         memcpy(out, self->buf + (self->rate - self->valid_bytes), tc);
 | |
| 
 | |
|         self->valid_bytes -= tc;
 | |
|         out               += tc;
 | |
|         length            -= tc;
 | |
| 
 | |
|         if (self->valid_bytes == 0) {
 | |
|             keccak_function (self->state, self->rounds);
 | |
|             keccak_squeeze_internal (self);
 | |
|             self->valid_bytes = self->rate;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| int keccak_digest(keccak_state *state, uint8_t *digest, size_t len, uint8_t padding)
 | |
| {
 | |
|     keccak_state tmp;
 | |
| 
 | |
|     if ((NULL==state) || (NULL==digest))
 | |
|         return ERR_NULL;
 | |
| 
 | |
|     if (2*len != state->capacity)
 | |
|         return ERR_UNKNOWN;
 | |
| 
 | |
|     tmp = *state;
 | |
|     return keccak_squeeze(&tmp, digest, len, padding);
 | |
| }
 | |
| 
 | |
| int keccak_copy(const keccak_state *src, keccak_state *dst)
 | |
| {
 | |
|     if (NULL == src || NULL == dst) {
 | |
|         return ERR_NULL;
 | |
|     }
 | |
| 
 | |
|     *dst = *src;
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| /* Keccak core function */
 | |
| 
 | |
| #define KECCAK_ROUNDS 24
 | |
| 
 | |
| #define ROT_01 36
 | |
| #define ROT_02 3
 | |
| #define ROT_03 41
 | |
| #define ROT_04 18
 | |
| #define ROT_05 1
 | |
| #define ROT_06 44
 | |
| #define ROT_07 10
 | |
| #define ROT_08 45
 | |
| #define ROT_09 2
 | |
| #define ROT_10 62
 | |
| #define ROT_11 6
 | |
| #define ROT_12 43
 | |
| #define ROT_13 15
 | |
| #define ROT_14 61
 | |
| #define ROT_15 28
 | |
| #define ROT_16 55
 | |
| #define ROT_17 25
 | |
| #define ROT_18 21
 | |
| #define ROT_19 56
 | |
| #define ROT_20 27
 | |
| #define ROT_21 20
 | |
| #define ROT_22 39
 | |
| #define ROT_23 8
 | |
| #define ROT_24 14
 | |
| 
 | |
| static const uint64_t roundconstants[KECCAK_ROUNDS] = {
 | |
|     0x0000000000000001ULL,
 | |
|     0x0000000000008082ULL,
 | |
|     0x800000000000808aULL,
 | |
|     0x8000000080008000ULL,
 | |
|     0x000000000000808bULL,
 | |
|     0x0000000080000001ULL,
 | |
|     0x8000000080008081ULL,
 | |
|     0x8000000000008009ULL,
 | |
|     0x000000000000008aULL,
 | |
|     0x0000000000000088ULL,
 | |
|     0x0000000080008009ULL,
 | |
|     0x000000008000000aULL,
 | |
|     0x000000008000808bULL,
 | |
|     0x800000000000008bULL,
 | |
|     0x8000000000008089ULL,
 | |
|     0x8000000000008003ULL,
 | |
|     0x8000000000008002ULL,
 | |
|     0x8000000000000080ULL,
 | |
|     0x000000000000800aULL,
 | |
|     0x800000008000000aULL,
 | |
|     0x8000000080008081ULL,
 | |
|     0x8000000000008080ULL,
 | |
|     0x0000000080000001ULL,
 | |
|     0x8000000080008008ULL
 | |
| };
 | |
| 
 | |
| static void keccak_function (uint64_t *state, unsigned rounds)
 | |
| {
 | |
|     unsigned i;
 | |
|     unsigned start_round;
 | |
| 
 | |
|     /* Temporary variables to avoid indexing overhead */
 | |
|     uint64_t a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12;
 | |
|     uint64_t a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24;
 | |
| 
 | |
|     uint64_t b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12;
 | |
|     uint64_t b13, b14, b15, b16, b17, b18, b19, b20, b21, b22, b23, b24;
 | |
| 
 | |
|     uint64_t c0, c1, c2, c3, c4, d;
 | |
| 
 | |
|     a0  = state[0];
 | |
|     a1  = state[1];
 | |
|     a2  = state[2];
 | |
|     a3  = state[3];
 | |
|     a4  = state[4];
 | |
|     a5  = state[5];
 | |
|     a6  = state[6];
 | |
|     a7  = state[7];
 | |
|     a8  = state[8];
 | |
|     a9  = state[9];
 | |
|     a10 = state[10];
 | |
|     a11 = state[11];
 | |
|     a12 = state[12];
 | |
|     a13 = state[13];
 | |
|     a14 = state[14];
 | |
|     a15 = state[15];
 | |
|     a16 = state[16];
 | |
|     a17 = state[17];
 | |
|     a18 = state[18];
 | |
|     a19 = state[19];
 | |
|     a20 = state[20];
 | |
|     a21 = state[21];
 | |
|     a22 = state[22];
 | |
|     a23 = state[23];
 | |
|     a24 = state[24];
 | |
| 
 | |
|     if (rounds == 24)
 | |
|         start_round = 0;
 | |
|     else /* rounds == 12 */
 | |
|         start_round = 12;
 | |
| 
 | |
|     for (i = start_round; i < KECCAK_ROUNDS; ++i) {
 | |
|         /*
 | |
|            Uses temporary variables and loop unrolling to
 | |
|            avoid array indexing and inner loops overhead
 | |
|         */
 | |
| 
 | |
|         /* Prepare column parity for Theta step */
 | |
|         c0 = a0 ^ a5 ^ a10 ^ a15 ^ a20;
 | |
|         c1 = a1 ^ a6 ^ a11 ^ a16 ^ a21;
 | |
|         c2 = a2 ^ a7 ^ a12 ^ a17 ^ a22;
 | |
|         c3 = a3 ^ a8 ^ a13 ^ a18 ^ a23;
 | |
|         c4 = a4 ^ a9 ^ a14 ^ a19 ^ a24;
 | |
| 
 | |
|         /* Theta + Rho + Pi steps */
 | |
|         d   = c4 ^ ROL64(c1, 1);
 | |
|         b0  = d ^ a0;
 | |
|         b16 = ROL64(d ^ a5,  ROT_01);
 | |
|         b7  = ROL64(d ^ a10, ROT_02);
 | |
|         b23 = ROL64(d ^ a15, ROT_03);
 | |
|         b14 = ROL64(d ^ a20, ROT_04);
 | |
| 
 | |
|         d   = c0 ^ ROL64(c2, 1);
 | |
|         b10 = ROL64(d ^ a1,  ROT_05);
 | |
|         b1  = ROL64(d ^ a6,  ROT_06);
 | |
|         b17 = ROL64(d ^ a11, ROT_07);
 | |
|         b8  = ROL64(d ^ a16, ROT_08);
 | |
|         b24 = ROL64(d ^ a21, ROT_09);
 | |
| 
 | |
|         d   = c1 ^ ROL64(c3, 1);
 | |
|         b20 = ROL64(d ^ a2,  ROT_10);
 | |
|         b11 = ROL64(d ^ a7,  ROT_11);
 | |
|         b2  = ROL64(d ^ a12, ROT_12);
 | |
|         b18 = ROL64(d ^ a17, ROT_13);
 | |
|         b9  = ROL64(d ^ a22, ROT_14);
 | |
| 
 | |
|         d   = c2 ^ ROL64(c4, 1);
 | |
|         b5  = ROL64(d ^ a3,  ROT_15);
 | |
|         b21 = ROL64(d ^ a8,  ROT_16);
 | |
|         b12 = ROL64(d ^ a13, ROT_17);
 | |
|         b3  = ROL64(d ^ a18, ROT_18);
 | |
|         b19 = ROL64(d ^ a23, ROT_19);
 | |
| 
 | |
|         d   = c3 ^ ROL64(c0, 1);
 | |
|         b15 = ROL64(d ^ a4,  ROT_20);
 | |
|         b6  = ROL64(d ^ a9,  ROT_21);
 | |
|         b22 = ROL64(d ^ a14, ROT_22);
 | |
|         b13 = ROL64(d ^ a19, ROT_23);
 | |
|         b4  = ROL64(d ^ a24, ROT_24);
 | |
| 
 | |
|         /* Chi + Iota steps */
 | |
|         a0  = b0  ^ (~b1  & b2) ^ roundconstants[i];
 | |
|         a1  = b1  ^ (~b2  & b3);
 | |
|         a2  = b2  ^ (~b3  & b4);
 | |
|         a3  = b3  ^ (~b4  & b0);
 | |
|         a4  = b4  ^ (~b0  & b1);
 | |
| 
 | |
|         a5  = b5  ^ (~b6  & b7);
 | |
|         a6  = b6  ^ (~b7  & b8);
 | |
|         a7  = b7  ^ (~b8  & b9);
 | |
|         a8  = b8  ^ (~b9  & b5);
 | |
|         a9  = b9  ^ (~b5  & b6);
 | |
| 
 | |
|         a10 = b10 ^ (~b11 & b12);
 | |
|         a11 = b11 ^ (~b12 & b13);
 | |
|         a12 = b12 ^ (~b13 & b14);
 | |
|         a13 = b13 ^ (~b14 & b10);
 | |
|         a14 = b14 ^ (~b10 & b11);
 | |
| 
 | |
|         a15 = b15 ^ (~b16 & b17);
 | |
|         a16 = b16 ^ (~b17 & b18);
 | |
|         a17 = b17 ^ (~b18 & b19);
 | |
|         a18 = b18 ^ (~b19 & b15);
 | |
|         a19 = b19 ^ (~b15 & b16);
 | |
| 
 | |
|         a20 = b20 ^ (~b21 & b22);
 | |
|         a21 = b21 ^ (~b22 & b23);
 | |
|         a22 = b22 ^ (~b23 & b24);
 | |
|         a23 = b23 ^ (~b24 & b20);
 | |
|         a24 = b24 ^ (~b20 & b21);
 | |
|     }
 | |
| 
 | |
|     state[0]  = a0;
 | |
|     state[1]  = a1;
 | |
|     state[2]  = a2;
 | |
|     state[3]  = a3;
 | |
|     state[4]  = a4;
 | |
|     state[5]  = a5;
 | |
|     state[6]  = a6;
 | |
|     state[7]  = a7;
 | |
|     state[8]  = a8;
 | |
|     state[9]  = a9;
 | |
|     state[10] = a10;
 | |
|     state[11] = a11;
 | |
|     state[12] = a12;
 | |
|     state[13] = a13;
 | |
|     state[14] = a14;
 | |
|     state[15] = a15;
 | |
|     state[16] = a16;
 | |
|     state[17] = a17;
 | |
|     state[18] = a18;
 | |
|     state[19] = a19;
 | |
|     state[20] = a20;
 | |
|     state[21] = a21;
 | |
|     state[22] = a22;
 | |
|     state[23] = a23;
 | |
|     state[24] = a24;
 | |
| }
 |