/*\ |*| |*| Edon-R helper routines by Sean O'Neil and Tor E. Bj{\o}rstad, (c) March-April, 2009 |*| |*| Based on: |*| |*| edon.c |*| |*| Compute forward/backward/partial quasigroup permutations in Edon-R-512 |*| Tor E. Bj{\o}rstad, January - March 2009 |*| \*/ // Define the word size first: #ifndef W #define W 64 // Default: Edon-R-512 #endif typedef unsigned char u8; typedef unsigned short u16; typedef unsigned long u32; typedef unsigned long long u64; /*\ |*| Define parameters for Edon-R-512 and Edon-R-256, and some ad-hoc values for reduced variants. \*/ #if (W>32) typedef u64 uw; #define NUMBER "%016llX " int rolf [8] = {0, 5, 15, 22, 31, 40, 50, 59}; int rolg [8] = {0, 10, 19, 29, 36, 44, 48, 55}; #elif (W>16) typedef u32 uw; #define NUMBER "%08X " int rolf [8] = {0, 4, 8, 13, 17, 22, 24, 29}; int rolg [8] = {0, 5, 9, 11, 15, 20, 25, 27}; #elif (W>8) typedef u16 uw; #define NUMBER "%04X " int rolf [8] = {0, 2, 4, 6, 8, 10, 12, 14}; int rolg [8] = {0, 1, 3, 5, 7, 9, 11, 13}; #else typedef u8 uw; #define NUMBER "%02X " int rolf [8] = {0, 1, 2, 3, 4, 5, 6, 7}; int rolg [8] = {0, 1, 2, 3, 4, 5, 6, 7}; #endif #define rotl(x,n) (((x)<<((n)&(W-1)))|((x)>>((0-(n))&(W-1)))) #define rotr(x,n) (((x)>>((n)&(W-1)))|((x)<<((0-(n))&(W-1)))) /////////////////////////////////////////////////////////////////////////// // // First Function f and fr // /////////////////////////////////////////////////////////////////////////// void f_addf (uw in [8], uw out [8]) { uw constant = (uw) 0xAAAAAAAAAAAAAAAAull; out [0] = constant + \ in [0] + in [1] + in [2] + in [4] + in [7]; out [1] = in [0] + in [1] + in [3] + in [4] + in [7]; out [2] = in [0] + in [1] + in [4] + in [6] + in [7]; out [3] = in [2] + in [3] + in [5] + in [6] + in [7]; out [4] = in [1] + in [2] + in [3] + in [5] + in [6] ; out [5] = in [0] + in [2] + in [3] + in [4] + in [5] ; out [6] = in [0] + in [1] + in [5] + in [6] + in [7]; out [7] = in [2] + in [3] + in [4] + in [5] + in [6] ; } void f_rolf (uw in [8], uw out [8]) { out [0] = in [0] ; out [1] = rotl (in [1], rolf [1]); out [2] = rotl (in [2], rolf [2]); out [3] = rotl (in [3], rolf [3]); out [4] = rotl (in [4], rolf [4]); out [5] = rotl (in [5], rolf [5]); out [6] = rotl (in [6], rolf [6]); out [7] = rotl (in [7], rolf [7]); } void f_xorf (uw in [8], uw out [8]) { out [0] = in [0] ^ in [1] ^ in [4] ; out [1] = in [0] ^ in [4] ^ in [7]; out [2] = in [1] ^ in [6] ^ in [7]; out [3] = in [2] ^ in [3] ^ in [4] ; out [4] = in [0] ^ in [1] ^ in [7]; out [5] = in [3] ^ in [5] ^ in [6] ; out [6] = in [2] ^ in [5] ^ in [6] ; out [7] = in [2] ^ in [3] ^ in [5] ; } void f_xorr (uw in [8], uw out [8]) { out [0] = in [0] ^ in [1] ^ in [4] ; out [1] = in [1] ^ in [3] ^ in [4] ^ in [5] ^ in [6] ; out [2] = in [0] ^ in [1] ^ in [2] ^ in [5] ^ in [7]; out [3] = in [0] ^ in [1] ^ in [2] ^ in [6] ^ in [7]; out [4] = in [3] ^ in [5] ^ in [6] ; out [5] = in [5] ^ in [6] ^ in [7]; out [6] = in [0] ^ in [1] ^ in [2] ; out [7] = in [0] ^ in [3] ^ in [4] ^ in [5] ^ in [6] ; } void f_rolr (uw in [8], uw out [8]) { out [0] = in [0] ; out [1] = rotr (in [1], rolf [1]); out [2] = rotr (in [2], rolf [2]); out [3] = rotr (in [3], rolf [3]); out [4] = rotr (in [4], rolf [4]); out [5] = rotr (in [5], rolf [5]); out [6] = rotr (in [6], rolf [6]); out [7] = rotr (in [7], rolf [7]); } void f_addr (uw in [8], uw out [8]) { uw constant = (uw) 0xAAAAAAAAAAAAAAAAull; uw inverse = (uw) 0xCCCCCCCCCCCCCCCDull; out [0] = (- 3 * (in [0] - constant) - 3 * in [1] + 7 * in [2] + 2 * in [3] + 2 * in [4] + 7 * in [5] - 3 * in [6] - 8 * in [7]) * inverse; out [1] = ( 2 * (in [0] - constant) + 2 * in [1] - 3 * in [2] - 3 * in [3] + 2 * in [4] - 3 * in [5] + 2 * in [6] + 2 * in [7]) * inverse; out [2] = ( 2 * (in [0] - constant) - 3 * in [1] + 2 * in [2] + 2 * in [3] + 2 * in [4] + 2 * in [5] - 3 * in [6] - 3 * in [7]) * inverse; out [3] = (- 3 * (in [0] - constant) + 2 * in [1] + 2 * in [2] + 2 * in [3] + 2 * in [4] + 2 * in [5] - 3 * in [6] - 3 * in [7]) * inverse; out [4] = ( 2 * (in [0] - constant) + 2 * in [1] - 3 * in [2] - 3 * in [3] - 3 * in [4] - 3 * in [5] + 2 * in [6] + 7 * in [7]) * inverse; out [5] = ( 2 * (in [0] - constant) + 2 * in [1] - 8 * in [2] - 3 * in [3] - 3 * in [4] - 3 * in [5] + 7 * in [6] + 7 * in [7]) * inverse; out [6] = (- 3 * (in [0] - constant) - 3 * in [1] + 7 * in [2] + 2 * in [3] + 2 * in [4] + 2 * in [5] - 3 * in [6] - 3 * in [7]) * inverse; out [7] = ( 2 * (in [0] - constant) + 2 * in [1] - 3 * in [2] + 2 * in [3] - 3 * in [4] - 3 * in [5] + 2 * in [6] + 2 * in [7]) * inverse; } void ff (uw in [8], uw out [8]) { uw t [8]; f_addf (in,t); f_rolf (t,t); f_xorf (t,out); } void fr (uw in [8], uw out [8]) { uw t [8]; f_xorr (in,t); f_rolr (t,t); f_addr (t,out); } /////////////////////////////////////////////////////////////////////////// // // Second function g and gr // /////////////////////////////////////////////////////////////////////////// void g_addf (uw in [8], uw out [8]) { uw constant = (uw) 0x5555555555555555ull; out [0] = constant + \ in [0] + in [1] + in [2] + in [5] + in [7]; out [1] = in [0] + in [1] + in [3] + in [4] + in [6] ; out [2] = in [0] + in [1] + in [2] + in [3] + in [5] ; out [3] = in [2] + in [3] + in [4] + in [6] + in [7]; out [4] = in [0] + in [1] + in [3] + in [4] + in [5] ; out [5] = in [2] + in [4] + in [5] + in [6] + in [7]; out [6] = in [1] + in [2] + in [5] + in [6] + in [7]; out [7] = in [0] + in [3] + in [4] + in [6] + in [7]; } void g_rolf (uw in [8], uw out [8]) { out [0] = in [0] ; out [1] = rotl (in [1], rolg [1]); out [2] = rotl (in [2], rolg [2]); out [3] = rotl (in [3], rolg [3]); out [4] = rotl (in [4], rolg [4]); out [5] = rotl (in [5], rolg [5]); out [6] = rotl (in [6], rolg [6]); out [7] = rotl (in [7], rolg [7]); } void g_xorf (uw in [8], uw out [8]) { out [0] = in [0] ^ in [1] ^ in [5] ; out [1] = in [2] ^ in [6] ^ in [7]; out [2] = in [0] ^ in [1] ^ in [3] ; out [3] = in [0] ^ in [3] ^ in [4] ; out [4] = in [1] ^ in [2] ^ in [5] ; out [5] = in [3] ^ in [4] ^ in [6] ; out [6] = in [2] ^ in [5] ^ in [7]; out [7] = in [4] ^ in [6] ^ in [7]; } void g_xorr (uw in [8], uw out [8]) { out [0] = in [2] ^ in [4] ^ in [5] ^ in [6] ^ in [7]; out [1] = in [0] ^ in [1] ^ in [3] ^ in [5] ^ in [6] ; out [2] = in [0] ^ in [2] ^ in [5] ^ in [6] ^ in [7]; out [3] = in [0] ^ in [1] ^ in [3] ^ in [4] ^ in [7]; out [4] = in [0] ^ in [1] ^ in [2] ^ in [5] ^ in [6] ; out [5] = in [1] ^ in [2] ^ in [3] ^ in [4] ^ in [7]; out [6] = in [2] ^ in [3] ^ in [4] ^ in [6] ^ in [7]; out [7] = in [0] ^ in [1] ^ in [3] ^ in [4] ^ in [5] ; } void g_rolr (uw in [8], uw out [8]) { out [0] = in [0] ; out [1] = rotr (in [1], rolg [1]); out [2] = rotr (in [2], rolg [2]); out [3] = rotr (in [3], rolg [3]); out [4] = rotr (in [4], rolg [4]); out [5] = rotr (in [5], rolg [5]); out [6] = rotr (in [6], rolg [6]); out [7] = rotr (in [7], rolg [7]); } void g_addr (uw in [8], uw out [8]) { uw constant = (uw) 0x5555555555555555ull; uw inverse = (uw) 0xCCCCCCCCCCCCCCCDull; out [0] = ( 2 * (in [0] - constant) + 2 * in [1] + 2 * in [2] - 3 * in [3] - 3 * in [4] + 2 * in [5] - 3 * in [6] + 2 * in [7]) * inverse; out [1] = ( 2 * (in [0] - constant) + 2 * in [1] - 3 * in [2] + 2 * in [3] + 2 * in [4] - 3 * in [5] + 2 * in [6] - 3 * in [7]) * inverse; out [2] = ( 2 * (in [0] - constant) + 2 * in [1] + 2 * in [2] + 2 * in [3] - 3 * in [4] + 2 * in [5] - 3 * in [6] - 3 * in [7]) * inverse; out [3] = (- 3 * (in [0] - constant) - 3 * in [1] + 2 * in [2] + 2 * in [3] + 2 * in [4] - 3 * in [5] + 2 * in [6] + 2 * in [7]) * inverse; out [4] = ( 2 * (in [0] - constant) + 2 * in [1] - 3 * in [2] + 2 * in [3] + 2 * in [4] + 2 * in [5] - 3 * in [6] - 3 * in [7]) * inverse; out [5] = (- 3 * (in [0] - constant) - 3 * in [1] + 2 * in [2] - 3 * in [3] + 2 * in [4] + 2 * in [5] + 2 * in [6] + 2 * in [7]) * inverse; out [6] = (- 3 * (in [0] - constant) + 2 * in [1] + 2 * in [2] - 3 * in [3] - 3 * in [4] + 2 * in [5] + 2 * in [6] + 2 * in [7]) * inverse; out [7] = ( 2 * (in [0] - constant) - 3 * in [1] - 3 * in [2] + 2 * in [3] + 2 * in [4] - 3 * in [5] + 2 * in [6] + 2 * in [7]) * inverse; } void gf (uw in [8], uw out [8]) { uw t [8]; g_addf (in,t); g_rolf (t,t); g_xorf (t,out); } void gr (uw in [8], uw out [8]) { uw t [8]; g_xorr (in,t); g_rolr (t,t); g_addr (t,out); } /////////////////////////////////////////////////////////////////////////// // // Helper routines; vector add and subtract, reversal // /////////////////////////////////////////////////////////////////////////// void vm (uw x [8], uw y [8], uw z [8]) // z = x - y { int i; for (i = 0; i < 8; ++i) z [i] = x [i] - y [i]; return; } void vp (uw x [8], uw y [8], uw z [8]) // z = x + y { int i; for (i = 0; i < 8; ++i) z [i] = x [i] + y [i]; return; } void rev (uw x [8]) { x [0] ^= x [7]; x [7] ^= x [0]; x [0] ^= x [7]; x [1] ^= x [6]; x [6] ^= x [1]; x [1] ^= x [6]; x [2] ^= x [5]; x [5] ^= x [2]; x [2] ^= x [5]; x [3] ^= x [4]; x [4] ^= x [3]; x [3] ^= x [4]; } /////////////////////////////////////////////////////////////////////////// // // Complete functions ef, ex, ey // /////////////////////////////////////////////////////////////////////////// void ef (uw x [8], uw y [8], uw z [8]) // z = f(x) + g (y) { uw fx [8], gy [8]; ff (x, fx); gf (y, gy); vp (fx, gy, z); } void ex (uw x [8], uw y [8], uw z [8]) // x = f^-1 (z - g (y)) { uw fx [8], gy [8]; gf (y, gy); vm (z, gy, fx); fr (fx, x); } void ey (uw x [8], uw y [8], uw z [8]) // y = g^-1 (z - f (x)) { uw fx [8], gy [8]; ff (x, fx); vm (z, fx, gy); gr (gy, y); }