Console Library 8.0.0
A header-only library that makes C++ simple
Loading...
Searching...
No Matches
crypto.h
Go to the documentation of this file.
1
10
11/*
12Copyright (c) 2026 MrXie1109
13
14Permission is hereby granted, free of charge, to any person obtaining a copy
15of this software and associated documentation files (the "Software"), to deal
16in the Software without restriction, including without limitation the rights
17to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18copies of the Software, and to permit persons to whom the Software is
19furnished to do so, subject to the following conditions:
20
21The above copyright notice and this permission notice shall be included in all
22copies or substantial portions of the Software.
23
24THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30SOFTWARE.
31*/
32
33#pragma once
34#include <algorithm>
35#include <chrono>
36#include <cstdint>
37#include <cstring>
38#include <fstream>
39#include <iomanip>
40#include <random>
41#include <sstream>
42#include <stdexcept>
43#include <vector>
44
45namespace console {
49 namespace crypto {
54 namespace sha256_impl {
58 static constexpr uint32_t K[64] = { //
59 0x428a2f98,
60 0x71374491,
61 0xb5c0fbcf,
62 0xe9b5dba5,
63 0x3956c25b,
64 0x59f111f1,
65 0x923f82a4,
66 0xab1c5ed5,
67 0xd807aa98,
68 0x12835b01,
69 0x243185be,
70 0x550c7dc3,
71 0x72be5d74,
72 0x80deb1fe,
73 0x9bdc06a7,
74 0xc19bf174,
75 0xe49b69c1,
76 0xefbe4786,
77 0x0fc19dc6,
78 0x240ca1cc,
79 0x2de92c6f,
80 0x4a7484aa,
81 0x5cb0a9dc,
82 0x76f988da,
83 0x983e5152,
84 0xa831c66d,
85 0xb00327c8,
86 0xbf597fc7,
87 0xc6e00bf3,
88 0xd5a79147,
89 0x06ca6351,
90 0x14292967,
91 0x27b70a85,
92 0x2e1b2138,
93 0x4d2c6dfc,
94 0x53380d13,
95 0x650a7354,
96 0x766a0abb,
97 0x81c2c92e,
98 0x92722c85,
99 0xa2bfe8a1,
100 0xa81a664b,
101 0xc24b8b70,
102 0xc76c51a3,
103 0xd192e819,
104 0xd6990624,
105 0xf40e3585,
106 0x106aa070,
107 0x19a4c116,
108 0x1e376c08,
109 0x2748774c,
110 0x34b0bcb5,
111 0x391c0cb3,
112 0x4ed8aa4a,
113 0x5b9cca4f,
114 0x682e6ff3,
115 0x748f82ee,
116 0x78a5636f,
117 0x84c87814,
118 0x8cc70208,
119 0x90befffa,
120 0xa4506ceb,
121 0xbef9a3f7,
122 0xc67178f2};
123
130 inline uint32_t rotr(uint32_t x, uint32_t n) {
131 return (x >> n) | (x << (32 - n));
132 }
133
141 inline uint32_t ch(uint32_t x, uint32_t y, uint32_t z) {
142 return (x & y) ^ (~x & z);
143 }
144
152 inline uint32_t maj(uint32_t x, uint32_t y, uint32_t z) {
153 return (x & y) ^ (x & z) ^ (y & z);
154 }
155
161 inline uint32_t sigma0(uint32_t x) {
162 return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22);
163 }
164
170 inline uint32_t sigma1(uint32_t x) {
171 return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25);
172 }
173
179 inline uint32_t gamma0(uint32_t x) {
180 return rotr(x, 7) ^ rotr(x, 18) ^ (x >> 3);
181 }
182
188 inline uint32_t gamma1(uint32_t x) {
189 return rotr(x, 17) ^ rotr(x, 19) ^ (x >> 10);
190 }
191
197 inline void transform(uint32_t *state, const uint8_t *data) {
198 uint32_t W[64];
199 uint32_t A, B, C, D, E, F, G, H, T1, T2;
200 for (int i = 0; i < 16; i++)
201 W[i] = (data[i * 4] << 24) | (data[i * 4 + 1] << 16)
202 | (data[i * 4 + 2] << 8) | data[i * 4 + 3];
203 for (int i = 16; i < 64; i++)
204 W[i] = gamma1(W[i - 2]) + W[i - 7] + gamma0(W[i - 15])
205 + W[i - 16];
206 A = state[0];
207 B = state[1];
208 C = state[2];
209 D = state[3];
210 E = state[4];
211 F = state[5];
212 G = state[6];
213 H = state[7];
214 for (int i = 0; i < 64; i++) {
215 T1 = H + sigma1(E) + ch(E, F, G) + K[i] + W[i];
216 T2 = sigma0(A) + maj(A, B, C);
217 H = G;
218 G = F;
219 F = E;
220 E = D + T1;
221 D = C;
222 C = B;
223 B = A;
224 A = T1 + T2;
225 }
226 state[0] += A;
227 state[1] += B;
228 state[2] += C;
229 state[3] += D;
230 state[4] += E;
231 state[5] += F;
232 state[6] += G;
233 state[7] += H;
234 }
235 }
236
242 inline std::string sha256(const std::string &input) {
243 using namespace sha256_impl;
244 uint32_t state[8] = {//
245 0x6a09e667,
246 0xbb67ae85,
247 0x3c6ef372,
248 0xa54ff53a,
249 0x510e527f,
250 0x9b05688c,
251 0x1f83d9ab,
252 0x5be0cd19};
253 std::vector<uint8_t> data(input.begin(), input.end());
254 uint64_t bit_len = data.size() * 8;
255 data.push_back(0x80);
256 while ((data.size() % 64) != 56) data.push_back(0x00);
257 for (int i = 7; i >= 0; i--)
258 data.push_back((bit_len >> (i * 8)) & 0xFF);
259 for (size_t i = 0; i < data.size(); i += 64)
260 transform(state, &data[i]);
261 std::stringstream ss;
262 for (int i = 0; i < 8; i++)
263 ss << std::hex << std::setfill('0') << std::setw(8) << state[i];
264 return ss.str();
265 }
266
273 inline std::string file_sha256(const std::string &filename) {
274 std::ifstream file(filename, std::ios::binary);
275 if (!file.is_open()) return "Cannot open file: " + filename;
276 using namespace sha256_impl;
277 uint32_t state[8] = {//
278 0x6a09e667,
279 0xbb67ae85,
280 0x3c6ef372,
281 0xa54ff53a,
282 0x510e527f,
283 0x9b05688c,
284 0x1f83d9ab,
285 0x5be0cd19};
286 std::vector<uint8_t> buffer(64);
287 uint64_t total_bits = 0;
288 while (file.read(reinterpret_cast<char *>(buffer.data()), 64)) {
289 transform(state, buffer.data());
290 total_bits += 512;
291 }
292 std::streamsize last_size = file.gcount();
293 total_bits += last_size * 8;
294 std::vector<uint8_t> last_block(
295 buffer.begin(), buffer.begin() + last_size);
296 last_block.push_back(0x80);
297 while ((last_block.size() % 64) != 56) last_block.push_back(0x00);
298 for (int i = 7; i >= 0; i--)
299 last_block.push_back((total_bits >> (i * 8)) & 0xFF);
300 for (size_t i = 0; i < last_block.size(); i += 64)
301 transform(state, &last_block[i]);
302 std::stringstream ss;
303 for (int i = 0; i < 8; i++)
304 ss << std::hex << std::setfill('0') << std::setw(8) << state[i];
305 return ss.str();
306 }
307
313 namespace md5_impl {
317 static constexpr uint32_t S[64] = { //
318 7,
319 12,
320 17,
321 22,
322 7,
323 12,
324 17,
325 22,
326 7,
327 12,
328 17,
329 22,
330 7,
331 12,
332 17,
333 22,
334 5,
335 9,
336 14,
337 20,
338 5,
339 9,
340 14,
341 20,
342 5,
343 9,
344 14,
345 20,
346 5,
347 9,
348 14,
349 20,
350 4,
351 11,
352 16,
353 23,
354 4,
355 11,
356 16,
357 23,
358 4,
359 11,
360 16,
361 23,
362 4,
363 11,
364 16,
365 23,
366 6,
367 10,
368 15,
369 21,
370 6,
371 10,
372 15,
373 21,
374 6,
375 10,
376 15,
377 21,
378 6,
379 10,
380 15,
381 21};
382
386 static constexpr uint32_t K[64] = { //
387 0xd76aa478,
388 0xe8c7b756,
389 0x242070db,
390 0xc1bdceee,
391 0xf57c0faf,
392 0x4787c62a,
393 0xa8304613,
394 0xfd469501,
395 0x698098d8,
396 0x8b44f7af,
397 0xffff5bb1,
398 0x895cd7be,
399 0x6b901122,
400 0xfd987193,
401 0xa679438e,
402 0x49b40821,
403 0xf61e2562,
404 0xc040b340,
405 0x265e5a51,
406 0xe9b6c7aa,
407 0xd62f105d,
408 0x02441453,
409 0xd8a1e681,
410 0xe7d3fbc8,
411 0x21e1cde6,
412 0xc33707d6,
413 0xf4d50d87,
414 0x455a14ed,
415 0xa9e3e905,
416 0xfcefa3f8,
417 0x676f02d9,
418 0x8d2a4c8a,
419 0xfffa3942,
420 0x8771f681,
421 0x6d9d6122,
422 0xfde5380c,
423 0xa4beea44,
424 0x4bdecfa9,
425 0xf6bb4b60,
426 0xbebfbc70,
427 0x289b7ec6,
428 0xeaa127fa,
429 0xd4ef3085,
430 0x04881d05,
431 0xd9d4d039,
432 0xe6db99e5,
433 0x1fa27cf8,
434 0xc4ac5665,
435 0xf4292244,
436 0x432aff97,
437 0xab9423a7,
438 0xfc93a039,
439 0x655b59c3,
440 0x8f0ccc92,
441 0xffeff47d,
442 0x85845dd1,
443 0x6fa87e4f,
444 0xfe2ce6e0,
445 0xa3014314,
446 0x4e0811a1,
447 0xf7537e82,
448 0xbd3af235,
449 0x2ad7d2bb,
450 0xeb86d391};
451
459 inline uint32_t F(uint32_t x, uint32_t y, uint32_t z) {
460 return (x & y) | (~x & z);
461 }
462
470 inline uint32_t G(uint32_t x, uint32_t y, uint32_t z) {
471 return (x & z) | (y & ~z);
472 }
473
481 inline uint32_t H(uint32_t x, uint32_t y, uint32_t z) {
482 return x ^ y ^ z;
483 }
484
492 inline uint32_t I(uint32_t x, uint32_t y, uint32_t z) {
493 return y ^ (x | ~z);
494 }
495
502 inline uint32_t rotate_left(uint32_t x, uint32_t n) {
503 return (x << n) | (x >> (32 - n));
504 }
505
511 inline void transform(uint32_t *state, const uint8_t *block) {
512 uint32_t a = state[0], b = state[1], c = state[2], d = state[3];
513 uint32_t M[16];
514 for (int i = 0; i < 16; i++) {
515 M[i] = block[i * 4] | (block[i * 4 + 1] << 8)
516 | (block[i * 4 + 2] << 16)
517 | (block[i * 4 + 3] << 24);
518 }
519 for (int i = 0; i < 64; i++) {
520 uint32_t f, g;
521 if (i < 16) {
522 f = F(b, c, d);
523 g = i;
524 } else if (i < 32) {
525 f = G(b, c, d);
526 g = (5 * i + 1) % 16;
527 } else if (i < 48) {
528 f = H(b, c, d);
529 g = (3 * i + 5) % 16;
530 } else {
531 f = I(b, c, d);
532 g = (7 * i) % 16;
533 }
534 uint32_t temp = d;
535 d = c;
536 c = b;
537 b = b + rotate_left(a + f + K[i] + M[g], S[i]);
538 a = temp;
539 }
540 state[0] += a;
541 state[1] += b;
542 state[2] += c;
543 state[3] += d;
544 }
545 }
546
554 inline std::string md5(const std::string &input) {
555 using namespace md5_impl;
556 uint32_t state[4]
557 = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476};
558 std::vector<uint8_t> data(input.begin(), input.end());
559 uint64_t bit_len = data.size() * 8;
560 data.push_back(0x80);
561 while ((data.size() % 64) != 56) data.push_back(0x00);
562 for (int i = 0; i < 8; i++)
563 data.push_back((bit_len >> (i * 8)) & 0xFF);
564 for (size_t i = 0; i < data.size(); i += 64)
565 transform(state, &data[i]);
566 std::stringstream ss;
567 for (int i = 0; i < 4; i++)
568 for (int j = 0; j < 4; j++)
569 ss << std::hex << std::setfill('0') << std::setw(2)
570 << ((state[i] >> (j * 8)) & 0xFF);
571 return ss.str();
572 }
573
580 inline std::string base64_encode(const std::string &input) {
581 const char *base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm"
582 "nopqrstuvwxyz0123456789+/";
583 std::string result;
584 result.reserve(((input.size() + 2) / 3) * 4);
585 uint32_t buffer = 0;
586 int bits_collected = 0;
587 for (char c : input) {
588 buffer = (buffer << 8) | static_cast<uint8_t>(c);
589 bits_collected += 8;
590 while (bits_collected >= 6) {
591 bits_collected -= 6;
592 result.push_back(
593 base64_chars[(buffer >> bits_collected) & 0x3F]);
594 }
595 }
596 if (bits_collected > 0) {
597 buffer <<= (6 - bits_collected);
598 result.push_back(base64_chars[buffer & 0x3F]);
599 }
600 while (result.size() % 4) result.push_back('=');
601 return result;
602 }
603
610 inline std::string base64_decode(const std::string &input) {
611 static const std::string base64_chars
612 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" //
613 "abcdefghijklmnopqrstuvwxyz" //
614 "0123456789+/";
615 std::string result;
616 result.reserve(input.size() / 4 * 3);
617 uint32_t buffer = 0;
618 int bits_collected = 0;
619 for (char c : input) {
620 if (c == '=') break;
621 size_t index = base64_chars.find(c);
622 if (index == std::string::npos) continue;
623 buffer = (buffer << 6) | index;
624 bits_collected += 6;
625 if (bits_collected >= 8) {
626 bits_collected -= 8;
627 result.push_back((buffer >> bits_collected) & 0xFF);
628 }
629 }
630 return result;
631 }
632
638 namespace aes_impl {
642 static constexpr uint8_t Sbox[256] = { //
643 0x63,
644 0x7c,
645 0x77,
646 0x7b,
647 0xf2,
648 0x6b,
649 0x6f,
650 0xc5,
651 0x30,
652 0x01,
653 0x67,
654 0x2b,
655 0xfe,
656 0xd7,
657 0xab,
658 0x76,
659 0xca,
660 0x82,
661 0xc9,
662 0x7d,
663 0xfa,
664 0x59,
665 0x47,
666 0xf0,
667 0xad,
668 0xd4,
669 0xa2,
670 0xaf,
671 0x9c,
672 0xa4,
673 0x72,
674 0xc0,
675 0xb7,
676 0xfd,
677 0x93,
678 0x26,
679 0x36,
680 0x3f,
681 0xf7,
682 0xcc,
683 0x34,
684 0xa5,
685 0xe5,
686 0xf1,
687 0x71,
688 0xd8,
689 0x31,
690 0x15,
691 0x04,
692 0xc7,
693 0x23,
694 0xc3,
695 0x18,
696 0x96,
697 0x05,
698 0x9a,
699 0x07,
700 0x12,
701 0x80,
702 0xe2,
703 0xeb,
704 0x27,
705 0xb2,
706 0x75,
707 0x09,
708 0x83,
709 0x2c,
710 0x1a,
711 0x1b,
712 0x6e,
713 0x5a,
714 0xa0,
715 0x52,
716 0x3b,
717 0xd6,
718 0xb3,
719 0x29,
720 0xe3,
721 0x2f,
722 0x84,
723 0x53,
724 0xd1,
725 0x00,
726 0xed,
727 0x20,
728 0xfc,
729 0xb1,
730 0x5b,
731 0x6a,
732 0xcb,
733 0xbe,
734 0x39,
735 0x4a,
736 0x4c,
737 0x58,
738 0xcf,
739 0xd0,
740 0xef,
741 0xaa,
742 0xfb,
743 0x43,
744 0x4d,
745 0x33,
746 0x85,
747 0x45,
748 0xf9,
749 0x02,
750 0x7f,
751 0x50,
752 0x3c,
753 0x9f,
754 0xa8,
755 0x51,
756 0xa3,
757 0x40,
758 0x8f,
759 0x92,
760 0x9d,
761 0x38,
762 0xf5,
763 0xbc,
764 0xb6,
765 0xda,
766 0x21,
767 0x10,
768 0xff,
769 0xf3,
770 0xd2,
771 0xcd,
772 0x0c,
773 0x13,
774 0xec,
775 0x5f,
776 0x97,
777 0x44,
778 0x17,
779 0xc4,
780 0xa7,
781 0x7e,
782 0x3d,
783 0x64,
784 0x5d,
785 0x19,
786 0x73,
787 0x60,
788 0x81,
789 0x4f,
790 0xdc,
791 0x22,
792 0x2a,
793 0x90,
794 0x88,
795 0x46,
796 0xee,
797 0xb8,
798 0x14,
799 0xde,
800 0x5e,
801 0x0b,
802 0xdb,
803 0xe0,
804 0x32,
805 0x3a,
806 0x0a,
807 0x49,
808 0x06,
809 0x24,
810 0x5c,
811 0xc2,
812 0xd3,
813 0xac,
814 0x62,
815 0x91,
816 0x95,
817 0xe4,
818 0x79,
819 0xe7,
820 0xc8,
821 0x37,
822 0x6d,
823 0x8d,
824 0xd5,
825 0x4e,
826 0xa9,
827 0x6c,
828 0x56,
829 0xf4,
830 0xea,
831 0x65,
832 0x7a,
833 0xae,
834 0x08,
835 0xba,
836 0x78,
837 0x25,
838 0x2e,
839 0x1c,
840 0xa6,
841 0xb4,
842 0xc6,
843 0xe8,
844 0xdd,
845 0x74,
846 0x1f,
847 0x4b,
848 0xbd,
849 0x8b,
850 0x8a,
851 0x70,
852 0x3e,
853 0xb5,
854 0x66,
855 0x48,
856 0x03,
857 0xf6,
858 0x0e,
859 0x61,
860 0x35,
861 0x57,
862 0xb9,
863 0x86,
864 0xc1,
865 0x1d,
866 0x9e,
867 0xe1,
868 0xf8,
869 0x98,
870 0x11,
871 0x69,
872 0xd9,
873 0x8e,
874 0x94,
875 0x9b,
876 0x1e,
877 0x87,
878 0xe9,
879 0xce,
880 0x55,
881 0x28,
882 0xdf,
883 0x8c,
884 0xa1,
885 0x89,
886 0x0d,
887 0xbf,
888 0xe6,
889 0x42,
890 0x68,
891 0x41,
892 0x99,
893 0x2d,
894 0x0f,
895 0xb0,
896 0x54,
897 0xbb,
898 0x16};
899
903 static constexpr uint8_t InvSbox[256] = { //
904 0x52,
905 0x09,
906 0x6a,
907 0xd5,
908 0x30,
909 0x36,
910 0xa5,
911 0x38,
912 0xbf,
913 0x40,
914 0xa3,
915 0x9e,
916 0x81,
917 0xf3,
918 0xd7,
919 0xfb,
920 0x7c,
921 0xe3,
922 0x39,
923 0x82,
924 0x9b,
925 0x2f,
926 0xff,
927 0x87,
928 0x34,
929 0x8e,
930 0x43,
931 0x44,
932 0xc4,
933 0xde,
934 0xe9,
935 0xcb,
936 0x54,
937 0x7b,
938 0x94,
939 0x32,
940 0xa6,
941 0xc2,
942 0x23,
943 0x3d,
944 0xee,
945 0x4c,
946 0x95,
947 0x0b,
948 0x42,
949 0xfa,
950 0xc3,
951 0x4e,
952 0x08,
953 0x2e,
954 0xa1,
955 0x66,
956 0x28,
957 0xd9,
958 0x24,
959 0xb2,
960 0x76,
961 0x5b,
962 0xa2,
963 0x49,
964 0x6d,
965 0x8b,
966 0xd1,
967 0x25,
968 0x72,
969 0xf8,
970 0xf6,
971 0x64,
972 0x86,
973 0x68,
974 0x98,
975 0x16,
976 0xd4,
977 0xa4,
978 0x5c,
979 0xcc,
980 0x5d,
981 0x65,
982 0xb6,
983 0x92,
984 0x6c,
985 0x70,
986 0x48,
987 0x50,
988 0xfd,
989 0xed,
990 0xb9,
991 0xda,
992 0x5e,
993 0x15,
994 0x46,
995 0x57,
996 0xa7,
997 0x8d,
998 0x9d,
999 0x84,
1000 0x90,
1001 0xd8,
1002 0xab,
1003 0x00,
1004 0x8c,
1005 0xbc,
1006 0xd3,
1007 0x0a,
1008 0xf7,
1009 0xe4,
1010 0x58,
1011 0x05,
1012 0xb8,
1013 0xb3,
1014 0x45,
1015 0x06,
1016 0xd0,
1017 0x2c,
1018 0x1e,
1019 0x8f,
1020 0xca,
1021 0x3f,
1022 0x0f,
1023 0x02,
1024 0xc1,
1025 0xaf,
1026 0xbd,
1027 0x03,
1028 0x01,
1029 0x13,
1030 0x8a,
1031 0x6b,
1032 0x3a,
1033 0x91,
1034 0x11,
1035 0x41,
1036 0x4f,
1037 0x67,
1038 0xdc,
1039 0xea,
1040 0x97,
1041 0xf2,
1042 0xcf,
1043 0xce,
1044 0xf0,
1045 0xb4,
1046 0xe6,
1047 0x73,
1048 0x96,
1049 0xac,
1050 0x74,
1051 0x22,
1052 0xe7,
1053 0xad,
1054 0x35,
1055 0x85,
1056 0xe2,
1057 0xf9,
1058 0x37,
1059 0xe8,
1060 0x1c,
1061 0x75,
1062 0xdf,
1063 0x6e,
1064 0x47,
1065 0xf1,
1066 0x1a,
1067 0x71,
1068 0x1d,
1069 0x29,
1070 0xc5,
1071 0x89,
1072 0x6f,
1073 0xb7,
1074 0x62,
1075 0x0e,
1076 0xaa,
1077 0x18,
1078 0xbe,
1079 0x1b,
1080 0xfc,
1081 0x56,
1082 0x3e,
1083 0x4b,
1084 0xc6,
1085 0xd2,
1086 0x79,
1087 0x20,
1088 0x9a,
1089 0xdb,
1090 0xc0,
1091 0xfe,
1092 0x78,
1093 0xcd,
1094 0x5a,
1095 0xf4,
1096 0x1f,
1097 0xdd,
1098 0xa8,
1099 0x33,
1100 0x88,
1101 0x07,
1102 0xc7,
1103 0x31,
1104 0xb1,
1105 0x12,
1106 0x10,
1107 0x59,
1108 0x27,
1109 0x80,
1110 0xec,
1111 0x5f,
1112 0x60,
1113 0x51,
1114 0x7f,
1115 0xa9,
1116 0x19,
1117 0xb5,
1118 0x4a,
1119 0x0d,
1120 0x2d,
1121 0xe5,
1122 0x7a,
1123 0x9f,
1124 0x93,
1125 0xc9,
1126 0x9c,
1127 0xef,
1128 0xa0,
1129 0xe0,
1130 0x3b,
1131 0x4d,
1132 0xae,
1133 0x2a,
1134 0xf5,
1135 0xb0,
1136 0xc8,
1137 0xeb,
1138 0xbb,
1139 0x3c,
1140 0x83,
1141 0x53,
1142 0x99,
1143 0x61,
1144 0x17,
1145 0x2b,
1146 0x04,
1147 0x7e,
1148 0xba,
1149 0x77,
1150 0xd6,
1151 0x26,
1152 0xe1,
1153 0x69,
1154 0x14,
1155 0x63,
1156 0x55,
1157 0x21,
1158 0x0c,
1159 0x7d};
1160
1165 inline void sub_bytes(uint8_t *state) {
1166 for (int i = 0; i < 16; i++) state[i] = Sbox[state[i]];
1167 }
1168
1173 inline void inv_sub_bytes(uint8_t *state) {
1174 for (int i = 0; i < 16; i++) state[i] = InvSbox[state[i]];
1175 }
1176
1181 inline void shift_rows(uint8_t *state) {
1182 uint8_t tmp;
1183 tmp = state[1];
1184 state[1] = state[5];
1185 state[5] = state[9];
1186 state[9] = state[13];
1187 state[13] = tmp;
1188 tmp = state[2];
1189 state[2] = state[10];
1190 state[10] = tmp;
1191 tmp = state[6];
1192 state[6] = state[14];
1193 state[14] = tmp;
1194 tmp = state[3];
1195 state[3] = state[15];
1196 state[15] = state[11];
1197 state[11] = state[7];
1198 state[7] = tmp;
1199 }
1200
1205 inline void inv_shift_rows(uint8_t *state) {
1206 uint8_t tmp;
1207 tmp = state[13];
1208 state[13] = state[9];
1209 state[9] = state[5];
1210 state[5] = state[1];
1211 state[1] = tmp;
1212 tmp = state[10];
1213 state[10] = state[2];
1214 state[2] = tmp;
1215 tmp = state[14];
1216 state[14] = state[6];
1217 state[6] = tmp;
1218 tmp = state[7];
1219 state[7] = state[11];
1220 state[11] = state[15];
1221 state[15] = state[3];
1222 state[3] = tmp;
1223 }
1224
1231 inline uint8_t gmul(uint8_t a, uint8_t b) {
1232 uint8_t p = 0;
1233 for (int i = 0; i < 8; i++) {
1234 if (b & 1) p ^= a;
1235 bool high = a & 0x80;
1236 a <<= 1;
1237 if (high) a ^= 0x1b;
1238 b >>= 1;
1239 }
1240 return p;
1241 }
1242
1247 inline void mix_columns(uint8_t *state) {
1248 uint8_t temp[4];
1249 for (int i = 0; i < 4; i++) {
1250 int idx = i * 4;
1251 temp[0] = gmul(state[idx], 2) ^ gmul(state[idx + 1], 3)
1252 ^ state[idx + 2] ^ state[idx + 3];
1253 temp[1] = state[idx] ^ gmul(state[idx + 1], 2)
1254 ^ gmul(state[idx + 2], 3) ^ state[idx + 3];
1255 temp[2] = state[idx] ^ state[idx + 1]
1256 ^ gmul(state[idx + 2], 2)
1257 ^ gmul(state[idx + 3], 3);
1258 temp[3] = gmul(state[idx], 3) ^ state[idx + 1]
1259 ^ state[idx + 2] ^ gmul(state[idx + 3], 2);
1260 std::memcpy(&state[idx], temp, 4);
1261 }
1262 }
1263
1268 inline void inv_mix_columns(uint8_t *state) {
1269 uint8_t temp[4];
1270 for (int i = 0; i < 4; i++) {
1271 int idx = i * 4;
1272 temp[0] = gmul(state[idx], 0x0e)
1273 ^ gmul(state[idx + 1], 0x0b)
1274 ^ gmul(state[idx + 2], 0x0d)
1275 ^ gmul(state[idx + 3], 0x09);
1276 temp[1] = gmul(state[idx], 0x09)
1277 ^ gmul(state[idx + 1], 0x0e)
1278 ^ gmul(state[idx + 2], 0x0b)
1279 ^ gmul(state[idx + 3], 0x0d);
1280 temp[2] = gmul(state[idx], 0x0d)
1281 ^ gmul(state[idx + 1], 0x09)
1282 ^ gmul(state[idx + 2], 0x0e)
1283 ^ gmul(state[idx + 3], 0x0b);
1284 temp[3] = gmul(state[idx], 0x0b)
1285 ^ gmul(state[idx + 1], 0x0d)
1286 ^ gmul(state[idx + 2], 0x09)
1287 ^ gmul(state[idx + 3], 0x0e);
1288 std::memcpy(&state[idx], temp, 4);
1289 }
1290 }
1291
1297 inline void add_round_key(uint8_t *state, const uint8_t *key) {
1298 for (int i = 0; i < 16; i++) state[i] ^= key[i];
1299 }
1300
1307 inline void key_expansion(const uint8_t *key, uint8_t *round_keys) {
1308 uint8_t temp[4];
1309 uint8_t rcon[4];
1310 for (int i = 0; i < 16; i++) round_keys[i] = key[i];
1311 for (int i = 4; i < 44; i++) {
1312 std::memcpy(temp, &round_keys[(i - 1) * 4], 4);
1313 if (i % 4 == 0) {
1314 uint8_t t = temp[0];
1315 temp[0] = Sbox[temp[1]];
1316 temp[1] = Sbox[temp[2]];
1317 temp[2] = Sbox[temp[3]];
1318 temp[3] = Sbox[t];
1319 rcon[0] = 0x01 << ((i / 4) - 1);
1320 rcon[1] = rcon[2] = rcon[3] = 0;
1321 if (rcon[0] == 0) rcon[0] = 0x1b;
1322 for (int j = 0; j < 4; j++) temp[j] ^= rcon[j];
1323 }
1324 for (int j = 0; j < 4; j++) {
1325 round_keys[i * 4 + j]
1326 = round_keys[(i - 4) * 4 + j] ^ temp[j];
1327 }
1328 }
1329 }
1330
1337 inline void aes_encrypt_block(const uint8_t *input,
1338 uint8_t *output,
1339 const uint8_t *round_keys) {
1340 uint8_t state[16];
1341 std::memcpy(state, input, 16);
1342 add_round_key(state, round_keys);
1343 for (int round = 1; round < 10; round++) {
1344 sub_bytes(state);
1345 shift_rows(state);
1346 mix_columns(state);
1347 add_round_key(state, round_keys + round * 16);
1348 }
1349 sub_bytes(state);
1350 shift_rows(state);
1351 add_round_key(state, round_keys + 10 * 16);
1352 std::memcpy(output, state, 16);
1353 }
1354
1361 inline void aes_decrypt_block(const uint8_t *input,
1362 uint8_t *output,
1363 const uint8_t *round_keys) {
1364 uint8_t state[16];
1365 std::memcpy(state, input, 16);
1366 add_round_key(state, round_keys + 10 * 16);
1367 for (int round = 9; round > 0; round--) {
1368 inv_shift_rows(state);
1369 inv_sub_bytes(state);
1370 add_round_key(state, round_keys + round * 16);
1371 inv_mix_columns(state);
1372 }
1373 inv_shift_rows(state);
1374 inv_sub_bytes(state);
1375 add_round_key(state, round_keys);
1376 std::memcpy(output, state, 16);
1377 }
1378
1385 inline std::string pad_key(const std::string &key) {
1386 std::string padded = key;
1387 padded.resize(16, 0);
1388 return padded;
1389 }
1390
1396 inline std::string random_bytes() {
1397 static std::random_device rd;
1398 static std::mt19937 gen(
1399 std::chrono::steady_clock::now().time_since_epoch().count()
1400 + rd());
1401 static std::uniform_int_distribution<> dis(0, 255);
1402 std::string bytes;
1403 bytes.reserve(16);
1404 for (int i = 0; i < 16; i++)
1405 bytes.push_back(static_cast<char>(dis(gen)));
1406 return bytes;
1407 }
1408 }
1409
1421 inline std::string
1422 aes_encrypt(const std::string &plaintext, const std::string &key) {
1423 std::string padded_key = aes_impl::pad_key(key);
1424 uint8_t round_keys[44 * 4];
1426 reinterpret_cast<const uint8_t *>(padded_key.c_str()),
1427 round_keys);
1428 std::string iv(aes_impl::random_bytes());
1429 std::string result;
1430 result.reserve(plaintext.size() + 16);
1431 result = iv;
1432 uint8_t counter[16];
1433 std::memcpy(counter, iv.c_str(), 16);
1434 for (size_t i = 0; i < plaintext.size(); i += 16) {
1435 uint8_t keystream[16];
1436 aes_impl::aes_encrypt_block(counter, keystream, round_keys);
1437 for (int j = 0; j < 16 && i + j < plaintext.size(); j++)
1438 result.push_back(plaintext[i + j] ^ keystream[j]);
1439 for (int j = 15; j >= 0; j--) {
1440 if (++counter[j] != 0) break;
1441 }
1442 }
1443 return base64_encode(result);
1444 }
1445
1454 inline std::string
1455 aes_decrypt(const std::string &ciphertext, const std::string &key) {
1456 std::string decoded = base64_decode(ciphertext);
1457 if (decoded.size() < 16) return "Invalid ciphertext";
1458 std::string padded_key = aes_impl::pad_key(key);
1459 uint8_t round_keys[44 * 4];
1461 reinterpret_cast<const uint8_t *>(padded_key.c_str()),
1462 round_keys);
1463 std::string iv = decoded.substr(0, 16);
1464 std::string encrypted_data = decoded.substr(16);
1465 std::string result;
1466 result.reserve(encrypted_data.size());
1467 uint8_t counter[16];
1468 std::memcpy(counter, iv.c_str(), 16);
1469 for (size_t i = 0; i < encrypted_data.size(); i += 16) {
1470 uint8_t keystream[16];
1471 aes_impl::aes_encrypt_block(counter, keystream, round_keys);
1472 for (int j = 0; j < 16 && i + j < encrypted_data.size(); j++)
1473 result.push_back(encrypted_data[i + j] ^ keystream[j]);
1474 for (int j = 15; j >= 0; j--)
1475 if (++counter[j] != 0) break;
1476 }
1477 return result;
1478 }
1479 }
1480}
MultiArray< T, Dims... > round(const MultiArray< T, Dims... > &arr)
对数组每个元素四舍五入。
Definition matools.h:806
AES加密算法的内部实现细节。
Definition crypto.h:638
void add_round_key(uint8_t *state, const uint8_t *key)
轮密钥加操作,将状态矩阵与轮密钥进行异或。
Definition crypto.h:1297
void mix_columns(uint8_t *state)
列混合操作,对状态矩阵的每一列进行线性变换。
Definition crypto.h:1247
uint8_t gmul(uint8_t a, uint8_t b)
在GF(2^8)有限域中执行乘法运算。
Definition crypto.h:1231
static constexpr uint8_t InvSbox[256]
AES算法的逆S盒,用于解密时的字节替换。
Definition crypto.h:903
std::string random_bytes()
生成随机字节序列。
Definition crypto.h:1396
static constexpr uint8_t Sbox[256]
AES算法的S盒,用于字节替换。
Definition crypto.h:642
void shift_rows(uint8_t *state)
行移位操作,将状态矩阵的各行循环左移不同偏移量。
Definition crypto.h:1181
void key_expansion(const uint8_t *key, uint8_t *round_keys)
AES密钥扩展算法,将原始密钥扩展为11轮使用的轮密钥。
Definition crypto.h:1307
void inv_sub_bytes(uint8_t *state)
逆字节替换操作,使用逆S盒替换状态矩阵中的每个字节。
Definition crypto.h:1173
std::string pad_key(const std::string &key)
将密钥填充到16字节(AES-128要求的密钥长度)。
Definition crypto.h:1385
void aes_encrypt_block(const uint8_t *input, uint8_t *output, const uint8_t *round_keys)
AES加密单个块(128位)。
Definition crypto.h:1337
void aes_decrypt_block(const uint8_t *input, uint8_t *output, const uint8_t *round_keys)
AES解密单个块(128位)。
Definition crypto.h:1361
void inv_shift_rows(uint8_t *state)
逆行移位操作,将状态矩阵的各行循环右移不同偏移量。
Definition crypto.h:1205
void sub_bytes(uint8_t *state)
字节替换操作,使用S盒替换状态矩阵中的每个字节。
Definition crypto.h:1165
void inv_mix_columns(uint8_t *state)
逆列混合操作,对状态矩阵的每一列进行逆线性变换。
Definition crypto.h:1268
MD5哈希算法的内部实现细节。
Definition crypto.h:313
uint32_t rotate_left(uint32_t x, uint32_t n)
对32位无符号整数进行循环左移。
Definition crypto.h:502
uint32_t I(uint32_t x, uint32_t y, uint32_t z)
MD5第四轮逻辑函数I。
Definition crypto.h:492
static constexpr uint32_t S[64]
MD5算法中每轮循环使用的左移位数数组。
Definition crypto.h:317
uint32_t F(uint32_t x, uint32_t y, uint32_t z)
MD5第一轮逻辑函数F。
Definition crypto.h:459
void transform(uint32_t *state, const uint8_t *block)
对64字节的数据块执行MD5变换。
Definition crypto.h:511
static constexpr uint32_t K[64]
MD5算法中使用的常量K数组。
Definition crypto.h:386
uint32_t G(uint32_t x, uint32_t y, uint32_t z)
MD5第二轮逻辑函数G。
Definition crypto.h:470
uint32_t H(uint32_t x, uint32_t y, uint32_t z)
MD5第三轮逻辑函数H。
Definition crypto.h:481
SHA256哈希算法的内部实现细节。
Definition crypto.h:54
uint32_t gamma1(uint32_t x)
SHA256中的小西格玛1函数。
Definition crypto.h:188
uint32_t sigma1(uint32_t x)
SHA256中的大西格玛1函数。
Definition crypto.h:170
uint32_t rotr(uint32_t x, uint32_t n)
对32位无符号整数进行循环右移。
Definition crypto.h:130
void transform(uint32_t *state, const uint8_t *data)
对64字节的数据块执行SHA256变换。
Definition crypto.h:197
uint32_t maj(uint32_t x, uint32_t y, uint32_t z)
SHA256中的多数函数Maj。
Definition crypto.h:152
uint32_t ch(uint32_t x, uint32_t y, uint32_t z)
SHA256中的选择函数Ch。
Definition crypto.h:141
uint32_t sigma0(uint32_t x)
SHA256中的大西格玛0函数。
Definition crypto.h:161
uint32_t gamma0(uint32_t x)
SHA256中的小西格玛0函数。
Definition crypto.h:179
static constexpr uint32_t K[64]
SHA256算法使用的常量K数组。
Definition crypto.h:58
密码学相关的命名空间。
Definition crypto.h:49
std::string sha256(const std::string &input)
计算输入字符串的SHA256哈希值。
Definition crypto.h:242
std::string aes_decrypt(const std::string &ciphertext, const std::string &key)
使用AES-128-CTR模式解密密文。
Definition crypto.h:1455
std::string file_sha256(const std::string &filename)
计算文件的SHA256哈希值。
Definition crypto.h:273
std::string md5(const std::string &input)
计算输入字符串的MD5哈希值。
Definition crypto.h:554
std::string base64_encode(const std::string &input)
对输入字符串进行Base64编码。
Definition crypto.h:580
std::string aes_encrypt(const std::string &plaintext, const std::string &key)
使用AES-128-CTR模式加密明文。
Definition crypto.h:1422
std::string base64_decode(const std::string &input)
对Base64编码的字符串进行解码。
Definition crypto.h:610
Definition gen.h:237
本库所有组件所在的顶层命名空间。
T input(const CharT *prompt="", const BasicInputSettings< CharT > &is=input_settings)
从标准输入读取一个值,支持类型模板。
Definition input.h:75
@ C
Definition kb.h:82
@ E
Definition kb.h:84
@ W
Definition kb.h:102
@ M
Definition kb.h:92
@ A
Definition kb.h:80
@ B
Definition kb.h:81
@ D
Definition kb.h:83