summaryrefslogtreecommitdiff
path: root/libsec/port/dsasign.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 /libsec/port/dsasign.c
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'libsec/port/dsasign.c')
-rw-r--r--libsec/port/dsasign.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/libsec/port/dsasign.c b/libsec/port/dsasign.c
new file mode 100644
index 00000000..137134be
--- /dev/null
+++ b/libsec/port/dsasign.c
@@ -0,0 +1,52 @@
+#include "os.h"
+#include <mp.h>
+#include <libsec.h>
+
+DSAsig*
+dsasign(DSApriv *priv, mpint *m)
+{
+ DSApub *pub = &priv->pub;
+ DSAsig *sig;
+ mpint *qm1, *k, *kinv, *r, *s;
+ mpint *q = pub->q, *p = pub->p, *alpha = pub->alpha;
+ int qlen = mpsignif(q);
+
+ qm1 = mpnew(0);
+ kinv = mpnew(0);
+ r = mpnew(0);
+ s = mpnew(0);
+ k = mpnew(0);
+ mpsub(pub->q, mpone, qm1);
+
+ // find a k that has an inverse mod q
+ while(1){
+ mprand(qlen, genrandom, k);
+ if((mpcmp(mpone, k) > 0) || (mpcmp(k, pub->q) >= 0))
+ continue;
+ mpextendedgcd(k, q, r, kinv, s);
+ if(mpcmp(r, mpone) != 0)
+ sysfatal("dsasign: pub->q not prime");
+ break;
+ }
+
+ // make kinv positive
+ mpmod(kinv, pub->q, kinv);
+
+ // r = ((alpha**k) mod p) mod q
+ mpexp(alpha, k, p, r);
+ mpmod(r, q, r);
+
+ // s = (kinv*(m + ar)) mod q
+ mpmul(r, priv->secret, s);
+ mpadd(s, m, s);
+ mpmul(s, kinv, s);
+ mpmod(s, q, s);
+
+ sig = dsasigalloc();
+ sig->r = r;
+ sig->s = s;
+ mpfree(qm1);
+ mpfree(k);
+ mpfree(kinv);
+ return sig;
+}