shithub: riscv

Download patch

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}