编辑代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>

/*******************************************************************************************
 ***** sha256 *****
 *******************************************************************************************/
#define SHA256_DIGEST_SIZE 32   // SHA256 输出 32-byte 摘要

/* 带符号整数类型 */
typedef   signed        char    int8_t;
typedef   signed short  int     int16_t;
typedef   signed        int     int32_t;

/* 无符号整数类型 */
typedef unsigned        char    uint8_t;    //  8-bit -> byte
typedef unsigned short  int     uint16_t;
typedef unsigned        int     uint32_t;   // 32-bit -> word

/********************************************************************
 * Context Structure
 *
 * SHA256 运算所使用的数据结构
 *********************************************************************/
typedef struct {
    uint8_t             data[64];   // 数据缓冲区: 消息的当前分块(512-bit)
    uint32_t            datalen;    // 数据缓冲区当前长度
    uint32_t            state[8];   // 存储哈希运算的中间状态
    unsigned long long  bitlen;     // 消息总长度: 单位 bit
} SHA256_CTX;

/********************************************************************
 P-CODE:
    Note: All variables are unsigned 32 bits and wrap modulo 232 when calculating

    Initialize variables
    (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
    h0 := 0x6a09e667
    h1 := 0xbb67ae85
    h2 := 0x3c6ef372
    h3 := 0xa54ff53a
    h4 := 0x510e527f
    h5 := 0x9b05688c
    h6 := 0x1f83d9ab
    h7 := 0x5be0cd19

    Initialize table of round constants
    (first 32 bits of the fractional parts of the cube roots of the first 64 primes 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

    Pre-processing:
    append the bit '1' to the message
    append k bits '0', where k is the minimum number >= 0 such that the resulting message
        length (in bits) is congruent to 448(mod 512)
    append length of message (before pre-processing), in bits, as 64-bit big-endian integer

    Process the message in successive 512-bit chunks:
    break message into 512-bit chunks
    for each chunk
        break chunk into sixteen 32-bit big-endian words w[0..15]

        Extend the sixteen 32-bit words into sixty-four 32-bit words:
        for i from 16 to 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

        Initialize hash value for this chunk:
        a := h0
        b := h1
        c := h2
        d := h3
        e := h4
        f := h5
        g := h6
        h := h7

        Main loop:
        for i from 0 to 63
            s0 := (a rightrotate 2) xor (a rightrotate 13) xor(a rightrotate 22)
            maj := (a and b) xor (a and c) xor(b and c)
            t2 := s0 + maj
            s1 := (e rightrotate 6) xor (e rightrotate 11) xor(e rightrotate 25)
            ch := (e and f) xor ((not e) and g)
            t1 := h + s1 + ch + k[i] + w[i]
            h := g
            g := f
            f := e
            e := d + t1
            d := c
            c := b
            b := a
            a := t1 + t2

        Add this chunk's hash to result so far:
        h0 := h0 + a
        h1 := h1 + b
        h2 := h2 + c
        h3 := h3 + d
        h4 := h4 + e
        h5 := h5 + f
        h6 := h6 + g
        h7 := h7 + h

    Produce the final hash value (big-endian):
    digest = hash = h0 append h1 append h2 append h3 append h4 append h5 append h6 append h7
********************************************************************/

/* 逻辑运算 */
#define ROTLEFT(a,b)    (((a) << (b)) | ((a) >> (32-(b))))
#define ROTRIGHT(a,b)   (((a) >> (b)) | ((a) << (32-(b))))

/* SHA256 非线性操作 */
#define CH(x,y,z)   (((x) & (y)) ^ (~(x) & (z)))
#define MAJ(x,y,z)  (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
#define EP0(x)      (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
#define EP1(x)      (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
#define SIG0(x)     (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
#define SIG1(x)     (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))

/* 常量 */
static const uint32_t k[64] = {
    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
};


/********************************************************************
 * SHA-256 循环加密操作
 *
 * 参数说明:
 *  ctx:    数据结构 SHA256_CTX
 *  data:   待加密数据, 一明文分组长度 (512-bit, 64-byte, 16-word)
 ********************************************************************/
