Skip to content

Instantly share code, notes, and snippets.

@cloudwu
Last active June 19, 2022 15:38
Show Gist options
  • Star 20 You must be signed in to star a gist
  • Fork 12 You must be signed in to fork a gist
  • Save cloudwu/8838724 to your computer and use it in GitHub Desktop.
Save cloudwu/8838724 to your computer and use it in GitHub Desktop.
Diffie-Hellman Key Exchange
// The biggest 64bit prime
#define P 0xffffffffffffffc5ull
#define G 5
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <stdlib.h>
// calc a * b % p , avoid 64bit overflow
static inline uint64_t
mul_mod_p(uint64_t a, uint64_t b) {
uint64_t m = 0;
while(b) {
if(b&1) {
uint64_t t = P-a;
if ( m >= t) {
m -= t;
} else {
m += a;
}
}
if (a >= P - a) {
a = a * 2 - P;
} else {
a = a * 2;
}
b>>=1;
}
return m;
}
static inline uint64_t
pow_mod_p(uint64_t a, uint64_t b) {
if (b==1) {
return a;
}
uint64_t t = pow_mod_p(a, b>>1);
t = mul_mod_p(t,t);
if (b % 2) {
t = mul_mod_p(t, a);
}
return t;
}
// calc a^b % p
uint64_t
powmodp(uint64_t a, uint64_t b) {
if (a > P)
a%=P;
return pow_mod_p(a,b);
}
uint64_t
randomint64() {
uint64_t a = rand();
uint64_t b = rand();
uint64_t c = rand();
uint64_t d = rand();
return a << 48 | b << 32 | c << 16 | d;
}
static void
test() {
uint64_t a = randomint64();
uint64_t b = randomint64();
uint64_t A = powmodp(G, a);
uint64_t B = powmodp(G, b);
uint64_t secret1 = powmodp(B,a);
uint64_t secret2 = powmodp(A,b);
assert(secret1 == secret2);
printf("a=%I64x b=%I64x s=%I64x\n", a,b,secret1);
}
int
main() {
int i;
for (i=0;i<100;i++) {
test();
}
return 0;
}
@elvishew
Copy link

elvishew commented Feb 6, 2014

test

@princegoyal1987
Copy link

Just asking, I am including this code in our production servers. Did you find any obvious problems in it? (any inconsistencies with different architectures or something?)

BTW we don't need very high encryption, just the basic one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment