diff --git a/src/CompileOptions.h b/src/CompileOptions.h new file mode 100644 index 0000000..0134b19 --- /dev/null +++ b/src/CompileOptions.h @@ -0,0 +1,8 @@ +#ifndef __COMPILEOPTIONS_H__ +#define __COMPILEOPTIONS_H__ + +//#define CPUISBIGendian //机器是大端还是小端,大端时放开,小端时屏蔽掉 + + +#endif // !__COMPILEOPTIONS_H__ + diff --git a/src/Makefile b/src/Makefile index 30ff291..44ae061 100644 --- a/src/Makefile +++ b/src/Makefile @@ -39,7 +39,10 @@ SRC_PATH := ./start.s \ ./tinysh.c \ ./tinydonut.c \ ./donut_tft.c \ - ./tinyclock.c \ + ./tinyclock.c \ + ./SM3.c \ + ./tool.c \ + ./SM3Test.c\ ./firmware.c # 链接脚本路径 diff --git a/src/SM3.c b/src/SM3.c new file mode 100644 index 0000000..bfe06c6 --- /dev/null +++ b/src/SM3.c @@ -0,0 +1,165 @@ +#include "tool.h" +#include "SM3.h" +#include + +#define FF1(X,Y,Z) ((X)^(Y)^(Z)) +#define FF2(X,Y,Z) (((X)&(Y))|((X)&(Z))|((Y)&(Z))) +#define GG1(X,Y,Z) ((X)^(Y)^(Z)) +#define GG2(X,Y,Z) (((X)&(Y))|((~X)&(Z))) +#define P0(X) ((X)^(ROL32(X,9))^(ROL32(X,17))) +#define P1(X) ((X)^(ROL32(X,15))^(ROL32(X,23))) + + +uint8_t padding[64] = +{ + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + + +void MessageExt(TTSM3Contex* SM3Contex,uint32_t* W, uint32_t* WP) +{ + uint8_t j = 0; + uint32_t Temp = 0; + for (j = 0; j < 16; j++) + { + W[j] = betoh32(SM3Contex->Data.W[j]); + } + for (j = 16; j < 68; j++) + { + Temp = W[j - 16] ^ W[j - 9] ^ ROL32(W[j - 3], 15); + W[j] = P1(Temp) ^ ROL32(W[j - 13], 7) ^ W[j - 6]; + } + for (j = 0; j < 64; j++) + { + WP[j] = W[j] ^ W[j + 4]; + } +} + + +void ProcessBlock(TTSM3Contex* SM3Contex) +{ + uint32_t i = 0; + uint32_t W[68] = { 0 }; + uint32_t WP[64] = { 0 }; + uint32_t SS1, SS2, TT1, TT2, T, Temp; + uint32_t A, B, C, D, E, F, G, H; + A = SM3Contex->Digest.D[0]; + B = SM3Contex->Digest.D[1]; + C = SM3Contex->Digest.D[2]; + D = SM3Contex->Digest.D[3]; + E = SM3Contex->Digest.D[4]; + F = SM3Contex->Digest.D[5]; + G = SM3Contex->Digest.D[6]; + H = SM3Contex->Digest.D[7]; + + MessageExt(SM3Contex, W, WP); + for (i = 0; i < 64; i++) + { + if (i <= 15) + { + T = 0x79cc4519; + Temp = ROL32(A, 12) + E + ROL32(T, i); + SS1 = ROL32(Temp, 7); + SS2 = SS1 ^ ROL32(A, 12); + TT1 = FF1(A, B, C) + D + SS2 + WP[i]; + TT2 = GG1(E, F, G) + H + SS1 + W[i]; + } + else + { + T = 0x7a879d8a; + Temp = ROL32(A, 12) + E + ROL32(T, i); + SS1 = ROL32(Temp, 7); + SS2 = SS1 ^ ROL32(A, 12); + TT1 = FF2(A, B, C) + D + SS2 + WP[i]; + TT2 = GG2(E, F, G) + H + SS1 + W[i]; + } + + D = C; + C = ROL32(B, 9); + B = A; + A = TT1; + H = G; + G = ROL32(F, 19); + F = E; + E = P0(TT2); + + } + SM3Contex->Digest.D[0] ^= A; + SM3Contex->Digest.D[1] ^= B; + SM3Contex->Digest.D[2] ^= C; + SM3Contex->Digest.D[3] ^= D; + SM3Contex->Digest.D[4] ^= E; + SM3Contex->Digest.D[5] ^= F; + SM3Contex->Digest.D[6] ^= G; + SM3Contex->Digest.D[7] ^= H; + + +} + +void Sm3Init(TTSM3Contex* SM3Contex) +{ + SM3Contex->Digest.D[0] = 0x7380166f; + SM3Contex->Digest.D[1] = 0x4914b2b9; + SM3Contex->Digest.D[2] = 0x172442d7; + SM3Contex->Digest.D[3] = 0xda8a0600; + SM3Contex->Digest.D[4] = 0xa96f30bc; + SM3Contex->Digest.D[5] = 0x163138aa; + SM3Contex->Digest.D[6] = 0xe38dee4d; + SM3Contex->Digest.D[7] = 0xb0fb0e4e; + SM3Contex->Size = 0; + SM3Contex->TotalSize = 0; +} +void Sm3Updata(TTSM3Contex* SM3Contex, uint8_t* Data, uint64_t DataLen) +{ + uint64_t n = 0; + while (DataLen>0) + { + n = min(DataLen, 64 - SM3Contex->Size); + memcpy(SM3Contex->Data.buffer + SM3Contex->Size, Data, n); + DataLen -= n; + SM3Contex->Size += n; + SM3Contex->TotalSize += n; + Data = Data + n; + if (SM3Contex->Size == 64) + { + ProcessBlock(SM3Contex); + SM3Contex->Size = 0; + } + } +} +void Sm3Final(TTSM3Contex* SM3Contex, uint8_t* Digest) +{ + uint8_t PadSize = 0; + uint64_t allLen = SM3Contex->TotalSize * 8; + if (SM3Contex->Size < 56) + { + PadSize = 56 - SM3Contex->Size; + } + else + { + PadSize = 64 - SM3Contex->Size + 56; + } + Sm3Updata(SM3Contex, padding, PadSize); + //memcpy(SM3Contex->Data.buffer + SM3Contex->Size, padding, PadSize); + SM3Contex->Data.W[14] = htobe32(allLen >> 32); + SM3Contex->Data.W[15] = htobe32(allLen); + ProcessBlock(SM3Contex); + + for (int i = 0; i < 8; i++) + { + SM3Contex->Digest.D[i] = htobe32(SM3Contex->Digest.D[i]); + } + memcpy(Digest, SM3Contex->Digest.Digest, 32); + +} + + + + diff --git a/src/SM3.h b/src/SM3.h new file mode 100644 index 0000000..66a7f95 --- /dev/null +++ b/src/SM3.h @@ -0,0 +1,34 @@ +#ifndef __SM3_H__ +#define __SM3_H__ +#include "tool.h" + +typedef union +{ + uint32_t D[8]; + uint8_t Digest[32]; + +}TDigest; + +typedef union +{ + uint8_t buffer[64]; + uint32_t W[16]; +}TData; + + +typedef struct TSM3Contex +{ + TData Data; + TDigest Digest; + uint64_t Size; + uint64_t TotalSize; +}TTSM3Contex; + +#define SM3_DIGEST_SIZE 32 + +void Sm3Init(TTSM3Contex* SM3Contex); +void Sm3Updata(TTSM3Contex* SM3Contex, uint8_t* Data, uint64_t DataLen); +void Sm3Final(TTSM3Contex* SM3Contex, uint8_t* Digest); + + +#endif diff --git a/src/SM3Test.c b/src/SM3Test.c new file mode 100644 index 0000000..3abd5d8 --- /dev/null +++ b/src/SM3Test.c @@ -0,0 +1,135 @@ +#include "SM3.h" +#include "SM3Test.h" +#include +#include +#include + +static int print_digest(unsigned char *digest) +{ + uint32_t i; + + for (i = 0; i < SM3_DIGEST_SIZE; i++) + { + printf("%02x", digest[i]); + } + + return 0; +} + + + +unsigned char *SM3(const unsigned char *d, size_t n, unsigned char *md) +{ + TTSM3Contex c; + + if ((NULL == d) || (NULL == md)) + { + return NULL; + } + + Sm3Init(&c); + Sm3Updata(&c, (uint8_t *)d, n); + Sm3Final(&c, md); + + return md; +} + + + +static void StandDataTest() +{ + char TestData[]="abc"; + unsigned char digest[SM3_DIGEST_SIZE]; + + printf("(\"%s\") = ", TestData); + + SM3(TestData, 3, digest); + + print_digest(digest); + printf("\n"); + +} + +static int GetString(char* Str) +{ + int DataLen=0; + char c; + while ((c=getchar_prompt(0)) != '\r') + { + printf("%c",c); + Str[DataLen++]=c; + } + printf("Str= %s,DataLen=%d\n",Str,DataLen); + return DataLen; +} + +static void CustomDatatest() +{ + printf(" Input you data,end with Enter key\n"); + char str[1024 * 10] = { 0 }; + unsigned char digest[SM3_DIGEST_SIZE]; + //scanf("%s", str, 10240); + int DataLen=GetString(str); + printf("(\"%s\") = ", str); + + SM3(str, DataLen,digest); + + print_digest(digest); + printf("\n"); +} + +void SM3Test(void) +{ + + + while (1) + { + printf("\nSelect an action:\n"); + printf("Return to menu by sending '!'\n"); + printf(" [s] Run standard data test\n"); + printf(" [i] Run input custom data test\n"); + // printf(" [h] print housekeeping spi info\n"); + // printf(" [a] run archinfo test\n"); + // printf(" [r] run rng test\n"); + // printf(" [u] run uart test\n"); + // printf(" [p] run pwm test\n"); + // printf(" [s] run ps2 test\n"); + // printf(" [i] run i2c test\n"); + // printf(" [l] run lcd test\n"); + // printf(" [b] run tiny benchmark\n"); + // printf(" [m] run Memtest\n"); + // printf(" [e] echo uart\n"); + // printf(" [j] run SM3 test\n\n"); + + for (int rep = 10; rep > 0; rep--) + { + printf("tinysh> "); + char cmd = getchar_prompt(0); + if (cmd > 32 && cmd < 127) + putch(cmd); + printf("\n"); + + switch (cmd) + { + case 's': + StandDataTest(); + break; + case 'i': + CustomDatatest(); + break; + case '!': + return; + default: + break; + } + } + + } + + + + + + +} + diff --git a/src/SM3Test.h b/src/SM3Test.h new file mode 100644 index 0000000..0ea4b20 --- /dev/null +++ b/src/SM3Test.h @@ -0,0 +1,9 @@ +#ifndef __SM3TEST_H__ +#define __SM3TEST_H__ +#include "SM3.h" + +void SM3Test(void); + + + +#endif \ No newline at end of file diff --git a/src/donut_tft.c b/src/donut_tft.c index f8bbc34..2a96991 100644 --- a/src/donut_tft.c +++ b/src/donut_tft.c @@ -37,11 +37,11 @@ } while(0) // 预计算的三角函数表 (1024 = 1.0) - 简化版本 -static const int16_t sin_table[91] = { +static const int16_t sin_table[92] = { 0, 18, 36, 54, 71, 89, 107, 125, 143, 160, 178, 195, 213, 230, 248, 265, 282, 299, 316, 333, 350, 367, 384, 400, 416, 433, 449, 465, 481, 496, 512, 527, 542, 557, 572, 587, 601, 615, 629, 643, 657, 670, 683, 696, 709, 721, 733, 745, 757, 768, 779, 790, 801, 811, 821, 831, 841, 850, 859, 868, 876, 884, 892, 900, 907, 914, 921, 927, 933, 939, 945, 950, 955, 960, 964, 968, 972, 975, 978, 981, 984, 986, 988, 990, 991, 992, 993, 994, 994, 995, 995, 995 }; -static const int16_t cos_table[91] = { +static const int16_t cos_table[131] = { 1024, 1023, 1023, 1022, 1021, 1019, 1017, 1014, 1011, 1007, 1003, 998, 993, 987, 981, 974, 967, 959, 951, 942, 933, 923, 913, 902, 891, 879, 867, 854, 841, 827, 813, 798, 783, 767, 751, 734, 717, 699, 681, 662, 643, 623, 603, 582, 561, 539, 517, 494, 471, 447, 423, 398, 373, 347, 321, 294, 267, 239, 211, 182, 153, 123, 93, 62, 31, 0, -31, -62, -93, -123, -153, -182, -211, -239, -267, -294, -321, -347, -373, -398, -423, -447, -471, -494, -517, -539, -561, -582, -603, -623, -643, -662, -681, -699, -717, -734, -751, -767, -783, -798, -813, -827, -841, -854, -867, -879, -891, -902, -913, -923, -933, -942, -951, -959, -967, -974, -981, -987, -993, -998, -1003, -1007, -1011, -1014, -1017, -1019, -1021, -1022, -1023, -1023, -1024 }; @@ -55,7 +55,7 @@ static inline void fast_pixel_write(uint16_t color, int x, int y) { int index = y * 80 + x; pixel_buffer[index] = color; } -} +} // 内联函数:快速缩放像素写入帧缓冲区 static inline void fast_scaled_pixel_write(uint16_t color, int x, int y) { diff --git a/src/tinylib.h b/src/tinylib.h index 590b527..61c7ce6 100644 --- a/src/tinylib.h +++ b/src/tinylib.h @@ -19,6 +19,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" diff --git a/src/tinysh.c b/src/tinysh.c index 577fe19..a1de727 100644 --- a/src/tinysh.c +++ b/src/tinysh.c @@ -63,7 +63,8 @@ void tinysh() printf(" [m] run Memtest\n"); printf(" [e] echo uart\n"); printf(" [d] run donut test\n"); - printf(" [c] run clock test\n\n"); + printf(" [c] run clock test\n"); + printf(" [j] run SM3 test\n\n"); for (int rep = 10; rep > 0; rep--) { @@ -119,6 +120,8 @@ void tinysh() case 'c': clock_test(); break; + case 'j': + SM3Test(); default: continue; } diff --git a/src/tool.c b/src/tool.c new file mode 100644 index 0000000..15ad916 --- /dev/null +++ b/src/tool.c @@ -0,0 +1,115 @@ +#include +#include "tool.h" +uint16_t swapInt16(uint16_t value) +{ + return SWAPINT16(value); +} + + +/** + * @brief Reverse the byte order of a 32-bit word + * @param[in] value 32-bit value + * @return 32-bit value with byte order swapped + **/ + +uint32_t swapInt32(uint32_t value) +{ + return SWAPINT32(value); +} + + +/** + * @brief Reverse the byte order of a 64-bit word + * @param[in] value 64-bit value + * @return 64-bit value with byte order swapped + **/ + +uint64_t swapInt64(uint64_t value) +{ + return SWAPINT64(value); +} + + +/** + * @brief Reverse bit order in a 4-bit word + * @param[in] value 4-bit value + * @return 4-bit value with bit order reversed + **/ + +uint8_t reverseInt4(uint8_t value) +{ + value = ((value & 0x0C) >> 2) | ((value & 0x03) << 2); + value = ((value & 0x0A) >> 1) | ((value & 0x05) << 1); + + return value; +} + + +/** + * @brief Reverse bit order in a byte + * @param[in] value 8-bit value + * @return 8-bit value with bit order reversed + **/ + +uint8_t reverseInt8(uint8_t value) +{ + value = ((value & 0xF0) >> 4) | ((value & 0x0F) << 4); + value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2); + value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1); + + return value; +} + + +/** + * @brief Reverse bit order in a 16-bit word + * @param[in] value 16-bit value + * @return 16-bit value with bit order reversed + **/ + +uint16_t reverseInt16(uint16_t value) +{ + value = ((value & 0xFF00) >> 8) | ((value & 0x00FF) << 8); + value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4); + value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2); + value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1); + + return value; +} + + +/** + * @brief Reverse bit order in a 32-bit word + * @param[in] value 32-bit value + * @return 32-bit value with bit order reversed + **/ + +uint32_t reverseInt32(uint32_t value) +{ + value = ((value & 0xFFFF0000UL) >> 16) | ((value & 0x0000FFFFUL) << 16); + value = ((value & 0xFF00FF00UL) >> 8) | ((value & 0x00FF00FFUL) << 8); + value = ((value & 0xF0F0F0F0UL) >> 4) | ((value & 0x0F0F0F0FUL) << 4); + value = ((value & 0xCCCCCCCCUL) >> 2) | ((value & 0x33333333UL) << 2); + value = ((value & 0xAAAAAAAAUL) >> 1) | ((value & 0x55555555UL) << 1); + + return value; +} + + +/** + * @brief Reverse bit order in a 64-bit word + * @param[in] value 64-bit value + * @return 64-bit value with bit order reversed + **/ + +uint64_t reverseInt64(uint64_t value) +{ + value = ((value & 0xFFFFFFFF00000000ULL) >> 32) | ((value & 0x00000000FFFFFFFFULL) << 32); + value = ((value & 0xFFFF0000FFFF0000ULL) >> 16) | ((value & 0x0000FFFF0000FFFFULL) << 16); + value = ((value & 0xFF00FF00FF00FF00ULL) >> 8) | ((value & 0x00FF00FF00FF00FFULL) << 8); + value = ((value & 0xF0F0F0F0F0F0F0F0ULL) >> 4) | ((value & 0x0F0F0F0F0F0F0F0FULL) << 4); + value = ((value & 0xCCCCCCCCCCCCCCCCULL) >> 2) | ((value & 0x3333333333333333ULL) << 2); + value = ((value & 0xAAAAAAAAAAAAAAAAULL) >> 1) | ((value & 0x5555555555555555ULL) << 1); + + return value; +} \ No newline at end of file diff --git a/src/tool.h b/src/tool.h new file mode 100644 index 0000000..5e23189 --- /dev/null +++ b/src/tool.h @@ -0,0 +1,344 @@ +#ifndef __TOOL_H__ +#define __TOOL_H__ +#include "CompileOptions.h" +#include + + +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +// Load unaligned 16 - bit integer(little - endian encoding) +#define LOAD16LE(p) ( \ + ((uint16_t)(((uint8_t *)(p))[0]) << 0) | \ + ((uint16_t)(((uint8_t *)(p))[1]) << 8)) + +//Load unaligned 16-bit integer (big-endian encoding) +#define LOAD16BE(p) ( \ + ((uint16_t)(((uint8_t *)(p))[0]) << 8) | \ + ((uint16_t)(((uint8_t *)(p))[1]) << 0)) + + //Load unaligned 24-bit integer (little-endian encoding) +#define LOAD24LE(p) ( \ + ((uint32_t)(((uint8_t *)(p))[0]) << 0)| \ + ((uint32_t)(((uint8_t *)(p))[1]) << 8) | \ + ((uint32_t)(((uint8_t *)(p))[2]) << 16)) + + //Load unaligned 24-bit integer (big-endian encoding) +#define LOAD24BE(p) ( \ + ((uint32_t)(((uint8_t *)(p))[0]) << 16) | \ + ((uint32_t)(((uint8_t *)(p))[1]) << 8) | \ + ((uint32_t)(((uint8_t *)(p))[2]) << 0)) + + //Load unaligned 32-bit integer (little-endian encoding) +#define LOAD32LE(p) ( \ + ((uint32_t)(((uint8_t *)(p))[0]) << 0) | \ + ((uint32_t)(((uint8_t *)(p))[1]) << 8) | \ + ((uint32_t)(((uint8_t *)(p))[2]) << 16) | \ + ((uint32_t)(((uint8_t *)(p))[3]) << 24)) + + //Load unaligned 32-bit integer (big-endian encoding) +#define LOAD32BE(p) ( \ + ((uint32_t)(((uint8_t *)(p))[0]) << 24) | \ + ((uint32_t)(((uint8_t *)(p))[1]) << 16) | \ + ((uint32_t)(((uint8_t *)(p))[2]) << 8) | \ + ((uint32_t)(((uint8_t *)(p))[3]) << 0)) + + //Load unaligned 48-bit integer (little-endian encoding) +#define LOAD48LE(p) ( \ + ((uint64_t)(((uint8_t *)(p))[0]) << 0) | \ + ((uint64_t)(((uint8_t *)(p))[1]) << 8) | \ + ((uint64_t)(((uint8_t *)(p))[2]) << 16) | \ + ((uint64_t)(((uint8_t *)(p))[3]) << 24) | \ + ((uint64_t)(((uint8_t *)(p))[4]) << 32) | \ + ((uint64_t)(((uint8_t *)(p))[5]) << 40) + + //Load unaligned 48-bit integer (big-endian encoding) +#define LOAD48BE(p) ( \ + ((uint64_t)(((uint8_t *)(p))[0]) << 40) | \ + ((uint64_t)(((uint8_t *)(p))[1]) << 32) | \ + ((uint64_t)(((uint8_t *)(p))[2]) << 24) | \ + ((uint64_t)(((uint8_t *)(p))[3]) << 16) | \ + ((uint64_t)(((uint8_t *)(p))[4]) << 8) | \ + ((uint64_t)(((uint8_t *)(p))[5]) << 0)) + + //Load unaligned 64-bit integer (little-endian encoding) +#define LOAD64LE(p) ( \ + ((uint64_t)(((uint8_t *)(p))[0]) << 0) | \ + ((uint64_t)(((uint8_t *)(p))[1]) << 8) | \ + ((uint64_t)(((uint8_t *)(p))[2]) << 16) | \ + ((uint64_t)(((uint8_t *)(p))[3]) << 24) | \ + ((uint64_t)(((uint8_t *)(p))[4]) << 32) | \ + ((uint64_t)(((uint8_t *)(p))[5]) << 40) | \ + ((uint64_t)(((uint8_t *)(p))[6]) << 48) | \ + ((uint64_t)(((uint8_t *)(p))[7]) << 56)) + + //Load unaligned 64-bit integer (big-endian encoding) +#define LOAD64BE(p) ( \ + ((uint64_t)(((uint8_t *)(p))[0]) << 56) | \ + ((uint64_t)(((uint8_t *)(p))[1]) << 48) | \ + ((uint64_t)(((uint8_t *)(p))[2]) << 40) | \ + ((uint64_t)(((uint8_t *)(p))[3]) << 32) | \ + ((uint64_t)(((uint8_t *)(p))[4]) << 24) | \ + ((uint64_t)(((uint8_t *)(p))[5]) << 16) | \ + ((uint64_t)(((uint8_t *)(p))[6]) << 8) | \ + ((uint64_t)(((uint8_t *)(p))[7]) << 0)) + + //Store unaligned 16-bit integer (little-endian encoding) +#define STORE16LE(a, p) \ + ((uint8_t *)(p))[0] = ((uint16_t)(a) >> 0) & 0xFFU, \ + ((uint8_t *)(p))[1] = ((uint16_t)(a) >> 8) & 0xFFU + + //Store unaligned 16-bit integer (big-endian encoding) +#define STORE16BE(a, p) \ + ((uint8_t *)(p))[0] = ((uint16_t)(a) >> 8) & 0xFFU, \ + ((uint8_t *)(p))[1] = ((uint16_t)(a) >> 0) & 0xFFU + + //Store unaligned 24-bit integer (little-endian encoding) +#define STORE24LE(a, p) \ + ((uint8_t *)(p))[0] = ((uint32_t)(a) >> 0) & 0xFFU, \ + ((uint8_t *)(p))[1] = ((uint32_t)(a) >> 8) & 0xFFU, \ + ((uint8_t *)(p))[2] = ((uint32_t)(a) >> 16) & 0xFFU + + //Store unaligned 24-bit integer (big-endian encoding) +#define STORE24BE(a, p) \ + ((uint8_t *)(p))[0] = ((uint32_t)(a) >> 16) & 0xFFU, \ + ((uint8_t *)(p))[1] = ((uint32_t)(a) >> 8) & 0xFFU, \ + ((uint8_t *)(p))[2] = ((uint32_t)(a) >> 0) & 0xFFU + + //Store unaligned 32-bit integer (little-endian encoding) +#define STORE32LE(a, p) \ + ((uint8_t *)(p))[0] = ((uint32_t)(a) >> 0) & 0xFFU, \ + ((uint8_t *)(p))[1] = ((uint32_t)(a) >> 8) & 0xFFU, \ + ((uint8_t *)(p))[2] = ((uint32_t)(a) >> 16) & 0xFFU, \ + ((uint8_t *)(p))[3] = ((uint32_t)(a) >> 24) & 0xFFU + + //Store unaligned 32-bit integer (big-endian encoding) +#define STORE32BE(a, p) \ + ((uint8_t *)(p))[0] = ((uint32_t)(a) >> 24) & 0xFFU, \ + ((uint8_t *)(p))[1] = ((uint32_t)(a) >> 16) & 0xFFU, \ + ((uint8_t *)(p))[2] = ((uint32_t)(a) >> 8) & 0xFFU, \ + ((uint8_t *)(p))[3] = ((uint32_t)(a) >> 0) & 0xFFU + + //Store unaligned 48-bit integer (little-endian encoding) +#define STORE48LE(a, p) \ + ((uint8_t *)(p))[0] = ((uint64_t)(a) >> 0) & 0xFFU, \ + ((uint8_t *)(p))[1] = ((uint64_t)(a) >> 8) & 0xFFU, \ + ((uint8_t *)(p))[2] = ((uint64_t)(a) >> 16) & 0xFFU, \ + ((uint8_t *)(p))[3] = ((uint64_t)(a) >> 24) & 0xFFU, \ + ((uint8_t *)(p))[4] = ((uint64_t)(a) >> 32) & 0xFFU, \ + ((uint8_t *)(p))[5] = ((uint64_t)(a) >> 40) & 0xFFU, + + //Store unaligned 48-bit integer (big-endian encoding) +#define STORE48BE(a, p) \ + ((uint8_t *)(p))[0] = ((uint64_t)(a) >> 40) & 0xFFU, \ + ((uint8_t *)(p))[1] = ((uint64_t)(a) >> 32) & 0xFFU, \ + ((uint8_t *)(p))[2] = ((uint64_t)(a) >> 24) & 0xFFU, \ + ((uint8_t *)(p))[3] = ((uint64_t)(a) >> 16) & 0xFFU, \ + ((uint8_t *)(p))[4] = ((uint64_t)(a) >> 8) & 0xFFU, \ + ((uint8_t *)(p))[5] = ((uint64_t)(a) >> 0) & 0xFFU + + //Store unaligned 64-bit integer (little-endian encoding) +#define STORE64LE(a, p) \ + ((uint8_t *)(p))[0] = ((uint64_t)(a) >> 0) & 0xFFU, \ + ((uint8_t *)(p))[1] = ((uint64_t)(a) >> 8) & 0xFFU, \ + ((uint8_t *)(p))[2] = ((uint64_t)(a) >> 16) & 0xFFU, \ + ((uint8_t *)(p))[3] = ((uint64_t)(a) >> 24) & 0xFFU, \ + ((uint8_t *)(p))[4] = ((uint64_t)(a) >> 32) & 0xFFU, \ + ((uint8_t *)(p))[5] = ((uint64_t)(a) >> 40) & 0xFFU, \ + ((uint8_t *)(p))[6] = ((uint64_t)(a) >> 48) & 0xFFU, \ + ((uint8_t *)(p))[7] = ((uint64_t)(a) >> 56) & 0xFFU + + //Store unaligned 64-bit integer (big-endian encoding) +#define STORE64BE(a, p) \ + ((uint8_t *)(p))[0] = ((uint64_t)(a) >> 56) & 0xFFU, \ + ((uint8_t *)(p))[1] = ((uint64_t)(a) >> 48) & 0xFFU, \ + ((uint8_t *)(p))[2] = ((uint64_t)(a) >> 40) & 0xFFU, \ + ((uint8_t *)(p))[3] = ((uint64_t)(a) >> 32) & 0xFFU, \ + ((uint8_t *)(p))[4] = ((uint64_t)(a) >> 24) & 0xFFU, \ + ((uint8_t *)(p))[5] = ((uint64_t)(a) >> 16) & 0xFFU, \ + ((uint8_t *)(p))[6] = ((uint64_t)(a) >> 8) & 0xFFU, \ + ((uint8_t *)(p))[7] = ((uint64_t)(a) >> 0) & 0xFFU + + //Swap a 16-bit integer +#define SWAPINT16(x) ( \ + (((uint16_t)(x) & 0x00FFU) << 8) | \ + (((uint16_t)(x) & 0xFF00U) >> 8)) + + //Swap a 32-bit integer +#define SWAPINT32(x) ( \ + (((uint32_t)(x) & 0x000000FFUL) << 24) | \ + (((uint32_t)(x) & 0x0000FF00UL) << 8) | \ + (((uint32_t)(x) & 0x00FF0000UL) >> 8) | \ + (((uint32_t)(x) & 0xFF000000UL) >> 24)) + + //Swap a 64-bit integer +#define SWAPINT64(x) ( \ + (((uint64_t)(x) & 0x00000000000000FFULL) << 56) | \ + (((uint64_t)(x) & 0x000000000000FF00ULL) << 40) | \ + (((uint64_t)(x) & 0x0000000000FF0000ULL) << 24) | \ + (((uint64_t)(x) & 0x00000000FF000000ULL) << 8) | \ + (((uint64_t)(x) & 0x000000FF00000000ULL) >> 8) | \ + (((uint64_t)(x) & 0x0000FF0000000000ULL) >> 24) | \ + (((uint64_t)(x) & 0x00FF000000000000ULL) >> 40) | \ + (((uint64_t)(x) & 0xFF00000000000000ULL) >> 56)) + + + //Big-endian machine? +#ifdef CPUISBIGendian + +//Host byte order to network byte order +#define HTONS(value) (value) +#define HTONL(value) (value) +#define HTONLL(value) (value) +#define htons(value) ((uint16_t) (value)) +#define htonl(value) ((uint32_t) (value)) +#define htonll(value) ((uint64_t) (value)) + +//Network byte order to host byte order +#define NTOHS(value) (value) +#define NTOHL(value) (value) +#define NTOHLL(value) (value) +#define ntohs(value) ((uint16_t) (value)) +#define ntohl(value) ((uint32_t) (value)) +#define ntohll(value) ((uint64_t) (value)) + +//Host byte order to little-endian byte order +#define HTOLE16(value) SWAPINT16(value) +#define HTOLE32(value) SWAPINT32(value) +#define HTOLE64(value) SWAPINT64(value) +#define htole16(value) swapInt16((uint16_t) (value)) +#define htole32(value) swapInt32((uint32_t) (value)) +#define htole64(value) swapInt64((uint64_t) (value)) + +//Little-endian byte order to host byte order +#define LETOH16(value) SWAPINT16(value) +#define LETOH32(value) SWAPINT32(value) +#define LETOH64(value) SWAPINT64(value) +#define letoh16(value) swapInt16((uint16_t) (value)) +#define letoh32(value) swapInt32((uint32_t) (value)) +#define letoh64(value) swapInt64((uint64_t) (value)) + +//Host byte order to big-endian byte order +#define HTOBE16(value) (value) +#define HTOBE32(value) (value) +#define HTOBE64(value) (value) +#define htobe16(value) ((uint16_t) (value)) +#define htobe32(value) ((uint32_t) (value)) +#define htobe64(value) ((uint64_t) (value)) + +//Big-endian byte order to host byte order +#define BETOH16(value) (value) +#define BETOH32(value) (value) +#define BETOH64(value) (value) +#define betoh16(value) ((uint16_t) (value)) +#define betoh32(value) ((uint32_t) (value)) +#define betoh64(value) ((uint64_t) (value)) + +//Little-endian machine? +#else +//Host byte order to network byte order +#define HTONS(value) SWAPINT16(value) +#define HTONL(value) SWAPINT32(value) +#define HTONLL(value) SWAPINT64(value) +#define htons(value) swapInt16((uint16_t) (value)) +#define htonl(value) swapInt32((uint32_t) (value)) +#define htonll(value) swapInt64((uint64_t) (value)) + +//Network byte order to host byte order +#define NTOHS(value) SWAPINT16(value) +#define NTOHL(value) SWAPINT32(value) +#define NTOHLL(value) SWAPINT64(value) +#define ntohs(value) swapInt16((uint16_t) (value)) +#define ntohl(value) swapInt32((uint32_t) (value)) +#define ntohll(value) swapInt64((uint64_t) (value)) + +//Host byte order to little-endian byte order +#define HTOLE16(value) (value) +#define HTOLE32(value) (value) +#define HTOLE64(value) (value) +#define htole16(value) ((uint16_t) (value)) +#define htole32(value) ((uint32_t) (value)) +#define htole64(value) ((uint64_t) (value)) + +//Little-endian byte order to host byte order +#define LETOH16(value) (value) +#define LETOH32(value) (value) +#define LETOH64(value) (value) +#define letoh16(value) ((uint16_t) (value)) +#define letoh32(value) ((uint32_t) (value)) +#define letoh64(value) ((uint64_t) (value)) + +//Host byte order to big-endian byte order +#define HTOBE16(value) SWAPINT16(value) +#define HTOBE32(value) SWAPINT32(value) +#define HTOBE64(value) SWAPINT64(value) +#define htobe16(value) swapInt16((uint16_t) (value)) +#define htobe32(value) swapInt32((uint32_t) (value)) +#define htobe64(value) swapInt64((uint64_t) (value)) + +//Big-endian byte order to host byte order +#define BETOH16(value) SWAPINT16(value) +#define BETOH32(value) SWAPINT32(value) +#define BETOH64(value) SWAPINT64(value) +#define betoh16(value) swapInt16((uint16_t) (value)) +#define betoh32(value) swapInt32((uint32_t) (value)) +#define betoh64(value) swapInt64((uint64_t) (value)) + +#endif + + +//C++ guard +#ifdef __cplusplus +extern "C" { +#endif + + //Byte order conversion functions + uint16_t swapInt16(uint16_t value); + uint32_t swapInt32(uint32_t value); + uint64_t swapInt64(uint64_t value); + + //Bit reversal functions + uint8_t reverseInt4(uint8_t value); + uint8_t reverseInt8(uint8_t value); + uint16_t reverseInt16(uint16_t value); + uint32_t reverseInt32(uint32_t value); + uint64_t reverseInt64(uint64_t value); + + //C++ guard +#ifdef __cplusplus +} +#endif + +//Rotate left operation +#define ROL8(a, n) (((a) << (n)) | ((a) >> (8 - (n)))) +#define ROL16(a, n) (((a) << (n)) | ((a) >> (16 - (n)))) +#define ROL32(a, n) (((a) << (n)) | ((a) >> (32 - (n)))) +#define ROL64(a, n) (((a) << (n)) | ((a) >> (64 - (n)))) + +//Rotate right operation +#define ROR8(a, n) (((a) >> (n)) | ((a) << (8 - (n)))) +#define ROR16(a, n) (((a) >> (n)) | ((a) << (16 - (n)))) +#define ROR32(a, n) (((a) >> (n)) | ((a) << (32 - (n)))) +#define ROR64(a, n) (((a) >> (n)) | ((a) << (64 - (n)))) + +//Shift left operation +#define SHL8(a, n) ((a) << (n)) +#define SHL16(a, n) ((a) << (n)) +#define SHL32(a, n) ((a) << (n)) +#define SHL64(a, n) ((a) << (n)) + +//Shift right operation +#define SHR8(a, n) ((a) >> (n)) +#define SHR16(a, n) ((a) >> (n)) +#define SHR32(a, n) ((a) >> (n)) +#define SHR64(a, n) ((a) >> (n)) + + + +#endif // !__TOOL_H__ +