#include #include #include #include #include typedef uint32_t uint32; #include "crypto_core.h" #include "crypto_test.h" /* From , Section 8. */ static const unsigned char zero8[64]; static const uint32 zero32[16]; static const unsigned char in0[64] = { 211,159, 13,115, 76, 55, 82,183, 3,117,222, 37,191,187,234,136, 49,237,179, 48, 1,106,178,219,175,199,166, 48, 86, 16,179,207, 31,240, 32, 63, 15, 83, 93,161,116,147, 48,113,238, 55,204, 36, 79,201,235, 79, 3, 81,156, 47,203, 26,244,243, 88,118,104, 54, }; static const unsigned char out0[64] = { 109, 42,178,168,156,240,248,238,168,196,190,203, 26,110,170,154, 29, 29,150, 26,150, 30,235,249,190,163,251, 48, 69,144, 51, 57, 118, 40,152,157,180, 57, 27, 94,107, 42,236, 35, 27,111,114,114, 219,236,232,135,111,155,110, 18, 24,232, 95,158,179, 19, 48,202, }; /* From , Section 9. */ static const unsigned char key[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216, }; static const unsigned char nonce[] = { 101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116, }; static const unsigned char sigma[] = "expand 32-byte k"; static const unsigned char in[] = { 101,120,112, 97, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,110,100, 32, 51,101,102,103,104,105,106,107,108, 109,110,111,112,113,114,115,116, 50, 45, 98,121,201,202,203,204, 205,206,207,208,209,210,211,212,213,214,215,216,116,101, 32,107, }; static const unsigned char out[] = { 69, 37, 68, 39, 41, 15,107,193,255,139,122, 6,170,233,217, 98, 89,144,182,106, 21, 51,200, 65,239, 49,222, 34,215,114, 40,126, 104,197, 7,225,197,153, 31, 2,102, 78, 76,176, 84,245,246,184, 177,160,133,130, 6, 72,149,119,192,195,132,236,234,103,246, 74, }; static uint32 rotate(uint32 u,int c) { return (u << c) | (u >> (32 - c)); } #define QUARTERROUND(v0,v1,v2,v3) do { \ (v1) ^= rotate((v0) + (v3), 7); \ (v2) ^= rotate((v1) + (v0), 9); \ (v3) ^= rotate((v2) + (v1),13); \ (v0) ^= rotate((v3) + (v2),18); \ } while (0) static uint32 load_littleendian(const unsigned char *x) { return (uint32) (x[0]) \ | (((uint32) (x[1])) << 8) \ | (((uint32) (x[2])) << 16) \ | (((uint32) (x[3])) << 24) ; } static void extract(uint32 n[4], uint32 h[4], uint32 k[4], uint32 s[4], const unsigned char i[64]) { s[0] = load_littleendian(i + 0); h[0] = load_littleendian(i + 4); h[1] = load_littleendian(i + 8); h[2] = load_littleendian(i + 12); h[3] = load_littleendian(i + 16); s[1] = load_littleendian(i + 20); n[0] = load_littleendian(i + 24); n[1] = load_littleendian(i + 28); n[2] = load_littleendian(i + 32); n[3] = load_littleendian(i + 36); s[2] = load_littleendian(i + 40); k[0] = load_littleendian(i + 44); k[1] = load_littleendian(i + 48); k[2] = load_littleendian(i + 52); k[3] = load_littleendian(i + 56); s[3] = load_littleendian(i + 60); } void crypto_test(void) { uint32 x0, x1, x2, x3; uint32 r[16], n[4], k[8], s[4]; unsigned int i; unsigned int d = 0; if (crypto_core_ROUNDS != 20) return; /* From , Section 3. */ x0 = x1 = x2 = x3 = 0; QUARTERROUND(x0, x1, x2, x3); if (x0 | x1 | x2 | x3) errx(1, "quarterround(0,0,0,0)"); x0 = 1; x1 = x2 = x3 = 0; QUARTERROUND(x0, x1, x2, x3); if (x0 != 0x08008145) errx(1, "quarterround(1,0,0,0)_0"); if (x1 != 0x00000080) errx(1, "quarterround(1,0,0,0)_1"); if (x2 != 0x00010200) errx(1, "quarterround(1,0,0,0)_2"); if (x3 != 0x20500000) errx(1, "quarterround(1,0,0,0)_3"); /* From , Section 8 (zeros). */ extract(n, k, k+4, s, zero8); crypto_core(r, n, k, s); for (i = 0; i < 16; i++) d |= r[i] ^ zero32[i]; if (d) { for (i = 0; i < 16; i++) printf("%08"PRIx32, r[i]); printf("\n"); for (i = 0; i < 16; i++) printf("%08"PRIx32, zero32[i]); printf("\n"); errx(1, "zero"); } extract(n, k, k+4, s, in0); crypto_core(r, n, k, s); for (i = 0; i < 16; i++) d |= r[i] ^ load_littleendian(&out0[i*4]); if (d) { for (i = 0; i < 16; i++) printf("%08"PRIx32, r[i]); printf("\n"); for (i = 0; i < 16; i++) printf("%08"PRIx32, load_littleendian(&out0[i*4])); printf("\n"); errx(1, "in0"); } n[0] = load_littleendian(nonce + 0); n[1] = load_littleendian(nonce + 4); n[2] = load_littleendian(nonce + 8); n[3] = load_littleendian(nonce + 12); s[0] = load_littleendian(sigma + 0); s[1] = load_littleendian(sigma + 4); s[2] = load_littleendian(sigma + 8); s[3] = load_littleendian(sigma + 12); k[0] = load_littleendian(key + 0); k[1] = load_littleendian(key + 4); k[2] = load_littleendian(key + 8); k[3] = load_littleendian(key + 12); k[4] = load_littleendian(key + 16); k[5] = load_littleendian(key + 20); k[6] = load_littleendian(key + 24); k[7] = load_littleendian(key + 28); /* XXX check against extract(in) */ crypto_core(r, n, k, s); for (i = 0; i < 16; i++) d |= r[i] ^ load_littleendian(&out[i*4]); if (d) { for (i = 0; i < 16; i++) printf("%08"PRIx32, r[i]); printf("\n"); for (i = 0; i < 16; i++) printf("%08"PRIx32, load_littleendian(&out[i*4])); printf("\n"); errx(1, "blah"); } }