ref: 6c68876db6d25b8c646295fecc75a6363d0bdc75
parent: 4cf00ca6cb40918c8ca89aebf02e8ca41c857e94
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Sep 13 22:29:18 EDT 2014
libsec: add diffie-hellman functions
--- a/sys/include/libsec.h
+++ b/sys/include/libsec.h
@@ -439,3 +439,22 @@
int base58dec(char *, uchar *, int);
DigestState* ripemd160(uchar *, ulong, uchar *, DigestState *);
+
+/*
+ * Diffie-Hellman key exchange
+ */
+
+typedef struct DHstate DHstate;
+struct DHstate
+{
+ mpint *g; /* base g */
+ mpint *p; /* large prime */
+ mpint *x; /* random secret */
+ mpint *y; /* public key y = g ^ x % p */
+};
+
+/* generate new public key: y = g ^ x % p */
+mpint* dh_new(DHstate *dh, mpint *p, mpint *g);
+
+/* calculate shared key: k = pub ^ x % p */
+mpint* dh_finish(DHstate *dh, mpint *pub);
--- /dev/null
+++ b/sys/src/libsec/port/dh.c
@@ -1,0 +1,40 @@
+#include "os.h"
+#include <mp.h>
+#include <libsec.h>
+
+mpint*
+dh_new(DHstate *dh, mpint *p, mpint *g)
+{
+ memset(dh, 0, sizeof(*dh));
+ dh->g = mpcopy(g);
+ dh->p = mpcopy(p);
+ if(dh->g != nil && dh->p != nil){
+ dh->x = mprand(mpsignif(dh->p), genrandom, nil);
+ dh->y = mpnew(0);
+ if(dh->x != nil && dh->y != nil){
+ mpexp(dh->g, dh->x, dh->p, dh->y);
+ return dh->y;
+ }
+ }
+ dh_finish(dh, nil);
+ return nil;
+}
+
+mpint*
+dh_finish(DHstate *dh, mpint *pub)
+{
+ mpint *k;
+
+ k = nil;
+ if(pub != nil && dh->x != nil && dh->p != nil){
+ if((k = mpnew(0)) != nil)
+ mpexp(pub, dh->x, dh->p, k);
+ }
+ mpfree(dh->g);
+ mpfree(dh->p);
+ mpfree(dh->x);
+ mpfree(dh->y);
+ memset(dh, 0, sizeof(*dh));
+ return k;
+}
+
--- a/sys/src/libsec/port/mkfile
+++ b/sys/src/libsec/port/mkfile
@@ -20,6 +20,7 @@
aes_xts.c \
ecc.c\
ripemd.c\
+ dh.c\
ALLOFILES=${CFILES:%.c=%.$O}