root/trunk/etc/bigint/modexp.d

Revision 13, 4.1 kB (checked in by Arcane Jill, 5 years ago)

--

Line 
1 module etc.bigint.modexp;
2 import etc.bigint.bigint_int;
3 import etc.bigint.modinv;
4
5 /*
6
7 Copyright (c) 2004, Arcane Jill
8
9 All rights reserved. Intellectual Property Me Arse!
10
11 Redistribution and use in source and binary forms, with or without modification, are permitted
12 provided that the following conditions are met:
13
14    * Redistributions of source code must retain the above copyright notice, the phrase
15      "Intellectual Property Me Arse!", this list of conditions, and the following disclaimer.
16    * Redistributions in binary form must reproduce the above copyright notice, the phrase
17      "Intellectual Property Me Arse!", this list of conditions and the following disclaimer
18      in the documentation and/or other materials provided with the distribution.
19    * The name Arcane Jill may not be used to endorse or promote products derived from this
20      software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
23 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER,
25 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED, AND ON ANY
28 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
30 OF SUCH DAMAGE.
31
32 */
33
34 /*  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
35     d = (x * y) % m
36 */
37
38 Int modMul(Int x, Int y, Int m)
39 {
40     return (x * y) % m;
41 }
42
43 /*  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
44     d = x ^ y
45 */
46
47 private
48 {
49     class ClassicMul : FMul
50     {
51         Int opCall(Int x, Int y)
52         {
53             return x * y;
54         }
55     }
56 }
57
58 Int pow(Int x, Int y)
59 {
60     ClassicMul f = new ClassicMul;
61     return x.powGen(y, Int.ONE, f);
62 }
63
64 /*  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
65     d = (x ^ y) % m
66 */
67
68 private
69 {
70     class ClassicModMul : FMul
71     {
72         this(Int m)
73         {
74             p = m;
75         }
76
77         Int opCall(Int x, Int y)
78         {
79             return (x * y) % p;
80         }
81
82         Int p;
83     }
84
85     class Barrett : FMul
86     {
87         this(Int m)
88         {
89             p = m;
90             k = p.end;
91             mu = shlWhole(1,k+k) / p;
92         }
93
94         Int opCall(Int x, Int y)
95         {
96             Int z = x * y;
97             Int q = shrWhole(z, k-1);
98             q = q * mu;
99             q = shrWhole(q, k+1);
100             Int r = lowWhole(z, k+1);
101             r = r - lowWhole(q*p, k+1);
102             if (r < 0)
103             {
104                 r = r + shlWhole(1,k+1);
105             }
106             while (r >= p)
107             {
108                 r = r - p;
109             }
110             return r;
111         }
112
113         uint k;
114         Int mu;
115         Int p;
116     }
117
118     class Montgomery : FMul
119     {
120         this(Int p)
121         in
122         {
123             assert((p & 1u) == 1u);
124         }
125         body
126         {
127             rEnd_ = p.end;
128             p_ = p;
129             R_ = shlWhole(1,rEnd_);
130             p1_ = modInv(p, R_);
131             if (p1_ != 0) p1_ = R_ - p1_;
132         }
133
134         Int opCall(Int x)
135         {
136             Int c = shrWhole(x + lowWhole(x * p1, rEnd) * p, rEnd);
137             if (c >= p) c = c - p;
138             return c;
139         }
140
141         Int opCall(Int x, Int y)
142         {
143             return opCall(x * y);
144         }
145
146         uint rEnd() { return rEnd_; }
147         Int R() { return R_; }
148         Int p() { return p_; }
149         Int p1() { return p1_; }
150
151         private
152         {
153             uint rEnd_;
154             Int R_;
155             Int p_;
156             Int p1_;
157         }
158     }
159 }
160
161 Int modPow(Int x, Int e, Int p)
162 in
163 {
164     assert(e > 0);
165     assert(p > 0);
166 }
167 body
168 {
169     if ((x.sign!=0) || (x > p))
170     {
171         x = x % p; // Get x in range
172     }
173
174     version(DisableMontgomery)
175     {
176         // If the Montgomery algorithm is disabled, don't do it.
177     }
178     else
179     {
180         if (((p & 1u) == 1u))
181         {
182             Montgomery f = new Montgomery(p);
183             Int x1 = shlWhole(x, f.rEnd) % p;
184             Int A = f.R % p;
185             A = x1.powGen(e, A, f);
186             return f(A);
187         }
188     }
189
190     version(DisableBarrett)
191     {
192         ClassicModMul f = new ClassicModMul(p);
193         return x.powGen(e, Int.ONE, f);
194     }
195     else
196     {
197         Barrett f = new Barrett(p);
198         return x.powGen(e, Int.ONE, f);
199     }
200
201 }
Note: See TracBrowser for help on using the browser.