void sha256_transform(SHA256_CTX* ctx, const uint8_t data[]) {
    uint32_t a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];

    // 初始化数据
    for (i = 0, j = 0; i < 16; ++i, j += 4)
        m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
    for (; i < 64; ++i)
        m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];

    a = ctx->state[0];
    b = ctx->state[1];
    c = ctx->state[2];
    d = ctx->state[3];
    e = ctx->state[4];
    f = ctx->state[5];
    g = ctx->state[6];
    h = ctx->state[7];

    for (i = 0; i < 64; ++i) {
        t1 = h + EP1(e) + CH(e, f, g) + k[i] + m[i];
        t2 = EP0(a) + MAJ(a, b, c);
        h = g;
        g = f;
        f = e;
        e = d + t1;
        d = c;
        c = b;
        b = a;
        a = t1 + t2;
    }

    ctx->state[0] += a;
    ctx->state[1] += b;
    ctx->state[2] += c;
    ctx->state[3] += d;
    ctx->state[4] += e;
    ctx->state[5] += f;
    ctx->state[6] += g;
    ctx->state[7] += h;
}

/********************************************************************
 * SHA256 上下文初始化
 *
 * 参数说明:
 *  ctx:    数据结构 SHA256_CTX
 ********************************************************************/
void sha256_init(SHA256_CTX* ctx) {
    ctx->datalen = 0;
    ctx->bitlen = 0;
    ctx->state[0] = 0x6a09e667;
    ctx->state[1] = 0xbb67ae85;
    ctx->state[2] = 0x3c6ef372;
    ctx->state[3] = 0xa54ff53a;
    ctx->state[4] = 0x510e527f;
    ctx->state[5] = 0x9b05688c;
    ctx->state[6] = 0x1f83d9ab;
    ctx->state[7] = 0x5be0cd19;
}

/********************************************************************
 * 导入待计算数据, 更新上下文
 *
 * 参数说明:
 *  ctx:    数据结构 SHA256_CTX
 *  data:   待加密数据
 *  len:    待加密数据长度
 ********************************************************************/
void sha256_update(SHA256_CTX* ctx, const uint8_t data[], uint8_t len)
{
    uint32_t i;

    for (i = 0; i < len; ++i) {
        ctx->data[ctx->datalen] = data[i];
        ctx->datalen++;

        /* 数据缓冲区 ctx->data 满时, 进行散列映射 */
        if (ctx->datalen == 64) {
            // 64 byte = 512 bit, 以为当前数据块已满
            // 对当前块进行 SHA256 散列映射
            sha256_transform(ctx, ctx->data);
            ctx->bitlen += 512;
            ctx->datalen = 0;
        }
    }
}

/********************************************************************
 * 生成 SHA-256 加密后的哈希值
 *
 * 参数说明:
 *  ctx:    数据结构 SHA256_CTX
 *  hash:   出参, 算法生成的哈希值
 ********************************************************************/
void sha256_finish(SHA256_CTX* ctx, uint8_t hash[])
{
    uint32_t i;

    i = ctx->datalen;

    // 填充数据缓冲区
    if (ctx->datalen < 56) {
        ctx->data[i++] = 0x80;  // 填充: 10000000 = 0x80
        while (i < 56)
            ctx->data[i++] = 0x00;
    }
    else {
        ctx->data[i++] = 0x80;
        while (i < 64)
            ctx->data[i++] = 0x00;
        sha256_transform(ctx, ctx->data);
        memset(ctx->data, 0, 56);
    }

    // 将长度信息添加在消息块末64位
    ctx->bitlen += ctx->datalen << 3;
    ctx->data[63] = ctx->bitlen;
    ctx->data[62] = ctx->bitlen >> 8;
    ctx->data[61] = ctx->bitlen >> 16;
    ctx->data[60] = ctx->bitlen >> 24;
    ctx->data[59] = ctx->bitlen >> 32;
    ctx->data[58] = ctx->bitlen >> 40;
    ctx->data[57] = ctx->bitlen >> 48;
    ctx->data[56] = ctx->bitlen >> 56;
    sha256_transform(ctx, ctx->data);

    // 将最终计算结果复制到输出散列 (大端存储)
    for (i = 0; i < 4; ++i) {
        hash[i]      = (ctx->state[0] >> (24 - (i << 3))) & 0x000000ff;
        hash[i + 4]  = (ctx->state[1] >> (24 - (i << 3))) & 0x000000ff;
        hash[i + 8]  = (ctx->state[2] >> (24 - (i << 3))) & 0x000000ff;
        hash[i + 12] = (ctx->state[3] >> (24 - (i << 3))) & 0x000000ff;
        hash[i + 16] = (ctx->state[4] >> (24 - (i << 3))) & 0x000000ff;
        hash[i + 20] = (ctx->state[5] >> (24 - (i << 3))) & 0x000000ff;
        hash[i + 24] = (ctx->state[6] >> (24 - (i << 3))) & 0x000000ff;
        hash[i + 28] = (ctx->state[7] >> (24 - (i << 3))) & 0x000000ff;
    }
}


