Skip to content

Instantly share code, notes, and snippets.

@DavidBuchanan314
Last active January 28, 2019 16:14
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 DavidBuchanan314/51c51208ebd02d441c7e35fbc206023c to your computer and use it in GitHub Desktop.
Save DavidBuchanan314/51c51208ebd02d441c7e35fbc206023c to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdint.h>
#define ADD_LOBIT(a, b, c) ((a)^(b)^(c))
#define ADD_CARRY(a, b, c) ((a&b)|(b&c)|(c&a))
#define ADD_ROUND(i) \
c|=ADD_LOBIT((a>>(i))&1,(b>>(i))&1,carry)<<(i); \
carry=ADD_CARRY((a>>(i))&1,(b>>(i))&1,carry);
#define MUL_ROUND(i) \
c <<= 1; \
if ((b<<(i))&(1L<<63)) c = add(c, a);
#define LOOP2(c,i) c(i) c(i|1)
#define LOOP4(c,i) LOOP2(c,i) LOOP2(c,i|2)
#define LOOP8(c,i) LOOP4(c,i) LOOP4(c,i|4)
#define LOOP16(c,i) LOOP8(c,i) LOOP8(c,i|8)
#define LOOP32(c,i) LOOP16(c,i) LOOP16(c,i|16)
#define LOOP64(c,i) LOOP32(c,i) LOOP32(c,i|32)
uint64_t add(uint64_t a, uint64_t b) {
uint64_t c = 0, carry = 0;
LOOP64(ADD_ROUND, 0);
return c;
}
uint64_t mul(uint64_t a, uint64_t b) {
uint64_t c = 0;
LOOP64(MUL_ROUND, 0);
return c;
}
int main() {
uint64_t a = 0xdeadbeef1337;
uint64_t b = 0xbadf00d31337;
printf("0x%lx + 0x%lx => 0x%lx\n", a, b, add(a, b));
printf("0x%lx * 0x%lx => 0x%lx\n", a, b, mul(a, b));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment