summaryrefslogtreecommitdiffstats
path: root/src/libsec/port/rsafill.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-03-21 14:04:56 +0000
committerrsc <devnull@localhost>2004-03-21 14:04:56 +0000
commit0fc65b37a1e7585ca2347bf61dcb8bc3a6b146a4 (patch)
treedd9189a823998f494082adb769451f12be056566 /src/libsec/port/rsafill.c
parent768206abfcf505fb034a0151bf263bc0b1f2380c (diff)
downloadplan9port-0fc65b37a1e7585ca2347bf61dcb8bc3a6b146a4.tar.gz
plan9port-0fc65b37a1e7585ca2347bf61dcb8bc3a6b146a4.zip
Add most of libsec.
Diffstat (limited to 'src/libsec/port/rsafill.c')
-rw-r--r--src/libsec/port/rsafill.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/libsec/port/rsafill.c b/src/libsec/port/rsafill.c
new file mode 100644
index 00000000..f514b073
--- /dev/null
+++ b/src/libsec/port/rsafill.c
@@ -0,0 +1,61 @@
+#include "os.h"
+#include <mp.h>
+#include <libsec.h>
+
+RSApriv*
+rsafill(mpint *n, mpint *e, mpint *d, mpint *p, mpint *q)
+{
+ mpint *c2, *kq, *kp, *x;
+ RSApriv *rsa;
+
+ // make sure we're not being hoodwinked
+ if(!probably_prime(p, 10) || !probably_prime(q, 10)){
+ werrstr("rsafill: p or q not prime");
+ return nil;
+ }
+ x = mpnew(0);
+ mpmul(p, q, x);
+ if(mpcmp(n, x) != 0){
+ werrstr("rsafill: n != p*q");
+ mpfree(x);
+ return nil;
+ }
+ c2 = mpnew(0);
+ mpsub(p, mpone, c2);
+ mpsub(q, mpone, x);
+ mpmul(c2, x, x);
+ mpmul(e, d, c2);
+ mpmod(c2, x, x);
+ if(mpcmp(x, mpone) != 0){
+ werrstr("rsafill: e*d != 1 mod (p-1)*(q-1)");
+ mpfree(x);
+ mpfree(c2);
+ return nil;
+ }
+
+ // compute chinese remainder coefficient
+ mpinvert(p, q, c2);
+
+ // for crt a**k mod p == (a**(k mod p-1)) mod p
+ kq = mpnew(0);
+ kp = mpnew(0);
+ mpsub(p, mpone, x);
+ mpmod(d, x, kp);
+ mpsub(q, mpone, x);
+ mpmod(d, x, kq);
+
+ rsa = rsaprivalloc();
+ rsa->pub.ek = mpcopy(e);
+ rsa->pub.n = mpcopy(n);
+ rsa->dk = mpcopy(d);
+ rsa->kp = kp;
+ rsa->kq = kq;
+ rsa->p = mpcopy(p);
+ rsa->q = mpcopy(q);
+ rsa->c2 = c2;
+
+ mpfree(x);
+
+ return rsa;
+}
+