summaryrefslogtreecommitdiff
path: root/libkeyring/egalg.c
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
commit37da2899f40661e3e9631e497da8dc59b971cbd0 (patch)
treecbc6d4680e347d906f5fa7fca73214418741df72 /libkeyring/egalg.c
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'libkeyring/egalg.c')
-rw-r--r--libkeyring/egalg.c212
1 files changed, 212 insertions, 0 deletions
diff --git a/libkeyring/egalg.c b/libkeyring/egalg.c
new file mode 100644
index 00000000..98567c95
--- /dev/null
+++ b/libkeyring/egalg.c
@@ -0,0 +1,212 @@
+#include <lib9.h>
+#include <kernel.h>
+#include <isa.h>
+#include "interp.h"
+#include "../libinterp/runt.h"
+#include "mp.h"
+#include "libsec.h"
+#include "keys.h"
+
+static char* pkattr[] = { "p", "alpha", "key", nil };
+static char* skattr[] = { "p", "alpha", "key", "!secret", nil };
+static char* sigattr[] = { "r", "s", nil };
+
+static void*
+eg_str2sk(char *str, char **strp)
+{
+ EGpriv *eg;
+ char *p;
+
+ eg = egprivalloc();
+ eg->pub.p = base64tobig(str, &p);
+ eg->pub.alpha = base64tobig(p, &p);
+ eg->pub.key = base64tobig(p, &p);
+ eg->secret = base64tobig(p, &p);
+ if(strp)
+ *strp = p;
+ return eg;
+}
+
+static void*
+eg_str2pk(char *str, char **strp)
+{
+ EGpub *eg;
+ char *p;
+
+ eg = egpuballoc();
+ eg->p = base64tobig(str, &p);
+ eg->alpha = base64tobig(p, &p);
+ eg->key = base64tobig(p, &p);
+ if(strp)
+ *strp = p;
+ return eg;
+}
+
+static void*
+eg_str2sig(char *str, char **strp)
+{
+ EGsig *eg;
+ char *p;
+
+ eg = egsigalloc();
+ eg->r = base64tobig(str, &p);
+ eg->s = base64tobig(p, &p);
+ if(strp)
+ *strp = p;
+ return eg;
+}
+
+static int
+eg_sk2str(void *veg, char *buf, int len)
+{
+ EGpriv *eg;
+ char *cp, *ep;
+
+ eg = (EGpriv*)veg;
+ ep = buf + len - 1;
+ cp = buf;
+
+ cp += snprint(cp, ep - cp, "%U\n", eg->pub.p);
+ cp += snprint(cp, ep - cp, "%U\n", eg->pub.alpha);
+ cp += snprint(cp, ep - cp, "%U\n", eg->pub.key);
+ cp += snprint(cp, ep - cp, "%U\n", eg->secret);
+ *cp = 0;
+
+ return cp - buf;
+}
+
+static int
+eg_pk2str(void *veg, char *buf, int len)
+{
+ EGpub *eg;
+ char *cp, *ep;
+
+ eg = (EGpub*)veg;
+ ep = buf + len - 1;
+ cp = buf;
+
+ cp += snprint(cp, ep - cp, "%U\n", eg->p);
+ cp += snprint(cp, ep - cp, "%U\n", eg->alpha);
+ cp += snprint(cp, ep - cp, "%U\n", eg->key);
+ *cp = 0;
+
+ return cp - buf;
+}
+
+static int
+eg_sig2str(void *veg, char *buf, int len)
+{
+ EGsig *eg;
+ char *cp, *ep;
+
+ eg = veg;
+ ep = buf + len - 1;
+ cp = buf;
+
+ cp += snprint(cp, ep - cp, "%U\n", eg->r);
+ cp += snprint(cp, ep - cp, "%U\n", eg->s);
+ *cp = 0;
+
+ return cp - buf;
+}
+
+static void*
+eg_sk2pk(void *vs)
+{
+ return egprivtopub((EGpriv*)vs);
+}
+
+/* generate an el gamal secret key with new params */
+static void*
+eg_gen(int len)
+{
+ return eggen(len, 0);
+}
+
+/* generate an el gamal secret key with same params as a public key */
+static void*
+eg_genfrompk(void *vpub)
+{
+ EGpub *pub;
+ EGpriv *priv;
+ int nlen;
+
+ pub = vpub;
+ priv = egprivalloc();
+ priv->pub.p = mpcopy(pub->p);
+ priv->pub.alpha = mpcopy(pub->alpha);
+ nlen = mpsignif(pub->p);
+ pub = &priv->pub;
+ pub->key = mpnew(0);
+ priv->secret = mpnew(0);
+ mprand(nlen-1, genrandom, priv->secret);
+ mpexp(pub->alpha, priv->secret, pub->p, pub->key);
+ return priv;
+}
+
+static void*
+eg_sign(BigInt mp, void *key)
+{
+ return egsign((EGpriv*)key, mp);
+}
+
+static int
+eg_verify(BigInt mp, void *sig, void *key)
+{
+ return egverify((EGpub*)key, (EGsig*)sig, mp) == 0;
+}
+
+static void
+eg_freepub(void *a)
+{
+ egpubfree((EGpub*)a);
+}
+
+static void
+eg_freepriv(void *a)
+{
+ egprivfree((EGpriv*)a);
+}
+
+static void
+eg_freesig(void *a)
+{
+ egsigfree((EGsig*)a);
+}
+
+SigAlgVec*
+elgamalinit(void)
+{
+ SigAlgVec *vec;
+
+ vec = malloc(sizeof(SigAlgVec));
+ if(vec == nil)
+ return nil;
+
+ vec->name = "elgamal";
+
+ vec->pkattr = pkattr;
+ vec->skattr = skattr;
+ vec->sigattr = sigattr;
+
+ vec->str2sk = eg_str2sk;
+ vec->str2pk = eg_str2pk;
+ vec->str2sig = eg_str2sig;
+
+ vec->sk2str = eg_sk2str;
+ vec->pk2str = eg_pk2str;
+ vec->sig2str = eg_sig2str;
+
+ vec->sk2pk = eg_sk2pk;
+
+ vec->gensk = eg_gen;
+ vec->genskfrompk = eg_genfrompk;
+ vec->sign = eg_sign;
+ vec->verify = eg_verify;
+
+ vec->skfree = eg_freepriv;
+ vec->pkfree = eg_freepub;
+ vec->sigfree = eg_freesig;
+
+ return vec;
+}