/********************************************************************
 * SHA-256 加密算法
 *
 * 参数说明:
 *  digest:     输出加密结果, 出参
 *  msg:        要加密的数据
 *  msg_len:    数据长度
 ********************************************************************/
void sha256(unsigned char digest[SHA256_DIGEST_SIZE],
    uint8_t* msg, uint8_t msg_len) {

    SHA256_CTX ctx;

    sha256_init(&ctx);
    sha256_update(&ctx, (unsigned char*)msg, msg_len);
    sha256_finish(&ctx, digest);
}

/*******************************************************************************************
 ***** hmac_sha256 *****
 *******************************************************************************************/
#define B 64                    // 明文分块长度 byte
#define I_PAD 0x36              // 内部填充
#define O_PAD 0x5C              // 外部填充
#define KEY_IOPAD_SIZE 64       // 填充字串长度 byte
#define SHA256_DIGEST_SIZE 32   // SHA-256摘要输出大小 32-byte
#define HMAC_SHA256_DIGEST_SIZE 32  // 与 SHA-256输出大小一致 32-byte

/********************************************************************
 * 将无符号 4-bit 二进制数据表示为十六进制形式.
 *  {1010} 将转换为 {'A'}.
 *
 * 参数说明:
 *  hb:         32-byte 摘要信息
 * 返回值:
 *   ASCII码 表示的十六进制数 [0-9A-F]
 ********************************************************************/
char bin2hex(unsigned char hb)
{
    hb = hb & 0xF;
    return (char)(hb < 10 ? '0' + hb : hb - 10 + 'A');
}

/********************************************************************
 *  256-bit 摘要信息, 转换为 64 char数组, 每位字符表示一个十六进制数.
 *  {0x5C, 0x5C, ... , 0x5C} 将转化为 {'5', 'C', '5', 'C', ... , '5', 'C'}.
 *
 * 参数说明:
 *  digest:     32-byte 摘要信息
 *  digest_hex: 出参, 转换后的 64 字符, 每位表示一个十六进制数,  ASCII码 形式存储
 ********************************************************************/
void digest2hex(unsigned char digest[HMAC_SHA256_DIGEST_SIZE],
    char digest_hex[HMAC_SHA256_DIGEST_SIZE*2])
{
    uint8_t i;
    for (i = 0; i < HMAC_SHA256_DIGEST_SIZE; i++) {
        digest_hex[i * 2] = bin2hex(digest[i] >> 4);
        digest_hex[i * 2 + 1] = bin2hex(digest[i]);
    }
}

