ref: a920c765f2b4130590fb5971a50690b21664957a
dir: /libkeyring/egalg.c/
#include <lib9.h> #include <kernel.h> #include <isa.h> #include "interp.h" #include "../libinterp/keyringif.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; if(eg->pub.p == nil || eg->pub.alpha == nil || eg->pub.key == nil || eg->secret == nil){ egprivfree(eg); return nil; } 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; if(eg->p == nil || eg->alpha == nil || eg->key == nil){ egpubfree(eg); return nil; } 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; if(eg->r == nil || eg->s == nil){ egsigfree(eg); return nil; } 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(mpint* mp, void *key) { return egsign((EGpriv*)key, mp); } static int eg_verify(mpint* 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; }