/* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0" * * Written by Nir Drucker and Shay Gueron * AWS Cryptographic Algorithms Group. * (ndrucker@amazon.com, gueron@amazon.com) */ #include "utilities.h" #include #define BITS_IN_QW 64ULL #define BITS_IN_BYTE 8ULL // Print a new line only if we prints in qw blocks _INLINE_ void print_newline(IN const uint64_t qw_pos) { #ifndef NO_NEWLINE if((qw_pos % 4) == 3) { printf("\n "); } #endif } // This function is stitched for R_BITS vector uint64_t r_bits_vector_weight(IN const r_t *in) { uint64_t acc = 0; for(size_t i = 0; i < (R_SIZE - 1); i++) { acc += __builtin_popcount(in->raw[i]); } acc += __builtin_popcount(in->raw[R_SIZE - 1] & LAST_R_BYTE_MASK); return acc; } // Prints a QW in LE/BE in win/linux format _INLINE_ void print_uint64(IN const uint64_t val) { // If printing in BE is required swap the order of bytes #ifdef PRINT_IN_BE uint64_t tmp = bswap_64(val); #else uint64_t tmp = val; #endif printf("%.16" PRIx64, tmp); #ifndef NO_SPACE printf(" "); #endif } // Last block requires a special handling as we should zero mask all the bits // above the desired number endien - 0 - BE, 1 - LE Return 1 if last block was // printed else 0 _INLINE_ uint8_t print_last_block(IN const uint8_t *last_bytes, IN const uint32_t bits_num, IN const uint32_t endien) { // Floor of bits/64 the reminder is in the next QW const uint32_t qw_num = bits_num / BITS_IN_QW; // How many bits to pad with zero const uint32_t rem_bits = bits_num - (BITS_IN_QW * qw_num); // We read byte byte and not the whole QW to avoid reading bad memory address const uint32_t bytes_num = ((rem_bits % 8) == 0) ? rem_bits / BITS_IN_BYTE : 1 + rem_bits / BITS_IN_BYTE; // Must be signed for the LE loop int i; if(0 == rem_bits) { return 0; } // Mask unneeded bits const uint8_t last_byte = (rem_bits % 8 == 0) ? last_bytes[bytes_num - 1] : last_bytes[bytes_num - 1] & MASK(rem_bits % 8); // BE if(0 == endien) { for(i = 0; (uint32_t)i < (bytes_num - 1); i++) { printf("%.2x", last_bytes[i]); } printf("%.2x", last_byte); for(i++; (uint32_t)i < sizeof(uint64_t); i++) { printf("__"); } } else { for(i = sizeof(uint64_t) - 1; (uint32_t)i >= bytes_num; i--) { printf("__"); } printf("%.2x", last_byte); for(i--; i >= 0; i--) { printf("%.2x", last_bytes[i]); } } #ifndef NO_SPACE printf(" "); #endif return 1; } void print_LE(IN const uint64_t *in, IN const uint32_t bits_num) { const uint32_t qw_num = bits_num / BITS_IN_QW; // Print the MSB QW uint32_t qw_pos = print_last_block((const uint8_t *)&in[qw_num], bits_num, 1); // Print each 8 bytes separated by space (if required) for(int i = ((int)qw_num) - 1; i >= 0; i--, qw_pos++) { print_uint64(in[i]); print_newline(qw_pos); } printf("\n"); } void print_BE(IN const uint64_t *in, IN const uint32_t bits_num) { const uint32_t qw_num = bits_num / BITS_IN_QW; // Print each 16 numbers separatly for(uint32_t i = 0; i < qw_num; ++i) { print_uint64(in[i]); print_newline(i); } // Print the MSB QW print_last_block((const uint8_t *)&in[qw_num], bits_num, 0); printf("\n"); }