Diffstat (limited to 'frontend/gamma/js/Clipperz/Crypto/BigInt.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/gamma/js/Clipperz/Crypto/BigInt.js | 1760 |
1 files changed, 1760 insertions, 0 deletions
diff --git a/frontend/gamma/js/Clipperz/Crypto/BigInt.js b/frontend/gamma/js/Clipperz/Crypto/BigInt.js new file mode 100644 index 0000000..d4d05d2 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/Crypto/BigInt.js | |||
@@ -0,0 +1,1760 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2011 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz's Javascript Crypto Library. | ||
6 | Javascript Crypto Library provides web developers with an extensive | ||
7 | and efficient set of cryptographic functions. The library aims to | ||
8 | obtain maximum execution speed while preserving modularity and | ||
9 | reusability. | ||
10 | For further information about its features and functionalities please | ||
11 | refer to http://www.clipperz.com | ||
12 | |||
13 | * Javascript Crypto Library is free software: you can redistribute | ||
14 | it and/or modify it under the terms of the GNU Affero General Public | ||
15 | License as published by the Free Software Foundation, either version | ||
16 | 3 of the License, or (at your option) any later version. | ||
17 | |||
18 | * Javascript Crypto Library is distributed in the hope that it will | ||
19 | be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
20 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
21 | See the GNU Affero General Public License for more details. | ||
22 | |||
23 | * You should have received a copy of the GNU Affero General Public | ||
24 | License along with Javascript Crypto Library. If not, see | ||
25 | <http://www.gnu.org/licenses/>. | ||
26 | |||
27 | */ | ||
28 | |||
29 | if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } | ||
30 | if (typeof(Clipperz.Crypto) == 'undefined') { Clipperz.Crypto = {}; } | ||
31 | |||
32 | //############################################################################# | ||
33 | //Downloaded on March 05, 2007 from http://www.leemon.com/crypto/BigInt.js | ||
34 | //############################################################################# | ||
35 | |||
36 | |||
37 | //////////////////////////////////////////////////////////////////////////////////////// | ||
38 | // Big Integer Library v. 5.0 | ||
39 | // Created 2000, last modified 2006 | ||
40 | // Leemon Baird | ||
41 | // www.leemon.com | ||
42 | // | ||
43 | // This file is public domain. You can use it for any purpose without restriction. | ||
44 | // I do not guarantee that it is correct, so use it at your own risk. If you use | ||
45 | // it for something interesting, I'd appreciate hearing about it. If you find | ||
46 | // any bugs or make any improvements, I'd appreciate hearing about those too. | ||
47 | // It would also be nice if my name and address were left in the comments. | ||
48 | // But none of that is required. | ||
49 | // | ||
50 | // This code defines a bigInt library for arbitrary-precision integers. | ||
51 | // A bigInt is an array of integers storing the value in chunks of bpe bits, | ||
52 | // little endian (buff[0] is the least significant word). | ||
53 | // Negative bigInts are stored two's complement. | ||
54 | // Some functions assume their parameters have at least one leading zero element. | ||
55 | // Functions with an underscore at the end of the name have unpredictable behavior in case of overflow, | ||
56 | // so the caller must make sure overflow won't happen. | ||
57 | // For each function where a parameter is modified, that same | ||
58 | // variable must not be used as another argument too. | ||
59 | // So, you cannot square x by doing multMod_(x,x,n). | ||
60 | // You must use squareMod_(x,n) instead, or do y=dup(x); multMod_(x,y,n). | ||
61 | // | ||
62 | // These functions are designed to avoid frequent dynamic memory allocation in the inner loop. | ||
63 | // For most functions, if it needs a BigInt as a local variable it will actually use | ||
64 | // a global, and will only allocate to it when it's not the right size. This ensures | ||
65 | // that when a function is called repeatedly with same-sized parameters, it only allocates | ||
66 | // memory on the first call. | ||
67 | // | ||
68 | // Note that for cryptographic purposes, the calls to Math.random() must | ||
69 | // be replaced with calls to a better pseudorandom number generator. | ||
70 | // | ||
71 | // In the following, "bigInt" means a bigInt with at least one leading zero element, | ||
72 | // and "integer" means a nonnegative integer less than radix. In some cases, integer | ||
73 | // can be negative. Negative bigInts are 2s complement. | ||
74 | // | ||
75 | // The following functions do not modify their inputs, but dynamically allocate memory every time they are called: | ||
76 | // | ||
77 | // function bigInt2str(x,base) //convert a bigInt into a string in a given base, from base 2 up to base 95 | ||
78 | // function dup(x) //returns a copy of bigInt x | ||
79 | // function findPrimes(n) //return array of all primes less than integer n | ||
80 | // function int2bigInt(t,n,m) //convert integer t to a bigInt with at least n bits and m array elements | ||
81 | // function int2bigInt(s,b,n,m) //convert string s in base b to a bigInt with at least n bits and m array elements | ||
82 | // function trim(x,k) //return a copy of x with exactly k leading zero elements | ||
83 | // | ||
84 | // The following functions do not modify their inputs, so there is never a problem with the result being too big: | ||
85 | // | ||
86 | // function bitSize(x) //returns how many bits long the bigInt x is, not counting leading zeros | ||
87 | // function equals(x,y) //is the bigInt x equal to the bigint y? | ||
88 | // function equalsInt(x,y) //is bigint x equal to integer y? | ||
89 | // function greater(x,y) //is x>y? (x and y are nonnegative bigInts) | ||
90 | // function greaterShift(x,y,shift)//is (x <<(shift*bpe)) > y? | ||
91 | // function isZero(x) //is the bigInt x equal to zero? | ||
92 | // function millerRabin(x,b) //does one round of Miller-Rabin base integer b say that bigInt x is possibly prime (as opposed to definitely composite)? | ||
93 | // function modInt(x,n) //return x mod n for bigInt x and integer n. | ||
94 | // function negative(x) //is bigInt x negative? | ||
95 | // | ||
96 | // The following functions do not modify their inputs, but allocate memory and call functions with underscores | ||
97 | // | ||
98 | // function add(x,y) //return (x+y) for bigInts x and y. | ||
99 | // function addInt(x,n) //return (x+n) where x is a bigInt and n is an integer. | ||
100 | // function expand(x,n) //return a copy of x with at least n elements, adding leading zeros if needed | ||
101 | // function inverseMod(x,n) //return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null | ||
102 | // function mod(x,n) //return a new bigInt equal to (x mod n) for bigInts x and n. | ||
103 | // function mult(x,y) //return x*y for bigInts x and y. This is faster when y<x. | ||
104 | // function multMod(x,y,n) //return (x*y mod n) for bigInts x,y,n. For greater speed, let y<x. | ||
105 | // function powMod(x,y,n) //return (x**y mod n) where x,y,n are bigInts and ** is exponentiation. 0**0=1. Faster for odd n. | ||
106 | // function randTruePrime(k) //return a new, random, k-bit, true prime using Maurer's algorithm. | ||
107 | // function sub(x,y) //return (x-y) for bigInts x and y. Negative answers will be 2s complement | ||
108 | // | ||
109 | // The following functions write a bigInt result to one of the parameters, but | ||
110 | // the result is never bigger than the original, so there can't be overflow problems: | ||
111 | // | ||
112 | // function divInt_(x,n) //do x=floor(x/n) for bigInt x and integer n, and return the remainder | ||
113 | // function GCD_(x,y) //set x to the greatest common divisor of bigInts x and y, (y is destroyed). | ||
114 | // function halve_(x) //do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement | ||
115 | // function mod_(x,n) //do x=x mod n for bigInts x and n. | ||
116 | // function rightShift_(x,n) //right shift bigInt x by n bits. 0 <= n < bpe. | ||
117 | // | ||
118 | // The following functions write a bigInt result to one of the parameters. The caller is responsible for | ||
119 | // ensuring it is large enough to hold the result. | ||
120 | // | ||
121 | // function addInt_(x,n) //do x=x+n where x is a bigInt and n is an integer | ||
122 | // function add_(x,y) //do x=x+y for bigInts x and y | ||
123 | // function addShift_(x,y,ys) //do x=x+(y<<(ys*bpe)) | ||
124 | // function copy_(x,y) //do x=y on bigInts x and y | ||
125 | // function copyInt_(x,n) //do x=n on bigInt x and integer n | ||
126 | // function carry_(x) //do carries and borrows so each element of the bigInt x fits in bpe bits. | ||
127 | // function divide_(x,y,q,r) //divide_ x by y giving quotient q and remainder r | ||
128 | // function eGCD_(x,y,d,a,b) //sets a,b,d to positive big integers such that d = GCD_(x,y) = a*x-b*y | ||
129 | // function inverseMod_(x,n) //do x=x**(-1) mod n, for bigInts x and n. Returns 1 (0) if inverse does (doesn't) exist | ||
130 | // function inverseModInt_(x,n) //return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse | ||
131 | // function leftShift_(x,n) //left shift bigInt x by n bits. n<bpe. | ||
132 | // function linComb_(x,y,a,b) //do x=a*x+b*y for bigInts x and y and integers a and b | ||
133 | // function linCombShift_(x,y,b,ys) //do x=x+b*(y<<(ys*bpe)) for bigInts x and y, and integers b and ys | ||
134 | // function mont_(x,y,n,np) //Montgomery multiplication (see comments where the function is defined) | ||
135 | // function mult_(x,y) //do x=x*y for bigInts x and y. | ||
136 | // function multInt_(x,n) //do x=x*n where x is a bigInt and n is an integer. | ||
137 | // function multMod_(x,y,n) //do x=x*y mod n for bigInts x,y,n. | ||
138 | // function powMod_(x,y,n) //do x=x**y mod n, where x,y,n are bigInts (n is odd) and ** is exponentiation. 0**0=1. | ||
139 | // function randBigInt_(b,n,s) //do b = an n-bit random BigInt. if s=1, then nth bit (most significant bit) is set to 1. n>=1. | ||
140 | // function randTruePrime_(ans,k) //do ans = a random k-bit true random prime (not just probable prime) with 1 in the msb. | ||
141 | // function squareMod_(x,n) //do x=x*x mod n for bigInts x,n | ||
142 | // function sub_(x,y) //do x=x-y for bigInts x and y. Negative answers will be 2s complement. | ||
143 | // function subShift_(x,y,ys) //do x=x-(y<<(ys*bpe)). Negative answers will be 2s complement. | ||
144 | // | ||
145 | // The following functions are based on algorithms from the _Handbook of Applied Cryptography_ | ||
146 | // powMod_() = algorithm 14.94, Montgomery exponentiation | ||
147 | // eGCD_,inverseMod_() = algorithm 14.61, Binary extended GCD_ | ||
148 | // GCD_() = algorothm 14.57, Lehmer's algorithm | ||
149 | // mont_() = algorithm 14.36, Montgomery multiplication | ||
150 | // divide_() = algorithm 14.20 Multiple-precision division | ||
151 | // squareMod_() = algorithm 14.16 Multiple-precision squaring | ||
152 | // randTruePrime_() = algorithm 4.62, Maurer's algorithm | ||
153 | // millerRabin() = algorithm 4.24, Miller-Rabin algorithm | ||
154 | // | ||
155 | // Profiling shows: | ||
156 | // randTruePrime_() spends: | ||
157 | // 10% of its time in calls to powMod_() | ||
158 | // 85% of its time in calls to millerRabin() | ||
159 | // millerRabin() spends: | ||
160 | // 99% of its time in calls to powMod_() (always with a base of 2) | ||
161 | // powMod_() spends: | ||
162 | // 94% of its time in calls to mont_() (almost always with x==y) | ||
163 | // | ||
164 | // This suggests there are several ways to speed up this library slightly: | ||
165 | // - convert powMod_ to use a Montgomery form of k-ary window (or maybe a Montgomery form of sliding window) | ||
166 | // -- this should especially focus on being fast when raising 2 to a power mod n | ||
167 | // - convert randTruePrime_() to use a minimum r of 1/3 instead of 1/2 with the appropriate change to the test | ||
168 | // - tune the parameters in randTruePrime_(), including c, m, and recLimit | ||
169 | // - speed up the single loop in mont_() that takes 95% of the runtime, perhaps by reducing checking | ||
170 | // within the loop when all the parameters are the same length. | ||
171 | // | ||
172 | // There are several ideas that look like they wouldn't help much at all: | ||
173 | // - replacing trial division in randTruePrime_() with a sieve (that speeds up something taking almost no time anyway) | ||
174 | // - increase bpe from 15 to 30 (that would help if we had a 32*32->64 multiplier, but not with JavaScript's 32*32->32) | ||
175 | // - speeding up mont_(x,y,n,np) when x==y by doing a non-modular, non-Montgomery square | ||
176 | // followed by a Montgomery reduction. The intermediate answer will be twice as long as x, so that | ||
177 | // method would be slower. This is unfortunate because the code currently spends almost all of its time | ||
178 | // doing mont_(x,x,...), both for randTruePrime_() and powMod_(). A faster method for Montgomery squaring | ||
179 | // would have a large impact on the speed of randTruePrime_() and powMod_(). HAC has a couple of poorly-worded | ||
180 | // sentences that seem to imply it's faster to do a non-modular square followed by a single | ||
181 | // Montgomery reduction, but that's obviously wrong. | ||
182 | //////////////////////////////////////////////////////////////////////////////////////// | ||
183 | |||
184 | //globals | ||
185 | bpe=0; //bits stored per array element | ||
186 | mask=0; //AND this with an array element to chop it down to bpe bits | ||
187 | radix=mask+1; //equals 2^bpe. A single 1 bit to the left of the last bit of mask. | ||
188 | |||
189 | //the digits for converting to different bases | ||
190 | digitsStr='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_=!@#$%^&*()[]{}|;:,.<>/?`~ \\\'\"+-'; | ||
191 | |||
192 | //initialize the global variables | ||
193 | for (bpe=0; (1<<(bpe+1)) > (1<<bpe); bpe++); //bpe=number of bits in the mantissa on this platform | ||
194 | bpe>>=1; //bpe=number of bits in one element of the array representing the bigInt | ||
195 | mask=(1<<bpe)-1; //AND the mask with an integer to get its bpe least significant bits | ||
196 | radix=mask+1; //2^bpe. a single 1 bit to the left of the first bit of mask | ||
197 | one=int2bigInt(1,1,1); //constant used in powMod_() | ||
198 | |||
199 | //the following global variables are scratchpad memory to | ||
200 | //reduce dynamic memory allocation in the inner loop | ||
201 | t=new Array(0); | ||
202 | ss=t; //used in mult_() | ||
203 | s0=t; //used in multMod_(), squareMod_() | ||
204 | s1=t; //used in powMod_(), multMod_(), squareMod_() | ||
205 | s2=t; //used in powMod_(), multMod_() | ||
206 | s3=t; //used in powMod_() | ||
207 | s4=t; s5=t; //used in mod_() | ||
208 | s6=t; //used in bigInt2str() | ||
209 | s7=t; //used in powMod_() | ||
210 | T=t; //used in GCD_() | ||
211 | sa=t; //used in mont_() | ||
212 | mr_x1=t; mr_r=t; mr_a=t; //used in millerRabin() | ||
213 | eg_v=t; eg_u=t; eg_A=t; eg_B=t; eg_C=t; eg_D=t; //used in eGCD_(), inverseMod_() | ||
214 | md_q1=t; md_q2=t; md_q3=t; md_r=t; md_r1=t; md_r2=t; md_tt=t; //used in mod_() | ||
215 | |||
216 | primes=t; pows=t; s_i=t; s_i2=t; s_R=t; s_rm=t; s_q=t; s_n1=t; | ||
217 | s_a=t; s_r2=t; s_n=t; s_b=t; s_d=t; s_x1=t; s_x2=t, s_aa=t; //used in randTruePrime_() | ||
218 | |||
219 | //////////////////////////////////////////////////////////////////////////////////////// | ||
220 | |||
221 | //return array of all primes less than integer n | ||
222 | function findPrimes(n) { | ||
223 | var i,s,p,ans; | ||
224 | s=new Array(n); | ||
225 | for (i=0;i<n;i++) | ||
226 | s[i]=0; | ||
227 | s[0]=2; | ||
228 | p=0; //first p elements of s are primes, the rest are a sieve | ||
229 | for(;s[p]<n;) { //s[p] is the pth prime | ||
230 | for(i=s[p]*s[p]; i<n; i+=s[p]) //mark multiples of s[p] | ||
231 | s[i]=1; | ||
232 | p++; | ||
233 | s[p]=s[p-1]+1; | ||
234 | for(; s[p]<n && s[s[p]]; s[p]++); //find next prime (where s[p]==0) | ||
235 | } | ||
236 | ans=new Array(p); | ||
237 | for(i=0;i<p;i++) | ||
238 | ans[i]=s[i]; | ||
239 | return ans; | ||
240 | } | ||
241 | |||
242 | //does a single round of Miller-Rabin base b consider x to be a possible prime? | ||
243 | //x is a bigInt, and b is an integer | ||
244 | function millerRabin(x,b) { | ||
245 | var i,j,k,s; | ||
246 | |||
247 | if (mr_x1.length!=x.length) { | ||
248 | mr_x1=dup(x); | ||
249 | mr_r=dup(x); | ||
250 | mr_a=dup(x); | ||
251 | } | ||
252 | |||
253 | copyInt_(mr_a,b); | ||
254 | copy_(mr_r,x); | ||
255 | copy_(mr_x1,x); | ||
256 | |||
257 | addInt_(mr_r,-1); | ||
258 | addInt_(mr_x1,-1); | ||
259 | |||
260 | //s=the highest power of two that divides mr_r | ||
261 | k=0; | ||
262 | for (i=0;i<mr_r.length;i++) | ||
263 | for (j=1;j<mask;j<<=1) | ||
264 | if (x[i] & j) { | ||
265 | s=(k<mr_r.length+bpe ? k : 0); | ||
266 | i=mr_r.length; | ||
267 | j=mask; | ||
268 | } else | ||
269 | k++; | ||
270 | |||
271 | if (s) | ||
272 | rightShift_(mr_r,s); | ||
273 | |||
274 | powMod_(mr_a,mr_r,x); | ||
275 | |||
276 | if (!equalsInt(mr_a,1) && !equals(mr_a,mr_x1)) { | ||
277 | j=1; | ||
278 | while (j<=s-1 && !equals(mr_a,mr_x1)) { | ||
279 | squareMod_(mr_a,x); | ||
280 | if (equalsInt(mr_a,1)) { | ||
281 | return 0; | ||
282 | } | ||
283 | j++; | ||
284 | } | ||
285 | if (!equals(mr_a,mr_x1)) { | ||
286 | return 0; | ||
287 | } | ||
288 | } | ||
289 | return 1; | ||
290 | } | ||
291 | |||
292 | //returns how many bits long the bigInt is, not counting leading zeros. | ||
293 | function bitSize(x) { | ||
294 | var j,z,w; | ||
295 | for (j=x.length-1; (x[j]==0) && (j>0); j--); | ||
296 | for (z=0,w=x[j]; w; (w>>=1),z++); | ||
297 | z+=bpe*j; | ||
298 | return z; | ||
299 | } | ||
300 | |||
301 | //return a copy of x with at least n elements, adding leading zeros if needed | ||
302 | function expand(x,n) { | ||
303 | var ans=int2bigInt(0,(x.length>n ? x.length : n)*bpe,0); | ||
304 | copy_(ans,x); | ||
305 | return ans; | ||
306 | } | ||
307 | |||
308 | //return a k-bit true random prime using Maurer's algorithm. | ||
309 | function randTruePrime(k) { | ||
310 | var ans=int2bigInt(0,k,0); | ||
311 | randTruePrime_(ans,k); | ||
312 | return trim(ans,1); | ||
313 | } | ||
314 | |||
315 | //return a new bigInt equal to (x mod n) for bigInts x and n. | ||
316 | function mod(x,n) { | ||
317 | var ans=dup(x); | ||
318 | mod_(ans,n); | ||
319 | return trim(ans,1); | ||
320 | } | ||
321 | |||
322 | //return (x+n) where x is a bigInt and n is an integer. | ||
323 | function addInt(x,n) { | ||
324 | var ans=expand(x,x.length+1); | ||
325 | addInt_(ans,n); | ||
326 | return trim(ans,1); | ||
327 | } | ||
328 | |||
329 | //return x*y for bigInts x and y. This is faster when y<x. | ||
330 | function mult(x,y) { | ||
331 | var ans=expand(x,x.length+y.length); | ||
332 | mult_(ans,y); | ||
333 | return trim(ans,1); | ||
334 | } | ||
335 | |||
336 | //return (x**y mod n) where x,y,n are bigInts and ** is exponentiation. 0**0=1. Faster for odd n. | ||
337 | function powMod(x,y,n) { | ||
338 | var ans=expand(x,n.length); | ||
339 | powMod_(ans,trim(y,2),trim(n,2),0); //this should work without the trim, but doesn't | ||
340 | return trim(ans,1); | ||
341 | } | ||
342 | |||
343 | //return (x-y) for bigInts x and y. Negative answers will be 2s complement | ||
344 | function sub(x,y) { | ||
345 | var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1)); | ||
346 | sub_(ans,y); | ||
347 | return trim(ans,1); | ||
348 | } | ||
349 | |||
350 | //return (x+y) for bigInts x and y. | ||
351 | function add(x,y) { | ||
352 | var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1)); | ||
353 | add_(ans,y); | ||
354 | return trim(ans,1); | ||
355 | } | ||
356 | |||
357 | //return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null | ||
358 | function inverseMod(x,n) { | ||
359 | var ans=expand(x,n.length); | ||
360 | var s; | ||
361 | s=inverseMod_(ans,n); | ||
362 | return s ? trim(ans,1) : null; | ||
363 | } | ||
364 | |||
365 | //return (x*y mod n) for bigInts x,y,n. For greater speed, let y<x. | ||
366 | function multMod(x,y,n) { | ||
367 | var ans=expand(x,n.length); | ||
368 | multMod_(ans,y,n); | ||
369 | return trim(ans,1); | ||
370 | } | ||
371 | |||
372 | //generate a k-bit true random prime using Maurer's algorithm, | ||
373 | //and put it into ans. The bigInt ans must be large enough to hold it. | ||
374 | function randTruePrime_(ans,k) { | ||
375 | var c,m,pm,dd,j,r,B,divisible,z,zz,recSize; | ||
376 | |||
377 | if (primes.length==0) | ||
378 | primes=findPrimes(30000); //check for divisibility by primes <=30000 | ||
379 | |||
380 | if (pows.length==0) { | ||
381 | pows=new Array(512); | ||
382 | for (j=0;j<512;j++) { | ||
383 | pows[j]=Math.pow(2,j/511.-1.); | ||
384 | } | ||
385 | } | ||
386 | |||
387 | //c and m should be tuned for a particular machine and value of k, to maximize speed | ||
388 | //this was: c=primes[primes.length-1]/k/k; //check using all the small primes. (c=0.1 in HAC) | ||
389 | c=0.1; | ||
390 | m=20; //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits | ||
391 | recLimit=20; /*must be at least 2 (was 29)*/ //stop recursion when k <=recLimit | ||
392 | |||
393 | if (s_i2.length!=ans.length) { | ||
394 | s_i2=dup(ans); | ||
395 | s_R =dup(ans); | ||
396 | s_n1=dup(ans); | ||
397 | s_r2=dup(ans); | ||
398 | s_d =dup(ans); | ||
399 | s_x1=dup(ans); | ||
400 | s_x2=dup(ans); | ||
401 | s_b =dup(ans); | ||
402 | s_n =dup(ans); | ||
403 | s_i =dup(ans); | ||
404 | s_rm=dup(ans); | ||
405 | s_q =dup(ans); | ||
406 | s_a =dup(ans); | ||
407 | s_aa=dup(ans); | ||
408 | } | ||
409 | |||
410 | if (k <= recLimit) { //generate small random primes by trial division up to its square root | ||
411 | pm=(1<<((k+2)>>1))-1; //pm is binary number with all ones, just over sqrt(2^k) | ||
412 | copyInt_(ans,0); | ||
413 | for (dd=1;dd;) { | ||
414 | dd=0; | ||
415 | ans[0]= 1 | (1<<(k-1)) | Math.floor(Math.random()*(1<<k)); //random, k-bit, odd integer, with msb 1 | ||
416 | for (j=1;(j<primes.length) && ((primes[j]&pm)==primes[j]);j++) { //trial division by all primes 3...sqrt(2^k) | ||
417 | if (0==(ans[0]%primes[j])) { | ||
418 | dd=1; | ||
419 | break; | ||
420 | } | ||
421 | } | ||
422 | } | ||
423 | carry_(ans); | ||
424 | return; | ||
425 | } | ||
426 | |||
427 | B=c*k*k; //try small primes up to B (or all the primes[] array if the largest is less than B). | ||
428 | if (k>2*m) //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits | ||
429 | for (r=1; k-k*r<=m; ) | ||
430 | r=pows[Math.floor(Math.random()*512)]; //r=Math.pow(2,Math.random()-1); | ||
431 | else | ||
432 | r=.5; | ||
433 | |||
434 | //simulation suggests the more complex algorithm using r=.333 is only slightly faster. | ||
435 | |||
436 | recSize=Math.floor(r*k)+1; | ||
437 | |||
438 | randTruePrime_(s_q,recSize); | ||
439 | copyInt_(s_i2,0); | ||
440 | s_i2[Math.floor((k-2)/bpe)] |= (1<<((k-2)%bpe)); //s_i2=2^(k-2) | ||
441 | divide_(s_i2,s_q,s_i,s_rm); //s_i=floor((2^(k-1))/(2q)) | ||
442 | |||
443 | z=bitSize(s_i); | ||
444 | |||
445 | for (;;) { | ||
446 | for (;;) { //generate z-bit numbers until one falls in the range [0,s_i-1] | ||
447 | randBigInt_(s_R,z,0); | ||
448 | if (greater(s_i,s_R)) | ||
449 | break; | ||
450 | } //now s_R is in the range [0,s_i-1] | ||
451 | addInt_(s_R,1); //now s_R is in the range [1,s_i] | ||
452 | add_(s_R,s_i); //now s_R is in the range [s_i+1,2*s_i] | ||
453 | |||
454 | copy_(s_n,s_q); | ||
455 | mult_(s_n,s_R); | ||
456 | multInt_(s_n,2); | ||
457 | addInt_(s_n,1); //s_n=2*s_R*s_q+1 | ||
458 | |||
459 | copy_(s_r2,s_R); | ||
460 | multInt_(s_r2,2); //s_r2=2*s_R | ||
461 | |||
462 | //check s_n for divisibility by small primes up to B | ||
463 | for (divisible=0,j=0; (j<primes.length) && (primes[j]<B); j++) | ||
464 | if (modInt(s_n,primes[j])==0) { | ||
465 | divisible=1; | ||
466 | break; | ||
467 | } | ||
468 | |||
469 | if (!divisible) //if it passes small primes check, then try a single Miller-Rabin base 2 | ||
470 | if (!millerRabin(s_n,2)) //this line represents 75% of the total runtime for randTruePrime_ | ||
471 | divisible=1; | ||
472 | |||
473 | if (!divisible) { //if it passes that test, continue checking s_n | ||
474 | addInt_(s_n,-3); | ||
475 | for (j=s_n.length-1;(s_n[j]==0) && (j>0); j--); //strip leading zeros | ||
476 | for (zz=0,w=s_n[j]; w; (w>>=1),zz++); | ||
477 | zz+=bpe*j; //zz=number of bits in s_n, ignoring leading zeros | ||
478 | for (;;) { //generate z-bit numbers until one falls in the range [0,s_n-1] | ||
479 | randBigInt_(s_a,zz,0); | ||
480 | if (greater(s_n,s_a)) | ||
481 | break; | ||
482 | } //now s_a is in the range [0,s_n-1] | ||
483 | addInt_(s_n,3); //now s_a is in the range [0,s_n-4] | ||
484 | addInt_(s_a,2); //now s_a is in the range [2,s_n-2] | ||
485 | copy_(s_b,s_a); | ||
486 | copy_(s_n1,s_n); | ||
487 | addInt_(s_n1,-1); | ||
488 | powMod_(s_b,s_n1,s_n); //s_b=s_a^(s_n-1) modulo s_n | ||
489 | addInt_(s_b,-1); | ||
490 | if (isZero(s_b)) { | ||
491 | copy_(s_b,s_a); | ||
492 | powMod_(s_b,s_r2,s_n); | ||
493 | addInt_(s_b,-1); | ||
494 | copy_(s_aa,s_n); | ||
495 | copy_(s_d,s_b); | ||
496 | GCD_(s_d,s_n); //if s_b and s_n are relatively prime, then s_n is a prime | ||
497 | if (equalsInt(s_d,1)) { | ||
498 | copy_(ans,s_aa); | ||
499 | return; //if we've made it this far, then s_n is absolutely guaranteed to be prime | ||
500 | } | ||
501 | } | ||
502 | } | ||
503 | } | ||
504 | } | ||
505 | |||
506 | //set b to an n-bit random BigInt. If s=1, then nth bit (most significant bit) is set to 1. | ||
507 | //array b must be big enough to hold the result. Must have n>=1 | ||
508 | function randBigInt_(b,n,s) { | ||
509 | var i,a; | ||
510 | for (i=0;i<b.length;i++) | ||
511 | b[i]=0; | ||
512 | a=Math.floor((n-1)/bpe)+1; //# array elements to hold the BigInt | ||
513 | for (i=0;i<a;i++) { | ||
514 | b[i]=Math.floor(Math.random()*(1<<(bpe-1))); | ||
515 | } | ||
516 | b[a-1] &= (2<<((n-1)%bpe))-1; | ||
517 | if (s) | ||
518 | b[a-1] |= (1<<((n-1)%bpe)); | ||
519 | } | ||
520 | |||
521 | //set x to the greatest common divisor of x and y. | ||
522 | //x,y are bigInts with the same number of elements. y is destroyed. | ||
523 | function GCD_(x,y) { | ||
524 | var i,xp,yp,A,B,C,D,q,sing; | ||
525 | if (T.length!=x.length) | ||
526 | T=dup(x); | ||
527 | |||
528 | sing=1; | ||
529 | while (sing) { //while y has nonzero elements other than y[0] | ||
530 | sing=0; | ||
531 | for (i=1;i<y.length;i++) //check if y has nonzero elements other than 0 | ||
532 | if (y[i]) { | ||
533 | sing=1; | ||
534 | break; | ||
535 | } | ||
536 | if (!sing) break; //quit when y all zero elements except possibly y[0] | ||
537 | |||
538 | for (i=x.length;!x[i] && i>=0;i--); //find most significant element of x | ||
539 | xp=x[i]; | ||
540 | yp=y[i]; | ||
541 | A=1; B=0; C=0; D=1; | ||
542 | while ((yp+C) && (yp+D)) { | ||
543 | q =Math.floor((xp+A)/(yp+C)); | ||
544 | qp=Math.floor((xp+B)/(yp+D)); | ||
545 | if (q!=qp) | ||
546 | break; | ||
547 | t= A-q*C; A=C; C=t; // do (A,B,xp, C,D,yp) = (C,D,yp, A,B,xp) - q*(0,0,0, C,D,yp) | ||
548 | t= B-q*D; B=D; D=t; | ||
549 | t=xp-q*yp; xp=yp; yp=t; | ||
550 | } | ||
551 | if (B) { | ||
552 | copy_(T,x); | ||
553 | linComb_(x,y,A,B); //x=A*x+B*y | ||
554 | linComb_(y,T,D,C); //y=D*y+C*T | ||
555 | } else { | ||
556 | mod_(x,y); | ||
557 | copy_(T,x); | ||
558 | copy_(x,y); | ||
559 | copy_(y,T); | ||
560 | } | ||
561 | } | ||
562 | if (y[0]==0) | ||
563 | return; | ||
564 | t=modInt(x,y[0]); | ||
565 | copyInt_(x,y[0]); | ||
566 | y[0]=t; | ||
567 | while (y[0]) { | ||
568 | x[0]%=y[0]; | ||
569 | t=x[0]; x[0]=y[0]; y[0]=t; | ||
570 | } | ||
571 | } | ||
572 | |||
573 | //do x=x**(-1) mod n, for bigInts x and n. | ||
574 | //If no inverse exists, it sets x to zero and returns 0, else it returns 1. | ||
575 | //The x array must be at least as large as the n array. | ||
576 | function inverseMod_(x,n) { | ||
577 | var k=1+2*Math.max(x.length,n.length); | ||
578 | |||
579 | if(!(x[0]&1) && !(n[0]&1)) { //if both inputs are even, then inverse doesn't exist | ||
580 | copyInt_(x,0); | ||
581 | return 0; | ||
582 | } | ||
583 | |||
584 | if (eg_u.length!=k) { | ||
585 | eg_u=new Array(k); | ||
586 | eg_v=new Array(k); | ||
587 | eg_A=new Array(k); | ||
588 | eg_B=new Array(k); | ||
589 | eg_C=new Array(k); | ||
590 | eg_D=new Array(k); | ||
591 | } | ||
592 | |||
593 | copy_(eg_u,x); | ||
594 | copy_(eg_v,n); | ||
595 | copyInt_(eg_A,1); | ||
596 | copyInt_(eg_B,0); | ||
597 | copyInt_(eg_C,0); | ||
598 | copyInt_(eg_D,1); | ||
599 | for (;;) { | ||
600 | while(!(eg_u[0]&1)) { //while eg_u is even | ||
601 | halve_(eg_u); | ||
602 | if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if eg_A==eg_B==0 mod 2 | ||
603 | halve_(eg_A); | ||
604 | halve_(eg_B); | ||
605 | } else { | ||
606 | add_(eg_A,n); halve_(eg_A); | ||
607 | sub_(eg_B,x); halve_(eg_B); | ||
608 | } | ||
609 | } | ||
610 | |||
611 | while (!(eg_v[0]&1)) { //while eg_v is even | ||
612 | halve_(eg_v); | ||
613 | if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if eg_C==eg_D==0 mod 2 | ||
614 | halve_(eg_C); | ||
615 | halve_(eg_D); | ||
616 | } else { | ||
617 | add_(eg_C,n); halve_(eg_C); | ||
618 | sub_(eg_D,x); halve_(eg_D); | ||
619 | } | ||
620 | } | ||
621 | |||
622 | if (!greater(eg_v,eg_u)) { //eg_v <= eg_u | ||
623 | sub_(eg_u,eg_v); | ||
624 | sub_(eg_A,eg_C); | ||
625 | sub_(eg_B,eg_D); | ||
626 | } else { //eg_v > eg_u | ||
627 | sub_(eg_v,eg_u); | ||
628 | sub_(eg_C,eg_A); | ||
629 | sub_(eg_D,eg_B); | ||
630 | } | ||
631 | |||
632 | if (equalsInt(eg_u,0)) { | ||
633 | if (negative(eg_C)) //make sure answer is nonnegative | ||
634 | add_(eg_C,n); | ||
635 | copy_(x,eg_C); | ||
636 | |||
637 | if (!equalsInt(eg_v,1)) { //if GCD_(x,n)!=1, then there is no inverse | ||
638 | copyInt_(x,0); | ||
639 | return 0; | ||
640 | } | ||
641 | return 1; | ||
642 | } | ||
643 | } | ||
644 | } | ||
645 | |||
646 | //return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse | ||
647 | function inverseModInt_(x,n) { | ||
648 | var a=1,b=0,t; | ||
649 | for (;;) { | ||
650 | if (x==1) return a; | ||
651 | if (x==0) return 0; | ||
652 | b-=a*Math.floor(n/x); | ||
653 | n%=x; | ||
654 | |||
655 | if (n==1) return b; //to avoid negatives, change this b to n-b, and each -= to += | ||
656 | if (n==0) return 0; | ||
657 | a-=b*Math.floor(x/n); | ||
658 | x%=n; | ||
659 | } | ||
660 | } | ||
661 | |||
662 | //Given positive bigInts x and y, change the bigints v, a, and b to positive bigInts such that: | ||
663 | // v = GCD_(x,y) = a*x-b*y | ||
664 | //The bigInts v, a, b, must have exactly as many elements as the larger of x and y. | ||
665 | function eGCD_(x,y,v,a,b) { | ||
666 | var g=0; | ||
667 | var k=Math.max(x.length,y.length); | ||
668 | if (eg_u.length!=k) { | ||
669 | eg_u=new Array(k); | ||
670 | eg_A=new Array(k); | ||
671 | eg_B=new Array(k); | ||
672 | eg_C=new Array(k); | ||
673 | eg_D=new Array(k); | ||
674 | } | ||
675 | while(!(x[0]&1) && !(y[0]&1)) { //while x and y both even | ||
676 | halve_(x); | ||
677 | halve_(y); | ||
678 | g++; | ||
679 | } | ||
680 | copy_(eg_u,x); | ||
681 | copy_(v,y); | ||
682 | copyInt_(eg_A,1); | ||
683 | copyInt_(eg_B,0); | ||
684 | copyInt_(eg_C,0); | ||
685 | copyInt_(eg_D,1); | ||
686 | for (;;) { | ||
687 | while(!(eg_u[0]&1)) { //while u is even | ||
688 | halve_(eg_u); | ||
689 | if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if A==B==0 mod 2 | ||
690 | halve_(eg_A); | ||
691 | halve_(eg_B); | ||
692 | } else { | ||
693 | add_(eg_A,y); halve_(eg_A); | ||
694 | sub_(eg_B,x); halve_(eg_B); | ||
695 | } | ||
696 | } | ||
697 | |||
698 | while (!(v[0]&1)) { //while v is even | ||
699 | halve_(v); | ||
700 | if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if C==D==0 mod 2 | ||
701 | halve_(eg_C); | ||
702 | halve_(eg_D); | ||
703 | } else { | ||
704 | add_(eg_C,y); halve_(eg_C); | ||
705 | sub_(eg_D,x); halve_(eg_D); | ||
706 | } | ||
707 | } | ||
708 | |||
709 | if (!greater(v,eg_u)) { //v<=u | ||
710 | sub_(eg_u,v); | ||
711 | sub_(eg_A,eg_C); | ||
712 | sub_(eg_B,eg_D); | ||
713 | } else { //v>u | ||
714 | sub_(v,eg_u); | ||
715 | sub_(eg_C,eg_A); | ||
716 | sub_(eg_D,eg_B); | ||
717 | } | ||
718 | if (equalsInt(eg_u,0)) { | ||
719 | if (negative(eg_C)) { //make sure a (C)is nonnegative | ||
720 | add_(eg_C,y); | ||
721 | sub_(eg_D,x); | ||
722 | } | ||
723 | multInt_(eg_D,-1); ///make sure b (D) is nonnegative | ||
724 | copy_(a,eg_C); | ||
725 | copy_(b,eg_D); | ||
726 | leftShift_(v,g); | ||
727 | return; | ||
728 | } | ||
729 | } | ||
730 | } | ||
731 | |||
732 | |||
733 | //is bigInt x negative? | ||
734 | function negative(x) { | ||
735 | return ((x[x.length-1]>>(bpe-1))&1); | ||
736 | } | ||
737 | |||
738 | |||
739 | //is (x << (shift*bpe)) > y? | ||
740 | //x and y are nonnegative bigInts | ||
741 | //shift is a nonnegative integer | ||
742 | function greaterShift(x,y,shift) { | ||
743 | var kx=x.length, ky=y.length; | ||
744 | k=((kx+shift)<ky) ? (kx+shift) : ky; | ||
745 | for (i=ky-1-shift; i<kx && i>=0; i++) | ||
746 | if (x[i]>0) | ||
747 | return 1; //if there are nonzeros in x to the left of the first column of y, then x is bigger | ||
748 | for (i=kx-1+shift; i<ky; i++) | ||
749 | if (y[i]>0) | ||
750 | return 0; //if there are nonzeros in y to the left of the first column of x, then x is not bigger | ||
751 | for (i=k-1; i>=shift; i--) | ||
752 | if (x[i-shift]>y[i]) return 1; | ||
753 | else if (x[i-shift]<y[i]) return 0; | ||
754 | return 0; | ||
755 | } | ||
756 | |||
757 | //is x > y? (x and y both nonnegative) | ||
758 | function greater(x,y) { | ||
759 | var i; | ||
760 | var k=(x.length<y.length) ? x.length : y.length; | ||
761 | |||
762 | for (i=x.length;i<y.length;i++) | ||
763 | if (y[i]) | ||
764 | return 0; //y has more digits | ||
765 | |||
766 | for (i=y.length;i<x.length;i++) | ||
767 | if (x[i]) | ||
768 | return 1; //x has more digits | ||
769 | |||
770 | for (i=k-1;i>=0;i--) | ||
771 | if (x[i]>y[i]) | ||
772 | return 1; | ||
773 | else if (x[i]<y[i]) | ||
774 | return 0; | ||
775 | return 0; | ||
776 | } | ||
777 | |||
778 | //divide_ x by y giving quotient q and remainder r. (q=floor(x/y), r=x mod y). All 4 are bigints. | ||
779 | //x must have at least one leading zero element. | ||
780 | //y must be nonzero. | ||
781 | //q and r must be arrays that are exactly the same length as x. | ||
782 | //the x array must have at least as many elements as y. | ||
783 | function divide_(x,y,q,r) { | ||
784 | var kx, ky; | ||
785 | var i,j,y1,y2,c,a,b; | ||
786 | copy_(r,x); | ||
787 | for (ky=y.length;y[ky-1]==0;ky--); //kx,ky is number of elements in x,y, not including leading zeros | ||
788 | for (kx=r.length;r[kx-1]==0 && kx>ky;kx--); | ||
789 | |||
790 | //normalize: ensure the most significant element of y has its highest bit set | ||
791 | b=y[ky-1]; | ||
792 | for (a=0; b; a++) | ||
793 | b>>=1; | ||
794 | a=bpe-a; //a is how many bits to shift so that the high order bit of y is leftmost in its array element | ||
795 | leftShift_(y,a); //multiply both by 1<<a now, then divide_ both by that at the end | ||
796 | leftShift_(r,a); | ||
797 | |||
798 | copyInt_(q,0); // q=0 | ||
799 | while (!greaterShift(y,r,kx-ky)) { // while (leftShift_(y,kx-ky) <= r) { | ||
800 | subShift_(r,y,kx-ky); // r=r-leftShift_(y,kx-ky) | ||
801 | q[kx-ky]++; // q[kx-ky]++; | ||
802 | } // } | ||
803 | |||
804 | for (i=kx-1; i>=ky; i--) { | ||
805 | if (r[i]==y[ky-1]) | ||
806 | q[i-ky]=mask; | ||
807 | else | ||
808 | q[i-ky]=Math.floor((r[i]*radix+r[i-1])/y[ky-1]); | ||
809 | |||
810 | //The following for(;;) loop is equivalent to the commented while loop, | ||
811 | //except that the uncommented version avoids overflow. | ||
812 | //The commented loop comes from HAC, which assumes r[-1]==y[-1]==0 | ||
813 | // while (q[i-ky]*(y[ky-1]*radix+y[ky-2]) > r[i]*radix*radix+r[i-1]*radix+r[i-2]) | ||
814 | // q[i-ky]--; | ||
815 | for (;;) { | ||
816 | y2=(ky>1 ? y[ky-2] : 0)*q[i-ky]; | ||
817 | c=y2>>bpe; | ||
818 | y2=y2 & mask; | ||
819 | y1=c+q[i-ky]*y[ky-1]; | ||
820 | c=y1>>bpe; | ||
821 | y1=y1 & mask; | ||
822 | |||
823 | if (c==r[i] ? y1==r[i-1] ? y2>(i>1 ? r[i-2] : 0) : y1>r[i-1] : c>r[i]) | ||
824 | q[i-ky]--; | ||
825 | else | ||
826 | break; | ||
827 | } | ||
828 | |||
829 | linCombShift_(r,y,-q[i-ky],i-ky); //r=r-q[i-ky]*leftShift_(y,i-ky) | ||
830 | if (negative(r)) { | ||
831 | addShift_(r,y,i-ky); //r=r+leftShift_(y,i-ky) | ||
832 | q[i-ky]--; | ||
833 | } | ||
834 | } | ||
835 | |||
836 | rightShift_(y,a); //undo the normalization step | ||
837 | rightShift_(r,a); //undo the normalization step | ||
838 | } | ||
839 | |||
840 | //do carries and borrows so each element of the bigInt x fits in bpe bits. | ||
841 | function carry_(x) { | ||
842 | var i,k,c,b; | ||
843 | k=x.length; | ||
844 | c=0; | ||
845 | for (i=0;i<k;i++) { | ||
846 | c+=x[i]; | ||
847 | b=0; | ||
848 | if (c<0) { | ||
849 | b=-(c>>bpe); | ||
850 | c+=b*radix; | ||
851 | } | ||
852 | x[i]=c & mask; | ||
853 | c=(c>>bpe)-b; | ||
854 | } | ||
855 | } | ||
856 | |||
857 | //return x mod n for bigInt x and integer n. | ||
858 | function modInt(x,n) { | ||
859 | var i,c=0; | ||
860 | for (i=x.length-1; i>=0; i--) | ||
861 | c=(c*radix+x[i])%n; | ||
862 | return c; | ||
863 | } | ||
864 | |||
865 | //convert the integer t into a bigInt with at least the given number of bits. | ||
866 | //the returned array stores the bigInt in bpe-bit chunks, little endian (buff[0] is least significant word) | ||
867 | //Pad the array with leading zeros so that it has at least minSize elements. | ||
868 | //There will always be at least one leading 0 element. | ||
869 | function int2bigInt(t,bits,minSize) { | ||
870 | var i,k; | ||
871 | k=Math.ceil(bits/bpe)+1; | ||
872 | k=minSize>k ? minSize : k; | ||
873 | buff=new Array(k); | ||
874 | copyInt_(buff,t); | ||
875 | return buff; | ||
876 | } | ||
877 | |||
878 | //return the bigInt given a string representation in a given base. | ||
879 | //Pad the array with leading zeros so that it has at least minSize elements. | ||
880 | //If base=-1, then it reads in a space-separated list of array elements in decimal. | ||
881 | //The array will always have at least one leading zero, unless base=-1. | ||
882 | function str2bigInt(s,base,minSize) { | ||
883 | var d, i, j, x, y, kk; | ||
884 | var k=s.length; | ||
885 | if (base==-1) { //comma-separated list of array elements in decimal | ||
886 | x=new Array(0); | ||
887 | for (;;) { | ||
888 | y=new Array(x.length+1); | ||
889 | for (i=0;i<x.length;i++) | ||
890 | y[i+1]=x[i]; | ||
891 | y[0]=parseInt(s,10); | ||
892 | x=y; | ||
893 | d=s.indexOf(',',0); | ||
894 | if (d<1) | ||
895 | break; | ||
896 | s=s.substring(d+1); | ||
897 | if (s.length==0) | ||
898 | break; | ||
899 | } | ||
900 | if (x.length<minSize) { | ||
901 | y=new Array(minSize); | ||
902 | copy_(y,x); | ||
903 | return y; | ||
904 | } | ||
905 | return x; | ||
906 | } | ||
907 | |||
908 | x=int2bigInt(0,base*k,0); | ||
909 | for (i=0;i<k;i++) { | ||
910 | d=digitsStr.indexOf(s.substring(i,i+1),0); | ||
911 | if (base<=36 && d>=36) //convert lowercase to uppercase if base<=36 | ||
912 | d-=26; | ||
913 | if (d<base && d>=0) { //ignore illegal characters | ||
914 | multInt_(x,base); | ||
915 | addInt_(x,d); | ||
916 | } | ||
917 | } | ||
918 | |||
919 | for (k=x.length;k>0 && !x[k-1];k--); //strip off leading zeros | ||
920 | k=minSize>k+1 ? minSize : k+1; | ||
921 | y=new Array(k); | ||
922 | kk=k<x.length ? k : x.length; | ||
923 | for (i=0;i<kk;i++) | ||
924 | y[i]=x[i]; | ||
925 | for (;i<k;i++) | ||
926 | y[i]=0; | ||
927 | return y; | ||
928 | } | ||
929 | |||
930 | //is bigint x equal to integer y? | ||
931 | //y must have less than bpe bits | ||
932 | function equalsInt(x,y) { | ||
933 | var i; | ||
934 | if (x[0]!=y) | ||
935 | return 0; | ||
936 | for (i=1;i<x.length;i++) | ||
937 | if (x[i]) | ||
938 | return 0; | ||
939 | return 1; | ||
940 | } | ||
941 | |||
942 | //are bigints x and y equal? | ||
943 | //this works even if x and y are different lengths and have arbitrarily many leading zeros | ||
944 | function equals(x,y) { | ||
945 | var i; | ||
946 | var k=x.length<y.length ? x.length : y.length; | ||
947 | for (i=0;i<k;i++) | ||
948 | if (x[i]!=y[i]) | ||
949 | return 0; | ||
950 | if (x.length>y.length) { | ||
951 | for (;i<x.length;i++) | ||
952 | if (x[i]) | ||
953 | return 0; | ||
954 | } else { | ||
955 | for (;i<y.length;i++) | ||
956 | if (y[i]) | ||
957 | return 0; | ||
958 | } | ||
959 | return 1; | ||
960 | } | ||
961 | |||
962 | //is the bigInt x equal to zero? | ||
963 | function isZero(x) { | ||
964 | var i; | ||
965 | for (i=0;i<x.length;i++) | ||
966 | if (x[i]) | ||
967 | return 0; | ||
968 | return 1; | ||
969 | } | ||
970 | |||
971 | //convert a bigInt into a string in a given base, from base 2 up to base 95. | ||
972 | //Base -1 prints the contents of the array representing the number. | ||
973 | function bigInt2str(x,base) { | ||
974 | var i,t,s=""; | ||
975 | |||
976 | if (s6.length!=x.length) | ||
977 | s6=dup(x); | ||
978 | else | ||
979 | copy_(s6,x); | ||
980 | |||
981 | if (base==-1) { //return the list of array contents | ||
982 | for (i=x.length-1;i>0;i--) | ||
983 | s+=x[i]+','; | ||
984 | s+=x[0]; | ||
985 | } | ||
986 | else { //return it in the given base | ||
987 | while (!isZero(s6)) { | ||
988 | t=divInt_(s6,base); //t=s6 % base; s6=floor(s6/base); | ||
989 | s=digitsStr.substring(t,t+1)+s; | ||
990 | } | ||
991 | } | ||
992 | if (s.length==0) | ||
993 | s="0"; | ||
994 | return s; | ||
995 | } | ||
996 | |||
997 | //returns a duplicate of bigInt x | ||
998 | function dup(x) { | ||
999 | var i; | ||
1000 | buff=new Array(x.length); | ||
1001 | copy_(buff,x); | ||
1002 | return buff; | ||
1003 | } | ||
1004 | |||
1005 | //do x=y on bigInts x and y. x must be an array at least as big as y (not counting the leading zeros in y). | ||
1006 | function copy_(x,y) { | ||
1007 | var i; | ||
1008 | var k=x.length<y.length ? x.length : y.length; | ||
1009 | for (i=0;i<k;i++) | ||
1010 | x[i]=y[i]; | ||
1011 | for (i=k;i<x.length;i++) | ||
1012 | x[i]=0; | ||
1013 | } | ||
1014 | |||
1015 | //do x=y on bigInt x and integer y. | ||
1016 | function copyInt_(x,n) { | ||
1017 | var i,c; | ||
1018 | for (c=n,i=0;i<x.length;i++) { | ||
1019 | x[i]=c & mask; | ||
1020 | c>>=bpe; | ||
1021 | } | ||
1022 | } | ||
1023 | |||
1024 | //do x=x+n where x is a bigInt and n is an integer. | ||
1025 | //x must be large enough to hold the result. | ||
1026 | function addInt_(x,n) { | ||
1027 | var i,k,c,b; | ||
1028 | x[0]+=n; | ||
1029 | k=x.length; | ||
1030 | c=0; | ||
1031 | for (i=0;i<k;i++) { | ||
1032 | c+=x[i]; | ||
1033 | b=0; | ||
1034 | if (c<0) { | ||
1035 | b=-(c>>bpe); | ||
1036 | c+=b*radix; | ||
1037 | } | ||
1038 | x[i]=c & mask; | ||
1039 | c=(c>>bpe)-b; | ||
1040 | if (!c) return; //stop carrying as soon as the carry_ is zero | ||
1041 | } | ||
1042 | } | ||
1043 | |||
1044 | //right shift bigInt x by n bits. 0 <= n < bpe. | ||
1045 | function rightShift_(x,n) { | ||
1046 | var i; | ||
1047 | var k=Math.floor(n/bpe); | ||
1048 | if (k) { | ||
1049 | for (i=0;i<x.length-k;i++) //right shift x by k elements | ||
1050 | x[i]=x[i+k]; | ||
1051 | for (;i<x.length;i++) | ||
1052 | x[i]=0; | ||
1053 | n%=bpe; | ||
1054 | } | ||
1055 | for (i=0;i<x.length-1;i++) { | ||
1056 | x[i]=mask & ((x[i+1]<<(bpe-n)) | (x[i]>>n)); | ||
1057 | } | ||
1058 | x[i]>>=n; | ||
1059 | } | ||
1060 | |||
1061 | //do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement | ||
1062 | function halve_(x) { | ||
1063 | var i; | ||
1064 | for (i=0;i<x.length-1;i++) { | ||
1065 | x[i]=mask & ((x[i+1]<<(bpe-1)) | (x[i]>>1)); | ||
1066 | } | ||
1067 | x[i]=(x[i]>>1) | (x[i] & (radix>>1)); //most significant bit stays the same | ||
1068 | } | ||
1069 | |||
1070 | //left shift bigInt x by n bits. | ||
1071 | function leftShift_(x,n) { | ||
1072 | var i; | ||
1073 | var k=Math.floor(n/bpe); | ||
1074 | if (k) { | ||
1075 | for (i=x.length; i>=k; i--) //left shift x by k elements | ||
1076 | x[i]=x[i-k]; | ||
1077 | for (;i>=0;i--) | ||
1078 | x[i]=0; | ||
1079 | n%=bpe; | ||
1080 | } | ||
1081 | if (!n) | ||
1082 | return; | ||
1083 | for (i=x.length-1;i>0;i--) { | ||
1084 | x[i]=mask & ((x[i]<<n) | (x[i-1]>>(bpe-n))); | ||
1085 | } | ||
1086 | x[i]=mask & (x[i]<<n); | ||
1087 | } | ||
1088 | |||
1089 | //do x=x*n where x is a bigInt and n is an integer. | ||
1090 | //x must be large enough to hold the result. | ||
1091 | function multInt_(x,n) { | ||
1092 | var i,k,c,b; | ||
1093 | if (!n) | ||
1094 | return; | ||
1095 | k=x.length; | ||
1096 | c=0; | ||
1097 | for (i=0;i<k;i++) { | ||
1098 | c+=x[i]*n; | ||
1099 | b=0; | ||
1100 | if (c<0) { | ||
1101 | b=-(c>>bpe); | ||
1102 | c+=b*radix; | ||
1103 | } | ||
1104 | x[i]=c & mask; | ||
1105 | c=(c>>bpe)-b; | ||
1106 | } | ||
1107 | } | ||
1108 | |||
1109 | //do x=floor(x/n) for bigInt x and integer n, and return the remainder | ||
1110 | function divInt_(x,n) { | ||
1111 | var i,r=0,s; | ||
1112 | for (i=x.length-1;i>=0;i--) { | ||
1113 | s=r*radix+x[i]; | ||
1114 | x[i]=Math.floor(s/n); | ||
1115 | r=s%n; | ||
1116 | } | ||
1117 | return r; | ||
1118 | } | ||
1119 | |||
1120 | //do the linear combination x=a*x+b*y for bigInts x and y, and integers a and b. | ||
1121 | //x must be large enough to hold the answer. | ||
1122 | function linComb_(x,y,a,b) { | ||
1123 | var i,c,k,kk; | ||
1124 | k=x.length<y.length ? x.length : y.length; | ||
1125 | kk=x.length; | ||
1126 | for (c=0,i=0;i<k;i++) { | ||
1127 | c+=a*x[i]+b*y[i]; | ||
1128 | x[i]=c & mask; | ||
1129 | c>>=bpe; | ||
1130 | } | ||
1131 | for (i=k;i<kk;i++) { | ||
1132 | c+=a*x[i]; | ||
1133 | x[i]=c & mask; | ||
1134 | c>>=bpe; | ||
1135 | } | ||
1136 | } | ||
1137 | |||
1138 | //do the linear combination x=a*x+b*(y<<(ys*bpe)) for bigInts x and y, and integers a, b and ys. | ||
1139 | //x must be large enough to hold the answer. | ||
1140 | function linCombShift_(x,y,b,ys) { | ||
1141 | var i,c,k,kk; | ||
1142 | k=x.length<ys+y.length ? x.length : ys+y.length; | ||
1143 | kk=x.length; | ||
1144 | for (c=0,i=ys;i<k;i++) { | ||
1145 | c+=x[i]+b*y[i-ys]; | ||
1146 | x[i]=c & mask; | ||
1147 | c>>=bpe; | ||
1148 | } | ||
1149 | for (i=k;c && i<kk;i++) { | ||
1150 | c+=x[i]; | ||
1151 | x[i]=c & mask; | ||
1152 | c>>=bpe; | ||
1153 | } | ||
1154 | } | ||
1155 | |||
1156 | //do x=x+(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys. | ||
1157 | //x must be large enough to hold the answer. | ||
1158 | function addShift_(x,y,ys) { | ||
1159 | var i,c,k,kk; | ||
1160 | k=x.length<ys+y.length ? x.length : ys+y.length; | ||
1161 | kk=x.length; | ||
1162 | for (c=0,i=ys;i<k;i++) { | ||
1163 | c+=x[i]+y[i-ys]; | ||
1164 | x[i]=c & mask; | ||
1165 | c>>=bpe; | ||
1166 | } | ||
1167 | for (i=k;c && i<kk;i++) { | ||
1168 | c+=x[i]; | ||
1169 | x[i]=c & mask; | ||
1170 | c>>=bpe; | ||
1171 | } | ||
1172 | } | ||
1173 | |||
1174 | //do x=x-(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys. | ||
1175 | //x must be large enough to hold the answer. | ||
1176 | function subShift_(x,y,ys) { | ||
1177 | var i,c,k,kk; | ||
1178 | k=x.length<ys+y.length ? x.length : ys+y.length; | ||
1179 | kk=x.length; | ||
1180 | for (c=0,i=ys;i<k;i++) { | ||
1181 | c+=x[i]-y[i-ys]; | ||
1182 | x[i]=c & mask; | ||
1183 | c>>=bpe; | ||
1184 | } | ||
1185 | for (i=k;c && i<kk;i++) { | ||
1186 | c+=x[i]; | ||
1187 | x[i]=c & mask; | ||
1188 | c>>=bpe; | ||
1189 | } | ||
1190 | } | ||
1191 | |||
1192 | //do x=x-y for bigInts x and y. | ||
1193 | //x must be large enough to hold the answer. | ||
1194 | //negative answers will be 2s complement | ||
1195 | function sub_(x,y) { | ||
1196 | var i,c,k,kk; | ||
1197 | k=x.length<y.length ? x.length : y.length; | ||
1198 | for (c=0,i=0;i<k;i++) { | ||
1199 | c+=x[i]-y[i]; | ||
1200 | x[i]=c & mask; | ||
1201 | c>>=bpe; | ||
1202 | } | ||
1203 | for (i=k;c && i<x.length;i++) { | ||
1204 | c+=x[i]; | ||
1205 | x[i]=c & mask; | ||
1206 | c>>=bpe; | ||
1207 | } | ||
1208 | } | ||
1209 | |||
1210 | //do x=x+y for bigInts x and y. | ||
1211 | //x must be large enough to hold the answer. | ||
1212 | function add_(x,y) { | ||
1213 | var i,c,k,kk; | ||
1214 | k=x.length<y.length ? x.length : y.length; | ||
1215 | for (c=0,i=0;i<k;i++) { | ||
1216 | c+=x[i]+y[i]; | ||
1217 | x[i]=c & mask; | ||
1218 | c>>=bpe; | ||
1219 | } | ||
1220 | for (i=k;c && i<x.length;i++) { | ||
1221 | c+=x[i]; | ||
1222 | x[i]=c & mask; | ||
1223 | c>>=bpe; | ||
1224 | } | ||
1225 | } | ||
1226 | |||
1227 | //do x=x*y for bigInts x and y. This is faster when y<x. | ||
1228 | function mult_(x,y) { | ||
1229 | var i; | ||
1230 | if (ss.length!=2*x.length) | ||
1231 | ss=new Array(2*x.length); | ||
1232 | copyInt_(ss,0); | ||
1233 | for (i=0;i<y.length;i++) | ||
1234 | if (y[i]) | ||
1235 | linCombShift_(ss,x,y[i],i); //ss=1*ss+y[i]*(x<<(i*bpe)) | ||
1236 | copy_(x,ss); | ||
1237 | } | ||
1238 | |||
1239 | //do x=x mod n for bigInts x and n. | ||
1240 | function mod_(x,n) { | ||
1241 | if (s4.length!=x.length) | ||
1242 | s4=dup(x); | ||
1243 | else | ||
1244 | copy_(s4,x); | ||
1245 | if (s5.length!=x.length) | ||
1246 | s5=dup(x); | ||
1247 | divide_(s4,n,s5,x); //x = remainder of s4 / n | ||
1248 | } | ||
1249 | |||
1250 | //do x=x*y mod n for bigInts x,y,n. | ||
1251 | //for greater speed, let y<x. | ||
1252 | function multMod_(x,y,n) { | ||
1253 | var i; | ||
1254 | if (s0.length!=2*x.length) | ||
1255 | s0=new Array(2*x.length); | ||
1256 | copyInt_(s0,0); | ||
1257 | for (i=0;i<y.length;i++) | ||
1258 | if (y[i]) | ||
1259 | linCombShift_(s0,x,y[i],i); //s0=1*s0+y[i]*(x<<(i*bpe)) | ||
1260 | mod_(s0,n); | ||
1261 | copy_(x,s0); | ||
1262 | } | ||
1263 | |||
1264 | //do x=x*x mod n for bigInts x,n. | ||
1265 | function squareMod_(x,n) { | ||
1266 | var i,j,d,c,kx,kn,k; | ||
1267 | for (kx=x.length; kx>0 && !x[kx-1]; kx--); //ignore leading zeros in x | ||
1268 | k=kx>n.length ? 2*kx : 2*n.length; //k=# elements in the product, which is twice the elements in the larger of x and n | ||
1269 | if (s0.length!=k) | ||
1270 | s0=new Array(k); | ||
1271 | copyInt_(s0,0); | ||
1272 | for (i=0;i<kx;i++) { | ||
1273 | c=s0[2*i]+x[i]*x[i]; | ||
1274 | s0[2*i]=c & mask; | ||
1275 | c>>=bpe; | ||
1276 | for (j=i+1;j<kx;j++) { | ||
1277 | c=s0[i+j]+2*x[i]*x[j]+c; | ||
1278 | s0[i+j]=(c & mask); | ||
1279 | c>>=bpe; | ||
1280 | } | ||
1281 | s0[i+kx]=c; | ||
1282 | } | ||
1283 | mod_(s0,n); | ||
1284 | copy_(x,s0); | ||
1285 | } | ||
1286 | |||
1287 | //return x with exactly k leading zero elements | ||
1288 | function trim(x,k) { | ||
1289 | var i,y; | ||
1290 | for (i=x.length; i>0 && !x[i-1]; i--); | ||
1291 | y=new Array(i+k); | ||
1292 | copy_(y,x); | ||
1293 | return y; | ||
1294 | } | ||
1295 | |||
1296 | //do x=x**y mod n, where x,y,n are bigInts and ** is exponentiation. 0**0=1. | ||
1297 | //this is faster when n is odd. x usually needs to have as many elements as n. | ||
1298 | function powMod_(x,y,n) { | ||
1299 | var k1,k2,kn,np; | ||
1300 | if(s7.length!=n.length) | ||
1301 | s7=dup(n); | ||
1302 | |||
1303 | //for even modulus, use a simple square-and-multiply algorithm, | ||
1304 | //rather than using the more complex Montgomery algorithm. | ||
1305 | if ((n[0]&1)==0) { | ||
1306 | copy_(s7,x); | ||
1307 | copyInt_(x,1); | ||
1308 | while(!equalsInt(y,0)) { | ||
1309 | if (y[0]&1) | ||
1310 | multMod_(x,s7,n); | ||
1311 | divInt_(y,2); | ||
1312 | squareMod_(s7,n); | ||
1313 | } | ||
1314 | return; | ||
1315 | } | ||
1316 | |||
1317 | //calculate np from n for the Montgomery multiplications | ||
1318 | copyInt_(s7,0); | ||
1319 | for (kn=n.length;kn>0 && !n[kn-1];kn--); | ||
1320 | np=radix-inverseModInt_(modInt(n,radix),radix); | ||
1321 | s7[kn]=1; | ||
1322 | multMod_(x ,s7,n); // x = x * 2**(kn*bp) mod n | ||
1323 | |||
1324 | if (s3.length!=x.length) | ||
1325 | s3=dup(x); | ||
1326 | else | ||
1327 | copy_(s3,x); | ||
1328 | |||
1329 | for (k1=y.length-1;k1>0 & !y[k1]; k1--); //k1=first nonzero element of y | ||
1330 | if (y[k1]==0) { //anything to the 0th power is 1 | ||
1331 | copyInt_(x,1); | ||
1332 | return; | ||
1333 | } | ||
1334 | for (k2=1<<(bpe-1);k2 && !(y[k1] & k2); k2>>=1); //k2=position of first 1 bit in y[k1] | ||
1335 | for (;;) { | ||
1336 | if (!(k2>>=1)) { //look at next bit of y | ||
1337 | k1--; | ||
1338 | if (k1<0) { | ||
1339 | mont_(x,one,n,np); | ||
1340 | return; | ||
1341 | } | ||
1342 | k2=1<<(bpe-1); | ||
1343 | } | ||
1344 | mont_(x,x,n,np); | ||
1345 | |||
1346 | if (k2 & y[k1]) //if next bit is a 1 | ||
1347 | mont_(x,s3,n,np); | ||
1348 | } | ||
1349 | } | ||
1350 | |||
1351 | //do x=x*y*Ri mod n for bigInts x,y,n, | ||
1352 | // where Ri = 2**(-kn*bpe) mod n, and kn is the | ||
1353 | // number of elements in the n array, not | ||
1354 | // counting leading zeros. | ||
1355 | //x must be large enough to hold the answer. | ||
1356 | //It's OK if x and y are the same variable. | ||
1357 | //must have: | ||
1358 | // x,y < n | ||
1359 | // n is odd | ||
1360 | // np = -(n^(-1)) mod radix | ||
1361 | function mont_(x,y,n,np) { | ||
1362 | var i,j,c,ui,t; | ||
1363 | var kn=n.length; | ||
1364 | var ky=y.length; | ||
1365 | |||
1366 | if (sa.length!=kn) | ||
1367 | sa=new Array(kn); | ||
1368 | |||
1369 | for (;kn>0 && n[kn-1]==0;kn--); //ignore leading zeros of n | ||
1370 | //this function sometimes gives wrong answers when the next line is uncommented | ||
1371 | //for (;ky>0 && y[ky-1]==0;ky--); //ignore leading zeros of y | ||
1372 | |||
1373 | copyInt_(sa,0); | ||
1374 | |||
1375 | //the following loop consumes 95% of the runtime for randTruePrime_() and powMod_() for large keys | ||
1376 | for (i=0; i<kn; i++) { | ||
1377 | t=sa[0]+x[i]*y[0]; | ||
1378 | ui=((t & mask) * np) & mask; //the inner "& mask" is needed on Macintosh MSIE, but not windows MSIE | ||
1379 | c=(t+ui*n[0]) >> bpe; | ||
1380 | t=x[i]; | ||
1381 | |||
1382 | //do sa=(sa+x[i]*y+ui*n)/b where b=2**bpe | ||
1383 | for (j=1;j<ky;j++) { | ||
1384 | c+=sa[j]+t*y[j]+ui*n[j]; | ||
1385 | sa[j-1]=c & mask; | ||
1386 | c>>=bpe; | ||
1387 | } | ||
1388 | for (;j<kn;j++) { | ||
1389 | c+=sa[j]+ui*n[j]; | ||
1390 | sa[j-1]=c & mask; | ||
1391 | c>>=bpe; | ||
1392 | } | ||
1393 | sa[j-1]=c & mask; | ||
1394 | } | ||
1395 | |||
1396 | if (!greater(n,sa)) | ||
1397 | sub_(sa,n); | ||
1398 | copy_(x,sa); | ||
1399 | } | ||
1400 | |||
1401 | |||
1402 | |||
1403 | |||
1404 | //############################################################################# | ||
1405 | //############################################################################# | ||
1406 | //############################################################################# | ||
1407 | //############################################################################# | ||
1408 | //############################################################################# | ||
1409 | //############################################################################# | ||
1410 | //############################################################################# | ||
1411 | |||
1412 | |||
1413 | |||
1414 | |||
1415 | |||
1416 | //############################################################################# | ||
1417 | |||
1418 | Clipperz.Crypto.BigInt = function (aValue, aBase) { | ||
1419 | varbase; | ||
1420 | varvalue; | ||
1421 | |||
1422 | if (typeof(aValue) == 'object') { | ||
1423 | this._internalValue = aValue; | ||
1424 | } else { | ||
1425 | if (typeof(aValue) == 'undefined') { | ||
1426 | value = "0"; | ||
1427 | } else { | ||
1428 | value = aValue + ""; | ||
1429 | } | ||
1430 | |||
1431 | if (typeof(aBase) == 'undefined') { | ||
1432 | base = 10; | ||
1433 | } else { | ||
1434 | base = aBase; | ||
1435 | } | ||
1436 | |||
1437 | this._internalValue = str2bigInt(value, base, 1, 1); | ||
1438 | } | ||
1439 | |||
1440 | return this; | ||
1441 | } | ||
1442 | |||
1443 | //============================================================================= | ||
1444 | |||
1445 | MochiKit.Base.update(Clipperz.Crypto.BigInt.prototype, { | ||
1446 | |||
1447 | 'clone': function() { | ||
1448 | return new Clipperz.Crypto.BigInt(this.internalValue()); | ||
1449 | }, | ||
1450 | |||
1451 | //------------------------------------------------------------------------- | ||
1452 | |||
1453 | 'internalValue': function () { | ||
1454 | return this._internalValue; | ||
1455 | }, | ||
1456 | |||
1457 | //------------------------------------------------------------------------- | ||
1458 | |||
1459 | 'isBigInt': true, | ||
1460 | |||
1461 | //------------------------------------------------------------------------- | ||
1462 | |||
1463 | 'toString': function(aBase) { | ||
1464 | return this.asString(aBase); | ||
1465 | }, | ||
1466 | |||
1467 | //------------------------------------------------------------------------- | ||
1468 | |||
1469 | 'asString': function (aBase, minimumLength) { | ||
1470 | varresult; | ||
1471 | varbase; | ||
1472 | |||
1473 | if (typeof(aBase) == 'undefined') { | ||
1474 | base = 10; | ||
1475 | } else { | ||
1476 | base = aBase; | ||
1477 | } | ||
1478 | |||
1479 | result = bigInt2str(this.internalValue(), base).toLowerCase(); | ||
1480 | |||
1481 | if ((typeof(minimumLength) != 'undefined') && (result.length < minimumLength)) { | ||
1482 | var i, c; | ||
1483 | //MochiKit.Logging.logDebug(">>> FIXING BigInt.asString length issue") | ||
1484 | c = (minimumLength - result.length); | ||
1485 | for (i=0; i<c; i++) { | ||
1486 | result = '0' + result; | ||
1487 | } | ||
1488 | } | ||
1489 | |||
1490 | return result; | ||
1491 | }, | ||
1492 | |||
1493 | //------------------------------------------------------------------------- | ||
1494 | |||
1495 | 'asByteArray': function() { | ||
1496 | return new Clipperz.ByteArray("0x" + this.asString(16), 16); | ||
1497 | }, | ||
1498 | |||
1499 | //------------------------------------------------------------------------- | ||
1500 | |||
1501 | 'equals': function (aValue) { | ||
1502 | var result; | ||
1503 | |||
1504 | if (aValue.isBigInt) { | ||
1505 | result = equals(this.internalValue(), aValue.internalValue()); | ||
1506 | } else if (typeof(aValue) == "number") { | ||
1507 | result = equalsInt(this.internalValue(), aValue); | ||
1508 | } else { | ||
1509 | throw Clipperz.Crypt.BigInt.exception.UnknownType; | ||
1510 | } | ||
1511 | |||
1512 | return result; | ||
1513 | }, | ||
1514 | |||
1515 | //------------------------------------------------------------------------- | ||
1516 | |||
1517 | 'compare': function(aValue) { | ||
1518 | /* | ||
1519 | var result; | ||
1520 | var thisAsString; | ||
1521 | var aValueAsString; | ||
1522 | |||
1523 | thisAsString = this.asString(10); | ||
1524 | aValueAsString = aValue.asString(10); | ||
1525 | |||
1526 | result = MochiKit.Base.compare(thisAsString.length, aValueAsString.length); | ||
1527 | if (result == 0) { | ||
1528 | result = MochiKit.Base.compare(thisAsString, aValueAsString); | ||
1529 | } | ||
1530 | |||
1531 | return result; | ||
1532 | */ | ||
1533 | var result; | ||
1534 | |||
1535 | if (equals(this.internalValue(), aValue.internalValue())) { | ||
1536 | result = 0; | ||
1537 | } else if (greater(this.internalValue(), aValue.internalValue())) { | ||
1538 | result = 1; | ||
1539 | } else { | ||
1540 | result = -1; | ||
1541 | } | ||
1542 | |||
1543 | return result; | ||
1544 | }, | ||
1545 | |||
1546 | //------------------------------------------------------------------------- | ||
1547 | |||
1548 | 'add': function (aValue) { | ||
1549 | var result; | ||
1550 | |||
1551 | if (aValue.isBigInt) { | ||
1552 | result = add(this.internalValue(), aValue.internalValue()); | ||
1553 | } else { | ||
1554 | result = addInt(this.internalValue(), aValue); | ||
1555 | } | ||
1556 | |||
1557 | return new Clipperz.Crypto.BigInt(result); | ||
1558 | }, | ||
1559 | |||
1560 | //------------------------------------------------------------------------- | ||
1561 | |||
1562 | 'subtract': function (aValue) { | ||
1563 | var result; | ||
1564 | var value; | ||
1565 | |||
1566 | if (aValue.isBigInt) { | ||
1567 | value = aValue; | ||
1568 | } else { | ||
1569 | value = new Clipperz.Crypto.BigInt(aValue); | ||
1570 | } | ||
1571 | |||
1572 | result = sub(this.internalValue(), value.internalValue()); | ||
1573 | |||
1574 | return new Clipperz.Crypto.BigInt(result); | ||
1575 | }, | ||
1576 | |||
1577 | //------------------------------------------------------------------------- | ||
1578 | |||
1579 | 'multiply': function (aValue, aModule) { | ||
1580 | var result; | ||
1581 | var value; | ||
1582 | |||
1583 | if (aValue.isBigInt) { | ||
1584 | value = aValue; | ||
1585 | } else { | ||
1586 | value = new Clipperz.Crypto.BigInt(aValue); | ||
1587 | } | ||
1588 | |||
1589 | if (typeof(aModule) == 'undefined') { | ||
1590 | result = mult(this.internalValue(), value.internalValue()); | ||
1591 | } else { | ||
1592 | if (greater(this.internalValue(), value.internalValue())) { | ||
1593 | result = multMod(this.internalValue(), value.internalValue(), aModule); | ||
1594 | } else { | ||
1595 | result = multMod(value.internalValue(), this.internalValue(), aModule); | ||
1596 | } | ||
1597 | } | ||
1598 | |||
1599 | return new Clipperz.Crypto.BigInt(result); | ||
1600 | }, | ||
1601 | |||
1602 | //------------------------------------------------------------------------- | ||
1603 | |||
1604 | 'module': function (aModule) { | ||
1605 | varresult; | ||
1606 | var module; | ||
1607 | |||
1608 | if (aModule.isBigInt) { | ||
1609 | module = aModule; | ||
1610 | } else { | ||
1611 | module = new Clipperz.Crypto.BigInt(aModule); | ||
1612 | } | ||
1613 | |||
1614 | result = mod(this.internalValue(), module.internalValue()); | ||
1615 | |||
1616 | return new Clipperz.Crypto.BigInt(result); | ||
1617 | }, | ||
1618 | |||
1619 | //------------------------------------------------------------------------- | ||
1620 | |||
1621 | 'powerModule': function(aValue, aModule) { | ||
1622 | varresult; | ||
1623 | varvalue; | ||
1624 | var module; | ||
1625 | |||
1626 | if (aValue.isBigInt) { | ||
1627 | value = aValue; | ||
1628 | } else { | ||
1629 | value = new Clipperz.Crypto.BigInt(aValue); | ||
1630 | } | ||
1631 | |||
1632 | if (aModule.isBigInt) { | ||
1633 | module = aModule; | ||
1634 | } else { | ||
1635 | module = new Clipperz.Crypto.BigInt(aModule); | ||
1636 | } | ||
1637 | |||
1638 | if (aValue == -1) { | ||
1639 | result = inverseMod(this.internalValue(), module.internalValue()); | ||
1640 | } else { | ||
1641 | result = powMod(this.internalValue(), value.internalValue(), module.internalValue()); | ||
1642 | } | ||
1643 | |||
1644 | return new Clipperz.Crypto.BigInt(result); | ||
1645 | }, | ||
1646 | |||
1647 | //------------------------------------------------------------------------- | ||
1648 | |||
1649 | 'xor': function(aValue) { | ||
1650 | var result; | ||
1651 | varthisByteArray; | ||
1652 | var aValueByteArray; | ||
1653 | var xorArray; | ||
1654 | |||
1655 | thisByteArray = new Clipperz.ByteArray("0x" + this.asString(16), 16); | ||
1656 | aValueByteArray = new Clipperz.ByteArray("0x" + aValue.asString(16), 16); | ||
1657 | xorArray = thisByteArray.xorMergeWithBlock(aValueByteArray, 'right'); | ||
1658 | result = new Clipperz.Crypto.BigInt(xorArray.toHexString(), 16); | ||
1659 | |||
1660 | return result; | ||
1661 | }, | ||
1662 | |||
1663 | //------------------------------------------------------------------------- | ||
1664 | |||
1665 | 'shiftLeft': function(aNumberOfBitsToShift) { | ||
1666 | var result; | ||
1667 | var internalResult; | ||
1668 | var wholeByteToShift; | ||
1669 | var bitsLeftToShift; | ||
1670 | |||
1671 | wholeByteToShift = Math.floor(aNumberOfBitsToShift / 8); | ||
1672 | bitsLeftToShift = aNumberOfBitsToShift % 8; | ||
1673 | |||
1674 | if (wholeByteToShift == 0) { | ||
1675 | internalResult = this.internalValue(); | ||
1676 | } else { | ||
1677 | var hexValue; | ||
1678 | var i,c; | ||
1679 | |||
1680 | hexValue = this.asString(16); | ||
1681 | c = wholeByteToShift; | ||
1682 | for (i=0; i<c; i++) { | ||
1683 | hexValue += "00"; | ||
1684 | } | ||
1685 | internalResult = str2bigInt(hexValue, 16, 1, 1); | ||
1686 | } | ||
1687 | |||
1688 | if (bitsLeftToShift > 0) { | ||
1689 | leftShift_(internalResult, bitsLeftToShift); | ||
1690 | } | ||
1691 | result = new Clipperz.Crypto.BigInt(internalResult); | ||
1692 | |||
1693 | return result; | ||
1694 | }, | ||
1695 | |||
1696 | //------------------------------------------------------------------------- | ||
1697 | |||
1698 | 'bitSize': function() { | ||
1699 | return bitSize(this.internalValue()); | ||
1700 | }, | ||
1701 | |||
1702 | //------------------------------------------------------------------------- | ||
1703 | |||
1704 | 'isBitSet': function(aBitPosition) { | ||
1705 | var result; | ||
1706 | |||
1707 | if (this.asByteArray().bitAtIndex(aBitPosition) == 0) { | ||
1708 | result = false; | ||
1709 | } else { | ||
1710 | result = true; | ||
1711 | }; | ||
1712 | |||
1713 | return result; | ||
1714 | }, | ||
1715 | |||
1716 | //------------------------------------------------------------------------- | ||
1717 | __syntaxFix__: "syntax fix" | ||
1718 | |||
1719 | }); | ||
1720 | |||
1721 | //############################################################################# | ||
1722 | |||
1723 | Clipperz.Crypto.BigInt.randomPrime = function(aBitSize) { | ||
1724 | return new Clipperz.Crypto.BigInt(randTruePrime(aBitSize)); | ||
1725 | } | ||
1726 | |||
1727 | //############################################################################# | ||
1728 | //############################################################################# | ||
1729 | |||
1730 | Clipperz.Crypto.BigInt.ZERO = new Clipperz.Crypto.BigInt(0); | ||
1731 | |||
1732 | //############################################################################# | ||
1733 | |||
1734 | Clipperz.Crypto.BigInt.equals = function(a, b) { | ||
1735 | return a.equals(b); | ||
1736 | } | ||
1737 | |||
1738 | Clipperz.Crypto.BigInt.add = function(a, b) { | ||
1739 | return a.add(b); | ||
1740 | } | ||
1741 | |||
1742 | Clipperz.Crypto.BigInt.subtract = function(a, b) { | ||
1743 | return a.subtract(b); | ||
1744 | } | ||
1745 | |||
1746 | Clipperz.Crypto.BigInt.multiply = function(a, b, module) { | ||
1747 | return a.multiply(b, module); | ||
1748 | } | ||
1749 | |||
1750 | Clipperz.Crypto.BigInt.module = function(a, module) { | ||
1751 | return a.module(module); | ||
1752 | } | ||
1753 | |||
1754 | Clipperz.Crypto.BigInt.powerModule = function(a, b, module) { | ||
1755 | return a.powerModule(b, module); | ||
1756 | } | ||
1757 | |||
1758 | Clipperz.Crypto.BigInt.exception = { | ||
1759 | UnknownType: new MochiKit.Base.NamedError("Clipperz.Crypto.BigInt.exception.UnknownType") | ||
1760 | } | ||