diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/unix/drawterm/libmp/crt.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/unix/drawterm/libmp/crt.c')
-rwxr-xr-x | sys/src/cmd/unix/drawterm/libmp/crt.c | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/sys/src/cmd/unix/drawterm/libmp/crt.c b/sys/src/cmd/unix/drawterm/libmp/crt.c new file mode 100755 index 000000000..ddf26ed57 --- /dev/null +++ b/sys/src/cmd/unix/drawterm/libmp/crt.c @@ -0,0 +1,122 @@ +#include "os.h" +#include <mp.h> +#include <libsec.h> + +// chinese remainder theorem +// +// handbook of applied cryptography, menezes et al, 1997, pp 610 - 613 + +struct CRTpre +{ + int n; // number of moduli + mpint **m; // pointer to moduli + mpint **c; // precomputed coefficients + mpint **p; // precomputed products + mpint *a[1]; // local storage +}; + +// setup crt info, returns a newly created structure +CRTpre* +crtpre(int n, mpint **m) +{ + CRTpre *crt; + int i, j; + mpint *u; + + crt = malloc(sizeof(CRTpre)+sizeof(mpint)*3*n); + if(crt == nil) + sysfatal("crtpre: %r"); + crt->m = crt->a; + crt->c = crt->a+n; + crt->p = crt->c+n; + crt->n = n; + + // make a copy of the moduli + for(i = 0; i < n; i++) + crt->m[i] = mpcopy(m[i]); + + // precompute the products + u = mpcopy(mpone); + for(i = 0; i < n; i++){ + mpmul(u, m[i], u); + crt->p[i] = mpcopy(u); + } + + // precompute the coefficients + for(i = 1; i < n; i++){ + crt->c[i] = mpcopy(mpone); + for(j = 0; j < i; j++){ + mpinvert(m[j], m[i], u); + mpmul(u, crt->c[i], u); + mpmod(u, m[i], crt->c[i]); + } + } + + mpfree(u); + + return crt; +} + +void +crtprefree(CRTpre *crt) +{ + int i; + + for(i = 0; i < crt->n; i++){ + if(i != 0) + mpfree(crt->c[i]); + mpfree(crt->p[i]); + mpfree(crt->m[i]); + } + free(crt); +} + +// convert to residues, returns a newly created structure +CRTres* +crtin(CRTpre *crt, mpint *x) +{ + int i; + CRTres *res; + + res = malloc(sizeof(CRTres)+sizeof(mpint)*crt->n); + if(res == nil) + sysfatal("crtin: %r"); + res->n = crt->n; + for(i = 0; i < res->n; i++){ + res->r[i] = mpnew(0); + mpmod(x, crt->m[i], res->r[i]); + } + return res; +} + +// garners algorithm for converting residue form to linear +void +crtout(CRTpre *crt, CRTres *res, mpint *x) +{ + mpint *u; + int i; + + u = mpnew(0); + mpassign(res->r[0], x); + + for(i = 1; i < crt->n; i++){ + mpsub(res->r[i], x, u); + mpmul(u, crt->c[i], u); + mpmod(u, crt->m[i], u); + mpmul(u, crt->p[i-1], u); + mpadd(x, u, x); + } + + mpfree(u); +} + +// free the residue +void +crtresfree(CRTres *res) +{ + int i; + + for(i = 0; i < res->n; i++) + mpfree(res->r[i]); + free(res); +} |