Last active
September 14, 2020 08:40
-
-
Save chiro-hiro/33542c9f7463752812d113a11bb9520d to your computer and use it in GitHub Desktop.
This file contains hidden or 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
/* | |
MIT License | |
Copyright (c) 2020 Chiro Hiro <[email protected]> | |
*/ | |
#include <stdio.h> | |
#include <string.h> | |
#include <immintrin.h> | |
// Global seed value | |
__m256i seed; | |
// Use SSE2 perform pesudo random for given seed | |
__m128i xor_shift_plus_pro() | |
{ | |
// t = 0 | |
__m128i t = _mm_setzero_si128(); | |
// s = 0 | |
__m128i s = _mm_setzero_si128(); | |
// t = seed >> 128 | |
// s = seed & 0xffffffffffffffff | |
_mm256_storeu2_m128i(&t, &s, seed); | |
// t ^= t << 23; | |
t = _mm_xor_si128(t, _mm_bslli_si128(t, 23)); | |
// t ^= t >> 17; | |
t = _mm_xor_si128(t, _mm_bsrli_si128(t, 17)); | |
// t ^= s ^ (t >> 26) | |
t = _mm_xor_si128(t, _mm_xor_si128(s, _mm_bsrli_si128(t, 26))); | |
// seed = (s << 128) | t | |
seed = _mm256_set_m128i(s, t); | |
return _mm_add_epi32(s, t); | |
} | |
// Xor plaintext by 128 bits | |
char *xor_shit(char *plaintext) | |
{ | |
char *ciphertext = malloc(65); | |
__m128i message; | |
__m128i key; | |
__m128i cipher; | |
// Xor 128 bits | |
for (int c = 0; c < 64; c += 16) | |
{ | |
key = xor_shift_plus_pro(); | |
message = _mm_loadu_si128((const __m128i *)(plaintext + c)); | |
// Xor each 128 bits | |
cipher = _mm_xor_si128(key, message); | |
// Store cipher text | |
_mm_storeu_si128((__m128i *)(ciphertext + c), cipher); | |
} | |
// String terminate NULL | |
ciphertext[64] = 0; | |
return ciphertext; | |
} | |
// Print hex string to console | |
void printHex(char *str) | |
{ | |
size_t l = strlen(str); | |
for (int i = 0; i < l; i++) | |
{ | |
printf("%x", (unsigned char)(str[i] & 0xff)); | |
} | |
printf("\n"); | |
} | |
// Build: clang main.c -mavx -o main && ./main | |
int main() | |
{ | |
// Seed with example key | |
seed = _mm256_set_epi32(0xee4877a9, | |
0x5010c9c1, | |
0xaa807d3c, | |
0x354f178a, | |
0x980a7ce2, | |
0xbd66205a, | |
0xdcb4218a, | |
0x28ba8b49); | |
// 64 bytes of plaintext | |
char *plaintext = "Lorem ipsum dolor sit amet, consectetur adipiscing elit gravida."; | |
char *ciphertext = xor_shit(plaintext); | |
printf("plaintext:\t%s\n", plaintext); | |
// Print ciphertext | |
printf("ciphertext:\t"); | |
printHex(ciphertext); | |
// Reset seed with the same key | |
seed = _mm256_set_epi32(0xee4877a9, | |
0x5010c9c1, | |
0xaa807d3c, | |
0x354f178a, | |
0x980a7ce2, | |
0xbd66205a, | |
0xdcb4218a, | |
0x28ba8b49); | |
char *deciphertext = xor_shit(ciphertext); | |
printf("Deciphertext:\t%s\n", deciphertext); | |
// Free result | |
free(deciphertext); | |
free(ciphertext); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment