5776637 [rkeene@sledge /home/rkeene/archive/floydssh/ssh]$ cat -n BigInteger.java
  1 /* java.math.BigInteger -- Arbitary precision integers
  2    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
  3    The file was changed by Radek Polak to work as midlet in MIDP 1.0
  4 
  5 This file is part of GNU Classpath.
  6 
  7 GNU Classpath is free software; you can redistribute it and/or modify
  8 it under the terms of the GNU General Public License as published by
  9 the Free Software Foundation; either version 2, or (at your option)
 10 any later version.
 11 
 12 GNU Classpath is distributed in the hope that it will be useful, but
 13 WITHOUT ANY WARRANTY; without even the implied warranty of
 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 15 General Public License for more details.
 16 
 17 You should have received a copy of the GNU General Public License
 18 along with GNU Classpath; see the file COPYING.  If not, write to the
 19 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 20 02111-1307 USA.
 21 
 22 Linking this library statically or dynamically with other modules is
 23 making a combined work based on this library.  Thus, the terms and
 24 conditions of the GNU General Public License cover the whole
 25 combination.
 26 
 27 As a special exception, the copyright holders of this library give you
 28 permission to link this library with independent modules to produce an
 29 executable, regardless of the license terms of these independent
 30 modules, and to copy and distribute the resulting executable under
 31 terms of your choice, provided that you also meet, for each linked
 32 independent module, the terms and conditions of the license of that
 33 module.  An independent module is a module which is not derived from
 34 or based on this library.  If you modify this library, you may extend
 35 this exception to your version of the library, but you are not
 36 obligated to do so.  If you do not wish to do so, delete this
 37 exception statement from your version. */
 38 
 39 package ssh;

 40 
 41 import java.util.Random;

 42 
 43 /**
 44  * @author Warren Levy <warrenl@cygnus.com>
 45  * @date December 20, 1999.
 46  */
 47 
 48 /**
 49  * Written using on-line Java Platform 1.2 API Specification, as well
 50  * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998) and
 51  * "Applied Cryptography, Second Edition" by Bruce Schneier (Wiley, 1996).
 52  *
 53  * Based primarily on IntNum.java BitOps.java by Per Bothner <per@bothner.com>
 54  * (found in Kawa 1.6.62).
 55  *
 56  * Status:  Believed complete and correct.
 57  */
 58 
 59 public class BigInteger
 60 {
 61   /** All integers are stored in 2's-complement form.
 62    * If words == null, the ival is the value of this BigInteger.
 63    * Otherwise, the first ival elements of words make the value
 64    * of this BigInteger, stored in little-endian order, 2's-complement form. */
 65   transient private int ival;
 66   transient private int[] words;
 67 
 68   /** We pre-allocate integers in the range minFixNum..maxFixNum. */
 69   private static final int minFixNum = -100;
 70   private static final int maxFixNum = 1024;
 71   private static final int numFixNum = maxFixNum-minFixNum+1;
 72   private static final BigInteger[] smallFixNums = new BigInteger[numFixNum];
 73 
 74   static {
 75     for (int i = numFixNum;  --i >= 0; )
 76       smallFixNums[i] = new BigInteger(i + minFixNum);
 77   }
 78 
 79   // JDK1.2

 80   public static final BigInteger ZERO = smallFixNums[-minFixNum];
 81 
 82   // JDK1.2

 83   public static final BigInteger ONE = smallFixNums[1 - minFixNum];
 84 
 85   /* Rounding modes: RADEK: just floor */
 86 //  private static final int FLOOR = 1;

 87 
 88   private BigInteger()
 89   {
 90   }
 91 
 92   /* Create a new (non-shared) BigInteger, and initialize to an int. */
 93   private BigInteger(int value)
 94   {
 95     ival = value;
 96   }
 97 
 98   // RADEK: cunstruct new BigInteger assuming that signum = 1

 99   public BigInteger( byte[] magnitude) {
100 
101     // Magnitude is always positive, so don't ever pass a sign of -1.

102     words = byteArrayToIntArray(magnitude, 0);
103     BigInteger result = make(words, words.length);
104     this.ival = result.ival;
105     this.words = result.words;
106   }
107 
108   /** Return a (possibly-shared) BigInteger with a given long value. */
109   public static BigInteger valueOf(long val)
110   {
111     if (val >= minFixNum && val <= maxFixNum)
112       return smallFixNums[(int) val - minFixNum];
113     int i = (int) val;
114     if ((long) i == val)
115       return new BigInteger(i);
116     BigInteger result = alloc(2);
117     result.ival = 2;
118     result.words[0] = i;
119     result.words[1] = (int)(val >> 32);
120     return result;
121   }
122 
123   /** Make a canonicalized BigInteger from an array of words.
124    * The array may be reused (without copying). */
125   private static BigInteger make(int[] words, int len)
126   {
127     if (words == null)
128       return valueOf(len);
129     len = BigInteger.wordsNeeded(words, len);
130     if (len <= 1)
131       return len == 0 ? ZERO : valueOf(words[0]);
132     BigInteger num = new BigInteger();
133     num.words = words;
134     num.ival = len;
135     return num;
136   }
137 
138   /** Convert a big-endian byte array to a little-endian array of words. */
139   private static int[] byteArrayToIntArray(byte[] bytes, int sign)
140   {
141     // Determine number of words needed.

142     int[] words = new int[bytes.length/4 + 1];
143     int nwords = words.length;
144 
145     // Create a int out of modulo 4 high order bytes.

146     int bptr = 0;
147     int word = sign;
148     for (int i = bytes.length % 4; i > 0; --i, bptr++)
149       word = (word << 8) | (bytes[bptr] & 0xff);
150     words[--nwords] = word;
151 
152     // Elements remaining in byte[] are a multiple of 4.

153     while (nwords > 0)
154       words[--nwords] = bytes[bptr++] << 24 |
155             (bytes[bptr++] & 0xff) << 16 |
156             (bytes[bptr++] & 0xff) << 8 |
157             (bytes[bptr++] & 0xff);
158     return words;
159   }
160 
161   /** Allocate a new non-shared BigInteger.
162    * @param nwords number of words to allocate
163    */
164   private static BigInteger alloc(int nwords)
165   {
166     BigInteger result = new BigInteger();
167     if (nwords > 1)
168     result.words = new int[nwords];
169     return result;
170   }
171 
172   /** Change words.length to nwords.
173    * We allow words.length to be upto nwords+2 without reallocating.
174    */
175   private void realloc(int nwords)
176   {
177     if (nwords == 0)
178       {
179     if (words != null)
180       {
181         if (ival > 0)
182           ival = words[0];
183         words = null;
184       }
185       }
186     else if (words == null
187          || words.length < nwords
188          || words.length > nwords + 2)
189       {
190     int[] new_words = new int [nwords];
191     if (words == null)
192       {
193         new_words[0] = ival;
194         ival = 1;
195       }
196     else
197       {
198         if (nwords < ival)
199           ival = nwords;
200         System.arraycopy(words, 0, new_words, 0, ival);
201       }
202     words = new_words;
203       }
204   }
205 
206 
207   private static int compareTo(BigInteger x, BigInteger y)
208   {
209     if (x.words == null && y.words == null)
210       return x.ival < y.ival ? -1 : x.ival > y.ival ? 1 : 0;
211     int x_len = x.words == null ? 1 : x.ival;
212     int y_len = y.words == null ? 1 : y.ival;
213     if (x_len != y_len)
214       return (x_len > y_len) ? 1 : -1;
215     return MPN.cmp(x.words, y.words, x_len);
216   }
217 
218 
219   public int compareTo(BigInteger val)
220   {
221     return compareTo(this, val);
222   }
223 
224   private final boolean isZero()
225   {
226     return words == null && ival == 0;
227   }
228 
229   private final boolean isOne()
230   {
231     return words == null && ival == 1;
232   }
233 
234   /** Calculate how many words are significant in words[0:len-1].
235    * Returns the least value x such that x>0 && words[0:x-1]==words[0:len-1],
236    * when words is viewed as a 2's complement integer.
237    */
238   private static int wordsNeeded(int[] words, int len)
239   {
240     int i = len;
241     if (i > 0)
242       {
243     int word = words[--i];
244     if (word == -1)
245       {
246         while (i > 0 && (word = words[i - 1]) < 0)
247           {
248         i--;
249         if (word != -1) break;
250           }
251       }
252     else
253       {
254         while (word == 0 && i > 0 && (word = words[i - 1]) >= 0)  i--;
255       }
256       }
257     return i + 1;
258   }
259 
260   private BigInteger canonicalize()
261   {
262     if (words != null
263     && (ival = BigInteger.wordsNeeded(words, ival)) <= 1)
264       {
265     if (ival == 1)
266       ival = words[0];
267     words = null;
268       }
269     if (words == null && ival >= minFixNum && ival <= maxFixNum)
270       return smallFixNums[ival - minFixNum];
271     return this;
272   }
273 
274   /** Add two ints, yielding a BigInteger. */
275   private static final BigInteger add(int x, int y)
276   {
277     return valueOf((long) x + (long) y);
278   }
279 
280   /** Add a BigInteger and an int, yielding a new BigInteger. */
281   private static BigInteger add(BigInteger x, int y)
282   {
283     if (x.words == null)
284       return BigInteger.add(x.ival, y);
285     BigInteger result = new BigInteger(0);
286     result.setAdd(x, y);
287     return result.canonicalize();
288   }
289 
290   /** Set this to the sum of x and y.
291    * OK if x==this. */
292   private void setAdd(BigInteger x, int y)
293   {
294     if (x.words == null)
295       {
296     set((long) x.ival + (long) y);
297     return;
298       }
299     int len = x.ival;
300     realloc(len + 1);
301     long carry = y;
302     for (int i = 0;  i < len;  i++)
303       {
304     carry += ((long) x.words[i] & 0xffffffffL);
305     words[i] = (int) carry;
306     carry >>= 32;
307       }
308     if (x.words[len - 1] < 0)
309       carry--;
310     words[len] = (int) carry;
311     ival = wordsNeeded(words, len + 1);
312   }
313 
314 
315   /** Destructively set the value of this to a long. */
316   private final void set(long y)
317   {
318     int i = (int) y;
319     if ((long) i == y)
320       {
321     ival = i;
322     words = null;
323       }
324     else
325       {
326     realloc(2);
327     words[0] = i;
328     words[1] = (int) (y >> 32);
329     ival = 2;
330       }
331   }
332 
333   /** Destructively set the value of this to the given words.
334   * The words array is reused, not copied. */
335   private final void set(int[] words, int length)
336   {
337     this.ival = length;
338     this.words = words;
339   }
340 
341   /** Destructively set the value of this to that of y. */
342   private final void set(BigInteger y)
343   {
344     if (y.words == null)
345       set(y.ival);
346     else if (this != y)
347       {
348     realloc(y.ival);
349     System.arraycopy(y.words, 0, words, 0, y.ival);
350     ival = y.ival;
351       }
352   }
353 
354   /** Add two BigIntegers, yielding their sum as another BigInteger. */
355   private static BigInteger add(BigInteger x, BigInteger y, int k)
356   {
357     if (x.words == null && y.words == null)
358       return valueOf((long) k * (long) y.ival + (long) x.ival);
359     if (k != 1)
360       y = BigInteger.times(y, valueOf(k));
361     if (x.words == null)
362       return BigInteger.add(y, x.ival);
363     if (y.words == null)
364       return BigInteger.add(x, y.ival);
365     // Both are big

366     if (y.ival > x.ival)
367       { // Swap so x is longer then y.

368     BigInteger tmp = x;  x = y;  y = tmp;
369       }
370     BigInteger result = alloc(x.ival + 1);
371     int i = y.ival;
372     long carry = MPN.add_n(result.words, x.words, y.words, i);
373     long y_ext = y.words[i - 1] < 0 ? 0xffffffffL : 0;
374     for (; i < x.ival;  i++)
375       {
376     carry += ((long) x.words[i] & 0xffffffffL) + y_ext;;
377     result.words[i] = (int) carry;
378     carry >>>= 32;
379       }
380     if (x.words[i - 1] < 0)
381       y_ext--;
382     result.words[i] = (int) (carry + y_ext);
383     result.ival = i+1;
384     return result.canonicalize();
385   }
386 
387   private static final BigInteger times(BigInteger x, int y)
388   {
389     if (y == 0)
390       return ZERO;
391     if (y == 1)
392       return x;
393     int[] xwords = x.words;
394     int xlen = x.ival;
395     if (xwords == null)
396       return valueOf((long) xlen * (long) y);
397     BigInteger result = BigInteger.alloc(xlen + 1);
398     result.words[xlen] = MPN.mul_1(result.words, xwords, xlen, y);
399     result.ival = xlen + 1;
400     return result.canonicalize();
401   }
402 
403   private static final BigInteger times(BigInteger x, BigInteger y)
404   {
405     if (y.words == null)
406       return times(x, y.ival);
407     if (x.words == null)
408       return times(y, x.ival);
409     int[] xwords;
410     int[] ywords;
411     int xlen = x.ival;
412     int ylen = y.ival;
413     xwords = x.words;
414     ywords = y.words;
415     // Swap if x is shorter then y.

416     if (xlen < ylen)
417       {
418     int[] twords = xwords;  xwords = ywords;  ywords = twords;
419     int tlen = xlen;  xlen = ylen;  ylen = tlen;
420       }
421     BigInteger result = BigInteger.alloc(xlen+ylen);
422     MPN.mul(result.words, xwords, xlen, ywords, ylen);
423     result.ival = xlen+ylen;
424     return result.canonicalize();
425   }
426 
427 
428 
429   private static void divide(long x, long y,
430                  BigInteger quotient, BigInteger remainder)
431   {
432     boolean xNegative, yNegative;
433     if (x < 0)
434       {
435     xNegative = true;
436     if (x == Long.MIN_VALUE)
437       {
438         divide(valueOf(x), valueOf(y),
439            quotient, remainder);
440         return;
441       }
442     x = -x;
443       }
444     else
445       xNegative = false;
446 
447     if (y < 0)
448       {
449     yNegative = true;
450     if (y == Long.MIN_VALUE)
451       {
452           divide(valueOf(x), valueOf(y),
453               quotient, remainder);
454         return;
455       }
456     y = -y;
457       }
458     else
459       yNegative = false;
460 
461     long q = x / y;
462     long r = x % y;
463     boolean qNegative = xNegative ^ yNegative;
464 
465     boolean add_one = false;
466     if (r != 0)
467       {
468         if (qNegative)
469           add_one = true;
470       }
471     if (quotient != null)
472       {
473     if (add_one)
474       q++;
475     if (qNegative)
476       q = -q;
477     quotient.set(q);
478       }
479     if (remainder != null)
480       {
481     // The remainder is by definition: X-Q*Y

482     if (add_one)
483       {
484         // Subtract the remainder from Y.

485         r = y - r;
486         // In this case, abs(Q*Y) > abs(X).

487         // So sign(remainder) = -sign(X).

488         xNegative = ! xNegative;
489       }
490     else
491       {
492         // If !add_one, then: abs(Q*Y) <= abs(X).

493         // So sign(remainder) = sign(X).

494       }
495     if (xNegative)
496       r = -r;
497     remainder.set(r);
498       }
499   }
500 
501   /** Divide two integers, yielding quotient and remainder.
502    * @param x the numerator in the division
503    * @param y the denominator in the division
504    * @param quotient is set to the quotient of the result (iff quotient!=null)
505    * @param remainder is set to the remainder of the result
506    *  (iff remainder!=null)
507    * @param rounding_mode one of FLOOR, CEILING, TRUNCATE, or ROUND.
508    */
509   private static void divide(BigInteger x, BigInteger y,
510                  BigInteger quotient, BigInteger remainder)
511   {
512     if ((x.words == null || x.ival <= 2)
513     && (y.words == null || y.ival <= 2))
514       {
515     long x_l = x.longValue();
516     long y_l = y.longValue();
517     if (x_l != Long.MIN_VALUE && y_l != Long.MIN_VALUE)
518       {
519         divide(x_l, y_l, quotient, remainder);
520         return;
521       }
522       }
523 
524     int ylen = y.words == null ? 1 : y.ival;
525     int[] ywords = new int[ylen];
526     y.getAbsolute(ywords);
527     while (ylen > 1 && ywords[ylen - 1] == 0)  ylen--;
528 
529     int xlen = x.words == null ? 1 : x.ival;
530     int[] xwords = new int[xlen+2];
531     x.getAbsolute(xwords);
532     while (xlen > 1 && xwords[xlen-1] == 0)  xlen--;
533 
534     int qlen, rlen;
535 
536     int cmpval = MPN.cmp(xwords, xlen, ywords, ylen);
537     if (cmpval < 0)  // abs(x) < abs(y)

538       { // quotient = 0;  remainder = num.

539     int[] rwords = xwords;  xwords = ywords;  ywords = rwords;
540     rlen = xlen;  qlen = 1;  xwords[0] = 0;
541       }
542     else if (cmpval == 0)  // abs(x) == abs(y)

543       {
544     xwords[0] = 1;  qlen = 1;  // quotient = 1

545     ywords[0] = 0;  rlen = 1;  // remainder = 0;

546       }
547     else if (ylen == 1)
548       {
549     qlen = xlen;
550     // Need to leave room for a word of leading zeros if dividing by 1

551     // and the dividend has the high bit set.  It might be safe to

552     // increment qlen in all cases, but it certainly is only necessary

553     // in the following case.

554     if (ywords[0] == 1 && xwords[xlen-1] < 0)
555       qlen++;
556     rlen = 1;
557     ywords[0] = MPN.divmod_1(xwords, xwords, xlen, ywords[0]);
558       }
559     else  // abs(x) > abs(y)

560       {
561     // Normalize the denominator, i.e. make its most significant bit set by

562     // shifting it normalization_steps bits to the left.  Also shift the

563     // numerator the same number of steps (to keep the quotient the same!).

564 
565     int nshift = MPN.count_leading_zeros(ywords[ylen - 1]);
566     if (nshift != 0)
567       {
568         // Shift up the denominator setting the most significant bit of

569         // the most significant word.

570         MPN.lshift(ywords, 0, ywords, ylen, nshift);
571 
572         // Shift up the numerator, possibly introducing a new most

573         // significant word.

574         int x_high = MPN.lshift(xwords, 0, xwords, xlen, nshift);
575         xwords[xlen++] = x_high;
576       }
577 
578     if (xlen == ylen)
579       xwords[xlen++] = 0;
580     MPN.divide(xwords, xlen, ywords, ylen);
581     rlen = ylen;
582     MPN.rshift0 (ywords, xwords, 0, rlen, nshift);
583 
584     qlen = xlen + 1 - ylen;
585     if (quotient != null)
586       {
587         for (int i = 0;  i < qlen;  i++)
588           xwords[i] = xwords[i+ylen];
589       }
590       }
591 
592     if (ywords[rlen-1] < 0)
593       {
594         ywords[rlen] = 0;
595         rlen++;
596       }
597 
598     // Now the quotient is in xwords, and the remainder is in ywords.

599 
600     if (quotient != null)
601     quotient.set(xwords, qlen);
602     if (remainder != null)
603     // The remainder is by definition: X-Q*Y

604     remainder.set(ywords, rlen);
605   }
606 
607 
608   public BigInteger mod(BigInteger m)
609   {
610     BigInteger rem = new BigInteger();
611     divide(this, m, null, rem);
612     return rem.canonicalize();
613   }
614 
615 
616   public BigInteger modPow(BigInteger exponent, BigInteger m)
617   {
618     if (exponent.isOne())
619       return mod(m);
620 
621     // To do this naively by first raising this to the power of exponent

622     // and then performing modulo m would be extremely expensive, especially

623     // for very large numbers.  The solution is found in Number Theory

624     // where a combination of partial powers and moduli can be done easily.

625     //

626     // We'll use the algorithm for Additive Chaining which can be found on

627     // p. 244 of "Applied Cryptography, Second Edition" by Bruce Schneier.

628     BigInteger s = ONE;
629     BigInteger t = this;
630     BigInteger u = exponent;
631 
632     while (!u.isZero())
633       {
634     if (u.and(ONE).isOne())
635       s = times(s, t).mod(m);
636 //  u = u.shiftRight(1);

637         u = valueOf( u.ival >> 1 );
638     t = times(t, t).mod(m);
639       }
640 
641     return s;
642   }
643 
644   public long longValue()
645   {
646     if (words == null)
647       return ival;
648     if (ival == 1)
649       return words[0];
650     return ((long)words[1] << 32) + ((long)words[0] & 0xffffffffL);
651   }
652 
653 
654 
655   /** Copy the abolute value of this into an array of words.
656    * Assumes words.length >= (this.words == null ? 1 : this.ival).
657    * Result is zero-extended, but need not be a valid 2's complement number.
658    */
659   private void getAbsolute(int[] words)
660   {
661     int len;
662     if (this.words == null)
663       {
664     len = 1;
665     words[0] = this.ival;
666       }
667     else
668       {
669     len = this.ival;
670     for (int i = len;  --i >= 0; )
671       words[i] = this.words[i];
672       }
673     for (int i = words.length;  --i > len; )
674       words[i] = 0;
675   }
676 
677   /** Calculates ceiling(log2(this < 0 ? -this : this+1))
678    * See Common Lisp: the Language, 2nd ed, p. 361.
679    */
680   public int bitLength()
681   {
682     if (words == null)
683       return MPN.intLength(ival);
684       return MPN.intLength(words, ival);
685   }
686 
687   public byte[] toByteArray()
688   {
689     // Determine number of bytes needed.  The method bitlength returns

690     // the size without the sign bit, so add one bit for that and then

691     // add 7 more to emulate the ceil function using integer math.

692     byte[] bytes = new byte[(bitLength() + 1 + 7) / 8];
693     int nbytes = bytes.length;
694 
695     int wptr = 0;
696     int word;
697 
698     // Deal with words array until one word or less is left to process.

699     // If BigInteger is an int, then it is in ival and nbytes will be <= 4.

700     while (nbytes > 4)
701       {
702     word = words[wptr++];
703     for (int i = 4; i > 0; --i, word >>= 8)
704           bytes[--nbytes] = (byte) word;
705       }
706 
707     // Deal with the last few bytes.  If BigInteger is an int, use ival.

708     word = (words == null) ? ival : words[wptr];
709     for ( ; nbytes > 0; word >>= 8)
710       bytes[--nbytes] = (byte) word;
711 
712     return bytes;
713   }
714 
715 
716 
717   /** Return the logical (bit-wise) "and" of a BigInteger and an int. */
718   private static BigInteger and(BigInteger x, int y)
719   {
720     if (x.words == null)
721       return valueOf(x.ival & y);
722     if (y >= 0)
723       return valueOf(x.words[0] & y);
724     int len = x.ival;
725     int[] words = new int[len];
726     words[0] = x.words[0] & y;
727     while (--len > 0)
728       words[len] = x.words[len];
729     return make(words, x.ival);
730   }
731 
732   /** Return the logical (bit-wise) "and" of two BigIntegers. */
733   public BigInteger and(BigInteger y)
734   {
735     if (y.words == null)
736       return and(this, y.ival);
737     else if (words == null)
738       return and(y, ival);
739 
740     BigInteger x = this;
741     if (ival < y.ival)
742       {
743         BigInteger temp = this;  x = y;  y = temp;
744       }
745     int i;
746     int len = y.ival;
747     int[] words = new int[len];
748     for (i = 0;  i < y.ival;  i++)
749       words[i] = x.words[i] & y.words[i];
750     for ( ; i < len;  i++)
751       words[i] = x.words[i];
752     return make(words, len);
753   }
754 }
5776638 [rkeene@sledge /home/rkeene/archive/floydssh/ssh]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2004-03-06 22:44:06