Created
July 22, 2017 14:26
-
-
Save yukoba/f2f0cff435b8140e686495564fb578a2 to your computer and use it in GitHub Desktop.
SpeckでROUNDSが外か中か
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
こちらのコードは ROUNDS がループの内側。 | |
https://en.wikipedia.org/wiki/Speck_(cipher) とほぼ同じ。 | |
自動ベクトル化はできないみたいです。 | |
*/ | |
#define ROR(x, r) ((x >> r) | (x << (64 - r))) | |
#define ROL(x, r) ((x << r) | (x >> (64 - r))) | |
#define R(x, y, k) (x = ROR(x, 8), x += y, x ^= k, y = ROL(y, 3), y ^= x) | |
#define ROUNDS 32 | |
void encrypt_stream(const uint8_t* data_in, size_t const len, uint8_t* data_out, uint64_t const key[static 2]) { | |
const uint64_t* data_in_64 = (const uint64_t *) data_in; | |
uint64_t* data_out_64 = (uint64_t *) data_out; | |
for (int i = 0; i < len / 8; i += 2) { | |
uint64_t y = data_in_64[i]; | |
uint64_t x = data_in_64[i + 1]; | |
uint64_t b = key[0]; | |
uint64_t a = key[1]; | |
R(x, y, b); | |
for (int j = 0; j < ROUNDS - 1; j++) { | |
R(a, b, j); | |
R(x, y, b); | |
} | |
data_out_64[i] = y; | |
data_out_64[i + 1] = x; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
こちらのコードは gcc -O3 -fopt-info -o speck.exe main.c すると | |
main.c:38:9: note: loop turned into non-loop; it never loops. | |
main.c:38:9: note: loop with 2 iterations completely unrolled | |
main.c:38:9: note: loop vectorized | |
のように出力されて自動ベクトル化されます。下記の21行目の所で自動ベクトル化されます。 | |
*/ | |
#define ROR(x, r) ((x >> r) | (x << (64 - r))) | |
#define ROL(x, r) ((x << r) | (x >> (64 - r))) | |
#define R(x, y, k) (x = ROR(x, 8), x += y, x ^= k, y = ROL(y, 3), y ^= x) | |
#define ROUNDS 32 | |
void encrypt_stream(const uint8_t* data_in, size_t const len, uint8_t* data_out, uint64_t const key[static 2]) { | |
memcpy(data_out, data_in, len); | |
uint64_t* data_out_64 = (uint64_t *) data_out; | |
uint64_t b = key[0]; | |
uint64_t a = key[1]; | |
for (int j = 0; j < ROUNDS; j++) { | |
for (int i = 0; i < len / 8; i += 2) { | |
uint64_t y = data_out_64[i]; | |
uint64_t x = data_out_64[i + 1]; | |
R(x, y, b); | |
data_out_64[i] = y; | |
data_out_64[i + 1] = x; | |
} | |
R(a, b, j); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment