Blob


1 #include "os.h"
2 #include <mp.h>
4 // chinese remainder theorem
5 //
6 // handbook of applied cryptography, menezes et al, 1997, pp 610 - 613
8 struct CRTpre
9 {
10 int n; // number of moduli
11 mpint **m; // pointer to moduli
12 mpint **c; // precomputed coefficients
13 mpint **p; // precomputed products
14 mpint *a[1]; // local storage
15 };
17 // setup crt info, returns a newly created structure
18 CRTpre*
19 crtpre(int n, mpint **m)
20 {
21 CRTpre *crt;
22 int i, j;
23 mpint *u;
25 crt = malloc(sizeof(CRTpre)+sizeof(mpint)*3*n);
26 if(crt == nil)
27 sysfatal("crtpre: %r");
28 crt->m = crt->a;
29 crt->c = crt->a+n;
30 crt->p = crt->c+n;
31 crt->n = n;
33 // make a copy of the moduli
34 for(i = 0; i < n; i++)
35 crt->m[i] = mpcopy(m[i]);
37 // precompute the products
38 u = mpcopy(mpone);
39 for(i = 0; i < n; i++){
40 mpmul(u, m[i], u);
41 crt->p[i] = mpcopy(u);
42 }
44 // precompute the coefficients
45 for(i = 1; i < n; i++){
46 crt->c[i] = mpcopy(mpone);
47 for(j = 0; j < i; j++){
48 mpinvert(m[j], m[i], u);
49 mpmul(u, crt->c[i], u);
50 mpmod(u, m[i], crt->c[i]);
51 }
52 }
54 mpfree(u);
56 return crt;
57 }
59 void
60 crtprefree(CRTpre *crt)
61 {
62 int i;
64 for(i = 0; i < crt->n; i++){
65 if(i != 0)
66 mpfree(crt->c[i]);
67 mpfree(crt->p[i]);
68 mpfree(crt->m[i]);
69 }
70 free(crt);
71 }
73 // convert to residues, returns a newly created structure
74 CRTres*
75 crtin(CRTpre *crt, mpint *x)
76 {
77 int i;
78 CRTres *res;
80 res = malloc(sizeof(CRTres)+sizeof(mpint)*crt->n);
81 if(res == nil)
82 sysfatal("crtin: %r");
83 res->n = crt->n;
84 for(i = 0; i < res->n; i++){
85 res->r[i] = mpnew(0);
86 mpmod(x, crt->m[i], res->r[i]);
87 }
88 return res;
89 }
91 // garners algorithm for converting residue form to linear
92 void
93 crtout(CRTpre *crt, CRTres *res, mpint *x)
94 {
95 mpint *u;
96 int i;
98 u = mpnew(0);
99 mpassign(res->r[0], x);
101 for(i = 1; i < crt->n; i++){
102 mpsub(res->r[i], x, u);
103 mpmul(u, crt->c[i], u);
104 mpmod(u, crt->m[i], u);
105 mpmul(u, crt->p[i-1], u);
106 mpadd(x, u, x);
109 mpfree(u);
112 // free the residue
113 void
114 crtresfree(CRTres *res)
116 int i;
118 for(i = 0; i < res->n; i++)
119 mpfree(res->r[i]);
120 free(res);