349 | static inline void init() noexcept {
350 | port::template pins::clr();
351 | port::template pins::out();
352 | }
353 | private:
354 | port();
355 | };
356 | private:
357 | gpio();
358 | };
359 |
360 |
361 | class uart {
362 | public:
363 | static constexpr unsigned baudrate_count = 2;
364 | static constexpr unsigned max_channel_count = 2;
365 | enum class baudrate_t {
366 | _57600,
367 | _115200
368 | };
369 | enum class blocking_t { blocking, non_blocking };
370 | enum class channel_t : uint_fast8_t { esci_a0, esci_a1 };
371 | enum class clk_src_t { uclk, aclk, smclk };
372 | enum class bits_t { _8, _7 };
373 | enum class parity_t { no, odd, even };
374 | enum class stopbits_t { one, two };
375 |
376 | struct params {
377 | uint16_t ctlw0;
378 | inline constexpr params(
379 | clk_src_t clk_src = clk_src_t::smclk,
380 | bits_t bits = bits_t::_8,
381 | parity_t parity = parity_t::no,
382 | stopbits_t stopbits = stopbits_t::one
383 | ) :
384 | ctlw0(
385 | (parity != parity_t::no ? 0x8000 : 0 ) |
386 | (parity == parity_t::even ? 0x4000 : 0 ) |
387 | /* always LSB first */
388 | (bits == bits_t::_7 ? 0x1000 : 0 ) |
389 | (stopbits == stopbits_t::one ? 0x0800 : 0 ) |
390 | /* always UART mode */
391 | /* always Asynchronous mode */
392 | (clk_src == clk_src_t::smclk ? 0x0080 : 0 ) |
393 | (clk_src == clk_src_t::aclk ? 0x0040 : 0 )
394 | ) { }
395 | };
396 |
397 |
398 | bool put(char, blocking_t = blocking_t::blocking) const noexcept;
399 | bool get(char&, blocking_t = blocking_t::blocking) const noexcept;
400 | inline constexpr uart(channel_t ch) noexcept : channel(ch) {}
401 | inline uart(channel_t ch, baudrate_t b) noexcept : channel(ch) { begin(b); }
402 | void begin(baudrate_t b, const params & p = params()) const noexcept;
403 | void end() const noexcept;
404 | void put(const char* msg) const noexcept {
405 | while(*msg) put(*msg++);
406 | }
407 | public:
408 | const channel_t channel;
409 | private:
410 | inline void init(uart::baudrate_t,const uart::params&) const noexcept;
411 | uart();
412 | };
413 | }
414 |
--------------------------------------------------------------------------------
/tests/master.inc:
--------------------------------------------------------------------------------
1 |
2 | const uint8_t master1[] = { 222,202,68,203,71,185,154,219,88,87,129,165,229,233,20,84 };
3 | const uint8_t master2[] = { 118,224,174,225,96,244,121,47,7,229,134,53,50,125,102,229 };
4 | const uint8_t master3[] = { 181,138,189,126,50,202,139,119,242,229,175,10,166,232,171,135 };
5 | const uint8_t master4[] = { 110,122,13,8,84,105,25,52,232,227,37,82,197,121,105,240 };
6 | const uint8_t master5[] = { 152,133,195,170,129,159,115,98,75,234,31,71,144,111,76,123 };
7 | const uint8_t master6[] = { 173,161,240,244,218,18,170,68,190,236,248,4,144,147,140,38 };
8 | const uint8_t master7[] = { 208,231,42,190,67,254,150,98,203,135,73,122,146,167,113,229 };
9 | const uint8_t master8[] = { 54,189,54,43,74,76,145,168,76,157,212,173,208,25,94,240 };
10 | const uint8_t master9[] = { 31,72,238,18,104,238,139,142,45,85,187,193,182,105,38,5 };
11 | const uint8_t master10[] = { 43,255,152,0,109,31,0,111,16,80,119,88,39,130,165,140 };
12 | const uint8_t master11[] = { 94,178,192,27,86,56,148,42,195,180,12,94,61,200,52,150 };
13 | const uint8_t master12[] = { 4,211,241,42,135,14,13,245,117,102,113,110,201,248,123,67 };
14 | const uint8_t master13[] = { 237,114,121,205,231,88,56,34,182,190,62,123,243,252,2,236 };
15 | const uint8_t master14[] = { 152,187,250,101,26,251,130,193,110,145,149,212,73,39,191,138 };
16 | const uint8_t master15[] = { 8,12,29,139,151,244,30,9,11,87,218,149,152,92,22,246 };
17 | const uint8_t master16[] = { 63,11,161,255,230,141,116,83,143,39,65,231,185,126,246,170 };
18 | const uint8_t master17[] = { 128,245,151,12,111,204,71,170,139,246,19,222,188,68,227,186,60,117,238, 67,4,170,100,95,104,133,87,153,124,212,128,12 };
19 | const uint8_t master18[] = { 20,77,65,9,13,109,229,60,0,3,186,56,190,90,48,93,186,122,200,16,202,13, 249,218,145,118,223,243,232,130,161,94 };
20 | const uint8_t master19[] = { 4,57,187,192,5,81,173,237,228,166,182,157,23,47,153,229,109,161,81,4,202, 190,174,72,69,192,98,174,228,68,109,26 };
21 | const uint8_t master20[] = { 247,71,207,142,146,27,182,0,67,12,235,174,107,70,38,165,186,169,21,187, 8,150,91,122,118,176,192,191,179,73,194,126 };
22 | const uint8_t master21[] = { 243,51,36,207,216,59,71,0,130,237,118,32,61,223,238,214,136,65,188,52,68, 85,5,116,68,66,7,76,55,14,120,129 };
23 | const uint8_t master22[] = { 132,15,0,170,117,62,62,232,76,31,204,103,92,224,225,162,224,244,164,189, 11,87,105,241,166,52,122,100,2,131,86,195 };
24 | const uint8_t master23[] = { 14,90,143,161,121,159,73,147,26,248,88,201,32,241,198,177,88,147,168,10, 51,161,85,86,153,111,216,159,16,252,171,50 };
25 | const uint8_t master24[] = { 46,137,166,99,10,9,161,19,201,26,190,248,124,221,138,23,18,119,130,83,66, 31,222,255,117,127,135,107,76,241,172,196 };
26 | const uint8_t master25[] = { 65,96,98,247,42,85,245,104,121,123,23,102,33,130,213,150,181,251,20,191, 179,109,207,13,133,68,150,154,136,143,17,127 };
27 | const uint8_t master26[] = { 238,77,117,246,217,33,56,85,205,216,1,163,42,189,112,85,104,65,145,65,200, 102,245,25,59,71,59,25,13,18,195,24 };
28 | const uint8_t master27[] = { 175,155,175,187,29,60,129,58,151,108,248,196,181,96,156,242,113,215,42, 220,224,154,193,233,161,108,45,40,235,201,145,173 };
29 | const uint8_t master28[] = { 143,58,180,175,39,226,132,151,224,46,144,191,193,230,87,90,46,125,106,225, 132,19,164,242,55,66,21,27,102,81,144,122 };
30 | const uint8_t master29[] = { 119,60,95,2,38,129,245,99,74,20,55,199,56,162,238,64,44,89,38,8,255,225, 61,149,118,93,166,195,45,242,240,116 };
31 | const uint8_t master30[] = { 1,140,255,176,19,225,59,182,85,220,132,29,98,57,1,59,33,163,1,83,60,3,232, 118,143,129,29,185,67,97,238,196 };
32 | const uint8_t master31[] = { 24,236,188,144,157,4,152,167,29,125,37,66,220,168,245,72,50,191,158,70, 190,26,98,59,166,241,193,103,162,233,246,160 };
33 | const uint8_t master32[] = { 89,121,164,54,147,181,38,167,34,213,245,92,174,126,14,74,144,110,146,95, 56,8,38,153,15,146,74,151,68,134,180,176 };
34 | const uint8_t master33[] = { 73,13,241,83,220,5,32,25,68,34,116,111,234,221,64,94,20,55,93,242,83,11, 10,59,4,39,196,222,150,229,198,25,197,128,19,78,216,100,168,207,141,207, 175,29,120,24,159,29 };
35 | const uint8_t master34[] = { 33,223,228,40,106,73,254,13,208,234,230,228,21,44,21,176,85,54,208,216, 187,55,175,198,63,31,60,191,244,84,76,25,115,157,106,166,73,145,102,46, 205,155,243,19,175,205,27,242 };
36 | const uint8_t master35[] = { 2,229,11,152,59,105,209,14,144,148,195,182,137,119,145,89,143,185,212,8, 92,100,130,107,224,49,77,12,117,89,242,28,147,67,78,81,207,254,255,35,104, 132,93,28,169,163,249,17 };
37 | const uint8_t master36[] = { 111,183,30,238,137,12,169,152,246,29,162,184,195,17,54,50,158,30,165,140, 231,255,180,250,127,237,85,80,133,88,228,246,97,52,13,120,114,104,192,7, 124,122,226,100,6,215,94,254 };
38 | const uint8_t master37[] = { 14,133,180,190,194,136,108,116,80,17,2,6,113,129,33,134,150,121,255,152, 92,11,119,196,41,190,114,154,218,224,100,158,252,173,25,54,78,14,152,253, 29,91,51,49,138,133,86,195 };
39 | const uint8_t master38[] = { 192,149,185,128,17,143,153,163,22,175,42,239,4,247,86,13,193,15,42,76,11, 22,17,17,110,117,125,251,35,30,218,133,190,140,152,74,106,130,88,87,68, 66,174,234,38,215,69,155 };
40 | const uint8_t master39[] = { 179,112,80,9,233,55,89,134,49,254,119,181,114,238,13,90,158,193,50,2,158, 190,123,71,69,116,117,112,97,248,229,220,189,64,119,137,124,204,221,98, 198,109,77,186,158,215,209,17 };
41 | const uint8_t master40[] = { 198,176,231,134,208,202,53,132,147,42,126,194,79,209,138,230,207,20,149, 59,47,229,137,27,126,46,234,18,240,100,194,183,201,199,175,190,166,133, 3,96,150,3,238,154,231,126,239,191 };
42 | const uint8_t master41[] = { 233,227,197,48,11,194,2,96,106,121,24,213,29,135,235,72,143,178,52,214, 40,169,50,108,229,158,18,236,235,164,101,76,21,14,97,243,92,93,225,101, 7,203,68,115,114,79,86,210 };
43 | const uint8_t master42[] = { 81,215,124,227,54,15,90,239,248,126,23,163,219,13,245,41,30,86,44,249,134, 52,221,127,240,30,141,123,249,8,126,221,226,156,188,235,158,84,165,56,158, 38,168,121,44,161,108,170 };
44 | const uint8_t master43[] = { 215,156,195,2,145,102,237,9,196,188,163,145,199,35,228,179,28,23,23,249, 85,178,209,135,93,115,173,126,89,48,247,135,179,30,19,89,183,168,203,102, 34,125,207,137,33,84,227,20 };
45 | const uint8_t master44[] = { 170,236,23,110,135,242,16,240,127,212,197,62,37,130,87,182,134,247,119, 78,61,134,173,159,214,68,203,93,143,247,247,101,163,234,79,216,76,234,227, 48,189,92,125,103,41,47,171,205 };
46 | const uint8_t master45[] = { 118,70,104,186,35,9,3,77,66,135,235,65,99,242,94,169,113,10,14,103,68,106, 70,10,7,149,242,62,30,100,71,50,149,137,115,146,220,185,252,36,127,222, 232,223,134,45,200,14 };
47 | const uint8_t master46[] = { 204,140,213,118,192,233,188,143,4,121,4,162,134,98,186,184,2,181,226,224, 108,234,26,82,94,22,96,49,161,202,40,239,201,13,29,73,250,175,210,176,50, 154,87,70,145,107,239,20 };
48 | const uint8_t master47[] = { 160,68,57,205,169,228,3,107,118,58,91,200,14,166,79,44,219,181,213,27,86, 55,142,117,151,55,78,224,219,81,220,167,183,230,20,196,175,133,245,162, 22,86,144,66,85,214,187,235 };
49 | const uint8_t master48[] = { 117,117,63,173,126,63,35,138,8,100,76,65,228,108,114,250,70,168,83,107, 133,12,248,18,209,232,62,247,111,94,200,8,174,49,96,108,36,74,30,114,188, 9,136,225,58,105,51,142 };
50 | const uint8_t master49[] = { 157,1,60,58,10,176,179,199,24,164,77,239,147,96,254,187,168,93,172,8,209, 103,62,122,61,41,35,55,119,107,79,203,4,137,86,53,211,205,221,229,143,71, 131,69,42,4,155,104,19,174,125,223,242,28,65,211,195,41,197,208,9,137,2, 78 };
51 | const uint8_t master50[] = { 161,212,83,134,155,103,237,212,88,188,177,162,36,16,53,8,52,218,66,239, 202,210,19,78,147,73,227,127,80,128,211,173,204,38,139,59,116,112,213,51, 177,127,54,250,142,13,149,250,174,240,91,131,2,217,59,89,21,210,246,95, 66,231,75,8 };
52 | const uint8_t master51[] = { 83,56,156,44,197,77,160,143,93,249,83,46,110,207,34,249,155,249,53,121, 66,232,94,72,59,131,210,129,52,13,60,111,5,114,192,85,26,153,9,232,165, 43,102,200,94,173,217,165,181,77,236,252,53,247,89,255,9,16,240,150,230, 180,19,88 };
53 | const uint8_t master52[] = { 6,9,131,74,104,2,18,36,129,24,75,80,246,121,209,152,247,9,20,55,148,155, 204,85,241,117,128,236,174,73,57,46,62,238,12,196,175,137,79,112,255,52, 218,205,195,135,94,141,213,213,170,144,62,45,91,199,225,185,22,145,155, 75,180,40 };
54 | const uint8_t master53[] = { 124,27,241,23,212,79,223,87,129,214,34,161,230,240,168,245,116,197,84,67, 41,197,102,155,244,188,36,21,201,194,105,78,28,74,28,212,67,148,94,239, 182,211,130,4,133,147,2,20,91,226,222,159,41,63,206,184,198,205,148,138, 44,41,209,176 };
55 | const uint8_t master54[] = { 84,104,143,97,29,117,50,48,5,241,116,142,186,158,229,99,95,186,245,237, 197,79,211,176,187,159,127,74,118,17,13,109,247,24,241,3,78,96,255,102, 180,70,228,123,173,59,151,163,110,9,111,199,107,146,179,188,137,61,103, 6,185,247,245,212 };
56 | const uint8_t master55[] = { 118,110,183,199,103,39,114,241,127,81,119,239,215,127,28,236,115,64,116, 215,102,93,214,207,89,250,200,192,36,25,87,11,44,222,212,149,204,148,44, 255,188,58,157,25,127,24,153,122,92,89,37,133,216,96,141,185,45,115,99, 238,182,33,112,95 };
57 | const uint8_t master56[] = { 196,213,190,214,69,184,227,220,28,132,237,60,124,167,236,17,174,150,24, 54,114,226,1,196,58,76,25,44,14,102,157,206,13,130,245,161,22,13,213,96, 116,154,246,227,241,139,102,219,182,152,20,131,26,167,38,159,239,236,210, 176,196,156,78,60 };
58 | const uint8_t master57[] = { 101,147,225,111,103,140,133,149,241,30,23,60,65,248,83,131,194,253,65,198, 18,236,205,213,115,120,194,165,245,70,82,13,125,178,225,131,15,64,240,72, 16,112,128,30,154,57,15,92,25,130,55,222,255,112,188,112,253,246,189,26, 236,207,114,47 };
59 | const uint8_t master58[] = { 199,161,228,120,85,125,46,243,141,87,89,70,88,113,253,104,68,254,5,237, 79,200,203,144,50,96,208,78,11,252,199,1,138,248,58,220,188,225,124,68, 197,210,249,31,167,107,86,202,222,124,145,187,104,231,99,155,255,235,59, 250,72,223,7,101 };
60 | const uint8_t master59[] = { 41,194,24,135,196,138,136,5,61,201,81,96,150,96,116,201,105,26,31,123,131, 17,29,120,92,6,70,70,121,35,195,157,218,41,224,155,223,95,191,65,225,217, 172,68,235,37,46,203,73,169,206,26,45,8,20,42,248,142,0,204,80,183,202, 177 };
61 | const uint8_t master60[] = { 99,45,35,44,153,237,60,32,122,156,158,17,225,48,53,103,117,46,94,91,200, 93,249,48,206,3,49,171,145,121,194,237,55,137,190,21,200,179,79,196,36, 24,114,252,203,99,187,180,235,139,174,154,64,206,219,5,87,11,209,203,254, 149,196,110 };
62 | const uint8_t master61[] = { 225,41,74,127,96,108,234,255,19,129,178,139,43,244,113,146,94,129,129,151, 162,53,237,55,166,238,103,141,215,190,234,142,213,53,110,62,155,188,217, 187,39,234,214,239,115,53,194,98,211,4,95,17,17,213,8,199,12,171,162,172, 211,68,203,177 };
63 | const uint8_t master62[] = { 133,100,189,25,253,43,51,103,6,1,99,156,196,62,72,216,144,23,214,84,223, 186,74,6,188,98,149,157,80,31,35,94,34,126,251,237,93,139,167,89,214,81, 30,116,203,109,6,84,53,239,29,119,201,20,195,143,161,81,55,14,75,20,212, 97 };
64 | const uint8_t master63[] = { 161,27,115,145,250,123,188,180,210,181,75,188,168,100,241,180,63,59,107, 97,45,130,179,244,244,236,131,108,31,3,180,168,187,141,72,135,252,234,134, 154,82,190,151,129,147,249,243,134,184,30,87,184,75,232,141,66,207,0,133, 53,15,51,67,212 };
65 | const uint8_t master64[] = { 101,160,120,89,138,55,143,101,195,183,206,125,109,67,250,237,41,114,174, 138,159,155,195,117 };
66 | const uint8_t master65[] = { 203,174,244,74,38,46,117,60,68,66,41,10,254,115,188,137,7,236,174,47,0, 232,136,195,236,252 };
67 | const uint8_t master66[] = { 174,186,45,36,166,134,195,43,166,108,76,55,250,33,26,63,162,119,54,236, 8,157,86,182,27,219,22,69 };
68 | const uint8_t master67[] = { 166,192,210,132,109,61,0,253,174,98,153,105,16,224,95,51,55,219,252,179, 121,165,155,99,244,45,8,209,93,236 };
69 | const uint8_t master68[] = { 204,231,166,234,4,44,45,128,31,41,88,61,211,74,103,23,150,216,55,191,117, 53,89,91,74,66,252,197,212,133,212,87 };
70 | const uint8_t master69[] = { 14,209,202,119,79,43,96,216,89,90,223,163,37,248,28,168,94,17,98,247,17, 185,97,234,177,223,176,120,25,214,233,206,114,2 };
71 | const uint8_t master70[] = { 228,190,242,61,252,95,94,21,207,75,6,8,131,254,215,92,42,219,131,136,175, 104,39,182,228,41,222,90,10,244,185,41,37,218,121,93 };
72 | const uint8_t master71[] = { 166,69,162,214,21,198,15,56,236,125,233,198,240,135,76,81,91,79,84,1,151, 70,106,223,201,230,201,85,175,88,16,17,242,217,28,161,121,104 };
73 | const uint8_t master72[] = { 177,104,86,135,228,33,176,89,104,110,111,15,240,197,48,207,121,235,40,129, 155,136,152,158,126,197,96,109,51,46,229,188 };
74 | const uint8_t master73[] = { 3,23,173,220,246,1,189,8,243,33,118,204,157,144,69,12,131,230,88,198,254, 195,123,145,195,41,146,9,216,80,53,70,229 };
75 | const uint8_t master74[] = { 44,194,119,220,37,79,65,47,132,215,159,182,87,94,165,188,100,159,23,16, 79,138,45,148,198,248,85,193,15,89,153,15,205,155 };
76 | const uint8_t master75[] = { 154,166,121,23,155,28,43,106,215,235,89,109,245,7,235,90,203,158,139,30, 231,114,154,54,77,144,168,145,106,95,22,156,170,239,203 };
77 | const uint8_t master76[] = { 190,26,115,144,206,183,93,13,47,174,150,237,36,71,248,202,217,237,94,112, 20,124,86,38,227,106,118,45,150,138,15,193,212,3,29,191 };
78 | const uint8_t master77[] = { 7,183,194,218,57,173,45,230,80,11,30,194,44,209,179,93,114,139,99,108,147, 162,179,112,71,75,0,103,22,19,7,95,53,119,159,190,194 };
79 | const uint8_t master78[] = { 204,109,168,196,153,13,43,138,85,164,29,155,94,196,219,10,227,110,93,125, 87,162,76,166,208,155,42,103,221,84,37,225,223,42,203,34,195,213 };
80 | const uint8_t master79[] = { 158,101,171,59,253,115,222,45,156,1,116,105,156,8,247,63,49,124,28,55,13, 187,10,135,14,253,36,182,199,93,191,102,169,159,37,250,172,88,227 };
81 |
--------------------------------------------------------------------------------
/compiler/avr-gcc-4.8/bits/c++config.h:
--------------------------------------------------------------------------------
1 | // Predefined symbols and macros -*- C++ -*-
2 |
3 | // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 | // 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
5 | //
6 | // This file is part of the GNU ISO C++ Library. This library is free
7 | // software; you can redistribute it and/or modify it under the
8 | // terms of the GNU General Public License as published by the
9 | // Free Software Foundation; either version 3, or (at your option)
10 | // any later version.
11 |
12 | // This library is distributed in the hope that it will be useful,
13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | // GNU General Public License for more details.
16 |
17 | // Under Section 7 of GPL version 3, you are granted additional
18 | // permissions described in the GCC Runtime Library Exception, version
19 | // 3.1, as published by the Free Software Foundation.
20 |
21 | // You should have received a copy of the GNU General Public License and
22 | // a copy of the GCC Runtime Library Exception along with this program;
23 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 | // .
25 |
26 | /** @file bits/c++config.h
27 | * This is an internal header file, included by other library headers.
28 | * Do not attempt to use it directly. @headername{iosfwd}
29 | */
30 |
31 | #ifndef _GLIBCXX_CXX_CONFIG_H
32 | #define _GLIBCXX_CXX_CONFIG_H 1
33 |
34 | // The current version of the C++ library in compressed ISO date format.
35 | #define __GLIBCXX__ 20120920
36 |
37 | // Macros for various attributes.
38 | // _GLIBCXX_PURE
39 | // _GLIBCXX_CONST
40 | // _GLIBCXX_NORETURN
41 | // _GLIBCXX_NOTHROW
42 | // _GLIBCXX_VISIBILITY
43 | #ifndef _GLIBCXX_PURE
44 | # define _GLIBCXX_PURE __attribute__ ((__pure__))
45 | #endif
46 |
47 | #ifndef _GLIBCXX_CONST
48 | # define _GLIBCXX_CONST __attribute__ ((__const__))
49 | #endif
50 |
51 | #ifndef _GLIBCXX_NORETURN
52 | # define _GLIBCXX_NORETURN __attribute__ ((__noreturn__))
53 | #endif
54 |
55 | // See below for C++
56 | #ifndef _GLIBCXX_NOTHROW
57 | # ifndef __cplusplus
58 | # define _GLIBCXX_NOTHROW __attribute__((__nothrow__))
59 | # endif
60 | #endif
61 |
62 | // Macros for visibility attributes.
63 | // _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY
64 | // _GLIBCXX_VISIBILITY
65 | # define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY 1
66 |
67 | #if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY
68 | # define _GLIBCXX_VISIBILITY(V) __attribute__ ((__visibility__ (#V)))
69 | #else
70 | // If this is not supplied by the OS-specific or CPU-specific
71 | // headers included below, it will be defined to an empty default.
72 | # define _GLIBCXX_VISIBILITY(V) _GLIBCXX_PSEUDO_VISIBILITY(V)
73 | #endif
74 |
75 | // Macros for deprecated attributes.
76 | // _GLIBCXX_USE_DEPRECATED
77 | // _GLIBCXX_DEPRECATED
78 | #ifndef _GLIBCXX_USE_DEPRECATED
79 | # define _GLIBCXX_USE_DEPRECATED 1
80 | #endif
81 |
82 | #if defined(__DEPRECATED) && defined(__GXX_EXPERIMENTAL_CXX0X__)
83 | # define _GLIBCXX_DEPRECATED __attribute__ ((__deprecated__))
84 | #else
85 | # define _GLIBCXX_DEPRECATED
86 | #endif
87 |
88 | #if __cplusplus
89 |
90 | // Macro for constexpr, to support in mixed 03/0x mode.
91 | #ifndef _GLIBCXX_CONSTEXPR
92 | # ifdef __GXX_EXPERIMENTAL_CXX0X__
93 | # define _GLIBCXX_CONSTEXPR constexpr
94 | # define _GLIBCXX_USE_CONSTEXPR constexpr
95 | # else
96 | # define _GLIBCXX_CONSTEXPR
97 | # define _GLIBCXX_USE_CONSTEXPR const
98 | # endif
99 | #endif
100 |
101 | // Macro for noexcept, to support in mixed 03/0x mode.
102 | #ifndef _GLIBCXX_NOEXCEPT
103 | # ifdef __GXX_EXPERIMENTAL_CXX0X__
104 | # define _GLIBCXX_NOEXCEPT noexcept
105 | # define _GLIBCXX_USE_NOEXCEPT noexcept
106 | # define _GLIBCXX_THROW(_EXC)
107 | # else
108 | # define _GLIBCXX_NOEXCEPT
109 | # define _GLIBCXX_USE_NOEXCEPT throw()
110 | # define _GLIBCXX_THROW(_EXC) throw(_EXC)
111 | # endif
112 | #endif
113 |
114 | #ifndef _GLIBCXX_NOTHROW
115 | # define _GLIBCXX_NOTHROW _GLIBCXX_USE_NOEXCEPT
116 | #endif
117 |
118 | // Macro for extern template, ie controling template linkage via use
119 | // of extern keyword on template declaration. As documented in the g++
120 | // manual, it inhibits all implicit instantiations and is used
121 | // throughout the library to avoid multiple weak definitions for
122 | // required types that are already explicitly instantiated in the
123 | // library binary. This substantially reduces the binary size of
124 | // resulting executables.
125 | // Special case: _GLIBCXX_EXTERN_TEMPLATE == -1 disallows extern
126 | // templates only in basic_string, thus activating its debug-mode
127 | // checks even at -O0.
128 | # define _GLIBCXX_EXTERN_TEMPLATE 1
129 |
130 | /*
131 | Outline of libstdc++ namespaces.
132 |
133 | namespace std
134 | {
135 | namespace __debug { }
136 | namespace __parallel { }
137 | namespace __profile { }
138 | namespace __cxx1998 { }
139 |
140 | namespace __detail { }
141 |
142 | namespace rel_ops { }
143 |
144 | namespace tr1
145 | {
146 | namespace placeholders { }
147 | namespace regex_constants { }
148 | namespace __detail { }
149 | }
150 |
151 | namespace tr2 { }
152 |
153 | namespace decimal { }
154 |
155 | namespace chrono { }
156 | namespace placeholders { }
157 | namespace regex_constants { }
158 | namespace this_thread { }
159 | }
160 |
161 | namespace abi { }
162 |
163 | namespace __gnu_cxx
164 | {
165 | namespace __detail { }
166 | }
167 |
168 | For full details see:
169 | http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/namespaces.html
170 | */
171 | namespace std
172 | {
173 | typedef __SIZE_TYPE__ size_t;
174 | typedef __PTRDIFF_TYPE__ ptrdiff_t;
175 |
176 | #ifdef __GXX_EXPERIMENTAL_CXX0X__
177 | typedef decltype(nullptr) nullptr_t;
178 | #endif
179 | }
180 |
181 |
182 | // Defined if inline namespaces are used for versioning.
183 | # define _GLIBCXX_INLINE_VERSION 0
184 |
185 | // Inline namespace for symbol versioning.
186 | #if _GLIBCXX_INLINE_VERSION
187 |
188 | namespace std
189 | {
190 | inline namespace __7 { }
191 |
192 | namespace rel_ops { inline namespace __7 { } }
193 |
194 | namespace tr1
195 | {
196 | inline namespace __7 { }
197 | namespace placeholders { inline namespace __7 { } }
198 | namespace regex_constants { inline namespace __7 { } }
199 | namespace __detail { inline namespace __7 { } }
200 | }
201 |
202 | namespace tr2
203 | { inline namespace __7 { } }
204 |
205 | namespace decimal { inline namespace __7 { } }
206 |
207 | namespace chrono { inline namespace __7 { } }
208 | namespace placeholders { inline namespace __7 { } }
209 | namespace regex_constants { inline namespace __7 { } }
210 | namespace this_thread { inline namespace __7 { } }
211 |
212 | namespace __detail { inline namespace __7 { } }
213 | namespace __regex { inline namespace __7 { } }
214 | }
215 |
216 | namespace __gnu_cxx
217 | {
218 | inline namespace __7 { }
219 | namespace __detail { inline namespace __7 { } }
220 | }
221 | # define _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __7 {
222 | # define _GLIBCXX_END_NAMESPACE_VERSION }
223 | #else
224 | # define _GLIBCXX_BEGIN_NAMESPACE_VERSION
225 | # define _GLIBCXX_END_NAMESPACE_VERSION
226 | #endif
227 |
228 |
229 | // Inline namespaces for special modes: debug, parallel, profile.
230 | #if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL) \
231 | || defined(_GLIBCXX_PROFILE)
232 | namespace std
233 | {
234 | // Non-inline namespace for components replaced by alternates in active mode.
235 | namespace __cxx1998
236 | {
237 | #if _GLIBCXX_INLINE_VERSION
238 | inline namespace __7 { }
239 | #endif
240 | }
241 |
242 | // Inline namespace for debug mode.
243 | # ifdef _GLIBCXX_DEBUG
244 | inline namespace __debug { }
245 | # endif
246 |
247 | // Inline namespaces for parallel mode.
248 | # ifdef _GLIBCXX_PARALLEL
249 | inline namespace __parallel { }
250 | # endif
251 |
252 | // Inline namespaces for profile mode
253 | # ifdef _GLIBCXX_PROFILE
254 | inline namespace __profile { }
255 | # endif
256 | }
257 |
258 | // Check for invalid usage and unsupported mixed-mode use.
259 | # if defined(_GLIBCXX_DEBUG) && defined(_GLIBCXX_PARALLEL)
260 | # error illegal use of multiple inlined namespaces
261 | # endif
262 | # if defined(_GLIBCXX_PROFILE) && defined(_GLIBCXX_DEBUG)
263 | # error illegal use of multiple inlined namespaces
264 | # endif
265 | # if defined(_GLIBCXX_PROFILE) && defined(_GLIBCXX_PARALLEL)
266 | # error illegal use of multiple inlined namespaces
267 | # endif
268 |
269 | // Check for invalid use due to lack for weak symbols.
270 | # if __NO_INLINE__ && !__GXX_WEAK__
271 | # warning currently using inlined namespace mode which may fail \
272 | without inlining due to lack of weak symbols
273 | # endif
274 | #endif
275 |
276 | // Macros for namespace scope. Either namespace std:: or the name
277 | // of some nested namespace within it corresponding to the active mode.
278 | // _GLIBCXX_STD_A
279 | // _GLIBCXX_STD_C
280 | //
281 | // Macros for opening/closing conditional namespaces.
282 | // _GLIBCXX_BEGIN_NAMESPACE_ALGO
283 | // _GLIBCXX_END_NAMESPACE_ALGO
284 | // _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
285 | // _GLIBCXX_END_NAMESPACE_CONTAINER
286 | #if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PROFILE)
287 | # define _GLIBCXX_STD_C __cxx1998
288 | # define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER \
289 | namespace _GLIBCXX_STD_C { _GLIBCXX_BEGIN_NAMESPACE_VERSION
290 | # define _GLIBCXX_END_NAMESPACE_CONTAINER \
291 | } _GLIBCXX_END_NAMESPACE_VERSION
292 | # undef _GLIBCXX_EXTERN_TEMPLATE
293 | # define _GLIBCXX_EXTERN_TEMPLATE -1
294 | #endif
295 |
296 | #ifdef _GLIBCXX_PARALLEL
297 | # define _GLIBCXX_STD_A __cxx1998
298 | # define _GLIBCXX_BEGIN_NAMESPACE_ALGO \
299 | namespace _GLIBCXX_STD_A { _GLIBCXX_BEGIN_NAMESPACE_VERSION
300 | # define _GLIBCXX_END_NAMESPACE_ALGO \
301 | } _GLIBCXX_END_NAMESPACE_VERSION
302 | #endif
303 |
304 | #ifndef _GLIBCXX_STD_A
305 | # define _GLIBCXX_STD_A std
306 | #endif
307 |
308 | #ifndef _GLIBCXX_STD_C
309 | # define _GLIBCXX_STD_C std
310 | #endif
311 |
312 | #ifndef _GLIBCXX_BEGIN_NAMESPACE_ALGO
313 | # define _GLIBCXX_BEGIN_NAMESPACE_ALGO
314 | #endif
315 |
316 | #ifndef _GLIBCXX_END_NAMESPACE_ALGO
317 | # define _GLIBCXX_END_NAMESPACE_ALGO
318 | #endif
319 |
320 | #ifndef _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
321 | # define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
322 | #endif
323 |
324 | #ifndef _GLIBCXX_END_NAMESPACE_CONTAINER
325 | # define _GLIBCXX_END_NAMESPACE_CONTAINER
326 | #endif
327 |
328 | // GLIBCXX_ABI Deprecated
329 | // Define if compatibility should be provided for -mlong-double-64.
330 | #undef _GLIBCXX_LONG_DOUBLE_COMPAT
331 |
332 | // Inline namespace for long double 128 mode.
333 | #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__
334 | namespace std
335 | {
336 | inline namespace __gnu_cxx_ldbl128 { }
337 | }
338 | # define _GLIBCXX_NAMESPACE_LDBL __gnu_cxx_ldbl128::
339 | # define _GLIBCXX_BEGIN_NAMESPACE_LDBL namespace __gnu_cxx_ldbl128 {
340 | # define _GLIBCXX_END_NAMESPACE_LDBL }
341 | #else
342 | # define _GLIBCXX_NAMESPACE_LDBL
343 | # define _GLIBCXX_BEGIN_NAMESPACE_LDBL
344 | # define _GLIBCXX_END_NAMESPACE_LDBL
345 | #endif
346 |
347 | // Assert.
348 | #if !defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_PARALLEL)
349 | # define __glibcxx_assert(_Condition)
350 | #else
351 | namespace std
352 | {
353 | // Avoid the use of assert, because we're trying to keep the
354 | // include out of the mix.
355 | inline void
356 | __replacement_assert(const char* __file, int __line,
357 | const char* __function, const char* __condition)
358 | {
359 | __builtin_printf("%s:%d: %s: Assertion '%s' failed.\n", __file, __line,
360 | __function, __condition);
361 | __builtin_abort();
362 | }
363 | }
364 | #define __glibcxx_assert(_Condition) \
365 | do \
366 | { \
367 | if (! (_Condition)) \
368 | std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \
369 | #_Condition); \
370 | } while (false)
371 | #endif
372 |
373 | // Macros for race detectors.
374 | // _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) and
375 | // _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) should be used to explain
376 | // atomic (lock-free) synchronization to race detectors:
377 | // the race detector will infer a happens-before arc from the former to the
378 | // latter when they share the same argument pointer.
379 | //
380 | // The most frequent use case for these macros (and the only case in the
381 | // current implementation of the library) is atomic reference counting:
382 | // void _M_remove_reference()
383 | // {
384 | // _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&this->_M_refcount);
385 | // if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount, -1) <= 0)
386 | // {
387 | // _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&this->_M_refcount);
388 | // _M_destroy(__a);
389 | // }
390 | // }
391 | // The annotations in this example tell the race detector that all memory
392 | // accesses occurred when the refcount was positive do not race with
393 | // memory accesses which occurred after the refcount became zero.
394 | #ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE
395 | # define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A)
396 | #endif
397 | #ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER
398 | # define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A)
399 | #endif
400 |
401 | // Macros for C linkage: define extern "C" linkage only when using C++.
402 | # define _GLIBCXX_BEGIN_EXTERN_C extern "C" {
403 | # define _GLIBCXX_END_EXTERN_C }
404 |
405 | #else // !__cplusplus
406 | # define _GLIBCXX_BEGIN_EXTERN_C
407 | # define _GLIBCXX_END_EXTERN_C
408 | #endif
409 |
410 |
411 | // First includes.
412 |
413 | // Pick up any OS-specific definitions.
414 | //#include
415 |
416 | // Pick up any CPU-specific definitions.
417 | //#include
418 |
419 | // If platform uses neither visibility nor psuedo-visibility,
420 | // specify empty default for namespace annotation macros.
421 | #ifndef _GLIBCXX_PSEUDO_VISIBILITY
422 | # define _GLIBCXX_PSEUDO_VISIBILITY(V)
423 | #endif
424 |
425 | // Certain function definitions that are meant to be overridable from
426 | // user code are decorated with this macro. For some targets, this
427 | // macro causes these definitions to be weak.
428 | #ifndef _GLIBCXX_WEAK_DEFINITION
429 | # define _GLIBCXX_WEAK_DEFINITION
430 | #endif
431 |
432 |
433 | // The remainder of the prewritten config is automatic; all the
434 | // user hooks are listed above.
435 |
436 | // Create a boolean flag to be used to determine if --fast-math is set.
437 | #ifdef __FAST_MATH__
438 | # define _GLIBCXX_FAST_MATH 1
439 | #else
440 | # define _GLIBCXX_FAST_MATH 0
441 | #endif
442 |
443 | // This marks string literals in header files to be extracted for eventual
444 | // translation. It is primarily used for messages in thrown exceptions; see
445 | // src/functexcept.cc. We use __N because the more traditional _N is used
446 | // for something else under certain OSes (see BADNAMES).
447 | #define __N(msgid) (msgid)
448 |
449 | // For example, is known to #define min and max as macros...
450 | #undef min
451 | #undef max
452 |
453 | #endif // _GLIBCXX_CXX_CONFIG_H
454 |
--------------------------------------------------------------------------------
/chaskey.js:
--------------------------------------------------------------------------------
1 | /* chaskey.js - a JS implementation of Chaskey algorithm in MAC and CBC modes
2 | * Chaskey algorithm invented by Nicky Mouha http://mouha.be/chaskey/
3 | *
4 | * Copyright (C) 2017 Eugene Hutorny
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"),
8 | * to deal in the Software without restriction, including without limitation
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | * and/or sell copies of the Software, and to permit persons to whom the
11 | * Software is furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 | * IN THE SOFTWARE.
23 | *
24 | * https://opensource.org/licenses/MIT
25 | */
26 |
27 | /**
28 | * creates a new block, 32x4 bits, copies content from a, if compatible
29 | */
30 | function block32x4(a) {
31 | var N = 4;
32 | this.v = a ? Uint32Array.from(a) : new Uint32Array(N);
33 | this.xor = function(blk) {
34 | for(var i in this.v) { this.v[i] ^= (blk.v||blk)[i]; }
35 | }
36 | this.xor_bytes = function(blk, size) {
37 | var v = new Uint8Array(this.v.buffer);
38 | var b = blk.v
39 | ? new Uint8Array(blk.v.buffer, blk.v.byteOffset)
40 | : new Uint8Array(blk.buffer, blk.byteOffset);
41 | for(var i = 0; i rounds
66 | * of transformations
67 | */
68 | function ChaskeyCipher(block, count) {
69 | block.call(this);
70 | var N = count;
71 | this.block_t = block;
72 | function ror(val, n) {
73 | return (val << (32-n)) | (val >>> n);
74 | }
75 |
76 | function rol(val, n) {
77 | return (val >>> (32-n)) | (val << n);
78 | }
79 | this.round = function() {
80 | var v = this.block();
81 | v[0] += v[1];
82 | v[1] = rol(v[1], 5);
83 | v[1] ^= v[0];
84 | v[0] = rol(v[0],16);
85 | v[2] += v[3];
86 | v[3] = rol(v[3], 8);
87 | v[3] ^= v[2];
88 | v[0] += v[3];
89 | v[3] = rol(v[3],13);
90 | v[3] ^= v[0];
91 | v[2] += v[1];
92 | v[1] = rol(v[1], 7);
93 | v[1] ^= v[2];
94 | v[2] = rol(v[2],16);
95 | }
96 |
97 | this.dnour = function(v) {
98 | //var v = this.block();
99 | v[2] = ror(v[2],16);
100 | v[1] ^= v[2];
101 | v[1] = ror(v[1], 7);
102 | v[2] -= v[1];
103 | v[3] ^= v[0];
104 | v[3] = ror(v[3],13);
105 | v[0] -= v[3];
106 | v[3] ^= v[2];
107 | v[3] = ror(v[3], 8);
108 | v[2] -= v[3];
109 | v[0] = ror(v[0],16);
110 | v[1] ^= v[0];
111 | v[1] = ror(v[1], 5);
112 | v[0] -= v[1];
113 | }
114 | this.permute = function() {
115 | for(var i = N; i--; ) {
116 | this.round();
117 | }
118 | }
119 | this.etumrep = function(v) {
120 | for(var i = N; i--; ) {
121 | this.dnour(v);
122 | }
123 | }
124 | this.derive = function(i) {
125 | i = i.v || i;
126 | return new this.block_t([
127 | (i[0] << 1) ^((i[3] >> 31) & 0x87), /* >> for signed shift */
128 | (i[1] << 1) | (i[0] >>> 31),
129 | (i[2] << 1) | (i[1] >>> 31),
130 | (i[3] << 1) | (i[2] >>> 31)]);
131 | }
132 | this.init = function(key) {
133 | this.assign(key);
134 | }
135 | this.clone = function() {
136 | return new ChaskeyCipher(this.block_t, N);
137 | }
138 | };
139 |
140 | /**
141 | * Constructs a new block formatter, n specifies blok length in bytes
142 | */
143 | function Formatter(n) {
144 | var N = n;
145 | var bytes = new Uint8Array(new ArrayBuffer(N));
146 | var pos = 0;
147 | var len = 0;
148 |
149 | this.init = function(n) {
150 | N = n;
151 | bytes = new Uint8Array(new ArrayBuffer(N));
152 | patch4IE(bytes);
153 | pos = 0;
154 | len = 0;
155 | }
156 | this.reset = function() {
157 | bytes.fill(0);
158 | pos = 0;
159 | len = 0;
160 | }
161 | function resize(l) {
162 | var res = new Uint8Array(new ArrayBuffer(l));
163 | res.set(bytes);
164 | bytes = res;
165 | patch4IE(bytes);
166 | }
167 |
168 | /* https://github.com/feross/buffer/issues/60 */
169 | function utf8ToBinaryString(str) {
170 | var escstr = encodeURIComponent(str);
171 | // replaces any uri escape sequence, such as %0A, with binary escape, such as 0x0A
172 | var binstr = escstr.replace(/%([0-9A-F]{2})/g, function(match, p1) {
173 | return String.fromCharCode('0x' + p1);
174 | });
175 |
176 | return binstr;
177 | }
178 |
179 | function utf8ToBuffer(str) {
180 | var binstr = utf8ToBinaryString(str);
181 | var buf = new Uint8Array(binstr.length);
182 | Array.prototype.forEach.call(binstr, function (ch, i) {
183 | buf[i] = ch.charCodeAt(0);
184 | });
185 | return buf;
186 | }
187 |
188 |
189 | this.append = function(message) {
190 | if( typeof(message) === typeof("") || message instanceof String) try {
191 | if( window.TextEncoder )
192 | message = new TextEncoder("utf-8").encode(message);
193 | else
194 | message = utf8ToBuffer(message);
195 | } catch(e) {
196 | console.log(e);
197 | message = utf8ToBuffer(message);
198 | }
199 | if( !(message instanceof Uint8Array) )
200 | throw Error("Message is not a byte string (Uint8Array or String)");
201 | var l = len + message.length;
202 | if( l > bytes.length ) {
203 | resize(l + ((l % N) ? N - (l % N) : 0));
204 | }
205 | bytes.set(message, len);
206 | len += message.length;
207 | }
208 | this.pad = function(firstbyte) {
209 | if( len && len == bytes.length ) return false;
210 | while(len < bytes.length ) {
211 | bytes[len++] = firstbyte;
212 | firstbyte = 0;
213 | }
214 | return true;
215 | }
216 | this.last = function() {
217 | return pos + N >= bytes.length;
218 | }
219 | this.block = function() {
220 | return new Uint32Array(bytes.buffer, pos, N/Uint32Array.BYTES_PER_ELEMENT);
221 | }
222 | this.next = function(data) {
223 | return (pos += N) < bytes.length;
224 | }
225 | this.move = function(data) {
226 | data && this.save(data);
227 | return (pos += N) < bytes.length;
228 | }
229 | this.save = function(data) {
230 | bytes.set(new Uint8Array(data.buffer), pos);
231 | }
232 | this.full = function() {
233 | return pos + N <= len;
234 | }
235 | this.bytes = function(l) {
236 | return Uint8Array.from(bytes.subarray(0,l||len));
237 | }
238 | this.len = function() {
239 | return len;
240 | }
241 | }
242 |
243 | /**
244 | * Constructs a MAC crypto primitive
245 | */
246 | function Mac(cipher, formatter) {
247 | var key = null;
248 | var subkey1 = null;
249 | var subkey2 = null;
250 | var buff = formatter || new Formatter(cipher.size);
251 | formatter && formatter.init(cipher.size);
252 | this.set = function(akey) {
253 | key = new cipher.block_t(akey);
254 | subkey1 = cipher.derive(key.block());
255 | subkey2 = cipher.derive(subkey1.block());
256 | cipher.init(key);
257 | }
258 | this.init = function () {
259 | cipher.init(key);
260 | }
261 | function encrypt(block) {
262 | cipher.xor(block);
263 | cipher.permute();
264 | }
265 | this.sign = function(message) {
266 | if( key === null ) throw new Error("key is not set");
267 | var finalkey = subkey1;
268 | cipher.init(key);
269 | buff.append(message);
270 | if ( buff.pad(1) ) finalkey = subkey2;
271 | do {
272 | if( buff.last() ) cipher.xor(finalkey);
273 | encrypt(buff.block());
274 | } while(buff.next());
275 | cipher.xor(finalkey);
276 | buff.reset();
277 | return new Uint8Array(cipher.block().buffer);
278 | }
279 | }
280 |
281 | /**
282 | * Constructs a Cbc crypto primitive
283 | */
284 | function Cbc(cipher, formatter) {
285 | var key = null;
286 | var buff = formatter || new Formatter(cipher.size);
287 | formatter && formatter.init(cipher.size);
288 | this.set = function(akey) {
289 | key = new cipher.block_t(akey);
290 | cipher.init(key);
291 | buff.reset();
292 | }
293 | function encrypt(block) {
294 | cipher.xor(block);
295 | cipher.permute();
296 | cipher.xor(key);
297 | }
298 | function decrypt(input) {
299 | var output = new cipher.block_t(input);
300 | output.xor(key);
301 | cipher.etumrep(output.block());
302 | output.xor(cipher.block());
303 | cipher.init(input);
304 | return output.block();
305 | }
306 | /** initialize the cipher with initialization vector iv */
307 | this.initIV = function(iv) {
308 | cipher.init(key);
309 | cipher.xor(new cipher.block_t(iv));
310 | buff.reset();
311 | }
312 | /** initialize the cipher with iv */
313 | this.init = function(nonce) {
314 | if( key === null ) throw new Error("key is not set");
315 | /* NIST Special Publication 800-38a
316 | * IV generation, recommended method number first.
317 | * Apply the forward cipher function, under the same key that is
318 | * used for the encryption of the plaintext, to a nonce */
319 | cipher.init(cipher.derive(key));
320 | buff.reset();
321 | buff.append(nonce);
322 | do {
323 | encrypt(buff.block());
324 | } while(buff.next());
325 | buff.reset();
326 | }
327 | this.encrypt = function(message, last) {
328 | if( key === null ) throw new Error("key is not set");
329 | buff.append(message);
330 | if( last !== false ) buff.pad(0);
331 | if(! buff.full() ) return new Uint8Array();
332 | do {
333 | encrypt(buff.block());
334 | } while( buff.move(cipher.block()) );
335 | return buff.bytes();
336 | }
337 | this.decrypt = function(message, last) {
338 | if( key === null ) throw new Error("key is not set");
339 | buff.append(message);
340 | if(! buff.full() ) return new Uint8Array();
341 | while( buff.move(decrypt(buff.block())));
342 | return buff.bytes();
343 | }
344 | }
345 |
346 | /**
347 | * Constructs a Cloc crypto primitive
348 | */
349 | function Cloc(Cipher, formatter) {
350 | var key = null;
351 | var ozp = false;
352 | var g1g2guard = false;
353 | var buff = formatter || new Formatter(Cipher.size);
354 | formatter && formatter.init(Cipher.size);
355 | var enc = Cipher;
356 | var tag = Cipher.clone();
357 |
358 | function asHex(b) {
359 | b = Array.from(b.v || b);
360 | return '[' + b.map(function(i){ return i.toString(16); }).join(",") + ']';
361 | }
362 |
363 | function cipher(input) {
364 | if( input ) tag.xor(input);
365 | tag.permute();
366 | tag.xor(key);
367 | }
368 |
369 | function prf(tailsize, block) {
370 | block && enc.assign(block);
371 | tag.xor(key);
372 | cipher(enc);
373 | fix1(enc.block());
374 | enc.xor(key)
375 | enc.permute();
376 | tailsize == enc.size ? enc.xor(key) : enc.xor_bytes(key, tailsize);
377 | }
378 |
379 | /* CLOC-specific tweak function, */
380 | /** f1(X) = (X[1, 3],X[2, 4],X[1, 2, 3],X[2, 3, 4]) */
381 | function f1(b) {
382 | b[0] ^= b[2]; /* X[1, 3] */
383 | var t = b[1];
384 | b[1] ^= b[3]; /* X[2, 4] */
385 | b[3] = b[2] ^ b[1]; /* X[2, 3, 4] */
386 | b[2] = b[0] ^ t; /* X[1, 2, 3] */
387 | }
388 | /** f2(X) = (X[2],X[3],X[4],X[1, 2]) */
389 | function f2(b) {
390 | var t = b[0] ^ b[1];
391 | b[0] = b[1]; /* X[2] */
392 | b[1] = b[2]; /* X[2] */
393 | b[2] = b[3]; /* X[4] */
394 | b[3] = t; /* X[1, 2] */
395 | }
396 | /** g1(X) = (X[3],X[4],X[1, 2],X[2, 3]) */
397 | function g1(b) {
398 | var t = b[0];
399 | b[0] = b[2]; /* X[3] */
400 | b[2] = b[1] ^ t; /* X[1, 2] */
401 | t = b[1];
402 | b[1] = b[3]; /* X[4] */
403 | b[3] = b[0] ^ t; /* X[2, 3] */
404 | }
405 | /** g2(X) = (X[2],X[3],X[4],X[1, 2]) */
406 | function g2(b) { f2(b); }
407 | /** h(X) = (X[1, 2],X[2, 3],X[3, 4],X[1, 2, 4]) */
408 | function h(b) {
409 | b[0] ^= b[1]; /* X[1, 2] */
410 | b[1] ^= b[2]; /* X[2, 3] */
411 | b[2] ^= b[3]; /* X[3, 4] */
412 | b[3] ^= b[0]; /* X[1, 2, 4] */
413 | }
414 | function fix0(b) {
415 | var fixed = b[0] & 0x80000000;
416 | b[0] &= ~ 0x80000000;
417 | return !! fixed;
418 | }
419 | function fix1(b) {
420 | b[0] |= 0x80000000;
421 | }
422 |
423 |
424 | this.init = function() {
425 | ozp = false;
426 | g1g2guard = false;
427 | enc.init(key);
428 | buff.reset();
429 | }
430 |
431 | this.set = function(akey) {
432 | key = new enc.block_t(akey);
433 | this.init();
434 | }
435 | function update(block) {
436 | enc.xor(block);
437 | enc.permute();
438 | enc.xor(key);
439 | }
440 |
441 | function process(block, tailsize, empty) {
442 | if( ! g1g2guard ) {
443 | if( empty ) g1(tag.block());
444 | else g2(tag.block());
445 | g1g2guard = true;
446 | }
447 | cipher();
448 | tailsize == enc.size ? enc.xor(block) : enc.xor_bytes(block, tailsize);
449 | }
450 | /** processes associated data */
451 | this.update = function(message) {
452 | if( key === null ) throw new Error("key is not set");
453 | var fixed0 = false;
454 | buff.append(message);
455 | ozp = buff.pad(0x80);
456 | do {
457 | if( buff.last() ) fixed0 = fix0(enc.block());
458 | update(buff.block());
459 | if( fixed0 ) h(enc.block());
460 | } while(buff.next());
461 | buff.reset();
462 | }
463 |
464 | /** applies a nonce */
465 | this.nonce = function(nonce) {
466 | if( key === null ) throw new Error("key is not set");
467 | buff.append(nonce);
468 | buff.pad(0x80);
469 | enc.xor(buff.block());
470 | if( ozp ) f2(enc.block());
471 | else f1(enc.block());
472 | tag.assign(enc.block());
473 | enc.permute();
474 | enc.xor(key);
475 | buff.reset();
476 | }
477 |
478 | /** encrypts a chunk of data */
479 | this.encrypt = function(message, last) {
480 | if( key === null ) throw new Error("key is not set");
481 | buff.append(message);
482 | last = ( last !== false );
483 | var len = buff.len();
484 | var tailsize = enc.size;
485 | if( last ) {
486 | tailsize = (buff.len() % enc.size) || enc.size;
487 | buff.pad(0);
488 | }
489 | while( buff.full() ) {
490 | var tail = buff.last() ? tailsize : enc.size;
491 | process(buff.block(), tail, last && len == 0);
492 | buff.save(enc.block());
493 | prf(tail);
494 | buff.move();
495 | }
496 | return buff.bytes(len);
497 | }
498 |
499 | /** decrypts a chunk of data */
500 | this.decrypt = function(message, last) {
501 | if( key === null ) throw new Error("key is not set");
502 | buff.append(message);
503 | last = ( last !== false );
504 | var len = buff.len();
505 | var tailsize = enc.size;
506 | if( last ) {
507 | tailsize = (buff.len() % enc.size) || enc.size;
508 | buff.pad(0);
509 | }
510 | while( buff.full() ) {
511 | var input = Uint32Array.from(buff.block());
512 | var tail = buff.last() ? tailsize : enc.size;
513 | process(buff.block(), tail, last && len == 0);
514 | buff.move(enc.block());
515 | prf(tail, input);
516 | }
517 | return buff.bytes(len);
518 | }
519 |
520 | /** returns digest (MAC) chunk of data */
521 | this.mac = function() {
522 | return tag.raw();
523 | }
524 | }
525 |
526 | /** ChaskeyCipher.Mac - a predefined primitive MAC using ChaskeyCipher */
527 | ChaskeyCipher.Mac = function(count) {
528 | Mac.call(this, new ChaskeyCipher(block32x4, count||8));
529 | }
530 |
531 | /** ChaskeyCipher.Cbc - a predefined primitive CBC using ChaskeyCipher */
532 | ChaskeyCipher.Cbc = function(count) {
533 | Cbc.call(this, new ChaskeyCipher(block32x4, count||8));
534 | }
535 |
536 | ChaskeyCipher.Cloc = function(count) {
537 | Cloc.call(this, new ChaskeyCipher(block32x4, count||8));
538 | }
539 |
540 | /** patching IE */
541 | if( ! Uint32Array.from ) {
542 | Uint32Array.from = function(src) {
543 | var dst = new Uint32Array(src.length||0);
544 | Array.prototype.every.call(dst, function(v,i) { dst[i] = src[i]; return true; });
545 | return dst;
546 | }
547 | }
548 | if( ! Uint8Array.from ) {
549 | Uint8Array.from = function(src) {
550 | var dst = new Uint8Array(src.length||0);
551 | Array.prototype.every.call(dst, function(v,i) { dst[i] = src[i]; return true; });
552 | return dst;
553 |
554 | }
555 | }
556 | if( ! Uint8Array.prototype.fill ) {
557 | Uint8Array.prototype.fill = function(val) {
558 | Array.prototype.every.call(this, function(v,i) { this[i] = val; return true; });
559 | }
560 | }
561 |
562 | if( ! Array.from ) {
563 | Array.from = function(src) {
564 | var dst = new Array(src.length);
565 | dst.every(function(v,i) { dst[i] = src[i]; return true; });
566 | return dst;
567 | }
568 | }
569 |
570 | function patch4IE(obj) {
571 | if( !obj.subarray )
572 | obj.subarray = function(b,e) {
573 | return Uint8Array.from(Array.prototype.slice.call(this,b,e));
574 | };
575 | return obj;
576 | }
577 |
578 | /* patching IE */
579 |
--------------------------------------------------------------------------------
/tests/hosted/main.cpp:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2017 Eugene Hutorny
2 | *
3 | * main.cpp - Command line interface for Chaskey Block Cipher
4 | * invented by Nicky Mouha http://mouha.be/chaskey/
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"),
8 | * to deal in the Software without restriction, including without limitation
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | * and/or sell copies of the Software, and to permit persons to whom the
11 | * Software is furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 | * IN THE SOFTWARE.
23 | *
24 | * https://opensource.org/licenses/MIT
25 | */
26 |
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 |
40 | #include "chaskey.h"
41 | #include "chaskey.hpp"
42 | #include "miculog.hpp"
43 |
44 | #ifdef WITH_AES128CLOC_TEST
45 | extern "C" {
46 | # include
47 | }
48 | #endif
49 |
50 | using namespace std;
51 |
52 | enum class operation {
53 | help,
54 | sign,
55 | verify,
56 | encrypt,
57 | decrypt,
58 | cloc,
59 | uncloc,
60 | test,
61 | bench,
62 | masters,
63 | };
64 |
65 | enum exitcode {
66 | success,
67 | err_test,
68 | err_verify,
69 | bad_args,
70 | ioerror,
71 | exit_help,
72 | aborted
73 | };
74 |
75 | struct options {
76 | const char* keyfile;
77 | const char* key;
78 | const char* textfile;
79 | const char* plaintext;
80 | const char* digest;
81 | const char* nonce;
82 | const char* iv;
83 | const char* ad;
84 | const char* adfile;
85 | const char* outfile;
86 | operation oper;
87 | bool hexout;
88 | bool hexkey;
89 | bool aes128cloc;
90 | bool tocerr;
91 | unsigned long param;
92 | };
93 |
94 | static int verbosity = 1;
95 |
96 | class error : public exception {
97 | public:
98 | error(const string& message) noexcept : msg(message) {}
99 | const char* what() const noexcept { return msg.c_str(); }
100 | private:
101 | const string msg;
102 | };
103 |
104 | void fillopts(int argc, char * const argv[], options& opts) {
105 | char c;
106 | while(-1 != (c = getopt(argc, argv, "edsm:cu:o:V:N:tT:b:k:K:i:I:X:a:A:hvqr2"))){
107 | switch(c) {
108 | case 'e': opts.oper = operation::encrypt; break;
109 | case 'd': opts.oper = operation::decrypt; break;
110 | case 's': opts.oper = operation::sign; break;
111 | case 'm': opts.oper = operation::verify; opts.digest = optarg; break;
112 | case 't': opts.oper = operation::test; break;
113 | case 'c': opts.oper = operation::cloc; break;
114 | case 'u': opts.oper = operation::uncloc; opts.digest = optarg; break;
115 | case 'N': opts.nonce = optarg; break;
116 | case 'V': opts.iv = optarg; break;
117 | case 'k': opts.keyfile = optarg; opts.key = nullptr; break;
118 | case 'X': opts.key = optarg; opts.keyfile = nullptr; opts.hexkey = true; break;
119 | case 'K': opts.key = optarg; opts.keyfile = nullptr; opts.hexkey = false; break;
120 | case 'A': opts.ad = optarg; opts.adfile = nullptr; break;
121 | case 'a': opts.adfile = optarg; opts.ad = nullptr; break;
122 | case 'i': opts.textfile = optarg; opts.plaintext = nullptr; break;
123 | case 'I': opts.plaintext = optarg; opts.textfile = nullptr; break;
124 | case 'o': opts.outfile = optarg; break;
125 | case 'h': opts.hexout = true; break;
126 | case '2': opts.tocerr = true; break;
127 | case 'v': verbosity = 2; break;
128 | case 'q': verbosity = 0; break;
129 | # ifdef WITH_AES128CLOC_TEST
130 | case 'r': opts.aes128cloc = true; break;
131 | # endif
132 | case '?': opts.oper = operation::help; break;
133 | case 'T': opts.oper = operation::masters; opts.param = strtol(optarg,nullptr, 10); break;
134 | case 'b': opts.oper = operation::bench; opts.param = strtol(optarg,nullptr, 10); break;
135 | default:
136 | throw error(string("Unrecognized option '") + c + "'");
137 | }
138 | }
139 | }
140 |
141 | static inline uint32_t hex(char c) {
142 | if( c == 0 ) return 0;
143 | if( c >= '0' && c <= '9' ) return c-'0';
144 | if( c >= 'A' && c <= 'F' ) return c-'A' +0xA;
145 | if( c >= 'a' && c <= 'f' ) return c-'a' +0xa;
146 | throw error(string("Invalid hex character '") + c + "'");
147 | }
148 |
149 | static inline uint32_t hex(const char * str) {
150 | return hex(str[1]) | (hex(str[0]) << 4);
151 | }
152 |
153 | using namespace crypto;
154 | using namespace chaskey;
155 | static constexpr block_t default_key {
156 | 0x01234567, 0x89ABCDEF, 0xFEDCBA98, 0x76543210
157 | };
158 |
159 | static ostream& operator<<(ostream& o, const block_t& k) {
160 | return o << '{' << hex << k[0] << ',' << k[1] << ',' << k[2] << ',' << k[3] << '}';
161 | }
162 |
163 | static void hex2block(const char* str, block_t& key) {
164 | if( ! str )
165 | throw error(string("Missing key, expected 32 hex digits"));
166 | if( 128 != (strlen(str) * 4) )
167 | throw error(string("Invalid hex key :'") + str + "', expected 32 hex digits");
168 | for(uint_fast8_t i = 0; i <16; ++i, str+=2) {
169 | key[i/4] |= hex(str) << (8*(i%4));
170 | }
171 | }
172 |
173 | static uint_fast8_t hex2bytes(const char* str, uint8_t* key, uint_fast8_t len) {
174 | if( ! str )
175 | throw error(string("Missing byte string"));
176 | uint_fast8_t i;
177 | for(i = 0; i < len && *str; ++i, str+=2) {
178 | key[i] = hex(str);
179 | if( ! str[1] ) break;
180 | }
181 | return i;
182 | }
183 |
184 | static bool getkeys(const options& opts, block_t& key, block_t& iv) {
185 | if( opts.keyfile ) {
186 | ifstream file(opts.keyfile, fstream::in | fstream::binary);
187 | if( ! file ) {
188 | throw error(string("Error accessing key file '") + opts.keyfile + "'");
189 | }
190 | file.read(reinterpret_cast(&key[0]), sizeof(block_t));
191 | if( ! file ) {
192 | throw error(string("Error reading key file '") + opts.keyfile + "'");
193 | }
194 | return true;
195 | }
196 | for(auto& k : key) k = 0;
197 | if( opts.key ) {
198 | if( opts.hexkey ) {
199 | hex2block(opts.key, key);
200 | } else {
201 | if( 128 != (strlen(opts.key) * 8) )
202 | throw error(string("Invalid key '") + opts.key + "', expected 16 characters");
203 | for(int i = 0; i < 16; ++i) {
204 | key[i/4] |= static_cast(opts.key[i]) << ((i%4)*8);
205 | }
206 | }
207 | return true;
208 | }
209 | if( opts.iv ) {
210 | hex2block(opts.iv, iv);
211 | }
212 |
213 | for(int i=0; i<4; ++i) key[i] = default_key[i];
214 | return false;
215 | }
216 |
217 | static istream& input(const options& opts) {
218 | static istringstream str;
219 | static fstream file;
220 | if(opts.plaintext) {
221 | str.str(opts.plaintext);
222 | return str;
223 | }
224 | if( opts.textfile ) {
225 | file.open(opts.textfile, fstream::in | fstream::binary );
226 | if( ! file.good() )
227 | cerr << "Error opening file '" << opts.textfile << "'" << endl;
228 | return file;
229 | }
230 | return cin;
231 | }
232 |
233 | static ostream& output(const options& opts) {
234 | static fstream file;
235 | if( opts.outfile ) {
236 | file.open(opts.outfile, fstream::out | fstream::binary );
237 | if( ! file.good() )
238 | cerr << "Error opening file '" << opts.outfile << "'" << endl;
239 | return file;
240 | }
241 | return cout;
242 | }
243 |
244 |
245 | static istream& adata(const options& opts) {
246 | static istringstream str;
247 | static fstream file;
248 | if(opts.ad) {
249 | str.str(opts.ad);
250 | return str;
251 | }
252 | if( opts.adfile) {
253 | file.open(opts.textfile, fstream::in | fstream::binary );
254 | if( ! file.good() )
255 | cerr << "Error opening file '" << opts.adfile << "'" << endl;
256 | return file;
257 | }
258 | str.str("");
259 | return str;
260 | }
261 |
262 |
263 | struct hexwrapper {
264 | ostream& out;
265 | void write(const char* data, size_t len) {
266 | while(len--) {
267 | out << hex << setw(2) << setfill('0') <<
268 | (static_cast(*data++) & 0xFF);
269 | }
270 | }
271 | };
272 |
273 | static int sign(istream& in, const block_t& key, bool hexout, bool tocerr) {
274 | crypto::chaskey::Cipher8::Mac mac(key);
275 | while(in) {
276 | char plaintext[sizeof(block_t)];
277 | size_t len = in.read(plaintext,sizeof(plaintext)).gcount();
278 | mac.update((const uint8_t*)plaintext, len, in.eof());
279 | }
280 | if( tocerr ) {
281 | mac.write(hexwrapper{cerr});
282 | cerr << endl;
283 | } else if( hexout ) {
284 | mac.write(hexwrapper{cout});
285 | cout << endl;
286 | } else
287 | mac.write(cout);
288 | return success;
289 | }
290 |
291 | static int verify(istream& in, const block_t& key, const uint8_t* signature, uint_fast8_t len) {
292 | crypto::chaskey::Cipher8::Mac mac(key);
293 | while(in) {
294 | char plaintext[sizeof(block_t)];
295 | size_t len = in.read(plaintext,sizeof(plaintext)).gcount();
296 | mac.update((const uint8_t*)plaintext, len, in.eof());
297 | }
298 | return mac.verify(signature, len) ? success : err_verify;
299 | }
300 |
301 | static int encrypt(istream& in, ostream& out,
302 | const block_t& key, const char* nonce, const block_t& iv) {
303 | crypto::chaskey::Cipher8::Cbc cbc(key);
304 | if( nonce )
305 | cbc.init(nonce, strlen(nonce));
306 | else
307 | cbc.init(iv);
308 | while(in) {
309 | char plaintext[sizeof(block_t)];
310 | size_t len = in.read(plaintext,sizeof(plaintext)).gcount();
311 | cbc.encrypt(out, (const uint8_t*)plaintext, len, in.peek() == EOF);
312 | }
313 | return success;
314 | }
315 |
316 | static int decrypt(istream& in, ostream& out,
317 | const block_t& key, const char* nonce, const block_t& iv) {
318 | crypto::chaskey::Cipher8::Cbc cbc(key);
319 | if( nonce )
320 | cbc.init(nonce, strlen(nonce));
321 | else
322 | cbc.init(iv);
323 | while(in) {
324 | char ciphertext[sizeof(block_t)];
325 | size_t len = in.read(ciphertext,sizeof(ciphertext)).gcount();
326 | cbc.decrypt(out, (const uint8_t*)ciphertext, len);
327 | }
328 | return success;
329 | }
330 |
331 | byte frominput[sizeof(block)] {};
332 |
333 | #ifdef WITH_AES128CLOC_TEST
334 |
335 | static int aes128cloc(istream& in, istream& ad, ostream& out,
336 | const block_t& key, const char* nonce, bool hexout, const byte* mac) {
337 | ae_cxt cxt;
338 | ae_init(&cxt, (const byte*) key, sizeof(key));
339 | if(ad) {
340 | stringstream sstr;
341 | sstr << ad.rdbuf();
342 | const string& str = sstr.str();
343 | process_ad(&cxt, reinterpret_cast(str.c_str()), str.length(),
344 | reinterpret_cast(nonce), strlen(nonce));
345 | } else {
346 | process_ad(&cxt, reinterpret_cast(""), 0,
347 | reinterpret_cast(nonce), strlen(nonce));
348 | }
349 | stringstream sstr;
350 | sstr << in.rdbuf();
351 | const string& str = sstr.str();
352 | std::vector cif(16 * ((str.length() + 15)/16));
353 | std::vector tag(16);
354 | if( ! mac ) {
355 | ae_encrypt(&cxt, (byte*) str.c_str(), str.length(), cif.data(), tag.data(), tag.size(), ENC);
356 | out.write(reinterpret_cast(cif.data()), str.length());
357 | if( hexout ) {
358 | hexwrapper{cout}.write(reinterpret_cast(tag.data()),tag.size());
359 | cout << endl;
360 | } else {
361 | cout.write(reinterpret_cast(tag.data()),tag.size());
362 | }
363 | return success;
364 | } else {
365 | auto len = str.length();
366 | if( mac == frominput ) {
367 | len -= 16;
368 | mac = reinterpret_cast(str.c_str() + len);
369 | }
370 | ae_encrypt(&cxt, cif.data(), len, (byte*) str.c_str(), tag.data(), tag.size(), DEC);
371 | out.write(reinterpret_cast(cif.data()), cif.size());
372 | return (memcmp(tag.data(), mac, 16) == 0) ? success : err_verify;
373 | }
374 | }
375 |
376 | #else
377 | static int aes128cloc(istream&, istream&, ostream&,
378 | const block_t&, const char*, bool, const byte* mac) throw(error) {
379 | throw error(string("aes128 is not available");
380 | }
381 | #endif
382 |
383 | static int cloc(istream& in, istream& ad, ostream& out,
384 | const block_t& key, const char* nonce, bool hexout, bool tocerr) {
385 | crypto::chaskey::Cipher8::Cloc cloc(key);
386 | while(ad) {
387 | char plaintext[sizeof(block_t)];
388 | size_t len = ad.read(plaintext,sizeof(plaintext)).gcount();
389 | cloc.update((const uint8_t*)plaintext, len, ad.peek() == EOF);
390 | }
391 | if( nonce )
392 | cloc.nonce((const uint8_t*)nonce, strlen(nonce));
393 | while(in) {
394 | char plaintext[sizeof(block_t)];
395 | size_t len = in.read(plaintext,sizeof(plaintext)).gcount();
396 | cloc.encrypt(out, (const uint8_t*)plaintext, len, in.peek() == EOF);
397 | }
398 | if( tocerr ) {
399 | cloc.write(hexwrapper{cerr});
400 | cerr << endl;
401 | } else if( hexout ) {
402 | cloc.write(hexwrapper{cout});
403 | cout << endl;
404 | } else
405 | cloc.write(cout);
406 | return success;
407 | }
408 |
409 | static int uncloc(istream& in, istream& ad, ostream& out, const block_t& key,
410 | const char* nonce, const uint8_t* signature, uint_fast8_t len) {
411 | crypto::chaskey::Cipher8::Cloc cloc(key);
412 | while(ad) {
413 | char plaintext[sizeof(block_t)];
414 | size_t len = ad.read(plaintext,sizeof(plaintext)).gcount();
415 | cloc.update((const uint8_t*)plaintext, len, ad.peek() == EOF);
416 | }
417 | if( nonce )
418 | cloc.nonce((const uint8_t*)nonce, strlen(nonce));
419 | istream::pos_type end = (1ULL << 63) -1;
420 | if( signature == frominput ) {
421 | in.seekg(0, in.end);
422 | end = in.tellg();
423 | end -= sizeof(frominput);
424 | in.seekg(end, in.beg);
425 | in.read((char*)frominput,sizeof(frominput));
426 | in.seekg(0, in.beg);
427 | len = sizeof(frominput);
428 | }
429 | while(in && in.tellg() < end ) {
430 | char ciphertext[sizeof(block_t)];
431 | size_t pos = in.tellg();
432 | size_t size = ((pos + sizeof(block_t)) > end)
433 | ? end - in.tellg()
434 | : sizeof(block_t);
435 | size_t len = in.read(ciphertext,size).gcount();
436 | cloc.decrypt(out, (const uint8_t*)ciphertext, len, in.peek() == EOF || size < sizeof(block_t));
437 | }
438 | if( signature && len ) return cloc.verify(signature, len) ? success : err_verify;
439 | cloc.write(hexwrapper{cerr});
440 | cerr << endl;
441 | return err_verify;
442 | }
443 |
444 |
445 | static int help() {
446 | cerr << "Usage: chaskey [options]" << endl
447 | << " is one of the following:" << endl
448 | << " -s : sign message" << endl
449 | << " -m : verify message signature " << endl
450 | << " -e : encrypt message" << endl
451 | << " -d : decrypt message" << endl
452 | << " -c : encrypt and sign message with CLOC" << endl
453 | << " -u : decrypt with CLOC and verify message signature " << endl
454 | << " -u . : decrypt with CLOC and verify message signature against last block in input" << endl
455 | << " -u - : decrypt with CLOC" << endl
456 | << " -t : self-test" << endl
457 | << " [options] are :" << endl
458 | << " -I : use message " << endl
459 | << " -i : read message from file " << endl
460 | << " -o : write output to file " << endl
461 | << " -K : set the key as byte string " << endl
462 | << " -X : set the key given as hexadecimal string " << endl
463 | << " -N : set the nonce as byte string " << endl
464 | << " -V : set the initialization vector as hexadecimal string " << endl
465 | << " -A : set the associated data as byte string " << endl
466 | << " -a : read associated data from file " << endl
467 | << " -k : read key from file " << endl
468 | << " -h : write signature in hexadecimal" << endl
469 | << " -2 : write hexadecimal signature to stderr" << endl
470 | << " -v : set verbose mode" << endl
471 | << " -q : set quite mode" << endl << endl
472 | << "For example: " << endl
473 | << "# chaskey -s -h -K secretkey16bytes -I Hello " << endl
474 | << "# chaskey -e -N nonce12bytes -K secretkey16bytes -i Hello.txt " << endl;
475 | return exit_help;
476 | }
477 |
478 | extern bool test();
479 | extern const block_t& get_test_vector(unsigned);
480 | extern const uint8_t* get_test_message();
481 | extern bool bench(unsigned long);
482 |
483 | __attribute__((weak))
484 | bool test() { cerr << "Tests are not available" << endl; return false; }
485 | __attribute__((weak))
486 | bool bench(unsigned) { cerr << "Benchmarking is not available" << endl; return false; }
487 | __attribute__((weak))
488 | const block_t& get_test_vector(unsigned) { return default_key; }
489 | __attribute__((weak))
490 | const uint8_t* get_test_message() { return (const uint8_t*)("Plain text message"); }
491 |
492 | unsigned long milliseconds() {
493 | return std::clock() / (CLOCKS_PER_SEC/1000);
494 | }
495 |
496 | const block_t iv { };
497 |
498 |
499 | static void make_cbcmaster(int param) {
500 | crypto::chaskey::Chaskey8::Cbc cbc(get_test_vector(param));
501 | cbc.init(iv);
502 | cbc.encrypt(cout, get_test_message(), param, true);
503 | }
504 |
505 |
506 | static void make_clocmaster(int i) {
507 | const uint8_t* msg = get_test_message();
508 | crypto::chaskey::Chaskey8::Cloc cloc(get_test_vector(i));
509 | cloc.update(msg + i%5, i, i >= 8);
510 | if( i < 8 )
511 | cloc.update(msg + i%5, 16 - i, true);
512 | cloc.nonce(msg+i, i+3);
513 | cloc.encrypt(cout, msg, i+8, i >= 8);
514 | if( i < 8 )
515 | cloc.encrypt(cout, msg+(i+8), i, true);
516 | cloc.write(cout);
517 | }
518 |
519 | static bool make_masters(int param) {
520 | if( param >= 80 ) return false;
521 | if( param >= 64 ) make_clocmaster(param-64);
522 | else make_cbcmaster(param);
523 | return true;
524 | }
525 |
526 | int main(int argc, char * const argv[]) {
527 | options opts = {};
528 | block_t key, iv {};
529 | opts.hexout = isatty(fileno(stdout));
530 | try {
531 | if(argc < 1 && isatty(fileno(stdin)) )
532 | cerr << "Processing stdin to stdout with a default key" << endl;
533 | else
534 | fillopts(argc, argv, opts);
535 |
536 | /* operations that require no key */
537 | switch(opts.oper) {
538 | case operation::help: return ! help();
539 | case operation::test: return ! test();
540 | case operation::bench: return ! bench(opts.param);
541 | case operation::masters:return ! make_masters(opts.param);
542 | default:;
543 | }
544 | if( ! getkeys(opts, key, iv) ) {
545 | if( verbosity > 1 || (verbosity == 1 && isatty(fileno(stdin))) )
546 | cerr << "Using default key " << key << endl;
547 | };
548 |
549 | if( (opts.oper == operation::encrypt || opts.oper == operation::decrypt) &&
550 | ! opts.nonce && ! opts.iv ) {
551 | if( verbosity > 1 || (verbosity == 1 && isatty(fileno(stdin))) )
552 | cerr << "Using default iv " << iv << endl;
553 | }
554 | istream& in = input(opts);
555 | ostream& out = output(opts);
556 | if( ! in || ! out ) return ioerror;
557 | switch(opts.oper) {
558 | case operation::sign:
559 | return sign(in, key, opts.hexout, opts.tocerr);
560 | case operation::verify: {
561 | uint8_t digest[16] {};
562 | auto len = hex2bytes(opts.digest, digest, sizeof(digest));
563 | int res = verify(in, key, digest, len);
564 | if( verbosity > 1 && res == success )
565 | cerr << "Verified" << endl;
566 | if( verbosity >= 1 && res != success )
567 | cerr << "Not verified" << endl;
568 | return res;
569 | }
570 | case operation::encrypt:
571 | return encrypt(in, out, key, opts.nonce, iv);
572 | case operation::decrypt:
573 | return decrypt(in, out, key, opts.nonce, iv);
574 | case operation::cloc: {
575 | istream& ad ( adata(opts) );
576 | return opts.aes128cloc
577 | ? aes128cloc(in, ad, out, key, opts.nonce, opts.hexout, nullptr)
578 | : cloc(in, ad, out, key, opts.nonce, opts.hexout, opts.tocerr);
579 | }
580 | case operation::uncloc: {
581 | istream& ad ( adata(opts) );
582 | uint8_t digest[16] {};
583 | uint8_t * mac = digest;
584 | uint_fast8_t len = 0;
585 | if( opts.digest ) {
586 | if( strcmp(opts.digest, ".") == 0 ) {
587 | mac = frominput;
588 | } else
589 | if( strcmp(opts.digest, "-") == 0 ) {
590 | mac = nullptr;
591 | } else
592 | len = hex2bytes(opts.digest, digest, sizeof(digest));
593 |
594 | }
595 | if( ! ad ) return ioerror;
596 | int res = opts.aes128cloc
597 | ? aes128cloc(in, ad, out, key, opts.nonce, len, digest)
598 | : uncloc(in, ad, out, key, opts.nonce, mac, len);
599 | if( verbosity > 1 && res == success )
600 | cerr << "Verified" << endl;
601 | if( verbosity >= 1 && res != success )
602 | cerr << "Not verified" << endl;
603 | return res;
604 | }
605 | default:;
606 | return bad_args;
607 | };
608 | if( isatty(fileno(stderr)))
609 | cerr << endl;
610 | } catch(const error& e) {
611 | if( verbosity >= 1 )
612 | cerr << e.what() << endl;
613 | return bad_args;
614 | } catch(const exception& e) {
615 | if( verbosity >= 1 )
616 | cerr << e.what() << endl;
617 | return ioerror;
618 | } catch(...) {
619 | if( verbosity >= 1 )
620 | cerr << "Aborted" << endl;
621 | return aborted;
622 | }
623 | }
624 |
625 | void LogAppender::log(miculog::level lvl, const char* fmt, ...) noexcept {
626 | using typename miculog::level;
627 | FILE* file = stderr;
628 | switch( lvl ) {
629 | case level::fail:
630 | if( verbosity < 1 ) return;
631 | fprintf(file, "FAILED\t:");
632 | break;
633 | case level::error:
634 | if( verbosity < 2 ) return;
635 | fprintf(file, "error\t:");
636 | break;
637 | case level::warn:
638 | file = stdout;
639 | break;
640 | case level::info:
641 | file = stdout;
642 | if( verbosity < 1 ) return;
643 | case level::debug:
644 | break;
645 | default:
646 | return;
647 | }
648 | va_list args;
649 | va_start(args, fmt);
650 | vfprintf(file, fmt, args);
651 | va_end(args);
652 | }
653 | /* this substitues AES_encrypt to experiment with a reference
654 | * aes128cloc implementation
655 | * /
656 | extern "C" void AES_encrypt(const unsigned char *in, unsigned char *out,
657 | const AES_KEY *key) {
658 | using block_t = crypto::chaskey::Cipher<8>::block_t;
659 | crypto::chaskey::Cipher<8> & cipher = crypto::chaskey::Cipher8::cast(out);
660 | if( in != out )
661 | cipher ^= *(const block_t*) in;
662 | cipher.permute();
663 | cipher ^= *(const block_t*) key->rd_key;
664 |
665 | }
666 | //*/
667 |
668 |
--------------------------------------------------------------------------------
/tests/test.cpp:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2017 Eugene Hutorny
2 | *
3 | * test.cpp - self-testing facilities for a Chaskey Block Cipher algorithm
4 | *
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"),
8 | * to deal in the Software without restriction, including without limitation
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | * and/or sell copies of the Software, and to permit persons to whom the
11 | * Software is furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 | * IN THE SOFTWARE.
23 | *
24 | * https://opensource.org/licenses/MIT
25 | */
26 |
27 | #include "configuration.h"
28 | #include
29 | #include
30 | #include "chaskey.h"
31 | #include "chaskey.hpp"
32 | #include "miculog.hpp"
33 | #ifdef WITH_AES128CLOC_TEST
34 | extern "C" {
35 | # include "cloc.h"
36 | }
37 | #endif
38 | #ifdef WITH_CHACHA_TEST
39 | /* https://rweather.github.io/arduinolibs/classChaCha.html */
40 | # include
41 | // chacha takes ~6200 bytes of ROM on AVR
42 | #endif
43 | namespace impl {
44 | #if defined(__AVR__) || defined(__MSP430__)
45 | typedef crypto::chaskey::Cipher8s Cipher8;
46 | #else
47 | typedef crypto::chaskey::Cipher8 Cipher8;
48 | #endif
49 | }
50 | struct memcpywrapper {
51 | uint8_t * data;
52 | size_t size;
53 | inline void write(const void* src, unsigned len) noexcept {
54 | memcpy(data, src, len);
55 | size += len;
56 | data += len;
57 | }
58 | };
59 |
60 | namespace crypto {
61 | namespace test_compile {
62 | typedef uint32_t block_t[8];
63 | struct Algorithm {
64 | static void permute(block_t&) {}
65 | static void etumrep(block_t&) {}
66 | };
67 | Cbc,details::simple_formatter> TestCbc;
68 | Mac,details::simple_formatter> TestMac;
69 |
70 | void test() {
71 | uint8_t data[32];
72 | TestCbc.init(data, sizeof(data));
73 | TestCbc.encrypt(memcpywrapper{data}, data, sizeof(data), true);
74 | TestCbc.decrypt(memcpywrapper{data}, data, sizeof(data));
75 | TestMac.update(data, sizeof(data), true);
76 | TestMac.write(memcpywrapper{data});
77 | TestMac.verify((const block_t*)data);
78 | }
79 | }
80 | }
81 |
82 | extern void (*chaskey_cpp)(uint8_t *, uint32_t, const uint8_t *, const uint32_t,
83 | const uint32_t [4], const uint32_t [4], const uint32_t [4]);
84 | extern void (*subkeys_cpp)(uint32_t [4], uint32_t [4], const uint32_t [4]);
85 |
86 | using namespace crypto;
87 | using namespace chaskey;
88 |
89 | struct Test {
90 | static const uint8_t * const masters[79];
91 | static const block_t vectors[64];
92 | static const char plaintext[];
93 | };
94 |
95 |
96 | struct vector : chaskey::Cipher<8> {
97 | inline vector(const item_t* val) noexcept {
98 | memcpy(v,val,sizeof(v));
99 | }
100 | using chaskey::Cipher<8>::dnour;
101 | using chaskey::Cipher<8>::round;
102 | inline void oround() noexcept {
103 | #define ROTL(x,b) (uint32_t)( ((x) >> (32 - (b))) | ( (x) << (b)) )
104 | v[0] += v[1]; v[1]=ROTL(v[1], 5); v[1] ^= v[0]; v[0]=ROTL(v[0],16);
105 | v[2] += v[3]; v[3]=ROTL(v[3], 8); v[3] ^= v[2];
106 | v[0] += v[3]; v[3]=ROTL(v[3],13); v[3] ^= v[0];
107 | v[2] += v[1]; v[1]=ROTL(v[1], 7); v[1] ^= v[2]; v[2]=ROTL(v[2],16);
108 | }
109 | };
110 |
111 | using miculog::level;
112 |
113 |
114 | struct Log : miculog::Log {
115 | static inline constexpr const char* fmt() noexcept {
116 | return sizeof(int) == sizeof(short) ?
117 | "%s{%08lX,%08lX,%08lX,%08lX}\n":"%s{%08X,%08X,%08X,%08X}\n";
118 | }
119 | static const void block(level lvl, const char* msg, const block_t& b) noexcept {
120 | if( enabled(lvl) )
121 | appender::log(lvl, fmt(), msg, b[0],b[1],b[2],b[3]);
122 | }
123 | static const void block(level lvl, const char* msg, const void* p) noexcept {
124 | const block_t& b = *static_cast(p);
125 | if( enabled(lvl) )
126 | appender::log(lvl, fmt(), msg, b[0],b[1],b[2],b[3]);
127 | }
128 | } log;
129 |
130 | using details::rol;
131 | using details::ror;
132 |
133 | bool test_vectors() {
134 | uint8_t m[64];
135 | uint8_t tag[16];
136 | uint32_t k[4] = { 0x833D3433, 0x009F389F, 0x2398E64F, 0x417ACF39 };
137 | uint32_t k1[4], k2[4];
138 | int i;
139 | int ok = 1;
140 | uint32_t taglen = 16;
141 |
142 | /* key schedule */
143 | subkeys(k1,k2,k);
144 | /* mac */
145 | for (i = 0; i < 64; i++) {
146 | m[i] = i;
147 |
148 | chaskey_cpp(tag, taglen, m, i, k, k1, k2);
149 | details::simple_formatter buff;
150 | const block_t& result = buff.result(Test::vectors[i]);
151 |
152 | if (memcmp( tag, result, taglen )) {
153 | log.fail("test_vectors : length %d\n",i);
154 | log.block(level::error, "got : ", tag);
155 | log.block(level::error, "expected : ", result);
156 | ok = 0;
157 | }
158 | }
159 |
160 | return ok;
161 | }
162 |
163 | extern unsigned long milliseconds();
164 |
165 | alignas(4)
166 | static uint8_t blank[32];
167 |
168 | unsigned long bench_refmac(unsigned long count) {
169 | block_t subkey1{}, subkey2{}, k1{};
170 | auto start = milliseconds();
171 | while(count--)
172 | ::chaskey(blank, 16, blank, sizeof(blank), k1, subkey1, subkey2);
173 | return milliseconds() - start;
174 | }
175 |
176 | unsigned long bench_cppmac(unsigned long count) {
177 | block_t subkey1{}, subkey2{}, k1{};
178 | auto start = milliseconds();
179 | while(count--)
180 | chaskey_cpp(blank, 16, blank, sizeof(blank), k1, subkey1, subkey2);
181 | return milliseconds() - start;
182 | }
183 |
184 |
185 | struct blockassignwrapper {
186 | impl::Cipher8::Block& data;
187 | inline void write(const void* src, unsigned) noexcept {
188 | data = *reinterpret_cast(src);
189 | }
190 | };
191 | unsigned long bench_mac(unsigned long count) {
192 | impl::Cipher8::Mac mac;
193 | const block_t& key{Test::vectors[0]};
194 | impl::Cipher8::Block result;
195 | mac.set(key);
196 | auto start = milliseconds();
197 | while(count--) {
198 | mac.init();
199 | mac.update(blank,sizeof(blank),true);
200 | mac.write(blockassignwrapper{result});
201 | }
202 | return milliseconds() - start;
203 | }
204 |
205 | #ifdef WITH_AES128CLOC_TEST
206 | unsigned long bench_aes128cloc(unsigned long count) {
207 | const block_t& key{Test::vectors[0]};
208 | byte ad[32] {}, nonce[16] {}, pt[32];
209 |
210 | ae_cxt ctx {};
211 | ae_init(&ctx, reinterpret_cast(&key), sizeof(key));
212 | auto start = milliseconds();
213 | while(count--) {
214 | process_ad(&ctx, ad, sizeof(ad), nonce, sizeof(nonce));
215 | ae_encrypt(&ctx, pt, sizeof(pt), ad, nonce, sizeof(nonce), ENC);
216 | }
217 | return milliseconds() - start;
218 | }
219 | #endif
220 |
221 | #ifdef WITH_CHACHA_TEST
222 | unsigned long bench_chacha(unsigned long count) {
223 | const block_t& key{Test::vectors[0]};
224 | const block_t& iv{Test::vectors[1]};
225 |
226 | uint8_t result[32];
227 | ChaCha cbc(8);
228 | cbc.setKey((const uint8_t*)key, sizeof(key));
229 | auto start = milliseconds();
230 | while(count--) {
231 | cbc.setIV((const uint8_t*)iv, sizeof(iv));
232 | cbc.encrypt(result,result,sizeof(result));
233 | }
234 | return milliseconds() - start;
235 | }
236 | #endif
237 |
238 |
239 | static impl::Cipher8::Block result[2];
240 |
241 |
242 | unsigned long bench_cloc(unsigned long count) {
243 | const block_t& key{Test::vectors[0]};
244 | uint8_t ad[32] {}, nonce[16] {}, pt[32];
245 | impl::Cipher8::Cloc cloc;
246 | cloc.set(key);
247 | cloc.init();
248 | auto start = milliseconds();
249 | while(count--) {
250 | cloc.update(ad, sizeof(ad), true);
251 | cloc.nonce(nonce, sizeof(nonce));
252 | cloc.encrypt(blockassignwrapper{result[0]},pt,sizeof(pt),true);
253 | }
254 | return milliseconds() - start;
255 | }
256 |
257 | unsigned long bench_encrypt(unsigned long count) {
258 | const block_t& key{Test::vectors[0]};
259 | const block_t& iv{Test::vectors[1]};
260 | impl::Cipher8::Cbc cbc;
261 | cbc.set(key);
262 | auto start = milliseconds();
263 | while(count--) {
264 | cbc.init(iv);
265 | cbc.encrypt(blockassignwrapper{result[0]},blank,sizeof(blank),true);
266 | }
267 | return milliseconds() - start;
268 | }
269 |
270 | unsigned long bench_decrypt(unsigned long count) {
271 | const block_t& key{Test::vectors[0]};
272 | const block_t& iv{Test::vectors[1]};
273 | impl::Cipher8::Cbc cbc;
274 | cbc.set(key);
275 | auto start = milliseconds();
276 | while(count--) {
277 | cbc.init(iv);
278 | cbc.decrypt(blockassignwrapper{result[0]},blank,sizeof(blank));
279 | }
280 | return milliseconds() - start;
281 | }
282 |
283 |
284 | bool bench(unsigned long count) {
285 | log.info("|%-12s|%-12s|%-12s|%-12s|%-12s|",
286 | " Ref MAC", " Cpp MAC", " MAC"," Encrypt", " Decrypt");
287 | # ifdef WITH_AES128CLOC_TEST
288 | log.info("%-12s|"," aes128cloc");
289 | # endif
290 | log.info("%-12s|"," CLOC");
291 | # ifdef WITH_CHACHA_TEST
292 | log.info("%-12s|"," ChaCha");
293 | # endif
294 | log.info("\n");
295 | if( chaskey_cpp == &::chaskey )
296 | log.warn("|%-12s", " -- N/A --");
297 | else
298 | log.warn("|%8lu%4s", bench_refmac(count),"");
299 | log.warn("|%8lu%4s", bench_cppmac(count),"");
300 | log.warn("|%8lu%4s", bench_mac(count),"");
301 | log.warn("|%8lu%4s", bench_encrypt(count),"");
302 | log.warn("|%8lu%4s", bench_decrypt(count),"");
303 | # ifdef WITH_AES128CLOC_TEST
304 | log.warn("|%8lu%4s", bench_aes128cloc(count),"");
305 | # endif
306 | log.warn("|%8lu%4s", bench_cloc(count),"");
307 | # ifdef WITH_CHACHA_TEST
308 | log.warn("|%8lu%4s", bench_chacha(count),"");
309 | # endif
310 |
311 | log.warn("|\n");
312 | return true;
313 | }
314 |
315 | /**
316 | * test rotation functions
317 | */
318 | unsigned test_rolror(const block_t& v) {
319 | unsigned res = 0;
320 | for(auto i : {16,17,13,8,5} ) {
321 | if( (ror(v[0],i) == rol(v[0],i)) != (i==16) ) {
322 | log.fail( "test_rolror/ror!=rol : %d\n",i);
323 | log.error("ror(%08X,%d) :", ror(v[0],i));
324 | log.error("rol(%08X,%d) :", rol(v[0],i));
325 | ++res;
326 | }
327 | if( rol(ror(v[0],i),i) != v[0] ) {
328 | log.fail( "test_rolror/rol(ror) : %d\n",i);
329 | log.error("rol(ror(%08X,%d),%d) : %08X\n",v[0],i,i,rol(ror(v[0],i),i));
330 | ++res;
331 | }
332 | }
333 | return res;
334 | }
335 |
336 | /**
337 | * test transformation
338 | */
339 | unsigned test_transform(const block_t& v) {
340 | unsigned res = 0;
341 | vector o(v), r(v), m(v);
342 | o.oround();
343 | r.round();
344 | if( r != o ) {
345 | log.block(level::fail, "test_transform/round :", v);
346 | log.block(level::error,"expected :", o);
347 | log.block(level::error,"got :", r);
348 | ++res;
349 | }
350 | r.dnour();
351 | if( r != m ) {
352 | log.block(level::fail, "test_transform/dnour :", v);
353 | log.block(level::error,"expected :", m);
354 | log.block(level::error,"got :", r);
355 | ++res;
356 | }
357 | r.permute();
358 | r.etumrep();
359 | if( r != m ) {
360 | log.block(level::fail, "test_transform/etumrep :", v);
361 | log.block(level::error,"expected :", m);
362 | log.block(level::error,"got :", r);
363 | ++res;
364 | }
365 | return res;
366 | }
367 |
368 | /**
369 | * test MAC reference chaskey head-to-head with crypto::chaskey implementations
370 | */
371 | unsigned test_head2head(const block_t& v) {
372 | unsigned res = 0;
373 | # ifdef CHASKEY_HEAD2HEAD_TEST
374 | block_t subkey1, subkey2, k1, k2;
375 | subkeys(subkey1, subkey2, v);
376 | subkeys_cpp(k1,k2, v);
377 | if( memcmp(k1, subkey1, sizeof(k1)) != 0 ) {
378 | log.block(level::fail, "test_head2head/subkey1 :", subkey1);
379 | ++res;
380 | }
381 | if( memcmp(k2, subkey2, sizeof(k2)) != 0 ) {
382 | log.block(level::fail, "test_head2head/subkey2 :", subkey2);
383 | ++res;
384 | }
385 | block_t tag = {};
386 | block_t mtag;
387 | for(auto i: {15, 16, 17, 31, 32, 33, 47, 48, 49, 50}) {
388 | ::chaskey((uint8_t*)tag, sizeof(tag), (uint8_t*)Test::plaintext+(i&3), i, v, subkey1, subkey2);
389 | chaskey_cpp((uint8_t*)mtag, sizeof(mtag), (uint8_t*)Test::plaintext+(i&3), i, v, subkey1, subkey2);
390 | if( memcmp(tag,mtag, sizeof(mtag)) != 0 ) {
391 | log.block(level::fail, "test_head2head/mismatch :", tag);
392 | log.block(level::error,"expected :", mtag);
393 | log.error("message :'%.*s'\n", i, Test::plaintext+(i&3));
394 | ++res;
395 | }
396 | }
397 | # endif
398 | return res;
399 | }
400 |
401 | /**
402 | * test MAC primitive with whole and partial messages
403 | */
404 | unsigned test_mac(const block_t& v) {
405 | unsigned res = 0;
406 | block_t tag = {};
407 | impl::Cipher8::Mac mac;
408 | block_t subkey1, subkey2;
409 | subkeys(subkey1, subkey2, v);
410 |
411 | mac.set(v);
412 | for(auto i: {15, 16, 17, 31, 32, 33, 47, 48, 49, 50}) {
413 | uint8_t* msg = (uint8_t*)(Test::plaintext+(i&3));
414 | chaskey_cpp((uint8_t*)&tag, sizeof(tag), msg, i, v, subkey1, subkey2);
415 | mac.init();
416 | mac.update(msg, i, true);
417 | if( ! mac.verify(tag) ) {
418 | block_t got = {};
419 | mac.write(memcpywrapper{(uint8_t*)&got, 0});
420 | log.block(level::fail, "test_mac/verify :", got);
421 | log.block(level::error,"expected :", tag);
422 | log.error("message :'%.*s' %d bytes\n", i, msg, i);
423 | ++res;
424 | }
425 | }
426 | unsigned len = 0;
427 | uint8_t* msg = (uint8_t*)(Test::plaintext);
428 | mac.init();
429 | for(auto i: {15, 17, 1, 14, 13}) {
430 | mac.update(msg, i, i == 13);
431 | msg += i;
432 | len += i;
433 | }
434 | chaskey_cpp((uint8_t*)&tag, sizeof(tag), (uint8_t*)(Test::plaintext), len, v, subkey1, subkey2);
435 | if( ! mac.verify(tag) ) {
436 | block_t got = {};
437 | mac.write(memcpywrapper{(uint8_t*)&got, 0});
438 | log.block(level::fail, "test_mac/update :", got);
439 | log.block(level::error,"expected :", tag);
440 | log.error("message :'%.*s'\n", len, Test::plaintext);
441 | ++res;
442 | }
443 | return res;
444 | }
445 |
446 | const block_t iv { };
447 | /**
448 | * test CBC primitive encrypt/decrypt
449 | */
450 | unsigned test_cbc(const block_t& v) {
451 | unsigned res = 0;
452 | impl::Cipher8::Cbc cbc;
453 | uint8_t tmp[64];
454 | uint8_t plain[64];
455 | cbc.set(v);
456 | for(auto i: {7, 8, 9, 15, 16, 17, 31, 32, 33, 47, 48, 49, 50}) {
457 | cbc.init(iv);
458 | memcpywrapper wrp{tmp, 0};
459 | cbc.encrypt(wrp, (const uint8_t*)Test::plaintext, i, true);
460 | cbc.init(iv);
461 | cbc.decrypt(memcpywrapper{plain,0}, tmp, wrp.size);
462 | if( strncmp(Test::plaintext,(const char*)plain, i) != 0) {
463 | log.fail( "test_cbc :\t'%.*s'\n", i, Test::plaintext);
464 | log.error("got :\t'%.*s'\n", i, plain);
465 | ++res;
466 | }
467 | }
468 | return res;
469 | }
470 |
471 | const block_t& get_test_vector(unsigned i) {
472 | if(i > 63) i = 0;
473 | return Test::vectors[i];
474 | }
475 | const uint8_t* get_test_message() {
476 | return (const uint8_t*) Test::plaintext;
477 | }
478 |
479 | static unsigned test_clocmaster(int i) {
480 | uint8_t tmp[64];
481 | unsigned res = 0;
482 | memcpywrapper cout{tmp,0};
483 | const uint8_t* msg = get_test_message();
484 | impl::Cipher8::Cloc cloc(get_test_vector(i));
485 | cloc.update(msg + i%5, i, i >= 8);
486 | if( i < 8 )
487 | cloc.update(msg + i%5, 16 - i, true);
488 | cloc.nonce(msg+i, i+3);
489 | cloc.encrypt(cout, msg, i+8, i >= 8);
490 | if( i < 8 )
491 | cloc.encrypt(cout, msg + (i+8), i, true);
492 | int size = cout.size;
493 | cloc.write(cout);
494 | int len = i+8+(i<8?i:0);
495 | if( memcmp(tmp,Test::masters[i+63],cout.size) != 0 ) {
496 | log.fail("test_master/cloc :'%.*s'\n", len, msg);
497 | log.block(level::error,"got :", tmp+(cout.size-16));
498 | log.block(level::error,"expected :", Test::masters[i+63]+(cout.size-16));
499 | ++res;
500 | }
501 | cloc.init();
502 | cloc.update(msg + i%5, i, i >= 8);
503 | if( i < 8 )
504 | cloc.update(msg + i%5, 16 - i, true);
505 | cloc.nonce(msg+i, i+3);
506 | cout = {tmp, 0};
507 | cloc.decrypt(cout, Test::masters[i+63], size, true);
508 | const block_t & tag{ *(const block_t*)(Test::masters[i+63]+size)};
509 | if( ! cloc.verify(tag) ) {
510 | log.fail("test_master/verify :'%.*s'\n", len, msg);
511 | impl::Cipher8::Block got;
512 | cloc.write(blockassignwrapper{got});
513 | log.block(level::error,"got :", got);
514 | log.block(level::error,"expected :", tag);
515 | ++res;
516 | }
517 | if( memcmp(tmp, msg, len) != 0 ) {
518 | log.fail("test_master/uncloc :'%.*s'\n", len, msg);
519 | log.error("got :\t'%.*s'\n", cout.size, tmp);
520 | ++res;
521 | }
522 |
523 | return res;
524 | }
525 |
526 |
527 | static unsigned test_cbcmaster(int i) {
528 | unsigned res = 0;
529 | uint8_t tmp[64];
530 | impl::Cipher8::Cbc cbc;
531 | cbc.set(Test::vectors[i]);
532 | cbc.init(iv);
533 | memcpywrapper out{tmp,0};
534 | cbc.encrypt(out, (const uint8_t*)Test::plaintext, i, true);
535 | if( memcmp(tmp,Test::masters[i-1],out.size) != 0 ) {
536 | log.fail("test_master/encrypt :'%.*s'\n", i, Test::plaintext);
537 | ++res;
538 | }
539 | cbc.init(iv);
540 | cbc.decrypt(memcpywrapper{tmp,0}, Test::masters[i-1], out.size);
541 | if( memcmp(tmp,Test::plaintext,i) != 0 ) {
542 | log.fail( "test_master/decrypt :'%.*s'\n", i, Test::plaintext);
543 | log.error("got :\t'%.*s'\n", i, tmp);
544 | ++res;
545 | }
546 |
547 | return res;
548 | }
549 |
550 | /**
551 | * test CBC adinst masters
552 | */
553 | unsigned test_master(int N = 64) { //N added to prevent loop unrolling
554 | unsigned res = 0;
555 | for(int i = 1; i < N; ++i)
556 | res += test_cbcmaster(i);
557 | for(int i = N; i < 80; ++i)
558 | res += test_clocmaster(i-64);
559 | return res;
560 | }
561 |
562 | static char nonce[] = "16 bytes nonce";
563 |
564 | /**
565 | * test CBC primitive encrypt/decrypt
566 | */
567 | unsigned test_cloc(const block_t& v) {
568 | unsigned res = 0;
569 | impl::Cipher8::Cloc cloc;
570 | uint8_t tmp[64];
571 | uint8_t plain[64];
572 | cloc.set(v);
573 | for(auto i: {7, 8, 9, 15, 16, 17, 31, 32, 33, 47, 48, 49, 50}) {
574 | cloc.init();
575 | cloc.update((const uint8_t*)(Test::plaintext + (i%4)), i, true);
576 | cloc.nonce((const uint8_t*)nonce,sizeof(nonce));
577 | memcpywrapper wrp{tmp,0};
578 | cloc.encrypt(wrp, (const uint8_t*)Test::plaintext + (i%6), i, true);
579 | cloc.init();
580 | cloc.update((const uint8_t*)(Test::plaintext + (i%4)), i, true);
581 | cloc.nonce((const uint8_t*)nonce,sizeof(nonce));
582 | cloc.decrypt(memcpywrapper{plain, 0}, tmp, i, true);
583 | if( strncmp(Test::plaintext + (i%6),(const char*)plain, i) != 0) {
584 | log.fail( "test_cloc :\t'%.*s'\n", i, Test::plaintext + (i%6));
585 | log.error("got :\t'%.*s'\n", i, plain);
586 | ++res;
587 | }
588 | }
589 | return res;
590 | }
591 |
592 | /**
593 | * test CBC primitive encrypt/decrypt
594 | */
595 | unsigned test_clocchunk() {
596 | unsigned adlen = 0, datalen = 0;
597 | impl::Cipher8::Cloc cloc;
598 | impl::Cipher8::Cloc verf;
599 | const block_t& v(Test::vectors[0]);
600 | uint8_t chunked[64];
601 | uint8_t solid[64];
602 | cloc.set(v);
603 | verf.set(v);
604 |
605 | uint8_t* ad = (uint8_t*)(Test::plaintext);
606 | for(auto i: {12, 5, 15, 1, 14, 13}) {
607 | cloc.update(ad, i, i == 13);
608 | ad += i;
609 | adlen += i;
610 | }
611 | cloc.nonce((uint8_t*)nonce, 7);
612 | uint8_t* msg = (uint8_t*)(Test::plaintext);
613 | memcpywrapper out{chunked,0};
614 | for(auto i: {15, 17, 1, 14, 13}) {
615 | cloc.encrypt(out, msg, i, i == 13);
616 | msg += i;
617 | datalen += i;
618 | }
619 | memcpywrapper vrf{solid,0};
620 | verf.update((uint8_t*)(Test::plaintext), adlen, true);
621 | verf.nonce((uint8_t*)nonce, 7);
622 | verf.encrypt(vrf, (uint8_t*)(Test::plaintext), datalen, true);
623 | if( memcmp(chunked, solid, vrf.size) ) {
624 | log.fail( "test_clocchunk\n");
625 | return 1;
626 | }
627 | return 0;
628 | }
629 |
630 | bool test_debug() {
631 | return true;
632 | }
633 |
634 |
635 | bool test() {
636 | if( ! test_debug() ) return false;
637 | log.info("Running self-test %s\n", (chaskey_cpp == &::chaskey ?
638 | "without head-2-head" : "with head-2-head"));
639 | unsigned res = ! test_vectors();
640 | for(const block_t& v : Test::vectors) {
641 | log.info(".");
642 | res += test_rolror(v);
643 | res += test_transform(v);
644 | res += test_cbc(v);
645 | res += test_cloc(v);
646 | }
647 | log.info(".");
648 | if( chaskey_cpp != &::chaskey )
649 | res += test_head2head(Test::vectors[0]);
650 | log.info(".");
651 | res += test_mac(Test::vectors[0]);
652 | log.info(".");
653 | res += test_clocchunk();
654 | log.info(".");
655 | res += test_master();
656 | if( res )
657 | log.warn("\n%d tests failed\n", res);
658 | else
659 | log.warn("\nAll tests pass\n");
660 | return ! res;
661 | }
662 |
663 | const char Test::plaintext[] = "Plain text message of sufficient length. "
664 | "Plain text message of sufficient length";
665 |
666 |
667 | const block_t Test::vectors[64] =
668 | {
669 | { 0x792E8FE5, 0x75CE87AA, 0x2D1450B5, 0x1191970B },
670 | { 0x13A9307B, 0x50E62C89, 0x4577BD88, 0xC0BBDC18 },
671 | { 0x55DF8922, 0x2C7FF577, 0x73809EF4, 0x4E5084C0 },
672 | { 0x1BDBB264, 0xA07680D8, 0x8E5B2AB8, 0x20660413 },
673 | { 0x30B2D171, 0xE38532FB, 0x16707C16, 0x73ED45F0 },
674 | { 0xBC983D0C, 0x31B14064, 0x234CD7A2, 0x0C92BBF9 },
675 | { 0x0DD0688A, 0xE131756C, 0x94C5E6DE, 0x84942131 },
676 | { 0x7F670454, 0xF25B03E0, 0x19D68362, 0x9F4D24D8 },
677 | { 0x09330F69, 0x62B5DCE0, 0xA4FBA462, 0xF20D3C12 },
678 | { 0x89B3B1BE, 0x95B97392, 0xF8444ABF, 0x755DADFE },
679 | { 0xAC5B9DAE, 0x6CF8C0AC, 0x56E7B945, 0xD7ECF8F0 },
680 | { 0xD5B0DBEC, 0xC1692530, 0xD13B368A, 0xC0AE6A59 },
681 | { 0xFC2C3391, 0x285C8CD5, 0x456508EE, 0xC789E206 },
682 | { 0x29496F33, 0xAC62D558, 0xE0BAD605, 0xC5A538C6 },
683 | { 0xBF668497, 0x275217A1, 0x40C17AD4, 0x2ED877C0 },
684 | { 0x51B94DA4, 0xEFCC4DE8, 0x192412EA, 0xBBC170DD },
685 | { 0x79271CA9, 0xD66A1C71, 0x81CA474E, 0x49831CAD },
686 | { 0x048DA968, 0x4E25D096, 0x2D6CF897, 0xBC3959CA },
687 | { 0x0C45D380, 0x2FD09996, 0x31F42F3B, 0x8F7FD0BF },
688 | { 0xD8153472, 0x10C37B1E, 0xEEBDD61D, 0x7E3DB1EE },
689 | { 0xFA4CA543, 0x0D75D71E, 0xAF61E0CC, 0x0D650C45 },
690 | { 0x808B1BCA, 0x7E034DE0, 0x6C8B597F, 0x3FACA725 },
691 | { 0xC7AFA441, 0x95A4EFED, 0xC9A9664E, 0xA2309431 },
692 | { 0x36200641, 0x2F8C1F4A, 0x27F6A5DE, 0x469D29F9 },
693 | { 0x37BA1E35, 0x43451A62, 0xE6865591, 0x19AF78EE },
694 | { 0x86B4F697, 0x93A4F64F, 0xCBCBD086, 0xB476BB28 },
695 | { 0xBE7D2AFA, 0xAC513DE7, 0xFC599337, 0x5EA03E3A },
696 | { 0xC56D7F54, 0x3E286A58, 0x79675A22, 0x099C7599 },
697 | { 0x3D0F08ED, 0xF32E3FDE, 0xBB8A1A8C, 0xC3A3FEC4 },
698 | { 0x2EC171F8, 0x33698309, 0x78EFD172, 0xD764B98C },
699 | { 0x5CECEEAC, 0xA174084C, 0x95C3A400, 0x98BEE220 },
700 | { 0xBBDD0C2D, 0xFAB6FCD9, 0xDCCC080E, 0x9F04B41F },
701 | { 0x60B3F7AF, 0x37EEE7C8, 0x836CFD98, 0x782CA060 },
702 | { 0xDF44EA33, 0xB0B2C398, 0x0583CE6F, 0x846D823E },
703 | { 0xC7E31175, 0x6DB4E34D, 0xDAD60CA1, 0xE95ABA60 },
704 | { 0xE0DC6938, 0x84A0A7E3, 0xB7F695B5, 0xB46A010B },
705 | { 0x1CEB6C66, 0x3535F274, 0x839DBC27, 0x80B4599C },
706 | { 0xBBA106F4, 0xD49B697C, 0xB454B5D9, 0x2B69E58B },
707 | { 0x5AD58A39, 0xDFD52844, 0x34973366, 0x8F467DDC },
708 | { 0x67A67B1F, 0x3575ECB3, 0x1C71B19D, 0xA885C92B },
709 | { 0xD5ABCC27, 0x9114EFF5, 0xA094340E, 0xA457374B },
710 | { 0xB559DF49, 0xDEC9B2CF, 0x0F97FE2B, 0x5FA054D7 },
711 | { 0x2ACA7229, 0x99FF1B77, 0x156D66E0, 0xF7A55486 },
712 | { 0x565996FD, 0x8F988CEF, 0x27DC2CE2, 0x2F8AE186 },
713 | { 0xBE473747, 0x2590827B, 0xDC852399, 0x2DE46519 },
714 | { 0xF860AB7D, 0x00F48C88, 0x0ABFBB33, 0x91EA1838 },
715 | { 0xDE15C7E1, 0x1D90EFF8, 0xABC70129, 0xD9B2F0B4 },
716 | { 0xB3F0A2C3, 0x775539A7, 0x6CAA3BC1, 0xD5A6FC7E },
717 | { 0x127C6E21, 0x6C07A459, 0xAD851388, 0x22E8BF5B },
718 | { 0x08F3F132, 0x57B587E3, 0x087AD505, 0xFA070C27 },
719 | { 0xA826E824, 0x3F851E6A, 0x9D1F2276, 0x7962AD37 },
720 | { 0x14A6A13A, 0x469962FD, 0x914DB278, 0x3A9E8EC2 },
721 | { 0xFE20DDF7, 0x06505229, 0xF9C9F394, 0x4361A98D },
722 | { 0x1DE7A33C, 0x37F81C96, 0xD9B967BE, 0xC00FA4FA },
723 | { 0x5FD01E9A, 0x9F2E486D, 0x93205409, 0x814D7CC2 },
724 | { 0xE17F5CA5, 0x37D4BDD0, 0x1F408335, 0x43B6B603 },
725 | { 0x817CEEAE, 0x796C9EC0, 0x1BB3DED7, 0xBAC7263B },
726 | { 0xB7827E63, 0x0988FEA0, 0x3800BD91, 0xCF876B00 },
727 | { 0xF0248D4B, 0xACA7BDC8, 0x739E30F3, 0xE0C469C2 },
728 | { 0x67363EB6, 0xFAE8E047, 0xF0C1C8E5, 0x828CCD47 },
729 | { 0x3DBD1D15, 0x05092D7B, 0x216FC6E3, 0x446860FB },
730 | { 0xEBF39102, 0x8F4C1708, 0x519D2F36, 0xC67C5437 },
731 | { 0x89A0D454, 0x9201A282, 0xEA1B1E50, 0x1771BEDC },
732 | { 0x9047FAD7, 0x88136D8C, 0xA488286B, 0x7FE9352C }
733 | };
734 |
735 | /* echo '' > tests/master.inc; for i in `seq 1 79`; do
736 | echo const uint8_t master$i[] = { `Debug/chaskey -T $i | file2c` }\; >> tests/master.inc; done;
737 | */
738 | #include "master.inc"
739 |
740 | const uint8_t * const Test::masters[] = {
741 | master1, master2, master3, master4, master5, master6, master7, master8,
742 | master9 ,master10,master11,master12,master13,master14,master15,master16,
743 | master17,master18,master19,master20,master21,master22,master23,master24,
744 | master25,master26,master27,master28,master29,master30,master31,master32,
745 | master33,master34,master35,master36,master37,master38,master39,master40,
746 | master41,master42,master43,master44,master45,master46,master47,master48,
747 | master49,master50,master51,master52,master53,master54,master55,master56,
748 | master57,master58,master59,master60,master61,master62,master63,master64,
749 | master65,master66,master67,master68,master69,master70,master71,master72,
750 | master73,master74,master75,master76,master77,master78,master79
751 | };
752 |
--------------------------------------------------------------------------------
/tests/chaskey_test.js:
--------------------------------------------------------------------------------
1 | function ChaskeyTests() {
2 |
3 | function block2hex(blk) {
4 | if( ! (blk instanceof Uint32Array ) ) blk = new Uint32Array(blk.buffer||blk);
5 | return Array.prototype.map.call(blk, function(v) {
6 | return '0x'+('0000000' + v.toString(16)).slice(-8);
7 | }).join(',');
8 | }
9 |
10 | function bytes2hex(blk, dlm) {
11 | return Array.prototype.map.call(new Uint8Array(blk.buffer||blk),
12 | function(s){ return ('00' + s.toString(16)).slice(-2); }).join(dlm||'');
13 | }
14 |
15 | function logblock(msg, blk) {
16 | console.log(msg.toString() + block2hex(blk));
17 | }
18 |
19 |
20 | this.loglevels = "fail,error,info,debug";
21 |
22 |
23 | function compare(a,b,n) {
24 | return Array.prototype.every.call(a, function(v, i){ return v === b[i] || i >= n; });
25 | }
26 |
27 | function string2bytes(str) {
28 | return Array.prototype.map.call(new Uint8Array(str.length),function(v,i) { return str.charCodeAt(i); });
29 | }
30 |
31 | function bytes2string(str) {
32 | return Uint8Array.from(str.match(/.{1,2}/g).map(function(v) {return parseInt(v, 16); }));
33 | }
34 |
35 | /* https://github.com/feross/buffer/issues/60 */
36 | function utf8ToBinaryString(str) {
37 | var escstr = encodeURIComponent(str);
38 | // replaces any uri escape sequence, such as %0A, with binary escape, such as 0x0A
39 | var binstr = escstr.replace(/%([0-9A-F]{2})/g, function(match, p1) {
40 | return String.fromCharCode('0x' + p1);
41 | });
42 |
43 | return binstr;
44 | }
45 |
46 | function utf8ToBuffer(str) {
47 | var binstr = utf8ToBinaryString(str);
48 | var buf = new Uint8Array(binstr.length);
49 | Array.prototype.forEach.call(binstr, function (ch, i) {
50 | buf[i] = ch.charCodeAt(0);
51 | });
52 | return buf;
53 | }
54 |
55 | function bufferToUtf8(arr) {
56 | return decodeURIComponent(escape(Array.prototype.map.call(arr, function(c) { return String.fromCharCode(c); }).join('')));
57 | }
58 |
59 | function log(clas, msg) {
60 | var div = document.createElement('div');
61 | div.setAttribute('class',clas);
62 | div.innerHTML = Array.prototype.map.call(msg, function(i) {
63 | return "" + i + "";
64 | }).join('');
65 | document.body.appendChild(div)
66 | }
67 |
68 | function generatePseudoRandomKey(func) {
69 | var key = new Uint8Array(16);
70 | Array.prototype.every.call(key, function(v,i) {
71 | key[i] = Math.random() * 256;
72 | return true;
73 | });
74 | func(key);
75 | }
76 |
77 |
78 | function generateRandomCryptoKey(func) {
79 | window.crypto.subtle.generateKey({name:"AES-CBC",length:128},true, ["encrypt"])
80 | .then(function(v) {
81 | window.crypto.subtle.exportKey("raw",v)
82 | .then(func);}).catch(function(e) {
83 | console.log('Fallback to pseaudo-random because "' + e.message + '"');
84 | generatePseudoRandomKey(func);
85 | } );
86 | }
87 |
88 | function generateRandomKey(func) {
89 | if( window.crypto && window.crypto.subtle )
90 | try {
91 | return generateRandomCryptoKey(func);
92 | } catch(err) {
93 | console.log(err.message);
94 | }
95 | generatePseudoRandomKey(func);
96 | }
97 |
98 | this.demo = function() {
99 | this.ui = {
100 | mode : '#mode',
101 | key : '#key',
102 | data : '#data',
103 | nonce : '#nonce',
104 | message : '#message',
105 | ciphertext : '#ciphertext',
106 | encrypt : '#encrypt',
107 | decrypt : '#decrypt',
108 | sign : '#sign',
109 | format : '#format'
110 | };
111 | var validmodes = {
112 | nonce : ['CBC','CLOC'],
113 | data : ['CLOC'],
114 | encrypt : ['CBC','CLOC'],
115 | decrypt : ['CBC','CLOC'],
116 | sign : ['MAC','CLOC']
117 | }
118 | var ui = this.ui;
119 | Object.keys(ui).every(function(id) {
120 | ui[id] = document.querySelector(ui[id]);
121 | return true;
122 | });
123 | var backend = this;
124 | backend.ui = ui;
125 |
126 | this.ui.encrypt.onclick = function() {
127 | backend.encrypt(ui.mode.value);
128 | }
129 | this.ui.decrypt.onclick = function() {
130 | backend.decrypt(ui.mode.value);
131 | }
132 | this.ui.sign.onclick = function() {
133 | backend.sign(ui.mode.value);
134 | }
135 | this.ui.format.onchange = function() {
136 | backend.formatchange();
137 | }
138 | this.ui.ciphertext.onchange = function() {
139 | this.format = null;
140 | }
141 | this.ui.mode.onchange = function() {
142 | var value = this.value;
143 | Object.keys(validmodes).every(function(id){
144 | ui[id].disabled = validmodes[id].indexOf(value) < 0;
145 | return true;
146 | });
147 | }
148 | if( !this.ui.key.value ) {
149 | generateRandomKey(function(key) {
150 | backend.renderKey(key);
151 | });
152 | }
153 | try { this.encoder = new TextEncoder('utf-8'); }
154 | catch(e) {
155 | console.log(e);
156 | this.encoder = { encode : utf8ToBuffer };
157 | }
158 | try { this.decoder = new TextDecoder('utf-8'); }
159 | catch(e) {
160 | console.log(e);
161 | this.decoder = { decode : bufferToUtf8 };
162 | }
163 | this.zero = this.decoder.decode(Uint8Array.from([0]))
164 | }
165 |
166 | this.renderKey = function(key) {
167 | this.ui.key.value = bytes2hex(key,'').toUpperCase();
168 | }
169 |
170 | function validByte(v,s) {
171 | if (v>=0 && v<=255) return v;
172 | throw new Error('Invalid key digit:' + s);
173 | }
174 | function validInt(v,s) {
175 | if (v>=0 && v<=0xFFFFFFFF) return v;
176 | throw new Error('Invalid key digit:' + s);
177 | }
178 |
179 | this.readKey = function() {
180 | var key = this.ui.key.value === '' ? [] : this.ui.key.value.split(',');
181 | if( key.length == 1 ) key = key[0].match(/.{1,2}/g);
182 | if( [4,16].indexOf(key.length) == -1 ) {
183 | throw new Error('Invalid key length:' + key.length);
184 | }
185 | if( key.length == 16) {
186 | key = key.map(function(v) { return validByte(parseInt(v, 16), v); });
187 | return new Uint32Array(Uint8Array.from(key).buffer);
188 | }
189 | if( key.length == 4) {
190 | key = key.map(function(v) { return validInt(parseInt(v, 16), v); });
191 | return Uint32Array.from(key);
192 | }
193 |
194 | }
195 |
196 | this.encryptCBC = function(text) {
197 | var cbc = new ChaskeyCipher.Cbc();
198 | cbc.set(this.readKey());
199 | cbc.init(this.ui.nonce.value);
200 | return cbc.encrypt(this.encoder.encode(this.ui.message.value));
201 | }
202 |
203 | this.encryptCLOC = function(text) {
204 | var cloc = new ChaskeyCipher.Cloc();
205 | cloc.set(this.readKey());
206 | cloc.update(this.ui.data.value);
207 | cloc.nonce(this.ui.nonce.value);
208 | return cloc.encrypt(text);
209 | }
210 |
211 |
212 | this.encrypt = function(mode) {
213 | try{
214 | var text = this.encoder.encode(this.ui.message.value);
215 | var cif = mode === 'CBC' ? this.encryptCBC(text) : this.encryptCLOC(text);
216 |
217 | if( this.ui.format.value === 'base-64' )
218 | this.ui.ciphertext.value = btoa(String.fromCharCode.apply(null, cif));
219 | else
220 | this.ui.ciphertext.value = bytes2hex(cif);
221 |
222 | this.ui.ciphertext.format = this.ui.format.value;
223 |
224 | } catch(e) {
225 | this.error('ERROR:',e.message)
226 | }
227 | }
228 |
229 | this.decryptCBC = function(cif) {
230 | var cbc = new ChaskeyCipher.Cbc();
231 | cbc.set(this.readKey());
232 | cbc.init(this.ui.nonce.value);
233 | return cbc.decrypt(cif);
234 | }
235 | this.decryptCLOC = function(cif) {
236 | var cloc = new ChaskeyCipher.Cloc();
237 | cloc.set(this.readKey());
238 | cloc.update(this.ui.data.value);
239 | cloc.nonce(this.ui.nonce.value);
240 | return cloc.decrypt(cif);
241 | }
242 |
243 | this.decrypt = function(mode) {
244 | try{
245 |
246 | var format = this.ui.ciphertext.format || this.ui.format.value;
247 | var cif;
248 |
249 | if( format === 'base-64' )
250 | cif = Uint8Array.from(atob(this.ui.ciphertext.value).split('').map(function (c) { return c.charCodeAt(0); }));
251 | else
252 | cif = bytes2string(this.ui.ciphertext.value);
253 | var text = mode === 'CBC' ? this.decryptCBC(cif) : this.decryptCLOC(cif);
254 | this.ui.message.value = this.decoder.decode(text).split(this.zero)[0];
255 | } catch(e) {
256 | this.error('ERROR:',e.message)
257 | }
258 | }
259 |
260 | this.signCLOC = function(text) {
261 | var mac = new ChaskeyCipher.Mac();
262 | mac.set(this.readKey());
263 | return mac.sign(this.encoder.encode(text));
264 | }
265 |
266 | this.signMAC = function(text) {
267 | var mac = new ChaskeyCipher.Mac();
268 | mac.set(this.readKey());
269 | return mac.sign(this.encoder.encode(text));
270 | }
271 |
272 |
273 | this.sign = function(mode) {
274 | try {
275 | var cif = mode === 'MAC' ? this.signMAC(this.ui.message.value)
276 | : this.signCLOC(this.ui.message.value);
277 | if( this.ui.format.value === 'base-64' )
278 | this.ui.ciphertext.value = btoa(String.fromCharCode.apply(null, cif));
279 | else
280 | this.ui.ciphertext.value = bytes2hex(cif);
281 |
282 | this.ui.ciphertext.format = this.ui.format.value;
283 |
284 | } catch(e) {
285 | this.error('ERROR:',e.message)
286 | }
287 | }
288 |
289 |
290 | this.formatchange = function() {
291 |
292 | }
293 |
294 | this.run = function() {
295 | this.info('INFO :', 'Starting chaskey tests');
296 | if( this.test_MAC() )
297 | this.info('PASS :', 'test_MAC');
298 | else
299 | this.fail('FAIL :', 'test_MAC');
300 | if( this.test_CBC() )
301 | this.info('PASS :', 'test_CBC');
302 | else
303 | this.fail('FAIL :', 'test_CBC');
304 | if( this.test_CLOC() )
305 | this.info('PASS :', 'test_CLOC');
306 | else
307 | this.fail('FAIL :', 'test_CLOC');
308 | }
309 |
310 | this.test_MAC = function() {
311 | var k = [ 0x833D3433, 0x009F389F, 0x2398E64F, 0x417ACF39 ];
312 | var mac = new Mac(new ChaskeyCipher(block32x4, 8));
313 | var m = new Uint8Array(64);
314 | var res = true;
315 | patch4IE(m);
316 | mac.set(k);
317 |
318 | for(var i=0; i < m.length; ++i) {
319 | m[i] = i;
320 | var tag = mac.sign(m.subarray(0,i));
321 | if( ! compare(new Uint32Array(tag.buffer), this.vectors[i]) ) {
322 | this.error("error: test_MAC : length ",i);
323 | this.debug("got : ", block2hex(tag));
324 | this.debug("expected : ", block2hex(this.vectors[i]));
325 | res = false;
326 | }
327 | }
328 | return res;
329 | }
330 | this.test_CBC = function() {
331 | var res = true;
332 | var cbc = new Cbc(new ChaskeyCipher(block32x4, 8));
333 | var plaintext = string2bytes(this.plaintext);
334 | patch4IE(plaintext);
335 | for(var i = 1; i < 64; ++i) {
336 | cbc.set(this.vectors[i]);
337 | cbc.initIV([0,0,0,0]);
338 | var msg = plaintext.subarray(0,i);
339 | var cif = cbc.encrypt(msg);
340 | if( ! compare(cif, this.masters[i-1]) ) {
341 | this.error("error: test_CBC/encrypt: ",this.plaintext.substr(0,i));
342 | this.debug("got : ", bytes2hex(cif));
343 | this.debug("expected : ", bytes2hex(this.masters[i-1]));
344 | res = false;
345 | }
346 | cbc.initIV([0,0,0,0]);
347 | var txt = cbc.decrypt(cif);
348 | if( ! compare(txt, msg, i) ) {
349 | this.error("error: test_CBC/decrypt: ", this.plaintext.substr(0,i));
350 | this.debug("got : ", bytes2hex(txt));
351 | this.debug("expected : ", bytes2hex(msg));
352 | res = false;
353 | }
354 | }
355 | return res;
356 | }
357 | var nonce = "16 bytes nonce";
358 | thiz = this;
359 |
360 | function test_cloc() {
361 | var res = true;
362 | var cloc = new Cloc(new ChaskeyCipher(block32x4, 8));
363 | var plaintext = string2bytes(thiz.plaintext);
364 | patch4IE(plaintext);
365 | var list = [7, 8, 9, 15, 16, 17, 31, 32, 33, 47, 48, 49, 50];
366 | for(var j in list) {
367 | var i = list[j];
368 | cloc.set(thiz.vectors[0]);
369 | cloc.update(plaintext.subarray(i%4,i+i%4), true);
370 | cloc.nonce(nonce);
371 | var msg = plaintext.subarray(i%6,i+i%6);
372 | var cif = cloc.encrypt(msg, true);
373 | cloc.init();
374 | cloc.update(plaintext.subarray(i%4,i+i%4), true);
375 | cloc.nonce(nonce);
376 | var txt = cloc.decrypt(cif, true);
377 | if( ! compare(txt, msg, i) ) {
378 | thiz.error("error:test_CLOC/decrypt: ", thiz.plaintext.substr(0,i));
379 | thiz.debug("got : ", bytes2hex(txt));
380 | thiz.debug("expected : ", bytes2hex(msg));
381 | res = false;
382 | }
383 | }
384 | return res;
385 | }
386 |
387 | function test_clocchunk() {
388 | var res = true;
389 | var cloc = new Cloc(new ChaskeyCipher(block32x4, 8));
390 | var verf = new Cloc(new ChaskeyCipher(block32x4, 8));
391 | var plaintext = string2bytes(thiz.plaintext);
392 | patch4IE(plaintext);
393 | var msglist = [15, 17, 1, 14, 13];
394 | cloc.set(thiz.vectors[0]);
395 | cloc.update(plaintext.subarray(0,18));
396 | cloc.nonce(nonce.substring(0,6));
397 | var out;
398 | var datalen = 0;
399 | for(var j in msglist) {
400 | var i = msglist[j];
401 | out = cloc.encrypt(plaintext.subarray(datalen, datalen+i), i == 13);
402 | datalen += i;
403 | }
404 | verf.set(thiz.vectors[0]);
405 | verf.update(plaintext.subarray(0,18));
406 | verf.nonce(nonce.substring(0,6));
407 | var vrf = verf.encrypt(plaintext.subarray(0,datalen), true);
408 | if( ! compare(out, vrf, datalen) ) {
409 | thiz.error("error:test_CLOC/chunk : ", thiz.plaintext.substr(0,datalen));
410 | thiz.debug("got : ", bytes2hex(out));
411 | thiz.debug("expected : ", bytes2hex(vrf));
412 | return false;
413 | }
414 | return true;
415 | }
416 |
417 | function test_clocmaster() {
418 | var res = true;
419 | var cloc = new Cloc(new ChaskeyCipher(block32x4, 8));
420 | var msg = string2bytes(thiz.plaintext);
421 | patch4IE(msg);
422 | for(var i = 0; i < 16; ++i) {
423 | cloc.set(thiz.vectors[i]);
424 | cloc.update(msg.subarray(i%5,i+i%5), i>=8);
425 | if( i < 8 )
426 | cloc.update(msg.subarray(i%5,16-i+i%5), true);
427 | cloc.nonce(msg.subarray(i,i+i+3));
428 | var out = cloc.encrypt(msg.subarray(0, i+8, i >= 8));
429 | if( i < 8 )
430 | out = cloc.encrypt(msg.subarray(i+8, i+i+8), true);
431 | var tmp = new Formatter(16);
432 | var len = i+8+(i<8?i:0);
433 | tmp.append(out);
434 | tmp.append(cloc.mac());
435 | if( ! compare(tmp, thiz.masters[i+63], thiz.masters[i+63].length) ) {
436 | thiz.error("error:test_CLOC/master : ", thiz.plaintext.substr(0,len));
437 | thiz.debug("got : ", bytes2hex(tmp));
438 | thiz.debug("expected : ", thiz.masters[i+63]);
439 | res = false;
440 | }
441 | }
442 | return res;
443 | }
444 |
445 | this.test_CLOC = function() {
446 | return !!(test_clocmaster() & test_cloc() & test_clocchunk());
447 | }
448 |
449 |
450 | this.fail = function() {
451 | console.log(Array.from(arguments).join(''));
452 | if( this.loglevels.indexOf('fail') >= 0 )
453 | log('test-fail', arguments);
454 | }
455 |
456 | this.error = function() {
457 | console.log(Array.from(arguments).join(''));
458 | if( this.loglevels.indexOf('error') >= 0 )
459 | log('test-error',arguments);
460 | }
461 |
462 | this.info = function() {
463 | console.log(Array.from(arguments).join(''));
464 | if( this.loglevels.indexOf('info') >= 0 )
465 | log('test-info',arguments);
466 | }
467 | this.debug = function() {
468 | console.log(Array.from(arguments).join(''));
469 | if( this.loglevels.indexOf('debug') >= 0 )
470 | log('test-debug',arguments);
471 | }
472 |
473 | this.plaintext = "Plain text message of sufficient length. Plain text message of sufficient length"
474 |
475 | this.vectors = [
476 | [ 0x792E8FE5, 0x75CE87AA, 0x2D1450B5, 0x1191970B ],
477 | [ 0x13A9307B, 0x50E62C89, 0x4577BD88, 0xC0BBDC18 ],
478 | [ 0x55DF8922, 0x2C7FF577, 0x73809EF4, 0x4E5084C0 ],
479 | [ 0x1BDBB264, 0xA07680D8, 0x8E5B2AB8, 0x20660413 ],
480 | [ 0x30B2D171, 0xE38532FB, 0x16707C16, 0x73ED45F0 ],
481 | [ 0xBC983D0C, 0x31B14064, 0x234CD7A2, 0x0C92BBF9 ],
482 | [ 0x0DD0688A, 0xE131756C, 0x94C5E6DE, 0x84942131 ],
483 | [ 0x7F670454, 0xF25B03E0, 0x19D68362, 0x9F4D24D8 ],
484 | [ 0x09330F69, 0x62B5DCE0, 0xA4FBA462, 0xF20D3C12 ],
485 | [ 0x89B3B1BE, 0x95B97392, 0xF8444ABF, 0x755DADFE ],
486 | [ 0xAC5B9DAE, 0x6CF8C0AC, 0x56E7B945, 0xD7ECF8F0 ],
487 | [ 0xD5B0DBEC, 0xC1692530, 0xD13B368A, 0xC0AE6A59 ],
488 | [ 0xFC2C3391, 0x285C8CD5, 0x456508EE, 0xC789E206 ],
489 | [ 0x29496F33, 0xAC62D558, 0xE0BAD605, 0xC5A538C6 ],
490 | [ 0xBF668497, 0x275217A1, 0x40C17AD4, 0x2ED877C0 ],
491 | [ 0x51B94DA4, 0xEFCC4DE8, 0x192412EA, 0xBBC170DD ],
492 | [ 0x79271CA9, 0xD66A1C71, 0x81CA474E, 0x49831CAD ],
493 | [ 0x048DA968, 0x4E25D096, 0x2D6CF897, 0xBC3959CA ],
494 | [ 0x0C45D380, 0x2FD09996, 0x31F42F3B, 0x8F7FD0BF ],
495 | [ 0xD8153472, 0x10C37B1E, 0xEEBDD61D, 0x7E3DB1EE ],
496 | [ 0xFA4CA543, 0x0D75D71E, 0xAF61E0CC, 0x0D650C45 ],
497 | [ 0x808B1BCA, 0x7E034DE0, 0x6C8B597F, 0x3FACA725 ],
498 | [ 0xC7AFA441, 0x95A4EFED, 0xC9A9664E, 0xA2309431 ],
499 | [ 0x36200641, 0x2F8C1F4A, 0x27F6A5DE, 0x469D29F9 ],
500 | [ 0x37BA1E35, 0x43451A62, 0xE6865591, 0x19AF78EE ],
501 | [ 0x86B4F697, 0x93A4F64F, 0xCBCBD086, 0xB476BB28 ],
502 | [ 0xBE7D2AFA, 0xAC513DE7, 0xFC599337, 0x5EA03E3A ],
503 | [ 0xC56D7F54, 0x3E286A58, 0x79675A22, 0x099C7599 ],
504 | [ 0x3D0F08ED, 0xF32E3FDE, 0xBB8A1A8C, 0xC3A3FEC4 ],
505 | [ 0x2EC171F8, 0x33698309, 0x78EFD172, 0xD764B98C ],
506 | [ 0x5CECEEAC, 0xA174084C, 0x95C3A400, 0x98BEE220 ],
507 | [ 0xBBDD0C2D, 0xFAB6FCD9, 0xDCCC080E, 0x9F04B41F ],
508 | [ 0x60B3F7AF, 0x37EEE7C8, 0x836CFD98, 0x782CA060 ],
509 | [ 0xDF44EA33, 0xB0B2C398, 0x0583CE6F, 0x846D823E ],
510 | [ 0xC7E31175, 0x6DB4E34D, 0xDAD60CA1, 0xE95ABA60 ],
511 | [ 0xE0DC6938, 0x84A0A7E3, 0xB7F695B5, 0xB46A010B ],
512 | [ 0x1CEB6C66, 0x3535F274, 0x839DBC27, 0x80B4599C ],
513 | [ 0xBBA106F4, 0xD49B697C, 0xB454B5D9, 0x2B69E58B ],
514 | [ 0x5AD58A39, 0xDFD52844, 0x34973366, 0x8F467DDC ],
515 | [ 0x67A67B1F, 0x3575ECB3, 0x1C71B19D, 0xA885C92B ],
516 | [ 0xD5ABCC27, 0x9114EFF5, 0xA094340E, 0xA457374B ],
517 | [ 0xB559DF49, 0xDEC9B2CF, 0x0F97FE2B, 0x5FA054D7 ],
518 | [ 0x2ACA7229, 0x99FF1B77, 0x156D66E0, 0xF7A55486 ],
519 | [ 0x565996FD, 0x8F988CEF, 0x27DC2CE2, 0x2F8AE186 ],
520 | [ 0xBE473747, 0x2590827B, 0xDC852399, 0x2DE46519 ],
521 | [ 0xF860AB7D, 0x00F48C88, 0x0ABFBB33, 0x91EA1838 ],
522 | [ 0xDE15C7E1, 0x1D90EFF8, 0xABC70129, 0xD9B2F0B4 ],
523 | [ 0xB3F0A2C3, 0x775539A7, 0x6CAA3BC1, 0xD5A6FC7E ],
524 | [ 0x127C6E21, 0x6C07A459, 0xAD851388, 0x22E8BF5B ],
525 | [ 0x08F3F132, 0x57B587E3, 0x087AD505, 0xFA070C27 ],
526 | [ 0xA826E824, 0x3F851E6A, 0x9D1F2276, 0x7962AD37 ],
527 | [ 0x14A6A13A, 0x469962FD, 0x914DB278, 0x3A9E8EC2 ],
528 | [ 0xFE20DDF7, 0x06505229, 0xF9C9F394, 0x4361A98D ],
529 | [ 0x1DE7A33C, 0x37F81C96, 0xD9B967BE, 0xC00FA4FA ],
530 | [ 0x5FD01E9A, 0x9F2E486D, 0x93205409, 0x814D7CC2 ],
531 | [ 0xE17F5CA5, 0x37D4BDD0, 0x1F408335, 0x43B6B603 ],
532 | [ 0x817CEEAE, 0x796C9EC0, 0x1BB3DED7, 0xBAC7263B ],
533 | [ 0xB7827E63, 0x0988FEA0, 0x3800BD91, 0xCF876B00 ],
534 | [ 0xF0248D4B, 0xACA7BDC8, 0x739E30F3, 0xE0C469C2 ],
535 | [ 0x67363EB6, 0xFAE8E047, 0xF0C1C8E5, 0x828CCD47 ],
536 | [ 0x3DBD1D15, 0x05092D7B, 0x216FC6E3, 0x446860FB ],
537 | [ 0xEBF39102, 0x8F4C1708, 0x519D2F36, 0xC67C5437 ],
538 | [ 0x89A0D454, 0x9201A282, 0xEA1B1E50, 0x1771BEDC ],
539 | [ 0x9047FAD7, 0x88136D8C, 0xA488286B, 0x7FE9352C ]
540 | ];
541 | this.masters = [
542 | [ 222,202,68,203,71,185,154,219,88,87,129,165,229,233,20,84 ],
543 | [ 118,224,174,225,96,244,121,47,7,229,134,53,50,125,102,229 ],
544 | [ 181,138,189,126,50,202,139,119,242,229,175,10,166,232,171,135 ],
545 | [ 110,122,13,8,84,105,25,52,232,227,37,82,197,121,105,240 ],
546 | [ 152,133,195,170,129,159,115,98,75,234,31,71,144,111,76,123 ],
547 | [ 173,161,240,244,218,18,170,68,190,236,248,4,144,147,140,38 ],
548 | [ 208,231,42,190,67,254,150,98,203,135,73,122,146,167,113,229 ],
549 | [ 54,189,54,43,74,76,145,168,76,157,212,173,208,25,94,240 ],
550 | [ 31,72,238,18,104,238,139,142,45,85,187,193,182,105,38,5 ],
551 | [ 43,255,152,0,109,31,0,111,16,80,119,88,39,130,165,140 ],
552 | [ 94,178,192,27,86,56,148,42,195,180,12,94,61,200,52,150 ],
553 | [ 4,211,241,42,135,14,13,245,117,102,113,110,201,248,123,67 ],
554 | [ 237,114,121,205,231,88,56,34,182,190,62,123,243,252,2,236 ],
555 | [ 152,187,250,101,26,251,130,193,110,145,149,212,73,39,191,138 ],
556 | [ 8,12,29,139,151,244,30,9,11,87,218,149,152,92,22,246 ],
557 | [ 63,11,161,255,230,141,116,83,143,39,65,231,185,126,246,170 ],
558 | [ 128,245,151,12,111,204,71,170,139,246,19,222,188,68,227,186,60,117,238, 67,4,170,100,95,104,133,87,153,124,212,128,12 ],
559 | [ 20,77,65,9,13,109,229,60,0,3,186,56,190,90,48,93,186,122,200,16,202,13, 249,218,145,118,223,243,232,130,161,94 ],
560 | [ 4,57,187,192,5,81,173,237,228,166,182,157,23,47,153,229,109,161,81,4,202, 190,174,72,69,192,98,174,228,68,109,26 ],
561 | [ 247,71,207,142,146,27,182,0,67,12,235,174,107,70,38,165,186,169,21,187, 8,150,91,122,118,176,192,191,179,73,194,126 ],
562 | [ 243,51,36,207,216,59,71,0,130,237,118,32,61,223,238,214,136,65,188,52,68, 85,5,116,68,66,7,76,55,14,120,129 ],
563 | [ 132,15,0,170,117,62,62,232,76,31,204,103,92,224,225,162,224,244,164,189, 11,87,105,241,166,52,122,100,2,131,86,195 ],
564 | [ 14,90,143,161,121,159,73,147,26,248,88,201,32,241,198,177,88,147,168,10, 51,161,85,86,153,111,216,159,16,252,171,50 ],
565 | [ 46,137,166,99,10,9,161,19,201,26,190,248,124,221,138,23,18,119,130,83,66, 31,222,255,117,127,135,107,76,241,172,196 ],
566 | [ 65,96,98,247,42,85,245,104,121,123,23,102,33,130,213,150,181,251,20,191, 179,109,207,13,133,68,150,154,136,143,17,127 ],
567 | [ 238,77,117,246,217,33,56,85,205,216,1,163,42,189,112,85,104,65,145,65,200, 102,245,25,59,71,59,25,13,18,195,24 ],
568 | [ 175,155,175,187,29,60,129,58,151,108,248,196,181,96,156,242,113,215,42, 220,224,154,193,233,161,108,45,40,235,201,145,173 ],
569 | [ 143,58,180,175,39,226,132,151,224,46,144,191,193,230,87,90,46,125,106,225, 132,19,164,242,55,66,21,27,102,81,144,122 ],
570 | [ 119,60,95,2,38,129,245,99,74,20,55,199,56,162,238,64,44,89,38,8,255,225, 61,149,118,93,166,195,45,242,240,116 ],
571 | [ 1,140,255,176,19,225,59,182,85,220,132,29,98,57,1,59,33,163,1,83,60,3,232, 118,143,129,29,185,67,97,238,196 ],
572 | [ 24,236,188,144,157,4,152,167,29,125,37,66,220,168,245,72,50,191,158,70, 190,26,98,59,166,241,193,103,162,233,246,160 ],
573 | [ 89,121,164,54,147,181,38,167,34,213,245,92,174,126,14,74,144,110,146,95, 56,8,38,153,15,146,74,151,68,134,180,176 ],
574 | [ 73,13,241,83,220,5,32,25,68,34,116,111,234,221,64,94,20,55,93,242,83,11, 10,59,4,39,196,222,150,229,198,25,197,128,19,78,216,100,168,207,141,207, 175,29,120,24,159,29 ],
575 | [ 33,223,228,40,106,73,254,13,208,234,230,228,21,44,21,176,85,54,208,216, 187,55,175,198,63,31,60,191,244,84,76,25,115,157,106,166,73,145,102,46, 205,155,243,19,175,205,27,242 ],
576 | [ 2,229,11,152,59,105,209,14,144,148,195,182,137,119,145,89,143,185,212,8, 92,100,130,107,224,49,77,12,117,89,242,28,147,67,78,81,207,254,255,35,104, 132,93,28,169,163,249,17 ],
577 | [ 111,183,30,238,137,12,169,152,246,29,162,184,195,17,54,50,158,30,165,140, 231,255,180,250,127,237,85,80,133,88,228,246,97,52,13,120,114,104,192,7, 124,122,226,100,6,215,94,254 ],
578 | [ 14,133,180,190,194,136,108,116,80,17,2,6,113,129,33,134,150,121,255,152, 92,11,119,196,41,190,114,154,218,224,100,158,252,173,25,54,78,14,152,253, 29,91,51,49,138,133,86,195 ],
579 | [ 192,149,185,128,17,143,153,163,22,175,42,239,4,247,86,13,193,15,42,76,11, 22,17,17,110,117,125,251,35,30,218,133,190,140,152,74,106,130,88,87,68, 66,174,234,38,215,69,155 ],
580 | [ 179,112,80,9,233,55,89,134,49,254,119,181,114,238,13,90,158,193,50,2,158, 190,123,71,69,116,117,112,97,248,229,220,189,64,119,137,124,204,221,98, 198,109,77,186,158,215,209,17 ],
581 | [ 198,176,231,134,208,202,53,132,147,42,126,194,79,209,138,230,207,20,149, 59,47,229,137,27,126,46,234,18,240,100,194,183,201,199,175,190,166,133, 3,96,150,3,238,154,231,126,239,191 ],
582 | [ 233,227,197,48,11,194,2,96,106,121,24,213,29,135,235,72,143,178,52,214, 40,169,50,108,229,158,18,236,235,164,101,76,21,14,97,243,92,93,225,101, 7,203,68,115,114,79,86,210 ],
583 | [ 81,215,124,227,54,15,90,239,248,126,23,163,219,13,245,41,30,86,44,249,134, 52,221,127,240,30,141,123,249,8,126,221,226,156,188,235,158,84,165,56,158, 38,168,121,44,161,108,170 ],
584 | [ 215,156,195,2,145,102,237,9,196,188,163,145,199,35,228,179,28,23,23,249, 85,178,209,135,93,115,173,126,89,48,247,135,179,30,19,89,183,168,203,102, 34,125,207,137,33,84,227,20 ],
585 | [ 170,236,23,110,135,242,16,240,127,212,197,62,37,130,87,182,134,247,119, 78,61,134,173,159,214,68,203,93,143,247,247,101,163,234,79,216,76,234,227, 48,189,92,125,103,41,47,171,205 ],
586 | [ 118,70,104,186,35,9,3,77,66,135,235,65,99,242,94,169,113,10,14,103,68,106, 70,10,7,149,242,62,30,100,71,50,149,137,115,146,220,185,252,36,127,222, 232,223,134,45,200,14 ],
587 | [ 204,140,213,118,192,233,188,143,4,121,4,162,134,98,186,184,2,181,226,224, 108,234,26,82,94,22,96,49,161,202,40,239,201,13,29,73,250,175,210,176,50, 154,87,70,145,107,239,20 ],
588 | [ 160,68,57,205,169,228,3,107,118,58,91,200,14,166,79,44,219,181,213,27,86, 55,142,117,151,55,78,224,219,81,220,167,183,230,20,196,175,133,245,162, 22,86,144,66,85,214,187,235 ],
589 | [ 117,117,63,173,126,63,35,138,8,100,76,65,228,108,114,250,70,168,83,107, 133,12,248,18,209,232,62,247,111,94,200,8,174,49,96,108,36,74,30,114,188, 9,136,225,58,105,51,142 ],
590 | [ 157,1,60,58,10,176,179,199,24,164,77,239,147,96,254,187,168,93,172,8,209, 103,62,122,61,41,35,55,119,107,79,203,4,137,86,53,211,205,221,229,143,71, 131,69,42,4,155,104,19,174,125,223,242,28,65,211,195,41,197,208,9,137,2, 78 ],
591 | [ 161,212,83,134,155,103,237,212,88,188,177,162,36,16,53,8,52,218,66,239, 202,210,19,78,147,73,227,127,80,128,211,173,204,38,139,59,116,112,213,51, 177,127,54,250,142,13,149,250,174,240,91,131,2,217,59,89,21,210,246,95, 66,231,75,8 ],
592 | [ 83,56,156,44,197,77,160,143,93,249,83,46,110,207,34,249,155,249,53,121, 66,232,94,72,59,131,210,129,52,13,60,111,5,114,192,85,26,153,9,232,165, 43,102,200,94,173,217,165,181,77,236,252,53,247,89,255,9,16,240,150,230, 180,19,88 ],
593 | [ 6,9,131,74,104,2,18,36,129,24,75,80,246,121,209,152,247,9,20,55,148,155, 204,85,241,117,128,236,174,73,57,46,62,238,12,196,175,137,79,112,255,52, 218,205,195,135,94,141,213,213,170,144,62,45,91,199,225,185,22,145,155, 75,180,40 ],
594 | [ 124,27,241,23,212,79,223,87,129,214,34,161,230,240,168,245,116,197,84,67, 41,197,102,155,244,188,36,21,201,194,105,78,28,74,28,212,67,148,94,239, 182,211,130,4,133,147,2,20,91,226,222,159,41,63,206,184,198,205,148,138, 44,41,209,176 ],
595 | [ 84,104,143,97,29,117,50,48,5,241,116,142,186,158,229,99,95,186,245,237, 197,79,211,176,187,159,127,74,118,17,13,109,247,24,241,3,78,96,255,102, 180,70,228,123,173,59,151,163,110,9,111,199,107,146,179,188,137,61,103, 6,185,247,245,212 ],
596 | [ 118,110,183,199,103,39,114,241,127,81,119,239,215,127,28,236,115,64,116, 215,102,93,214,207,89,250,200,192,36,25,87,11,44,222,212,149,204,148,44, 255,188,58,157,25,127,24,153,122,92,89,37,133,216,96,141,185,45,115,99, 238,182,33,112,95 ],
597 | [ 196,213,190,214,69,184,227,220,28,132,237,60,124,167,236,17,174,150,24, 54,114,226,1,196,58,76,25,44,14,102,157,206,13,130,245,161,22,13,213,96, 116,154,246,227,241,139,102,219,182,152,20,131,26,167,38,159,239,236,210, 176,196,156,78,60 ],
598 | [ 101,147,225,111,103,140,133,149,241,30,23,60,65,248,83,131,194,253,65,198, 18,236,205,213,115,120,194,165,245,70,82,13,125,178,225,131,15,64,240,72, 16,112,128,30,154,57,15,92,25,130,55,222,255,112,188,112,253,246,189,26, 236,207,114,47 ],
599 | [ 199,161,228,120,85,125,46,243,141,87,89,70,88,113,253,104,68,254,5,237, 79,200,203,144,50,96,208,78,11,252,199,1,138,248,58,220,188,225,124,68, 197,210,249,31,167,107,86,202,222,124,145,187,104,231,99,155,255,235,59, 250,72,223,7,101 ],
600 | [ 41,194,24,135,196,138,136,5,61,201,81,96,150,96,116,201,105,26,31,123,131, 17,29,120,92,6,70,70,121,35,195,157,218,41,224,155,223,95,191,65,225,217, 172,68,235,37,46,203,73,169,206,26,45,8,20,42,248,142,0,204,80,183,202, 177 ],
601 | [ 99,45,35,44,153,237,60,32,122,156,158,17,225,48,53,103,117,46,94,91,200, 93,249,48,206,3,49,171,145,121,194,237,55,137,190,21,200,179,79,196,36, 24,114,252,203,99,187,180,235,139,174,154,64,206,219,5,87,11,209,203,254, 149,196,110 ],
602 | [ 225,41,74,127,96,108,234,255,19,129,178,139,43,244,113,146,94,129,129,151, 162,53,237,55,166,238,103,141,215,190,234,142,213,53,110,62,155,188,217, 187,39,234,214,239,115,53,194,98,211,4,95,17,17,213,8,199,12,171,162,172, 211,68,203,177 ],
603 | [ 133,100,189,25,253,43,51,103,6,1,99,156,196,62,72,216,144,23,214,84,223, 186,74,6,188,98,149,157,80,31,35,94,34,126,251,237,93,139,167,89,214,81, 30,116,203,109,6,84,53,239,29,119,201,20,195,143,161,81,55,14,75,20,212, 97 ],
604 | [ 161,27,115,145,250,123,188,180,210,181,75,188,168,100,241,180,63,59,107, 97,45,130,179,244,244,236,131,108,31,3,180,168,187,141,72,135,252,234,134, 154,82,190,151,129,147,249,243,134,184,30,87,184,75,232,141,66,207,0,133, 53,15,51,67,212 ],
605 | [ 101,160,120,89,138,55,143,101,149,250,239,152,122,121,84,36,214,3,120,13, 136,24,77,150 ],
606 | [ 203,174,244,74,38,46,117,60,68,66,72,177,59,67,128,132,145,155,75,155,158, 184,152,248,112,114 ],
607 | [ 174,186,45,36,166,134,195,43,166,108,76,55,245,5,165,205,26,117,120,118, 91,84,128,109,248,65,3,96 ],
608 | [ 166,192,210,132,109,61,0,253,174,98,153,105,16,224,193,146,94,252,231,155, 12,117,68,168,16,79,193,74,238,98 ],
609 | [ 204,231,166,234,4,44,45,128,31,41,88,61,211,74,103,23,115,20,240,79,191, 85,176,28,201,232,251,73,118,217,238,47 ],
610 | [ 14,209,202,119,79,43,96,216,89,90,223,163,37,248,28,168,129,187,100,114, 72,199,168,20,109,194,49,72,48,185,97,120,41,82 ],
611 | [ 228,190,242,61,252,95,94,21,207,75,6,8,131,254,215,92,34,180,100,2,59,79, 70,67,85,190,230,161,70,182,219,114,103,239,104,19 ],
612 | [ 166,69,162,214,21,198,15,56,236,125,233,198,240,135,76,81,80,9,126,200, 209,190,28,55,165,230,72,5,187,49,171,199,189,83,43,183,171,165 ],
613 | [ 177,104,86,135,228,33,176,89,104,110,111,15,240,197,48,207,123,81,89,55, 116,150,14,68,146,182,12,108,211,32,144,183 ],
614 | [ 3,23,173,220,246,1,189,8,243,33,118,204,157,144,69,12,155,20,149,55,254, 9,10,48,19,130,156,28,32,213,178,103,173 ],
615 | [ 44,194,119,220,37,79,65,47,132,215,159,182,87,94,165,188,26,73,227,116, 226,189,48,4,226,71,125,220,25,11,181,221,232,32 ],
616 | [ 154,166,121,23,155,28,43,106,215,235,89,109,245,7,235,90,161,140,15,100, 64,2,35,58,45,49,203,157,132,42,19,86,11,180,248 ],
617 | [ 190,26,115,144,206,183,93,13,47,174,150,237,36,71,248,202,42,23,154,31, 212,8,111,199,18,75,138,153,168,207,225,232,212,197,242,234 ],
618 | [ 7,183,194,218,57,173,45,230,80,11,30,194,44,209,179,93,113,191,126,147, 117,174,4,4,174,98,246,59,74,120,233,65,176,39,0,220,234 ],
619 | [ 204,109,168,196,153,13,43,138,85,164,29,155,94,196,219,10,1,0,204,253,87, 227,228,104,77,42,45,139,116,82,100,110,250,30,225,12,157,244 ],
620 | [ 158,101,171,59,253,115,222,45,156,1,116,105,156,8,247,63,131,52,177,40, 52,245,6,115,127,73,142,76,223,215,11,151,73,84,164,13,205,213,51 ]
621 | ];
622 | }
623 |
--------------------------------------------------------------------------------