ISAACEngine.java 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. package com.oblivm.backend.rand;
  2. import java.security.SecureRandom;
  3. import java.security.SecureRandomSpi;
  4. /**
  5. * This class defines the Service Provider for the ISAAC algorithm.
  6. *
  7. * @author Daniel Berlin
  8. */
  9. public class ISAACEngine extends SecureRandomSpi {
  10. /**
  11. *
  12. */
  13. private static final long serialVersionUID = 1L;
  14. private ISAACAlgorithm isaac;
  15. private byte[] remainder;
  16. private int remCount = 0;
  17. /**
  18. * Creates a new instance and seeds it with random data obtained from
  19. * <code>java.security.SecureRandom</code>'s <code>getSeed()</code> method.
  20. */
  21. public ISAACEngine() {
  22. byte[] temp = new byte[1024];// SecureRandom.getSeed (1024);
  23. new SecureRandom().nextBytes(temp);
  24. this.isaac = new ISAACAlgorithm(ISAACEngine.packToIntArray(temp));
  25. }
  26. /**
  27. * Returns the given number of seed bytes computed using the ISAAC
  28. * algorithm.<br>
  29. * It just calls <code>engineNextBytes()</code> internally.<br>
  30. * This call may be used to seed other random number generators.
  31. *
  32. * @param numBytes
  33. * The number of seed bytes to generate.
  34. * @return The seed bytes.
  35. */
  36. public byte[] engineGenerateSeed(int numBytes) {
  37. byte[] seed = new byte[numBytes];
  38. this.engineNextBytes(seed);
  39. return (seed);
  40. }
  41. /**
  42. * Generates a user-specified number of random bytes.
  43. *
  44. * @param bytes
  45. * The array to fill with random bytes.
  46. */
  47. public void engineNextBytes(byte[] bytes) {
  48. int index = 0;
  49. int todo;
  50. byte[] output = this.remainder;
  51. // First use remainder from last time
  52. int rC = this.remCount;
  53. if (rC > 0) {
  54. todo = (bytes.length - index) < (4 - rC) ? (bytes.length - index) : (4 - rC);
  55. for (int i = 0; i < todo; i++, rC++)
  56. bytes[i] = output[rC];
  57. this.remCount += todo;
  58. index += todo;
  59. }
  60. // If we need more bytes, get them
  61. while (index < bytes.length) {
  62. output = ISAACEngine.toByteArray(this.isaac.nextInt());
  63. todo = (bytes.length - index) > 4 ? 4 : (bytes.length - index);
  64. for (int i = 0; i < todo; i++, index++)
  65. bytes[index] = output[i];
  66. this.remCount += todo;
  67. }
  68. // Store remainder for next time
  69. this.remainder = output;
  70. this.remCount %= 4;
  71. }
  72. /**
  73. * Reseeds this random object. The given seed supplements, rather than
  74. * replaces, the existing seed.
  75. *
  76. * @param seed
  77. * The seed.
  78. */
  79. public void engineSetSeed(byte[] seed) {
  80. this.isaac.supplementSeed(ISAACEngine.packToIntArray(seed));
  81. }
  82. // ====================================
  83. // ===== private "helper" methods =====
  84. // ====================================
  85. private static final int[] mask = new int[] { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF };
  86. /**
  87. * Returns a byte array containing the two's-complement representation of
  88. * the integer.<br>
  89. * The byte array will be in big-endian byte-order with a fixes length of 4
  90. * (the least significant byte is in the 4th element).<br>
  91. * <br>
  92. * <u>Example:</u><br>
  93. * <code>toByteArray(258)</code> returns { 0, 0, 1, 2 },<br>
  94. * <code>BigInteger.valueOf(258).toByteArray()</code> returns { 1, 2 }.
  95. *
  96. * @param intValue
  97. * The integer to be converted.
  98. * @return The byte array of length 4.
  99. */
  100. private static byte[] toByteArray(final int intValue) {
  101. int byteNum = (40 - numberOfLeadingZeros(intValue < 0 ? ~intValue : intValue)) / 8;
  102. byte[] byteArray = new byte[4];
  103. for (int i = 0; i < byteNum; i++)
  104. byteArray[3 - i] = (byte) (intValue >>> (i * 8));
  105. return (byteArray);
  106. }
  107. /**
  108. * Returns the number of zero bits preceding the highest-order ("leftmost")
  109. * one-bit in the two's complement binary representation of the specified
  110. * integer value.
  111. *
  112. * @return The number of zero bits preceding the highest-order one-bit in
  113. * the two's complement binary representation of the specified
  114. * integer value, or 32 if the value is equal to zero.
  115. */
  116. private static int numberOfLeadingZeros(int intValue) {
  117. if (intValue == 0)
  118. return (32);
  119. int num = 1;
  120. for (int i = 16, j = 16; j > 1; i += j) {
  121. if (intValue >>> i == 0) {
  122. num += j;
  123. intValue <<= j;
  124. }
  125. j /= 2;
  126. }
  127. num -= intValue >>> 31;
  128. return (num);
  129. }
  130. /**
  131. * Creates an array of integers and "packs" the bytes from the byte array
  132. * into it.<br>
  133. * This method returns an integer array of length zero if <code>ba</code> is
  134. * <code>null</code>.<br>
  135. * <br>
  136. * <u>Example:</u><br>
  137. * <code>packToIntArray(new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5 })</code>
  138. * returns an integer array<br>
  139. * containing the values <code>0x01020304</code> and <code>0x00000005</code>
  140. * .
  141. *
  142. * @param ba
  143. * The byte array, may be <code>null</code>.
  144. * @return An array of integers containing the "packed" byte(s).
  145. */
  146. private static int[] packToIntArray(final byte[] ba) {
  147. if (ba == null)
  148. return (new int[0]);
  149. int[] ia = new int[(ba.length + 3) / 4];
  150. for (int i = 0; i < ia.length; i++) {
  151. int restLen = Math.min(4, ba.length - i * 4);
  152. for (int b = 0; b < restLen; b++)
  153. ia[i] |= (ba[b + i * 4] << ((restLen - b - 1) * 8)) & mask[b + 4 - restLen];
  154. }
  155. return (ia);
  156. }
  157. }