/********************************************************************
 * HMAC-SHA256 摘要生成算法:
 *  HMAC-SHA256(K, M) == SHA256((K ^ opad)  SHA256((K ^ ipad)  M))
 *     K:      密钥
*      M:      消息
*      ipad:   内部填充字符串
*      opad:   外部填充字符串
*      ∥:      数据连接操作
*
*   数参数:
*      digest: 出参, 输出 32-byte 加密结果
*      msg:    要加密的数据
*      msgLen: 数据长度
*      key:    加密因子
*      keyLen: 加密因子长度
********************************************************************/
void hmac_sha256(unsigned char digest[HMAC_SHA256_DIGEST_SIZE],
    uint8_t* msg, uint8_t msg_len,
    uint8_t* key, uint8_t key_len)
{
    // SHA256_CTX ctx;
    // unsigned char k_ipad[KEY_IOPAD_SIZE];   // 内部填充
    // unsigned char k_opad[KEY_IOPAD_SIZE];   // 外部填充
    // int i;

    // /* 预处理密钥 key */
    // if (key_len > B) {
    //     // 长度大于分组长度 (64-byte) ,
    //     //  key 进行 SHA256 运算, 转为 32-byte 数据
    //     uint8_t temp[SHA256_DIGEST_SIZE];
    //     sha256(temp, key, key_len);
    //     key_len = SHA256_DIGEST_SIZE;
    //     key = temp;
    // }

    // /* 数据备份 */
    // memset(k_ipad, 0, sizeof(k_ipad));  // 密钥较短时, 填充 0
    // memset(k_opad, 0, sizeof(k_opad));
    // memcpy(k_ipad, key, key_len);       // 拷贝密钥到填充数组
    // memcpy(k_opad, key, key_len);

    // /* key 分别与 ipad/opad 进行异或 */
    // for (i = 0; i < KEY_IOPAD_SIZE; i++) {
    //     k_ipad[i] ^= 0x36;
    //     k_opad[i] ^= 0x5c;
    // }

    // /* 执行内部 SHA-256 加密 */
    // sha256_init(&ctx);                                  // SHA-256 上下文 第1次初始化
    // sha256_update(&ctx, k_ipad, KEY_IOPAD_SIZE);        // 加入内部填充
    // sha256_update(&ctx, (unsigned char*)msg, msg_len);  // 加入消息报文
    // sha256_finish(&ctx, digest);                        // 结束第1次哈希映射

    // /* 执行外部 SHA-256 加密 */
    // sha256_init(&ctx);                                  // SHA-256 上下文 第2次初始化
    // sha256_update(&ctx, k_opad, KEY_IOPAD_SIZE);        // 加入外部填充
    // sha256_update(&ctx, digest, SHA256_DIGEST_SIZE);    // 加入第1次的哈希值
    // sha256_finish(&ctx, digest);                        // 结束第2次哈希映射

    SHA256_CTX ctx;
    unsigned char k_pad[KEY_IOPAD_SIZE];   // 填充
    int i;

    /* 预处理密钥 key */
    if (key_len > B) {
        // 长度大于分组长度 (64-byte) ,
        //  key 进行 SHA256 运算, 转为 32-byte 数据
        uint8_t temp[SHA256_DIGEST_SIZE];
        sha256(temp, key, key_len);
        key_len = SHA256_DIGEST_SIZE;
        key = temp;
    }


    /* 执行内部 SHA-256 加密 */
    /* 数据备份 */
    memset(k_pad, 0, sizeof(k_pad));  // 密钥较短时, 填充 0
    memcpy(k_pad, key, key_len);       // 拷贝密钥到填充数组

    /* key  ipad 进行异或 */
    for (i = 0; i < KEY_IOPAD_SIZE; i++) {
        k_pad[i] ^= 0x36;
    }
    sha256_init(&ctx);                                  // SHA-256 上下文 第1次初始化
    sha256_update(&ctx, k_pad, KEY_IOPAD_SIZE);        // 加入内部填充
    sha256_update(&ctx, (unsigned char*)msg, msg_len);  // 加入消息报文
    sha256_finish(&ctx, digest);                        // 结束第1次哈希映射

    /* 执行外部 SHA-256 加密 */
    /* 数据备份 */
    memset(k_pad, 0, sizeof(k_pad));  // 密钥较短时, 填充 0
    memcpy(k_pad, key, key_len);       // 拷贝密钥到填充数组

    /* key 与opad 进行异或 */
    for (i = 0; i < KEY_IOPAD_SIZE; i++) {
        k_pad[i] ^= 0x5c;
    }
    sha256_init(&ctx);                                  // SHA-256 上下文 第2次初始化
    sha256_update(&ctx, k_pad, KEY_IOPAD_SIZE);        // 加入外部填充
    sha256_update(&ctx, digest, SHA256_DIGEST_SIZE);    // 加入第1次的哈希值
    sha256_finish(&ctx, digest);                        // 结束第2次哈希映射
}

#define LINE_BYTE 8
static void print_memory(uint32_t start_addr, uint8_t* data, uint16_t len) {
    uint32_t data32;
    uint32_t line = (len & (LINE_BYTE - 1)) ? (len / LINE_BYTE + 1) : (len / LINE_BYTE);

    for (uint16_t i = 0; i < line; i++) {
        printf("0x%04X  ", i * LINE_BYTE + start_addr);
        for (uint16_t j = 0; j < LINE_BYTE; j += 4) {
            data32 = *(uint32_t*)(data + i * LINE_BYTE + j);
            for (uint8_t k = 0; k < 4; k++) {
                if (i * LINE_BYTE + j + k >= len) {
                    printf("\n");
                    goto ret;
                }
                printf(" %02X", (uint8_t)(data32 >> (k * 8)));
            }
        }
        printf("\n");
    }
ret:
    printf("\n");
}


static void _transform(uint8_t *key, uint8_t key_len, uint8_t *factor, uint8_t factor_len) {
    uint8_t i = 0, j = 0;
    while (i < key_len) {
        key[i] = key[i] ^ factor[j];
        i++; j++;
        if (j >= factor_len)
            j = 0;
    }
}

const uint32_t m_secret[] = {
    0x00000000, 0x00000000, 0x00000000, 0x00000000,
    0x00000000, 0x00000000, 0x00000000, 0x00000000
};
int main () {
    uint32_t d0[] = {0x80fac1e3,0x70f60d0b,0x90d350cb,0x309b9138};
    uint32_t r0[] = {0x1d8fe744,0x245a2152,0xa3d71181,0x1ec0736e};

    uint32_t d1[] = {0x80fac1e3,0x70f60d0b,0x90d350cb,0x309b9138,0x00082040};
    uint32_t r1[] = {0x1d8fe744,0x245a2152,0xa3d71181,0x1ec0736e};

    uint32_t d2[] = {0x8c6834c5,0x2499a8b9,0x108461dd,0x34deac9d};
    uint32_t r2[] = {0x500143ad,0x057631a4,0xa66b2d28,0xef23f2f3};

    uint32_t s3[] = {0x09e47c32,0x760fb2fa,0xcfc5843d,0xf0716465};
    uint32_t d3[] = {0xd018a506,0x9bf37656,0xd38795e2,0xdc527e1a,0x0000a55d};
    uint32_t r3[] = {0xae9fc9b9,0xf5321618,0xd9a13137,0x159ac0a3};

    uint32_t d4[] = {0xd018a506,0x9bf37656,0xd38795e2,0xdc527e1a,0x0000a55d};
    uint32_t r4[] = {0xBA0675FD,0x79CFA4BD,0xA8F13B4F,0x7F54EE54};

    // uint32_t s5[] = {0x11223344,0x55667788,0x99AABBCCDD,0xDDEEFF00};
    // uint32_t d5[] = {0xF8B9F192,0xD91DACA6,0x3852CFC2,0xBF06B2E0,0x00007651};
    // uint32_t r5[] = {0xBA0675FD,0x79CFA4BD,0xA8F13B4F,0x7F54EE54};

    uint32_t s5[] = {0x56B7470C,0x9D6F22CA,0x003E4032,0x6FA77EB5};
    uint32_t d5[] = {0xF8B9F192,0xD91DACA6,0x3852CFC2,0xBF06B2E0,0x00007651};
    uint32_t r5[] = {0xBA0675FD,0x79CFA4BD,0xA8F13B4F,0x7F54EE54};

    uint8_t m[32] = {0};
    uint8_t s[32] = {0};
    uint8_t sha256_out[32] = {0};
    
    /**** sha256 ****/
#if 0
    memcpy(s, c_secret, sizeof(c_secret));
    _transform(s, sizeof(c_secret), (uint8_t *)secret_mix_factors, sizeof(secret_mix_factors));
    for (uint8_t i = 0; i < sizeof(d2)/sizeof(uint32_t); i++) {
        d2[i] = __builtin_bswap32(d2[i]);
    }
    memcpy(&s[16], d2, sizeof(d2));
    print_memory(0, s, sizeof(s));
    sha256(sha256_out, s, 32);
    print_memory(0, sha256_out, sizeof(sha256_out));
#endif

    /**** hmac_sha256 m ****/
#if 1
    memcpy(s, m_secret, sizeof(m_secret));
    // _transform(s, sizeof(m_secret), (uint8_t *)secret_mix_factors, sizeof(secret_mix_factors));
    print_memory(0, s, sizeof(s));

    for (uint8_t i = 0; i < sizeof(s5)/sizeof(uint32_t); i++) {
        s5[i] = __builtin_bswap32(s5[i]);
    }
    hmac_sha256(m, (uint8_t *)s5, sizeof(s5), s, sizeof(s));
    // print_memory(0, m, sizeof(m));

    for (uint8_t i = 0; i < sizeof(d5)/sizeof(uint32_t) - 1; i++) {
        d5[i] = __builtin_bswap32(d5[i]);
    }
    hmac_sha256(sha256_out, (uint8_t *)d5, sizeof(d5), m, sizeof(m));
    print_memory(0, sha256_out, sizeof(sha256_out));
#endif

    /**** hmac_sha256 c ****/
#if 0
    // memcpy(s, c_secret, sizeof(c_secret));
    // _transform(s, sizeof(c_secret), (uint8_t *)secret_mix_factors, sizeof(secret_mix_factors));
    // print_memory(0, s, sizeof(s));
    // for (uint8_t i = 0; i < sizeof(d0)/sizeof(uint32_t); i++) {
    //     d0[i] = __builtin_bswap32(d0[i]);
    // }
    hmac_sha256(sha256_out, (uint8_t *)d0, sizeof(d0), s, sizeof(s));
    print_memory(0, sha256_out, sizeof(sha256_out));
#endif

    return 0;
}