{"id":242,"date":"2025-10-20T17:26:56","date_gmt":"2025-10-20T09:26:56","guid":{"rendered":"https:\/\/wp.ytdx.cc\/?p=242"},"modified":"2025-10-20T17:26:56","modified_gmt":"2025-10-20T09:26:56","slug":"chacha20%e5%9c%a8%e5%8d%95%e7%89%87%e6%9c%ba%e4%b8%8a%e7%9a%84%e5%ae%9e%e7%8e%b0%e6%8c%87%e5%8d%97","status":"publish","type":"post","link":"https:\/\/wp.ytdx.cc\/index.php\/2025\/10\/20\/chacha20%e5%9c%a8%e5%8d%95%e7%89%87%e6%9c%ba%e4%b8%8a%e7%9a%84%e5%ae%9e%e7%8e%b0%e6%8c%87%e5%8d%97\/","title":{"rendered":"ChaCha20\u5728\u5355\u7247\u673a\u4e0a\u7684\u5b9e\u73b0\u6307\u5357"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">ChaCha20\u662f\u4e00\u79cd\u9ad8\u6548\u4e14\u5b89\u5168\u7684\u6d41\u5bc6\u7801\u7b97\u6cd5\uff0c\u975e\u5e38\u9002\u5408\u5728\u8d44\u6e90\u53d7\u9650\u7684\u5355\u7247\u673a(\u5305\u62ecSTC\u7cfb\u5217)\u4e0a\u4f7f\u7528\u3002\u4e0b\u9762\u8be6\u7ec6\u4ecb\u7ecd\u5b9e\u73b0\u65b9\u6cd5\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. \u57fa\u7840\u5b9e\u73b0\u539f\u7406<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">ChaCha20\u7684\u6838\u5fc3\u662f\u901a\u8fc7\u4e00\u4e2a256\u4f4d\u5bc6\u94a5\u548c96\u4f4dnonce(\u968f\u673a\u6570)\u751f\u6210\u5bc6\u94a5\u6d41\uff0c\u7136\u540e\u4e0e\u660e\u6587\u8fdb\u884c\u5f02\u6216\u8fd0\u7b97\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u5bc6\u94a5\u6d41 = ChaCha20(\u5bc6\u94a5, nonce, \u8ba1\u6570\u5668)\n\u5bc6\u6587 = \u660e\u6587 \u2295 \u5bc6\u94a5\u6d41<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">2. \u6838\u5fc3\u7b97\u6cd5\u5b9e\u73b0<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u4ee5\u4e0b\u662f\u9002\u7528\u4e8e\u5355\u7247\u673a\u7684\u7b80\u5316ChaCha20\u5b9e\u73b0\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdint.h&gt;\n#include &lt;string.h&gt;\n\n\/\/ ChaCha20\u5e38\u91cf\nstatic const uint32_t cha_cha_const&#91;4] = {\n    0x61707865, 0x3320646e, 0x79622d32, 0x6b206574\n};\n\n\/\/ Quarter Round\u64cd\u4f5c (\u6838\u5fc3\u8fd0\u7b97)\n#define ROTL32(x, n) (((x) &lt;&lt; (n)) | ((x) &gt;&gt; (32 - (n))))\n#define QR(a, b, c, d) \\\n    a += b; d ^= a; d = ROTL32(d, 16); \\\n    c += d; b ^= c; b = ROTL32(b, 12); \\\n    a += b; d ^= a; d = ROTL32(d, 8);  \\\n    c += d; b ^= c; b = ROTL32(b, 7);\n\n\/\/ ChaCha20\u5757\u51fd\u6570\nstatic void chacha20_block(const uint32_t key&#91;8], const uint32_t counter&#91;2], \n                          const uint32_t nonce&#91;3], uint32_t output&#91;16]) {\n    uint32_t x&#91;16];\n    int i;\n\n    \/\/ \u521d\u59cb\u5316\u72b6\u6001\u77e9\u9635\n    \/\/ \u5e38\u91cf\n    memcpy(x, cha_cha_const, sizeof(cha_cha_const));\n    \/\/ \u5bc6\u94a5\n    memcpy(x + 4, key, 8 * sizeof(uint32_t));\n    \/\/ \u8ba1\u6570\u5668\n    memcpy(x + 12, counter, 2 * sizeof(uint32_t));\n    \/\/ Nonce\n    memcpy(x + 14, nonce, 3 * sizeof(uint32_t));\n\n    uint32_t working_state&#91;16];\n    memcpy(working_state, x, sizeof(x));\n\n    \/\/ 20\u8f6e\u64cd\u4f5c (10\u6b21\u53cc\u8f6e)\n    for (i = 0; i &lt; 10; i++) {\n        \/\/ \u5217\u8f6e\n        QR(working_state&#91;0], working_state&#91;4], working_state&#91;8],  working_state&#91;12]);\n        QR(working_state&#91;1], working_state&#91;5], working_state&#91;9],  working_state&#91;13]);\n        QR(working_state&#91;2], working_state&#91;6], working_state&#91;10], working_state&#91;14]);\n        QR(working_state&#91;3], working_state&#91;7], working_state&#91;11], working_state&#91;15]);\n        \/\/ \u5bf9\u89d2\u8f6e\n        QR(working_state&#91;0], working_state&#91;5], working_state&#91;10], working_state&#91;15]);\n        QR(working_state&#91;1], working_state&#91;6], working_state&#91;11], working_state&#91;12]);\n        QR(working_state&#91;2], working_state&#91;7], working_state&#91;8],  working_state&#91;13]);\n        QR(working_state&#91;3], working_state&#91;4], working_state&#91;9],  working_state&#91;14]);\n    }\n\n    \/\/ \u52a0\u56de\u521d\u59cb\u72b6\u6001\n    for (i = 0; i &lt; 16; i++) {\n        output&#91;i] = working_state&#91;i] + x&#91;i];\n    }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">3. \u5b8c\u6574\u7684\u52a0\u5bc6\/\u89e3\u5bc6\u51fd\u6570<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>typedef struct {\n    uint32_t key&#91;8];\n    uint32_t counter&#91;2];  \/\/ 64\u4f4d\u8ba1\u6570\u5668\n    uint32_t nonce&#91;3];    \/\/ 96\u4f4d\u968f\u673a\u6570\n    uint8_t keystream&#91;64];\n    uint8_t keystream_pos;\n} chacha20_ctx;\n\n\/\/ \u521d\u59cb\u5316\u4e0a\u4e0b\u6587\nvoid chacha20_init(chacha20_ctx *ctx, const uint8_t key&#91;32], \n                   const uint8_t nonce&#91;12], uint64_t initial_counter) {\n    memcpy(ctx-&gt;key, key, 32);\n    memcpy(ctx-&gt;nonce, nonce, 12);\n    ctx-&gt;counter&#91;0] = (uint32_t)initial_counter;\n    ctx-&gt;counter&#91;1] = (uint32_t)(initial_counter &gt;&gt; 32);\n    ctx-&gt;keystream_pos = 64; \/\/ \u5f3a\u5236\u91cd\u65b0\u751f\u6210\u5bc6\u94a5\u6d41\n}\n\n\/\/ \u751f\u6210\u5bc6\u94a5\u6d41\nstatic void generate_keystream(chacha20_ctx *ctx) {\n    chacha20_block(ctx-&gt;key, ctx-&gt;counter, ctx-&gt;nonce, (uint32_t*)ctx-&gt;keystream);\n    ctx-&gt;keystream_pos = 0;\n\n    \/\/ \u9012\u589e\u8ba1\u6570\u5668\n    if (++ctx-&gt;counter&#91;0] == 0) {\n        ctx-&gt;counter&#91;1]++;\n    }\n}\n\n\/\/ \u52a0\u5bc6\/\u89e3\u5bc6\u6570\u636e\nvoid chacha20_crypt(chacha20_ctx *ctx, const uint8_t *input, \n                    uint8_t *output, size_t len) {\n    size_t i;\n\n    for (i = 0; i &lt; len; i++) {\n        if (ctx-&gt;keystream_pos &gt;= 64) {\n            generate_keystream(ctx);\n        }\n        output&#91;i] = input&#91;i] ^ ctx-&gt;keystream&#91;ctx-&gt;keystream_pos++];\n    }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">4. \u4e32\u53e3\u901a\u4fe1\u96c6\u6210\u793a\u4f8b<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u5168\u5c40\u52a0\u5bc6\u4e0a\u4e0b\u6587\nchacha20_ctx uart_enc_ctx;\n\n\/\/ \u521d\u59cb\u5316\u52a0\u5bc6\u901a\u4fe1\nvoid uart_encryption_init(void) {\n    \/\/ \u9884\u5171\u4eab\u5bc6\u94a5 (\u5b9e\u9645\u5e94\u7528\u4e2d\u5e94\u8be5\u5b89\u5168\u5b58\u50a8)\n    uint8_t secret_key&#91;32] = {\n        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\n        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,\n        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,\n        0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F\n    };\n\n    \/\/ \u968f\u673a\u6570 (\u6bcf\u6b21\u901a\u4fe1\u4f1a\u8bdd\u5e94\u8be5\u4e0d\u540c)\n    uint8_t nonce&#91;12] = {0};\n    \/\/ \u5728\u5b9e\u9645\u5e94\u7528\u4e2d\u5e94\u8be5\u4f7f\u7528\u771f\u968f\u673a\u6570\u751f\u6210\u5668\n    \/\/ \u8fd9\u91cc\u4f7f\u7528\u7b80\u5355\u793a\u4f8b\n    for(int i = 0; i &lt; 12; i++) {\n        nonce&#91;i] = i * 11; \/\/ \u5e94\u8be5\u66ff\u6362\u4e3a\u771f\u6b63\u7684\u968f\u673a\u5b57\u8282\n    }\n\n    chacha20_init(&amp;uart_enc_ctx, secret_key, nonce, 0);\n}\n\n\/\/ \u52a0\u5bc6\u5e76\u53d1\u9001\u6570\u636e\nvoid uart_send_encrypted(const uint8_t *data, size_t len) {\n    uint8_t encrypted&#91;256]; \/\/ \u6839\u636e\u5b9e\u9645\u9700\u6c42\u8c03\u6574\u5927\u5c0f\n    uint8_t len_byte = (uint8_t)len;\n\n    \/\/ \u52a0\u5bc6\u957f\u5ea6\u5b57\u8282\n    chacha20_crypt(&amp;uart_enc_ctx, &amp;len_byte, &amp;len_byte, 1);\n    UART_SendByte(len_byte);\n\n    \/\/ \u52a0\u5bc6\u6570\u636e\n    chacha20_crypt(&amp;uart_enc_ctx, data, encrypted, len);\n\n    \/\/ \u53d1\u9001\u52a0\u5bc6\u6570\u636e\n    for(size_t i = 0; i &lt; len; i++) {\n        UART_SendByte(encrypted&#91;i]);\n    }\n}\n\n\/\/ \u63a5\u6536\u5e76\u89e3\u5bc6\u6570\u636e\nsize_t uart_receive_decrypted(uint8_t *buffer, size_t max_len) {\n    uint8_t encrypted_len;\n\n    \/\/ \u63a5\u6536\u52a0\u5bc6\u7684\u957f\u5ea6\u5b57\u8282\n    if(!UART_ReceiveByte(&amp;encrypted_len)) {\n        return 0;\n    }\n\n    \/\/ \u89e3\u5bc6\u957f\u5ea6\n    uint8_t data_len = encrypted_len;\n    chacha20_crypt(&amp;uart_enc_ctx, &amp;encrypted_len, &amp;data_len, 1);\n\n    if(data_len &gt; max_len) {\n        return 0; \/\/ \u7f13\u51b2\u533a\u592a\u5c0f\n    }\n\n    \/\/ \u63a5\u6536\u52a0\u5bc6\u6570\u636e\n    for(uint8_t i = 0; i &lt; data_len; i++) {\n        uint8_t encrypted_byte;\n        if(!UART_ReceiveByte(&amp;encrypted_byte)) {\n            return 0;\n        }\n        buffer&#91;i] = encrypted_byte;\n    }\n\n    \/\/ \u89e3\u5bc6\u6570\u636e\n    chacha20_crypt(&amp;uart_enc_ctx, buffer, buffer, data_len);\n\n    return data_len;\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">5. \u4f18\u5316\u5efa\u8bae<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">\u5185\u5b58\u4f18\u5316\u7248\u672c\uff08\u9002\u5408\u8d44\u6e90\u6781\u5176\u53d7\u9650\u7684MCU\uff09<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u6700\u5c0f\u5185\u5b58\u5360\u7528\u7684ChaCha20\u5b9e\u73b0\nvoid chacha20_minimal(const uint8_t key&#91;32], const uint8_t nonce&#91;12],\n                     uint64_t counter, const uint8_t *input, \n                     uint8_t *output, size_t len) {\n    uint32_t state&#91;16];\n    uint8_t keystream&#91;64];\n    size_t bytes_processed = 0;\n\n    while(bytes_processed &lt; len) {\n        \/\/ \u6784\u5efa\u72b6\u6001\n        memcpy(state, cha_cha_const, 16);\n        memcpy(state + 4, key, 32);\n        state&#91;12] = (uint32_t)counter;\n        state&#91;13] = (uint32_t)(counter &gt;&gt; 32);\n        memcpy(state + 14, nonce, 12);\n\n        \/\/ \u751f\u6210\u5bc6\u94a5\u6d41\u5757\n        uint32_t working&#91;16];\n        memcpy(working, state, 64);\n\n        \/\/ \u5e94\u752820\u8f6eChaCha\n        for(int i = 0; i &lt; 10; i++) {\n            QR(working&#91;0], working&#91;4], working&#91;8],  working&#91;12]);\n            QR(working&#91;1], working&#91;5], working&#91;9],  working&#91;13]);\n            QR(working&#91;2], working&#91;6], working&#91;10], working&#91;14]);\n            QR(working&#91;3], working&#91;7], working&#91;11], working&#91;15]);\n            QR(working&#91;0], working&#91;5], working&#91;10], working&#91;15]);\n            QR(working&#91;1], working&#91;6], working&#91;11], working&#91;12]);\n            QR(working&#91;2], working&#91;7], working&#91;8],  working&#91;13]);\n            QR(working&#91;3], working&#91;4], working&#91;9],  working&#91;14]);\n        }\n\n        \/\/ \u52a0\u56de\u521d\u59cb\u72b6\u6001\u5e76\u8f6c\u6362\u4e3a\u5b57\u8282\n        for(int i = 0; i &lt; 16; i++) {\n            uint32_t result = working&#91;i] + state&#91;i];\n            keystream&#91;i*4]   = (uint8_t)(result);\n            keystream&#91;i*4+1] = (uint8_t)(result &gt;&gt; 8);\n            keystream&#91;i*4+2] = (uint8_t)(result &gt;&gt; 16);\n            keystream&#91;i*4+3] = (uint8_t)(result &gt;&gt; 24);\n        }\n\n        \/\/ \u52a0\u5bc6\u6570\u636e\n        size_t block_remaining = 64;\n        if(len - bytes_processed &lt; 64) {\n            block_remaining = len - bytes_processed;\n        }\n\n        for(size_t i = 0; i &lt; block_remaining; i++) {\n            output&#91;bytes_processed + i] = input&#91;bytes_processed + i] ^ keystream&#91;i];\n        }\n\n        bytes_processed += block_remaining;\n        counter++;\n    }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">6. \u5b89\u5168\u6ce8\u610f\u4e8b\u9879<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Nonce\u7ba1\u7406<\/strong>\uff1a<\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u6bcf\u4e2a\u4f1a\u8bdd\u4f7f\u7528\u4e0d\u540c\u7684nonce<\/li>\n\n\n\n<li>\u7edd\u5bf9\u4e0d\u8981\u91cd\u590d\u4f7f\u7528(\u5bc6\u94a5, nonce)\u5bf9<\/li>\n\n\n\n<li>\u53ef\u4ee5\u4f7f\u7528\u9012\u589e\u8ba1\u6570\u5668\u6216\u968f\u673a\u6570\u751f\u6210\u5668<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5bc6\u94a5\u5b89\u5168<\/strong>\uff1a<\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u4f7f\u7528\u5b89\u5168\u7684\u5bc6\u94a5\u751f\u6210\u65b9\u6cd5<\/li>\n\n\n\n<li>\u8003\u8651\u5b9a\u671f\u66f4\u6362\u5bc6\u94a5<\/li>\n\n\n\n<li>\u4e0d\u8981\u5728\u4ee3\u7801\u4e2d\u786c\u7f16\u7801\u751f\u4ea7\u5bc6\u94a5<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5b8c\u6574\u6027\u4fdd\u62a4<\/strong>\uff1a<\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ChaCha20\u53ea\u63d0\u4f9b\u4fdd\u5bc6\u6027\uff0c\u4e0d\u63d0\u4f9b\u5b8c\u6574\u6027<\/li>\n\n\n\n<li>\u8003\u8651\u7ed3\u5408Poly1305\u8ba4\u8bc1\uff08ChaCha20-Poly1305 AEAD\uff09<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">7. \u6027\u80fd\u8003\u8651<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u5185\u5b58\u4f7f\u7528<\/strong>\uff1a\u57fa\u672c\u5b9e\u73b0\u9700\u8981\u7ea6200\u5b57\u8282RAM<\/li>\n\n\n\n<li><strong>\u8ba1\u7b97\u901f\u5ea6<\/strong>\uff1a\u572848MHz\u7684STC8\u4e0a\uff0c\u52a0\u5bc61KB\u6570\u636e\u7ea6\u9700\u51e0\u6beb\u79d2<\/li>\n\n\n\n<li><strong>\u4f18\u5316\u6280\u5de7<\/strong>\uff1a<\/li>\n\n\n\n<li>\u4f7f\u7528\u67e5\u8868\u6cd5\u4f18\u5316ROTL32\u64cd\u4f5c<\/li>\n\n\n\n<li>\u5185\u8054\u5173\u952e\u51fd\u6570<\/li>\n\n\n\n<li>\u4f7f\u7528\u82af\u7247\u7279\u5b9a\u7684\u6307\u4ee4\u96c6\u4f18\u5316<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u8fd9\u79cd\u5b9e\u73b0\u65b9\u6848\u5728STC8\u7b49\u589e\u5f3a\u578b8051\u5355\u7247\u673a\u4e0a\u662f\u5b8c\u5168\u53ef\u884c\u7684\uff0c\u63d0\u4f9b\u4e86\u826f\u597d\u7684\u5b89\u5168\u6027\u548c\u53ef\u63a5\u53d7\u7684\u6027\u80fd\u8868\u73b0\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>ChaCha20\u662f\u4e00\u79cd\u9ad8\u6548\u4e14\u5b89\u5168\u7684\u6d41\u5bc6\u7801\u7b97\u6cd5\uff0c\u975e\u5e38\u9002\u5408\u5728\u8d44\u6e90\u53d7\u9650\u7684\u5355\u7247\u673a(\u5305\u62ecSTC\u7cfb\u5217)\u4e0a\u4f7f\u7528\u3002\u4e0b\u9762\u8be6\u7ec6\u4ecb\u7ecd &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/wp.ytdx.cc\/index.php\/2025\/10\/20\/chacha20%e5%9c%a8%e5%8d%95%e7%89%87%e6%9c%ba%e4%b8%8a%e7%9a%84%e5%ae%9e%e7%8e%b0%e6%8c%87%e5%8d%97\/\" class=\"more-link\">\u7ee7\u7eed\u9605\u8bfb<span class=\"screen-reader-text\">\u201cChaCha20\u5728\u5355\u7247\u673a\u4e0a\u7684\u5b9e\u73b0\u6307\u5357\u201d<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4],"tags":[],"class_list":["post-242","post","type-post","status-publish","format-standard","hentry","category-date","entry"],"jetpack_featured_media_url":"","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wp.ytdx.cc\/index.php\/wp-json\/wp\/v2\/posts\/242","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wp.ytdx.cc\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wp.ytdx.cc\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wp.ytdx.cc\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wp.ytdx.cc\/index.php\/wp-json\/wp\/v2\/comments?post=242"}],"version-history":[{"count":1,"href":"https:\/\/wp.ytdx.cc\/index.php\/wp-json\/wp\/v2\/posts\/242\/revisions"}],"predecessor-version":[{"id":243,"href":"https:\/\/wp.ytdx.cc\/index.php\/wp-json\/wp\/v2\/posts\/242\/revisions\/243"}],"wp:attachment":[{"href":"https:\/\/wp.ytdx.cc\/index.php\/wp-json\/wp\/v2\/media?parent=242"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wp.ytdx.cc\/index.php\/wp-json\/wp\/v2\/categories?post=242"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wp.ytdx.cc\/index.php\/wp-json\/wp\/v2\/tags?post=242"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}