Skip to content

Instantly share code, notes, and snippets.

@wanderer
Created October 21, 2017 01:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wanderer/eff4fc592a621e65105a467d22c57bfc to your computer and use it in GitHub Desktop.
Save wanderer/eff4fc592a621e65105a467d22c57bfc to your computer and use it in GitHub Desktop.
// https://people.csail.mit.edu/rivest/Rivest-rc5rev.pdf
#include <stdio.h>
#include <stdint.h>
uint32_t shift_left(uint32_t v, uint32_t n) {
return v << n;
}
uint32_t shift_right(uint32_t v, uint32_t n) {
return v >> n;
}
uint32_t rotate_left(uint32_t v, uint32_t n) {
n &= 0x1f;
return shift_left(v, n) | shift_right(v, 32 - n);
}
uint32_t rotate_right(uint32_t v, uint32_t n) {
n &= 0x1f;
return shift_right(v, n) | shift_left(v, 32 - n);
}
void encrypt(uint32_t S[26], uint32_t inout[4]) {
for (uint32_t i = 0; i < 4; i += 2) {
uint32_t A = inout[i];
uint32_t B = inout[i+1];
A += S[0];
B += S[1];
for (int j = 0; j < 12; ++j) {
A = rotate_left((A ^ B), B) + S[2 * i];
B = rotate_left((B ^ A), A) + S[2 * i + 1];
}
inout[i] = A;
inout[i+1] = B;
}
}
void decrypt(uint32_t S[26], uint32_t inout[4]) {
for (uint32_t i = 0; i < 4; i += 2) {
uint32_t A = inout[i];
uint32_t B = inout[i+1];
for (int j = 12; j > 0; --j) {
B = rotate_right(B - S[2 * i + 1], A) ^ A;
A = rotate_right(A - S[2 * i], B) ^ B;
}
B -= S[1];
A -= S[0];
inout[i] = A;
inout[i+1] = B;
}
}
// expand key into S array using magic numbers derived from e and phi
void expand(uint32_t L[4], uint32_t S[26]) {
uint32_t A = 0;
uint32_t B = 0;
uint32_t i = 0;
uint32_t j = 0;
S[0] = 0xb7e15163;
for (i = 1; i < 26; ++i)
S[i] = S[i - 1] + 0x9e3779b9;
i = j = 0;
int n = 3*26;
while (n-- > 0) {
A = S[i] = rotate_left((S[i] + A + B), 3);
B = L[j] = rotate_left((L[j] + A + B), A + B);
i = ++i % 26;
j = ++j % 4;
}
}
uint32_t save[4];
// decrypt of encrypt should be the same
int test(uint32_t S[26], uint32_t messg[4]) {
memcpy(save, messg, sizeof save);
encrypt(S, messg);
decrypt(S, messg);
for (int i = 0; i < 4; ++i) {
if (messg[i] != save[i]) {
printf("fail");
return 0;
}
}
return 1;
}
uint32_t key[4] = { 0x243F6A88, 0x85A308D3, 0x452821E6, 0x38D01377 };
uint32_t box[26];
uint32_t message[4] = { 0xfeedface, 0xdeadbeef, 0xfeedbabe, 0xcafebeef };
int main() {
expand(key, box);
for (int i = 0; i < 43690; ++i)
test(box, message);
return message[0];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment