]> source.dussan.org Git - jgit.git/commitdiff
SHA-1: collision detection support 52/91852/8
authorShawn Pearce <spearce@spearce.org>
Sat, 25 Feb 2017 19:43:42 +0000 (11:43 -0800)
committerShawn Pearce <spearce@spearce.org>
Wed, 1 Mar 2017 00:38:43 +0000 (16:38 -0800)
Update SHA1 class to include a Java port of sha1dc[1]'s ubc_check,
which can detect the attack pattern used by the SHAttered[2] authors.

Given the shattered example files that have the same SHA-1, this
modified implementation can identify there is risk of collision given
only one file in the pair:

  $ jgit ...
  [main] WARN org.eclipse.jgit.util.sha1.SHA1 - SHA-1 collision 38762cf7f55934b34d179ae6a4c80cadccbb7f0a

When JGit detects probability of a collision the SHA1 class now warns
on the logger, reporting the object's SHA-1 hash, and then throws a
Sha1CollisionException to the caller.

From the paper[3] by Marc Stevens, the probability of a false positive
identification of a collision is about 14 * 2^(-160), sufficiently low
enough for any detected collision to likely be a real collision.

git-core[4] may adopt sha1dc before the system migrates to an entirely
new hash function.  This commit enables JGit to remain compatible with
that move to sha1dc, and help protect users by warning if similar
attacks as SHAttered are identified.

Performance declined about 8% (detection off), now:

  MessageDigest        238.41 MiB/s
  MessageDigest        244.52 MiB/s
  MessageDigest        244.06 MiB/s
  MessageDigest        242.58 MiB/s

  SHA1                 216.77 MiB/s (was ~240.83 MiB/s)
  SHA1                 220.98 MiB/s
  SHA1                 221.76 MiB/s
  SHA1                 221.34 MiB/s

This decline in throughput is attributed to the step loop unrolling in
compress(), which was necessary to easily fit the UbcCheck logic into
the hash function.  Using helper functions s1-s4 reduces the code
explosion, providing acceptable throughput.

With detection enabled (default):

  SHA1 detectCollision 180.12 MiB/s
  SHA1 detectCollision 181.59 MiB/s
  SHA1 detectCollision 181.64 MiB/s
  SHA1 detectCollision 182.24 MiB/s

  sha1dc (native C)   ~206.28 MiB/s
  sha1dc (native C)   ~204.47 MiB/s
  sha1dc (native C)   ~203.74 MiB/s

Average time across 100,000 calls to hash 4100 bytes (such as a commit
or tree) for the various algorithms available to JGit also shows SHA1
is slower than MessageDigest, but by an acceptable margin:

  MessageDigest        17 usec
  SHA1                 18 usec
  SHA1 detectCollision 22 usec

Time to index-pack for git.git (217982 objects, 69 MiB) has increased:

  MessageDigest   SHA1 w/ detectCollision
  -------------   -----------------------
         20.12s   25.25s
         19.87s   25.48s
         20.04s   25.26s

    avg  20.01s   25.33s    +26%

Being implemented in Java with these additional safety checks is
clearly a penalty, but throughput is still acceptable given the
increased security against object name collisions.

[1] https://github.com/cr-marcstevens/sha1collisiondetection
[2] https://shattered.it/
[3] https://marc-stevens.nl/research/papers/C13-S.pdf
[4] https://public-inbox.org/git/20170223230621.43anex65ndoqbgnf@sigill.intra.peff.net/

Change-Id: I9fe4c6d8fc5e5a661af72cd3246c9e67b1b9fee6

org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/sha1/shattered-1.pdf [new file with mode: 0644]
org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/sha1/shattered-2.pdf [new file with mode: 0644]
org.eclipse.jgit.test/tst/org/eclipse/jgit/util/sha1/SHA1Test.java
org.eclipse.jgit/about.html
org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.compress [new file with mode: 0644]
org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java
org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.recompress [new file with mode: 0644]
org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/Sha1CollisionException.java [new file with mode: 0644]
org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/UbcCheck.java [new file with mode: 0644]

diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/sha1/shattered-1.pdf b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/sha1/shattered-1.pdf
new file mode 100644 (file)
index 0000000..ba9aaa1
Binary files /dev/null and b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/sha1/shattered-1.pdf differ
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/sha1/shattered-2.pdf b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/sha1/shattered-2.pdf
new file mode 100644 (file)
index 0000000..b621eec
Binary files /dev/null and b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/sha1/shattered-2.pdf differ
index 8642db79e3982d70ca9cc132b9fc3cce51b1c64d..07789898a4c3ec8fc97eac47ecc7298b81371b77 100644 (file)
 package org.eclipse.jgit.util.sha1;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
 import java.nio.charset.StandardCharsets;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 
+import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.util.IO;
 import org.junit.Test;
 
 public class SHA1Test {
@@ -124,4 +132,107 @@ public class SHA1Test {
                assertEquals(exp, s1);
                assertEquals(exp, s2);
        }
+
+       @Test
+       public void shatteredCollision()
+                       throws IOException, NoSuchAlgorithmException {
+               byte[] pdf1 = read("shattered-1.pdf", 422435);
+               byte[] pdf2 = read("shattered-2.pdf", 422435);
+               MessageDigest md;
+               SHA1 s;
+
+               // SHAttered attack generated these PDFs to have identical SHA-1.
+               ObjectId bad = ObjectId
+                               .fromString("38762cf7f55934b34d179ae6a4c80cadccbb7f0a");
+               md = MessageDigest.getInstance("SHA-1");
+               md.update(pdf1);
+               assertEquals("shattered-1 collides", bad,
+                               ObjectId.fromRaw(md.digest()));
+               s = SHA1.newInstance().setDetectCollision(false);
+               s.update(pdf1);
+               assertEquals("shattered-1 collides", bad, s.toObjectId());
+
+               md = MessageDigest.getInstance("SHA-1");
+               md.update(pdf2);
+               assertEquals("shattered-2 collides", bad,
+                               ObjectId.fromRaw(md.digest()));
+               s = SHA1.newInstance().setDetectCollision(false);
+               s.update(pdf2);
+               assertEquals("shattered-2 collides", bad, s.toObjectId());
+
+               // SHA1 with detectCollision shouldn't be fooled.
+               s = SHA1.newInstance().setDetectCollision(true);
+               s.update(pdf1);
+               try {
+                       s.digest();
+                       fail("expected " + Sha1CollisionException.class.getSimpleName());
+               } catch (Sha1CollisionException e) {
+                       assertEquals(e.getMessage(),
+                                       "SHA-1 collision detected on " + bad.name());
+               }
+
+               s = SHA1.newInstance().setDetectCollision(true);
+               s.update(pdf2);
+               try {
+                       s.digest();
+                       fail("expected " + Sha1CollisionException.class.getSimpleName());
+               } catch (Sha1CollisionException e) {
+                       assertEquals(e.getMessage(),
+                                       "SHA-1 collision detected on " + bad.name());
+               }
+       }
+
+       @Test
+       public void shatteredStoredInGitBlob() throws IOException {
+               byte[] pdf1 = read("shattered-1.pdf", 422435);
+               byte[] pdf2 = read("shattered-2.pdf", 422435);
+
+               // Although the prior test detects the chance of a collision, adding
+               // the Git blob header permutes the data enough for this specific
+               // attack example to not be detected as a collision. (A different file
+               // pair that takes the Git header into account however, would.)
+               ObjectId id1 = blob(pdf1, SHA1.newInstance().setDetectCollision(true));
+               ObjectId id2 = blob(pdf2, SHA1.newInstance().setDetectCollision(true));
+
+               assertEquals(
+                               ObjectId.fromString("ba9aaa145ccd24ef760cf31c74d8f7ca1a2e47b0"),
+                               id1);
+               assertEquals(
+                               ObjectId.fromString("b621eeccd5c7edac9b7dcba35a8d5afd075e24f2"),
+                               id2);
+       }
+
+       @Test
+       public void detectsShatteredByDefault() throws IOException {
+               assumeTrue(System.getProperty("org.eclipse.jgit.util.sha1.detectCollision") == null);
+               assumeTrue(System.getProperty("org.eclipse.jgit.util.sha1.safeHash") == null);
+
+               byte[] pdf1 = read("shattered-1.pdf", 422435);
+               SHA1 s = SHA1.newInstance();
+               s.update(pdf1);
+               try {
+                       s.digest();
+                       fail("expected " + Sha1CollisionException.class.getSimpleName());
+               } catch (Sha1CollisionException e) {
+                       assertTrue("shattered-1 detected", true);
+               }
+       }
+
+       private static ObjectId blob(byte[] pdf1, SHA1 s) {
+               s.update(Constants.encodedTypeString(Constants.OBJ_BLOB));
+               s.update((byte) ' ');
+               s.update(Constants.encodeASCII(pdf1.length));
+               s.update((byte) 0);
+               s.update(pdf1);
+               return s.toObjectId();
+       }
+
+       private byte[] read(String name, int sizeHint) throws IOException {
+               try (InputStream in = getClass().getResourceAsStream(name)) {
+                       ByteBuffer buf = IO.readWholeStream(in, sizeHint);
+                       byte[] r = new byte[buf.remaining()];
+                       buf.get(r);
+                       return r;
+               }
+       }
 }
index 01a267187508cfcac84fc15a59de82e95cf8f12c..f971af18d0e7267473de028b1b29493745dccf25 100644 (file)
     margin-top:  0.05em;
     margin-bottom: 0.05em;
     }
+  .ubc-name {
+    margin-left: 0.5in;
+    white-space: pre;
+  }
   </style>
 
 </head>
@@ -54,6 +58,39 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 POSSIBILITY OF SUCH DAMAGE.</p>
 
+<hr>
+<p><b>SHA-1 UbcCheck - MIT</b></p>
+
+<p>Copyright (c) 2017:</p>
+<div class="ubc-name">
+Marc Stevens
+Cryptology Group
+Centrum Wiskunde & Informatica
+P.O. Box 94079, 1090 GB Amsterdam, Netherlands
+marc@marc-stevens.nl
+</div>
+<div class="ubc-name">
+Dan Shumow
+Microsoft Research
+danshu@microsoft.com
+</div>
+<p>Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+</p>
+<ul><li>The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.</li></ul>
+<p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.</p>
+
 </body>
 
 </html>
index 76d35b0a3b801ce6fce0dc24c458bc5d0d128dd3..6ac5813e73dab8f17ea8e31f7e6371c1639b16d9 100644 (file)
@@ -564,6 +564,7 @@ selectingCommits=Selecting commits
 sequenceTooLargeForDiffAlgorithm=Sequence too large for difference algorithm.
 serviceNotEnabledNoName=Service not enabled
 serviceNotPermitted={0} not permitted
+sha1CollisionDetected1=SHA-1 collision detected on {0}
 shallowCommitsAlreadyInitialized=Shallow commits have already been initialized
 shallowPacksRequireDepthWalk=Shallow packs require a DepthWalk
 shortCompressedStreamAt=Short compressed stream at {0}
index 37499bbb3edcbaca07ba42251ee3cbfe9d3bb426..a81c93a013b628662522814a8ab4fef5efc01954 100644 (file)
@@ -623,6 +623,7 @@ public class JGitText extends TranslationBundle {
        /***/ public String sequenceTooLargeForDiffAlgorithm;
        /***/ public String serviceNotEnabledNoName;
        /***/ public String serviceNotPermitted;
+       /***/ public String sha1CollisionDetected1;
        /***/ public String shallowCommitsAlreadyInitialized;
        /***/ public String shallowPacksRequireDepthWalk;
        /***/ public String shortCompressedStreamAt;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.compress b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.compress
new file mode 100644 (file)
index 0000000..3a80fd2
--- /dev/null
@@ -0,0 +1,92 @@
+/* Template for compress method; run through cpp. */
+
+#define ROUND1_STEP(a, b, c, d, e, T) e += s1(a,b,c,d,w[T]); b = rotateLeft(b, 30)
+#define ROUND2_STEP(a, b, c, d, e, T) e += s2(a,b,c,d,w[T]); b = rotateLeft(b, 30)
+#define ROUND3_STEP(a, b, c, d, e, T) e += s3(a,b,c,d,w[T]); b = rotateLeft(b, 30)
+#define ROUND4_STEP(a, b, c, d, e, T) e += s4(a,b,c,d,w[T]); b = rotateLeft(b, 30)
+
+       ROUND1_STEP(a, b, c, d, e, 0);
+       ROUND1_STEP(e, a, b, c, d, 1);
+       ROUND1_STEP(d, e, a, b, c, 2);
+       ROUND1_STEP(c, d, e, a, b, 3);
+       ROUND1_STEP(b, c, d, e, a, 4);
+       ROUND1_STEP(a, b, c, d, e, 5);
+       ROUND1_STEP(e, a, b, c, d, 6);
+       ROUND1_STEP(d, e, a, b, c, 7);
+       ROUND1_STEP(c, d, e, a, b, 8);
+       ROUND1_STEP(b, c, d, e, a, 9);
+       ROUND1_STEP(a, b, c, d, e, 10);
+       ROUND1_STEP(e, a, b, c, d, 11);
+       ROUND1_STEP(d, e, a, b, c, 12);
+       ROUND1_STEP(c, d, e, a, b, 13);
+       ROUND1_STEP(b, c, d, e, a, 14);
+       ROUND1_STEP(a, b, c, d, e, 15);
+       ROUND1_STEP(e, a, b, c, d, 16);
+       ROUND1_STEP(d, e, a, b, c, 17);
+       ROUND1_STEP(c, d, e, a, b, 18);
+       ROUND1_STEP(b, c, d, e, a, 19);
+
+       ROUND2_STEP(a, b, c, d, e, 20);
+       ROUND2_STEP(e, a, b, c, d, 21);
+       ROUND2_STEP(d, e, a, b, c, 22);
+       ROUND2_STEP(c, d, e, a, b, 23);
+       ROUND2_STEP(b, c, d, e, a, 24);
+       ROUND2_STEP(a, b, c, d, e, 25);
+       ROUND2_STEP(e, a, b, c, d, 26);
+       ROUND2_STEP(d, e, a, b, c, 27);
+       ROUND2_STEP(c, d, e, a, b, 28);
+       ROUND2_STEP(b, c, d, e, a, 29);
+       ROUND2_STEP(a, b, c, d, e, 30);
+       ROUND2_STEP(e, a, b, c, d, 31);
+       ROUND2_STEP(d, e, a, b, c, 32);
+       ROUND2_STEP(c, d, e, a, b, 33);
+       ROUND2_STEP(b, c, d, e, a, 34);
+       ROUND2_STEP(a, b, c, d, e, 35);
+       ROUND2_STEP(e, a, b, c, d, 36);
+       ROUND2_STEP(d, e, a, b, c, 37);
+       ROUND2_STEP(c, d, e, a, b, 38);
+       ROUND2_STEP(b, c, d, e, a, 39);
+
+       ROUND3_STEP(a, b, c, d, e, 40);
+       ROUND3_STEP(e, a, b, c, d, 41);
+       ROUND3_STEP(d, e, a, b, c, 42);
+       ROUND3_STEP(c, d, e, a, b, 43);
+       ROUND3_STEP(b, c, d, e, a, 44);
+       ROUND3_STEP(a, b, c, d, e, 45);
+       ROUND3_STEP(e, a, b, c, d, 46);
+       ROUND3_STEP(d, e, a, b, c, 47);
+       ROUND3_STEP(c, d, e, a, b, 48);
+       ROUND3_STEP(b, c, d, e, a, 49);
+       ROUND3_STEP(a, b, c, d, e, 50);
+       ROUND3_STEP(e, a, b, c, d, 51);
+       ROUND3_STEP(d, e, a, b, c, 52);
+       ROUND3_STEP(c, d, e, a, b, 53);
+       ROUND3_STEP(b, c, d, e, a, 54);
+       ROUND3_STEP(a, b, c, d, e, 55);
+       ROUND3_STEP(e, a, b, c, d, 56);
+       ROUND3_STEP(d, e, a, b, c, 57);
+       state58.save(a, b, c, d, e);
+       ROUND3_STEP(c, d, e, a, b, 58);
+       ROUND3_STEP(b, c, d, e, a, 59);
+
+       ROUND4_STEP(a, b, c, d, e, 60);
+       ROUND4_STEP(e, a, b, c, d, 61);
+       ROUND4_STEP(d, e, a, b, c, 62);
+       ROUND4_STEP(c, d, e, a, b, 63);
+       ROUND4_STEP(b, c, d, e, a, 64);
+       state65.save(a, b, c, d, e);
+       ROUND4_STEP(a, b, c, d, e, 65);
+       ROUND4_STEP(e, a, b, c, d, 66);
+       ROUND4_STEP(d, e, a, b, c, 67);
+       ROUND4_STEP(c, d, e, a, b, 68);
+       ROUND4_STEP(b, c, d, e, a, 69);
+       ROUND4_STEP(a, b, c, d, e, 70);
+       ROUND4_STEP(e, a, b, c, d, 71);
+       ROUND4_STEP(d, e, a, b, c, 72);
+       ROUND4_STEP(c, d, e, a, b, 73);
+       ROUND4_STEP(b, c, d, e, a, 74);
+       ROUND4_STEP(a, b, c, d, e, 75);
+       ROUND4_STEP(e, a, b, c, d, 76);
+       ROUND4_STEP(d, e, a, b, c, 77);
+       ROUND4_STEP(c, d, e, a, b, 78);
+       ROUND4_STEP(b, c, d, e, a, 79);
index 293b4ac56d61fcb6a90c31f530642fc70b50243a..544971199ef793bf36a0cbf0e487c85602f67f4a 100644 (file)
 
 package org.eclipse.jgit.util.sha1;
 
+import static java.lang.Integer.lowestOneBit;
+import static java.lang.Integer.numberOfTrailingZeros;
+import static java.lang.Integer.rotateLeft;
+import static java.lang.Integer.rotateRight;
+
 import java.util.Arrays;
 
 import org.eclipse.jgit.lib.MutableObjectId;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.util.NB;
+import org.eclipse.jgit.util.SystemReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Pure Java implementation of SHA-1 from FIPS 180-1 / RFC 3174.
  *
  * <p>
  * See <a href="https://tools.ietf.org/html/rfc3174">RFC 3174</a>.
+ * <p>
+ * Unlike MessageDigest, this implementation includes the algorithm used by
+ * {@code sha1dc} to detect cryptanalytic collision attacks against SHA-1, such
+ * as the one used by <a href="https://shattered.it/">SHAttered</a>. See
+ * <a href="https://github.com/cr-marcstevens/sha1collisiondetection">
+ * sha1collisiondetection</a> for more information.
+ * <p>
+ * When detectCollision is true (default), this implementation throws
+ * {@link Sha1CollisionException} from any digest method if a potential
+ * collision was detected.
  *
  * @since 4.7
  */
 public class SHA1 {
+       private static Logger LOG = LoggerFactory.getLogger(SHA1.class);
+       private static final boolean DETECT_COLLISIONS;
+
+       static {
+               SystemReader sr = SystemReader.getInstance();
+               String v = sr.getProperty("org.eclipse.jgit.util.sha1.detectCollision"); //$NON-NLS-1$
+               DETECT_COLLISIONS = v != null ? Boolean.parseBoolean(v) : true;
+       }
+
        /** @return a new context to compute a SHA-1 hash of data. */
        public static SHA1 newInstance() {
                return new SHA1();
        }
 
-       private int h0;
-       private int h1;
-       private int h2;
-       private int h3;
-       private int h4;
+       private final State h = new State();
        private final int[] w = new int[80];
 
        /** Buffer to accumulate partial blocks to 64 byte alignment. */
@@ -76,30 +99,35 @@ public class SHA1 {
        /** Total number of bytes in the message. */
        private long length;
 
+       private boolean detectCollision = DETECT_COLLISIONS;
+       private boolean foundCollision;
+
+       private final int[] w2 = new int[80];
+       private final State state58 = new State();
+       private final State state65 = new State();
+       private final State hIn = new State();
+       private final State hTmp = new State();
+
        private SHA1() {
-               init();
+               h.init();
        }
 
        /**
-        * Reset this instance to compute another hash.
+        * Enable likely collision detection.
+        * <p>
+        * Default is {@code true}.
+        * <p>
+        * May also be set by system property:
+        * {@code -Dorg.eclipse.jgit.util.sha1.detectCollision=true}.
         *
-        * @return {@code this}.
+        * @param detect
+        * @return {@code this}
         */
-       public SHA1 reset() {
-               init();
-               length = 0;
+       public SHA1 setDetectCollision(boolean detect) {
+               detectCollision = detect;
                return this;
        }
 
-       private void init() {
-               // Magic initialization constants defined by FIPS180.
-               h0 = 0x67452301;
-               h1 = 0xEFCDAB89;
-               h2 = 0x98BADCFE;
-               h3 = 0x10325476;
-               h4 = 0xC3D2E1F0;
-       }
-
        /**
         * Update the digest computation by adding a byte.
         *
@@ -161,83 +189,283 @@ public class SHA1 {
        }
 
        private void compress(byte[] block, int p) {
-               // Method 1 from RFC 3174 section 6.1.
-               // Method 2 (circular queue of 16 words) is slower.
-               int a = h0, b = h1, c = h2, d = h3, e = h4;
+               initBlock(block, p);
+               int ubcDvMask = detectCollision ? UbcCheck.check(w) : 0;
+               compress();
 
-               // Round 1: 0 <= t <= 15 comes from the input block.
+               while (ubcDvMask != 0) {
+                       int b = numberOfTrailingZeros(lowestOneBit(ubcDvMask));
+                       UbcCheck.DvInfo dv = UbcCheck.DV[b];
+                       for (int i = 0; i < 80; i++) {
+                               w2[i] = w[i] ^ dv.dm[i];
+                       }
+                       recompress(dv.testt);
+                       if (eq(hTmp, h)) {
+                               foundCollision = true;
+                               break;
+                       }
+                       ubcDvMask &= ~(1 << b);
+               }
+       }
+
+       private void initBlock(byte[] block, int p) {
                for (int t = 0; t < 16; t++) {
-                       int temp = NB.decodeInt32(block, p + (t << 2));
-                       w[t] = temp;
-                       temp += ((a << 5) | (a >>> 27)) // S^5(A)
-                                       + (((c ^ d) & b) ^ d) // f: 0 <= t <= 19
-                                       + e + 0x5A827999;
-                       e = d;
-                       d = c;
-                       c = (b << 30) | (b >>> 2); // S^30(B)
-                       b = a;
-                       a = temp;
+                       w[t] = NB.decodeInt32(block, p + (t << 2));
                }
 
                // RFC 3174 6.1.b, extend state vector to 80 words.
                for (int t = 16; t < 80; t++) {
                        int x = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16];
-                       w[t] = (x << 1) | (x >>> 31); // S^1(...)
+                       w[t] = rotateLeft(x, 1); // S^1(...)
                }
+       }
 
-               // Round 1: tail
-               for (int t = 16; t < 20; t++) {
-                       int temp = ((a << 5) | (a >>> 27)) // S^5(A)
-                                       + (((c ^ d) & b) ^ d) // f: 0 <= t <= 19
-                                       + e + w[t] + 0x5A827999;
-                       e = d;
-                       d = c;
-                       c = (b << 30) | (b >>> 2); // S^30(B)
-                       b = a;
-                       a = temp;
-               }
+       private void compress() {
+               // Method 1 from RFC 3174 section 6.1.
+               // Method 2 (circular queue of 16 words) is slower.
+               int a = h.a, b = h.b, c = h.c, d = h.d, e = h.e;
 
-               // Round 2
-               for (int t = 20; t < 40; t++) {
-                       int temp = ((a << 5) | (a >>> 27)) // S^5(A)
-                                       + (b ^ c ^ d) // f: 20 <= t <= 39
-                                       + e + w[t] + 0x6ED9EBA1;
-                       e = d;
-                       d = c;
-                       c = (b << 30) | (b >>> 2); // S^30(B)
-                       b = a;
-                       a = temp;
-               }
+               // @formatter:off
+                e += s1(a, b, c, d,w[ 0]);  b = rotateLeft( b, 30);
+                d += s1(e, a, b, c,w[ 1]);  a = rotateLeft( a, 30);
+                c += s1(d, e, a, b,w[ 2]);  e = rotateLeft( e, 30);
+                b += s1(c, d, e, a,w[ 3]);  d = rotateLeft( d, 30);
+                a += s1(b, c, d, e,w[ 4]);  c = rotateLeft( c, 30);
+                e += s1(a, b, c, d,w[ 5]);  b = rotateLeft( b, 30);
+                d += s1(e, a, b, c,w[ 6]);  a = rotateLeft( a, 30);
+                c += s1(d, e, a, b,w[ 7]);  e = rotateLeft( e, 30);
+                b += s1(c, d, e, a,w[ 8]);  d = rotateLeft( d, 30);
+                a += s1(b, c, d, e,w[ 9]);  c = rotateLeft( c, 30);
+                e += s1(a, b, c, d,w[ 10]);  b = rotateLeft( b, 30);
+                d += s1(e, a, b, c,w[ 11]);  a = rotateLeft( a, 30);
+                c += s1(d, e, a, b,w[ 12]);  e = rotateLeft( e, 30);
+                b += s1(c, d, e, a,w[ 13]);  d = rotateLeft( d, 30);
+                a += s1(b, c, d, e,w[ 14]);  c = rotateLeft( c, 30);
+                e += s1(a, b, c, d,w[ 15]);  b = rotateLeft( b, 30);
+                d += s1(e, a, b, c,w[ 16]);  a = rotateLeft( a, 30);
+                c += s1(d, e, a, b,w[ 17]);  e = rotateLeft( e, 30);
+                b += s1(c, d, e, a,w[ 18]);  d = rotateLeft( d, 30);
+                a += s1(b, c, d, e,w[ 19]);  c = rotateLeft( c, 30);
 
-               // Round 3
-               for (int t = 40; t < 60; t++) {
-                       int temp = ((a << 5) | (a >>> 27)) // S^5(A)
-                                       + ((b & c) | (d & (b | c))) // f: 40 <= t <= 59
-                                       + e + w[t] + 0x8F1BBCDC;
-                       e = d;
-                       d = c;
-                       c = (b << 30) | (b >>> 2); // S^30(B)
-                       b = a;
-                       a = temp;
-               }
+                e += s2(a, b, c, d,w[ 20]);  b = rotateLeft( b, 30);
+                d += s2(e, a, b, c,w[ 21]);  a = rotateLeft( a, 30);
+                c += s2(d, e, a, b,w[ 22]);  e = rotateLeft( e, 30);
+                b += s2(c, d, e, a,w[ 23]);  d = rotateLeft( d, 30);
+                a += s2(b, c, d, e,w[ 24]);  c = rotateLeft( c, 30);
+                e += s2(a, b, c, d,w[ 25]);  b = rotateLeft( b, 30);
+                d += s2(e, a, b, c,w[ 26]);  a = rotateLeft( a, 30);
+                c += s2(d, e, a, b,w[ 27]);  e = rotateLeft( e, 30);
+                b += s2(c, d, e, a,w[ 28]);  d = rotateLeft( d, 30);
+                a += s2(b, c, d, e,w[ 29]);  c = rotateLeft( c, 30);
+                e += s2(a, b, c, d,w[ 30]);  b = rotateLeft( b, 30);
+                d += s2(e, a, b, c,w[ 31]);  a = rotateLeft( a, 30);
+                c += s2(d, e, a, b,w[ 32]);  e = rotateLeft( e, 30);
+                b += s2(c, d, e, a,w[ 33]);  d = rotateLeft( d, 30);
+                a += s2(b, c, d, e,w[ 34]);  c = rotateLeft( c, 30);
+                e += s2(a, b, c, d,w[ 35]);  b = rotateLeft( b, 30);
+                d += s2(e, a, b, c,w[ 36]);  a = rotateLeft( a, 30);
+                c += s2(d, e, a, b,w[ 37]);  e = rotateLeft( e, 30);
+                b += s2(c, d, e, a,w[ 38]);  d = rotateLeft( d, 30);
+                a += s2(b, c, d, e,w[ 39]);  c = rotateLeft( c, 30);
+
+                e += s3(a, b, c, d,w[ 40]);  b = rotateLeft( b, 30);
+                d += s3(e, a, b, c,w[ 41]);  a = rotateLeft( a, 30);
+                c += s3(d, e, a, b,w[ 42]);  e = rotateLeft( e, 30);
+                b += s3(c, d, e, a,w[ 43]);  d = rotateLeft( d, 30);
+                a += s3(b, c, d, e,w[ 44]);  c = rotateLeft( c, 30);
+                e += s3(a, b, c, d,w[ 45]);  b = rotateLeft( b, 30);
+                d += s3(e, a, b, c,w[ 46]);  a = rotateLeft( a, 30);
+                c += s3(d, e, a, b,w[ 47]);  e = rotateLeft( e, 30);
+                b += s3(c, d, e, a,w[ 48]);  d = rotateLeft( d, 30);
+                a += s3(b, c, d, e,w[ 49]);  c = rotateLeft( c, 30);
+                e += s3(a, b, c, d,w[ 50]);  b = rotateLeft( b, 30);
+                d += s3(e, a, b, c,w[ 51]);  a = rotateLeft( a, 30);
+                c += s3(d, e, a, b,w[ 52]);  e = rotateLeft( e, 30);
+                b += s3(c, d, e, a,w[ 53]);  d = rotateLeft( d, 30);
+                a += s3(b, c, d, e,w[ 54]);  c = rotateLeft( c, 30);
+                e += s3(a, b, c, d,w[ 55]);  b = rotateLeft( b, 30);
+                d += s3(e, a, b, c,w[ 56]);  a = rotateLeft( a, 30);
+                c += s3(d, e, a, b,w[ 57]);  e = rotateLeft( e, 30);
+               state58.save(a, b, c, d, e);
+                b += s3(c, d, e, a,w[ 58]);  d = rotateLeft( d, 30);
+                a += s3(b, c, d, e,w[ 59]);  c = rotateLeft( c, 30);
 
-               // Round 4
-               for (int t = 60; t < 80; t++) {
-                       int temp = ((a << 5) | (a >>> 27)) // S^5(A)
-                                       + (b ^ c ^ d) // f: 60 <= t <= 79
-                                       + e + w[t] + 0xCA62C1D6;
-                       e = d;
-                       d = c;
-                       c = (b << 30) | (b >>> 2); // S^30(B)
-                       b = a;
-                       a = temp;
+                e += s4(a, b, c, d,w[ 60]);  b = rotateLeft( b, 30);
+                d += s4(e, a, b, c,w[ 61]);  a = rotateLeft( a, 30);
+                c += s4(d, e, a, b,w[ 62]);  e = rotateLeft( e, 30);
+                b += s4(c, d, e, a,w[ 63]);  d = rotateLeft( d, 30);
+                a += s4(b, c, d, e,w[ 64]);  c = rotateLeft( c, 30);
+               state65.save(a, b, c, d, e);
+                e += s4(a, b, c, d,w[ 65]);  b = rotateLeft( b, 30);
+                d += s4(e, a, b, c,w[ 66]);  a = rotateLeft( a, 30);
+                c += s4(d, e, a, b,w[ 67]);  e = rotateLeft( e, 30);
+                b += s4(c, d, e, a,w[ 68]);  d = rotateLeft( d, 30);
+                a += s4(b, c, d, e,w[ 69]);  c = rotateLeft( c, 30);
+                e += s4(a, b, c, d,w[ 70]);  b = rotateLeft( b, 30);
+                d += s4(e, a, b, c,w[ 71]);  a = rotateLeft( a, 30);
+                c += s4(d, e, a, b,w[ 72]);  e = rotateLeft( e, 30);
+                b += s4(c, d, e, a,w[ 73]);  d = rotateLeft( d, 30);
+                a += s4(b, c, d, e,w[ 74]);  c = rotateLeft( c, 30);
+                e += s4(a, b, c, d,w[ 75]);  b = rotateLeft( b, 30);
+                d += s4(e, a, b, c,w[ 76]);  a = rotateLeft( a, 30);
+                c += s4(d, e, a, b,w[ 77]);  e = rotateLeft( e, 30);
+                b += s4(c, d, e, a,w[ 78]);  d = rotateLeft( d, 30);
+                a += s4(b, c, d, e,w[ 79]);  c = rotateLeft( c, 30);
+
+               // @formatter:on
+               h.save(h.a + a, h.b + b, h.c + c, h.d + d, h.e + e);
+       }
+
+       private void recompress(int t) {
+               State s;
+               if (t == 58) {
+                       s = state58;
+               } else if (t == 65) {
+                       s = state65;
+               } else {
+                       throw new IllegalStateException();
                }
+               int a = s.a, b = s.b, c = s.c, d = s.d, e = s.e;
+
+               // @formatter:off
+         if (t == 65) {
+               { c = rotateRight( c, 30);  a -= s4(b, c, d, e,w2[ 64]);}
+               { d = rotateRight( d, 30);  b -= s4(c, d, e, a,w2[ 63]);}
+               { e = rotateRight( e, 30);  c -= s4(d, e, a, b,w2[ 62]);}
+               { a = rotateRight( a, 30);  d -= s4(e, a, b, c,w2[ 61]);}
+               { b = rotateRight( b, 30);  e -= s4(a, b, c, d,w2[ 60]);}
+
+               { c = rotateRight( c, 30);  a -= s3(b, c, d, e,w2[ 59]);}
+               { d = rotateRight( d, 30);  b -= s3(c, d, e, a,w2[ 58]);}
+         }
+               { e = rotateRight( e, 30);  c -= s3(d, e, a, b,w2[ 57]);}
+               { a = rotateRight( a, 30);  d -= s3(e, a, b, c,w2[ 56]);}
+               { b = rotateRight( b, 30);  e -= s3(a, b, c, d,w2[ 55]);}
+               { c = rotateRight( c, 30);  a -= s3(b, c, d, e,w2[ 54]);}
+               { d = rotateRight( d, 30);  b -= s3(c, d, e, a,w2[ 53]);}
+               { e = rotateRight( e, 30);  c -= s3(d, e, a, b,w2[ 52]);}
+               { a = rotateRight( a, 30);  d -= s3(e, a, b, c,w2[ 51]);}
+               { b = rotateRight( b, 30);  e -= s3(a, b, c, d,w2[ 50]);}
+               { c = rotateRight( c, 30);  a -= s3(b, c, d, e,w2[ 49]);}
+               { d = rotateRight( d, 30);  b -= s3(c, d, e, a,w2[ 48]);}
+               { e = rotateRight( e, 30);  c -= s3(d, e, a, b,w2[ 47]);}
+               { a = rotateRight( a, 30);  d -= s3(e, a, b, c,w2[ 46]);}
+               { b = rotateRight( b, 30);  e -= s3(a, b, c, d,w2[ 45]);}
+               { c = rotateRight( c, 30);  a -= s3(b, c, d, e,w2[ 44]);}
+               { d = rotateRight( d, 30);  b -= s3(c, d, e, a,w2[ 43]);}
+               { e = rotateRight( e, 30);  c -= s3(d, e, a, b,w2[ 42]);}
+               { a = rotateRight( a, 30);  d -= s3(e, a, b, c,w2[ 41]);}
+               { b = rotateRight( b, 30);  e -= s3(a, b, c, d,w2[ 40]);}
+
+               { c = rotateRight( c, 30);  a -= s2(b, c, d, e,w2[ 39]);}
+               { d = rotateRight( d, 30);  b -= s2(c, d, e, a,w2[ 38]);}
+               { e = rotateRight( e, 30);  c -= s2(d, e, a, b,w2[ 37]);}
+               { a = rotateRight( a, 30);  d -= s2(e, a, b, c,w2[ 36]);}
+               { b = rotateRight( b, 30);  e -= s2(a, b, c, d,w2[ 35]);}
+               { c = rotateRight( c, 30);  a -= s2(b, c, d, e,w2[ 34]);}
+               { d = rotateRight( d, 30);  b -= s2(c, d, e, a,w2[ 33]);}
+               { e = rotateRight( e, 30);  c -= s2(d, e, a, b,w2[ 32]);}
+               { a = rotateRight( a, 30);  d -= s2(e, a, b, c,w2[ 31]);}
+               { b = rotateRight( b, 30);  e -= s2(a, b, c, d,w2[ 30]);}
+               { c = rotateRight( c, 30);  a -= s2(b, c, d, e,w2[ 29]);}
+               { d = rotateRight( d, 30);  b -= s2(c, d, e, a,w2[ 28]);}
+               { e = rotateRight( e, 30);  c -= s2(d, e, a, b,w2[ 27]);}
+               { a = rotateRight( a, 30);  d -= s2(e, a, b, c,w2[ 26]);}
+               { b = rotateRight( b, 30);  e -= s2(a, b, c, d,w2[ 25]);}
+               { c = rotateRight( c, 30);  a -= s2(b, c, d, e,w2[ 24]);}
+               { d = rotateRight( d, 30);  b -= s2(c, d, e, a,w2[ 23]);}
+               { e = rotateRight( e, 30);  c -= s2(d, e, a, b,w2[ 22]);}
+               { a = rotateRight( a, 30);  d -= s2(e, a, b, c,w2[ 21]);}
+               { b = rotateRight( b, 30);  e -= s2(a, b, c, d,w2[ 20]);}
+
+               { c = rotateRight( c, 30);  a -= s1(b, c, d, e,w2[ 19]);}
+               { d = rotateRight( d, 30);  b -= s1(c, d, e, a,w2[ 18]);}
+               { e = rotateRight( e, 30);  c -= s1(d, e, a, b,w2[ 17]);}
+               { a = rotateRight( a, 30);  d -= s1(e, a, b, c,w2[ 16]);}
+               { b = rotateRight( b, 30);  e -= s1(a, b, c, d,w2[ 15]);}
+               { c = rotateRight( c, 30);  a -= s1(b, c, d, e,w2[ 14]);}
+               { d = rotateRight( d, 30);  b -= s1(c, d, e, a,w2[ 13]);}
+               { e = rotateRight( e, 30);  c -= s1(d, e, a, b,w2[ 12]);}
+               { a = rotateRight( a, 30);  d -= s1(e, a, b, c,w2[ 11]);}
+               { b = rotateRight( b, 30);  e -= s1(a, b, c, d,w2[ 10]);}
+               { c = rotateRight( c, 30);  a -= s1(b, c, d, e,w2[ 9]);}
+               { d = rotateRight( d, 30);  b -= s1(c, d, e, a,w2[ 8]);}
+               { e = rotateRight( e, 30);  c -= s1(d, e, a, b,w2[ 7]);}
+               { a = rotateRight( a, 30);  d -= s1(e, a, b, c,w2[ 6]);}
+               { b = rotateRight( b, 30);  e -= s1(a, b, c, d,w2[ 5]);}
+               { c = rotateRight( c, 30);  a -= s1(b, c, d, e,w2[ 4]);}
+               { d = rotateRight( d, 30);  b -= s1(c, d, e, a,w2[ 3]);}
+               { e = rotateRight( e, 30);  c -= s1(d, e, a, b,w2[ 2]);}
+               { a = rotateRight( a, 30);  d -= s1(e, a, b, c,w2[ 1]);}
+               { b = rotateRight( b, 30);  e -= s1(a, b, c, d,w2[ 0]);}
+
+               hIn.save(a, b, c, d, e);
+               a = s.a; b = s.b; c = s.c; d = s.d; e = s.e;
 
-               h0 += a;
-               h1 += b;
-               h2 += c;
-               h3 += d;
-               h4 += e;
+         if (t == 58) {
+               { b += s3(c, d, e, a,w2[ 58]);  d = rotateLeft( d, 30);}
+               { a += s3(b, c, d, e,w2[ 59]);  c = rotateLeft( c, 30);}
+
+               { e += s4(a, b, c, d,w2[ 60]);  b = rotateLeft( b, 30);}
+               { d += s4(e, a, b, c,w2[ 61]);  a = rotateLeft( a, 30);}
+               { c += s4(d, e, a, b,w2[ 62]);  e = rotateLeft( e, 30);}
+               { b += s4(c, d, e, a,w2[ 63]);  d = rotateLeft( d, 30);}
+               { a += s4(b, c, d, e,w2[ 64]);  c = rotateLeft( c, 30);}
+         }
+               { e += s4(a, b, c, d,w2[ 65]);  b = rotateLeft( b, 30);}
+               { d += s4(e, a, b, c,w2[ 66]);  a = rotateLeft( a, 30);}
+               { c += s4(d, e, a, b,w2[ 67]);  e = rotateLeft( e, 30);}
+               { b += s4(c, d, e, a,w2[ 68]);  d = rotateLeft( d, 30);}
+               { a += s4(b, c, d, e,w2[ 69]);  c = rotateLeft( c, 30);}
+               { e += s4(a, b, c, d,w2[ 70]);  b = rotateLeft( b, 30);}
+               { d += s4(e, a, b, c,w2[ 71]);  a = rotateLeft( a, 30);}
+               { c += s4(d, e, a, b,w2[ 72]);  e = rotateLeft( e, 30);}
+               { b += s4(c, d, e, a,w2[ 73]);  d = rotateLeft( d, 30);}
+               { a += s4(b, c, d, e,w2[ 74]);  c = rotateLeft( c, 30);}
+               { e += s4(a, b, c, d,w2[ 75]);  b = rotateLeft( b, 30);}
+               { d += s4(e, a, b, c,w2[ 76]);  a = rotateLeft( a, 30);}
+               { c += s4(d, e, a, b,w2[ 77]);  e = rotateLeft( e, 30);}
+               { b += s4(c, d, e, a,w2[ 78]);  d = rotateLeft( d, 30);}
+               { a += s4(b, c, d, e,w2[ 79]);  c = rotateLeft( c, 30);}
+
+               // @formatter:on
+               hTmp.save(hIn.a + a, hIn.b + b, hIn.c + c, hIn.d + d, hIn.e + e);
+       }
+
+       private static int s1(int a, int b, int c, int d, int w_t) {
+               return rotateLeft(a, 5)
+                               // f: 0 <= t <= 19
+                               + ((b & c) | ((~b) & d))
+                               + 0x5A827999 + w_t;
+       }
+
+       private static int s2(int a, int b, int c, int d, int w_t) {
+               return rotateLeft(a, 5)
+                               // f: 20 <= t <= 39
+                               + (b ^ c ^ d)
+                               + 0x6ED9EBA1 + w_t;
+       }
+
+       private static int s3(int a, int b, int c, int d, int w_t) {
+               return rotateLeft(a, 5)
+                               // f: 40 <= t <= 59
+                               + ((b & c) | (b & d) | (c & d))
+                               + 0x8F1BBCDC + w_t;
+       }
+
+       private static int s4(int a, int b, int c, int d, int w_t) {
+               return rotateLeft(a, 5)
+                               // f: 60 <= t <= 79
+                               + (b ^ c ^ d)
+                               + 0xCA62C1D6 + w_t;
+       }
+
+       private static boolean eq(State q, State r) {
+               return q.a == r.a
+                               && q.b == r.b
+                               && q.c == r.c
+                               && q.d == r.d
+                               && q.e == r.e;
        }
 
        private void finish() {
@@ -261,6 +489,12 @@ public class SHA1 {
                NB.encodeInt32(buffer, 56, (int) (length >>> (32 - 3)));
                NB.encodeInt32(buffer, 60, (int) (length << 3));
                compress(buffer, 0);
+
+               if (foundCollision) {
+                       ObjectId id = h.toObjectId();
+                       LOG.warn("possible SHA-1 collision " + id.name()); //$NON-NLS-1$
+                       throw new Sha1CollisionException(id);
+               }
        }
 
        /**
@@ -269,16 +503,18 @@ public class SHA1 {
         * Once {@code digest()} is called, this instance should be discarded.
         *
         * @return the bytes for the resulting hash.
+        * @throws Sha1CollisionException
+        *             if a collision was detected and safeHash is false.
         */
-       public byte[] digest() {
+       public byte[] digest() throws Sha1CollisionException {
                finish();
 
                byte[] b = new byte[20];
-               NB.encodeInt32(b, 0, h0);
-               NB.encodeInt32(b, 4, h1);
-               NB.encodeInt32(b, 8, h2);
-               NB.encodeInt32(b, 12, h3);
-               NB.encodeInt32(b, 16, h4);
+               NB.encodeInt32(b, 0, h.a);
+               NB.encodeInt32(b, 4, h.b);
+               NB.encodeInt32(b, 8, h.c);
+               NB.encodeInt32(b, 12, h.d);
+               NB.encodeInt32(b, 16, h.e);
                return b;
        }
 
@@ -288,10 +524,12 @@ public class SHA1 {
         * Once {@code digest()} is called, this instance should be discarded.
         *
         * @return the ObjectId for the resulting hash.
+        * @throws Sha1CollisionException
+        *             if a collision was detected and safeHash is false.
         */
-       public ObjectId toObjectId() {
+       public ObjectId toObjectId() throws Sha1CollisionException {
                finish();
-               return new ObjectId(h0, h1, h2, h3, h4);
+               return h.toObjectId();
        }
 
        /**
@@ -301,9 +539,63 @@ public class SHA1 {
         *
         * @param id
         *            destination to copy the digest to.
+        * @throws Sha1CollisionException
+        *             if a collision was detected and safeHash is false.
         */
-       public void digest(MutableObjectId id) {
+       public void digest(MutableObjectId id) throws Sha1CollisionException {
                finish();
-               id.set(h0, h1, h2, h3, h4);
+               id.set(h.a, h.b, h.c, h.d, h.e);
+       }
+
+       /**
+        * Check if a collision was detected.
+        *
+        * <p>
+        * This method only returns an accurate result after the digest was obtained
+        * through {@link #digest()}, {@link #digest(MutableObjectId)} or
+        * {@link #toObjectId()}, as the hashing function must finish processing to
+        * know the final state.
+        *
+        * @return {@code true} if a likely collision was detected.
+        */
+       public boolean hasCollision() {
+               return foundCollision;
+       }
+
+       /**
+        * Reset this instance to compute another hash.
+        *
+        * @return {@code this}.
+        */
+       public SHA1 reset() {
+               h.init();
+               length = 0;
+               foundCollision = false;
+               return this;
+       }
+
+       private static final class State {
+               int a;
+               int b;
+               int c;
+               int d;
+               int e;
+
+               final void init() {
+                       // Magic initialization constants defined by FIPS180.
+                       save(0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0);
+               }
+
+               final void save(int a1, int b1, int c1, int d1, int e1) {
+                       a = a1;
+                       b = b1;
+                       c = c1;
+                       d = d1;
+                       e = e1;
+               }
+
+               ObjectId toObjectId() {
+                       return new ObjectId(a, b, c, d, e);
+               }
        }
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.recompress b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.recompress
new file mode 100644 (file)
index 0000000..44d3d6d
--- /dev/null
@@ -0,0 +1,192 @@
+/* Template for recompress method; run through cpp. */
+
+#define ROUND1_STEP(a, b, c, d, e, T) {e += s1(a,b,c,d,w2[T]); b = rotateLeft(b, 30);}
+#define ROUND2_STEP(a, b, c, d, e, T) {e += s2(a,b,c,d,w2[T]); b = rotateLeft(b, 30);}
+#define ROUND3_STEP(a, b, c, d, e, T) {e += s3(a,b,c,d,w2[T]); b = rotateLeft(b, 30);}
+#define ROUND4_STEP(a, b, c, d, e, T) {e += s4(a,b,c,d,w2[T]); b = rotateLeft(b, 30);}
+
+#define ROUND1_STEP_BW(a, b, c, d, e, T) {b = rotateRight(b, 30); e -= s1(a,b,c,d,w2[T]);}
+#define ROUND2_STEP_BW(a, b, c, d, e, T) {b = rotateRight(b, 30); e -= s2(a,b,c,d,w2[T]);}
+#define ROUND3_STEP_BW(a, b, c, d, e, T) {b = rotateRight(b, 30); e -= s3(a,b,c,d,w2[T]);}
+#define ROUND4_STEP_BW(a, b, c, d, e, T) {b = rotateRight(b, 30); e -= s4(a,b,c,d,w2[T]);}
+
+       /* Condition to go backwards: if (t > step) */
+  /* t=80-66 have no identified DV; skip.
+       ROUND4_STEP_BW(b, c, d, e, a, 79)
+       ROUND4_STEP_BW(c, d, e, a, b, 78)
+       ROUND4_STEP_BW(d, e, a, b, c, 77)
+       ROUND4_STEP_BW(e, a, b, c, d, 76)
+       ROUND4_STEP_BW(a, b, c, d, e, 75)
+       ROUND4_STEP_BW(b, c, d, e, a, 74)
+       ROUND4_STEP_BW(c, d, e, a, b, 73)
+       ROUND4_STEP_BW(d, e, a, b, c, 72)
+       ROUND4_STEP_BW(e, a, b, c, d, 71)
+       ROUND4_STEP_BW(a, b, c, d, e, 70)
+       ROUND4_STEP_BW(b, c, d, e, a, 69)
+       ROUND4_STEP_BW(c, d, e, a, b, 68)
+       ROUND4_STEP_BW(d, e, a, b, c, 67)
+       ROUND4_STEP_BW(e, a, b, c, d, 66)
+       ROUND4_STEP_BW(a, b, c, d, e, 65)
+  */
+  if (t == 65) {
+       ROUND4_STEP_BW(b, c, d, e, a, 64)
+       ROUND4_STEP_BW(c, d, e, a, b, 63)
+       ROUND4_STEP_BW(d, e, a, b, c, 62)
+       ROUND4_STEP_BW(e, a, b, c, d, 61)
+       ROUND4_STEP_BW(a, b, c, d, e, 60)
+
+       ROUND3_STEP_BW(b, c, d, e, a, 59)
+       ROUND3_STEP_BW(c, d, e, a, b, 58)
+  }
+       ROUND3_STEP_BW(d, e, a, b, c, 57)
+       ROUND3_STEP_BW(e, a, b, c, d, 56)
+       ROUND3_STEP_BW(a, b, c, d, e, 55)
+       ROUND3_STEP_BW(b, c, d, e, a, 54)
+       ROUND3_STEP_BW(c, d, e, a, b, 53)
+       ROUND3_STEP_BW(d, e, a, b, c, 52)
+       ROUND3_STEP_BW(e, a, b, c, d, 51)
+       ROUND3_STEP_BW(a, b, c, d, e, 50)
+       ROUND3_STEP_BW(b, c, d, e, a, 49)
+       ROUND3_STEP_BW(c, d, e, a, b, 48)
+       ROUND3_STEP_BW(d, e, a, b, c, 47)
+       ROUND3_STEP_BW(e, a, b, c, d, 46)
+       ROUND3_STEP_BW(a, b, c, d, e, 45)
+       ROUND3_STEP_BW(b, c, d, e, a, 44)
+       ROUND3_STEP_BW(c, d, e, a, b, 43)
+       ROUND3_STEP_BW(d, e, a, b, c, 42)
+       ROUND3_STEP_BW(e, a, b, c, d, 41)
+       ROUND3_STEP_BW(a, b, c, d, e, 40)
+
+       ROUND2_STEP_BW(b, c, d, e, a, 39)
+       ROUND2_STEP_BW(c, d, e, a, b, 38)
+       ROUND2_STEP_BW(d, e, a, b, c, 37)
+       ROUND2_STEP_BW(e, a, b, c, d, 36)
+       ROUND2_STEP_BW(a, b, c, d, e, 35)
+       ROUND2_STEP_BW(b, c, d, e, a, 34)
+       ROUND2_STEP_BW(c, d, e, a, b, 33)
+       ROUND2_STEP_BW(d, e, a, b, c, 32)
+       ROUND2_STEP_BW(e, a, b, c, d, 31)
+       ROUND2_STEP_BW(a, b, c, d, e, 30)
+       ROUND2_STEP_BW(b, c, d, e, a, 29)
+       ROUND2_STEP_BW(c, d, e, a, b, 28)
+       ROUND2_STEP_BW(d, e, a, b, c, 27)
+       ROUND2_STEP_BW(e, a, b, c, d, 26)
+       ROUND2_STEP_BW(a, b, c, d, e, 25)
+       ROUND2_STEP_BW(b, c, d, e, a, 24)
+       ROUND2_STEP_BW(c, d, e, a, b, 23)
+       ROUND2_STEP_BW(d, e, a, b, c, 22)
+       ROUND2_STEP_BW(e, a, b, c, d, 21)
+       ROUND2_STEP_BW(a, b, c, d, e, 20)
+
+       ROUND1_STEP_BW(b, c, d, e, a, 19)
+       ROUND1_STEP_BW(c, d, e, a, b, 18)
+       ROUND1_STEP_BW(d, e, a, b, c, 17)
+       ROUND1_STEP_BW(e, a, b, c, d, 16)
+       ROUND1_STEP_BW(a, b, c, d, e, 15)
+       ROUND1_STEP_BW(b, c, d, e, a, 14)
+       ROUND1_STEP_BW(c, d, e, a, b, 13)
+       ROUND1_STEP_BW(d, e, a, b, c, 12)
+       ROUND1_STEP_BW(e, a, b, c, d, 11)
+       ROUND1_STEP_BW(a, b, c, d, e, 10)
+       ROUND1_STEP_BW(b, c, d, e, a, 9)
+       ROUND1_STEP_BW(c, d, e, a, b, 8)
+       ROUND1_STEP_BW(d, e, a, b, c, 7)
+       ROUND1_STEP_BW(e, a, b, c, d, 6)
+       ROUND1_STEP_BW(a, b, c, d, e, 5)
+       ROUND1_STEP_BW(b, c, d, e, a, 4)
+       ROUND1_STEP_BW(c, d, e, a, b, 3)
+       ROUND1_STEP_BW(d, e, a, b, c, 2)
+       ROUND1_STEP_BW(e, a, b, c, d, 1)
+       ROUND1_STEP_BW(a, b, c, d, e, 0)
+
+       hIn.save(a, b, c, d, e);
+       a = s.a; b = s.b; c = s.c; d = s.d; e = s.e;
+
+       /* Condition to go fowards: if (t <= step) */
+  /* Earliest restart is T=58; skip.
+       ROUND1_STEP(a, b, c, d, e, 0)
+       ROUND1_STEP(e, a, b, c, d, 1)
+       ROUND1_STEP(d, e, a, b, c, 2)
+       ROUND1_STEP(c, d, e, a, b, 3)
+       ROUND1_STEP(b, c, d, e, a, 4)
+       ROUND1_STEP(a, b, c, d, e, 5)
+       ROUND1_STEP(e, a, b, c, d, 6)
+       ROUND1_STEP(d, e, a, b, c, 7)
+       ROUND1_STEP(c, d, e, a, b, 8)
+       ROUND1_STEP(b, c, d, e, a, 9)
+       ROUND1_STEP(a, b, c, d, e, 10)
+       ROUND1_STEP(e, a, b, c, d, 11)
+       ROUND1_STEP(d, e, a, b, c, 12)
+       ROUND1_STEP(c, d, e, a, b, 13)
+       ROUND1_STEP(b, c, d, e, a, 14)
+       ROUND1_STEP(a, b, c, d, e, 15)
+       ROUND1_STEP(e, a, b, c, d, 16)
+       ROUND1_STEP(d, e, a, b, c, 17)
+       ROUND1_STEP(c, d, e, a, b, 18)
+       ROUND1_STEP(b, c, d, e, a, 19)
+
+       ROUND2_STEP(a, b, c, d, e, 20)
+       ROUND2_STEP(e, a, b, c, d, 21)
+       ROUND2_STEP(d, e, a, b, c, 22)
+       ROUND2_STEP(c, d, e, a, b, 23)
+       ROUND2_STEP(b, c, d, e, a, 24)
+       ROUND2_STEP(a, b, c, d, e, 25)
+       ROUND2_STEP(e, a, b, c, d, 26)
+       ROUND2_STEP(d, e, a, b, c, 27)
+       ROUND2_STEP(c, d, e, a, b, 28)
+       ROUND2_STEP(b, c, d, e, a, 29)
+       ROUND2_STEP(a, b, c, d, e, 30)
+       ROUND2_STEP(e, a, b, c, d, 31)
+       ROUND2_STEP(d, e, a, b, c, 32)
+       ROUND2_STEP(c, d, e, a, b, 33)
+       ROUND2_STEP(b, c, d, e, a, 34)
+       ROUND2_STEP(a, b, c, d, e, 35)
+       ROUND2_STEP(e, a, b, c, d, 36)
+       ROUND2_STEP(d, e, a, b, c, 37)
+       ROUND2_STEP(c, d, e, a, b, 38)
+       ROUND2_STEP(b, c, d, e, a, 39)
+
+       ROUND3_STEP(a, b, c, d, e, 40)
+       ROUND3_STEP(e, a, b, c, d, 41)
+       ROUND3_STEP(d, e, a, b, c, 42)
+       ROUND3_STEP(c, d, e, a, b, 43)
+       ROUND3_STEP(b, c, d, e, a, 44)
+       ROUND3_STEP(a, b, c, d, e, 45)
+       ROUND3_STEP(e, a, b, c, d, 46)
+       ROUND3_STEP(d, e, a, b, c, 47)
+       ROUND3_STEP(c, d, e, a, b, 48)
+       ROUND3_STEP(b, c, d, e, a, 49)
+       ROUND3_STEP(a, b, c, d, e, 50)
+       ROUND3_STEP(e, a, b, c, d, 51)
+       ROUND3_STEP(d, e, a, b, c, 52)
+       ROUND3_STEP(c, d, e, a, b, 53)
+       ROUND3_STEP(b, c, d, e, a, 54)
+       ROUND3_STEP(a, b, c, d, e, 55)
+       ROUND3_STEP(e, a, b, c, d, 56)
+       ROUND3_STEP(d, e, a, b, c, 57)
+  */
+  if (t == 58) {
+       ROUND3_STEP(c, d, e, a, b, 58)
+       ROUND3_STEP(b, c, d, e, a, 59)
+
+       ROUND4_STEP(a, b, c, d, e, 60)
+       ROUND4_STEP(e, a, b, c, d, 61)
+       ROUND4_STEP(d, e, a, b, c, 62)
+       ROUND4_STEP(c, d, e, a, b, 63)
+       ROUND4_STEP(b, c, d, e, a, 64)
+  }
+       ROUND4_STEP(a, b, c, d, e, 65)
+       ROUND4_STEP(e, a, b, c, d, 66)
+       ROUND4_STEP(d, e, a, b, c, 67)
+       ROUND4_STEP(c, d, e, a, b, 68)
+       ROUND4_STEP(b, c, d, e, a, 69)
+       ROUND4_STEP(a, b, c, d, e, 70)
+       ROUND4_STEP(e, a, b, c, d, 71)
+       ROUND4_STEP(d, e, a, b, c, 72)
+       ROUND4_STEP(c, d, e, a, b, 73)
+       ROUND4_STEP(b, c, d, e, a, 74)
+       ROUND4_STEP(a, b, c, d, e, 75)
+       ROUND4_STEP(e, a, b, c, d, 76)
+       ROUND4_STEP(d, e, a, b, c, 77)
+       ROUND4_STEP(c, d, e, a, b, 78)
+       ROUND4_STEP(b, c, d, e, a, 79)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/Sha1CollisionException.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/Sha1CollisionException.java
new file mode 100644 (file)
index 0000000..be126a5
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017, Google Inc.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.util.sha1;
+
+import java.text.MessageFormat;
+
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.lib.ObjectId;
+
+/**
+ * Thrown by {@link SHA1} if it detects a likely hash collision.
+ *
+ * @since 4.7
+ */
+public class Sha1CollisionException extends RuntimeException {
+       private static final long serialVersionUID = 1L;
+
+       /**
+        * Initialize with default message.
+        *
+        * @param id
+        *            object whose contents are a hash collision.
+        */
+       public Sha1CollisionException(ObjectId id) {
+               super(MessageFormat.format(
+                               JGitText.get().sha1CollisionDetected1,
+                               id.name()));
+       }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/UbcCheck.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/UbcCheck.java
new file mode 100644 (file)
index 0000000..cebdbee
--- /dev/null
@@ -0,0 +1,1040 @@
+/*
+* Copyright 2017 Marc Stevens <marc@marc-stevens.nl>, Dan Shumow <danshu@microsoft.com>
+* Distributed under the MIT Software License.
+* MIT License
+*
+* Copyright (c) 2017:
+*     Marc Stevens
+*     Cryptology Group
+*     Centrum Wiskunde & Informatica
+*     P.O. Box 94079, 1090 GB Amsterdam, Netherlands
+*     marc@marc-stevens.nl
+*
+*     Dan Shumow
+*     Microsoft Research
+*     danshu@microsoft.com
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all
+* copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*/
+
+package org.eclipse.jgit.util.sha1;
+
+// Converted by hand by Shawn Pearce (Google), using lib/ubc_check.c from
+// https://github.com/cr-marcstevens/sha1collisiondetection/
+//
+// this file was generated by the 'parse_bitrel' program in the tools section
+// using the data files from directory 'tools/data/3565'
+//
+// Array DV contains a list of SHA-1 Disturbance Vectors (DV) to check
+// dvType, dvK and dvB define the DV: I(K,B) or II(K,B) (see the paper)
+// dm[80] is the expanded message block XOR-difference defined by the DV
+// testt is the step to do the recompression from for collision detection
+// maski and maskb define the bit to check for each DV in the dvmask returned by ubc_check
+//
+// ubc_check takes as input an expanded message block and verifies the unavoidable bitconditions for all listed DVs
+// it returns a dvmask where each bit belonging to a DV is set if all unavoidable bitconditions for that DV have been met
+// thus one needs to do the recompression check for each DV that has its bit set
+//
+// ubc_check is programmatically generated and the unavoidable bitconditions have been hardcoded
+// a directly verifiable version named ubc_check_verify can be found in ubc_check_verify.c
+// ubc_check has been verified against ubc_check_verify using the 'ubc_check_test' program in the tools section
+
+final class UbcCheck {
+       private static final int DV_I_43_0_bit = 1 << 0;
+       private static final int DV_I_44_0_bit = 1 << 1;
+       private static final int DV_I_45_0_bit = 1 << 2;
+       private static final int DV_I_46_0_bit = 1 << 3;
+       private static final int DV_I_46_2_bit = 1 << 4;
+       private static final int DV_I_47_0_bit = 1 << 5;
+       private static final int DV_I_47_2_bit = 1 << 6;
+       private static final int DV_I_48_0_bit = 1 << 7;
+       private static final int DV_I_48_2_bit = 1 << 8;
+       private static final int DV_I_49_0_bit = 1 << 9;
+       private static final int DV_I_49_2_bit = 1 << 10;
+       private static final int DV_I_50_0_bit = 1 << 11;
+       private static final int DV_I_50_2_bit = 1 << 12;
+       private static final int DV_I_51_0_bit = 1 << 13;
+       private static final int DV_I_51_2_bit = 1 << 14;
+       private static final int DV_I_52_0_bit = 1 << 15;
+       private static final int DV_II_45_0_bit = 1 << 16;
+       private static final int DV_II_46_0_bit = 1 << 17;
+       private static final int DV_II_46_2_bit = 1 << 18;
+       private static final int DV_II_47_0_bit = 1 << 19;
+       private static final int DV_II_48_0_bit = 1 << 20;
+       private static final int DV_II_49_0_bit = 1 << 21;
+       private static final int DV_II_49_2_bit = 1 << 22;
+       private static final int DV_II_50_0_bit = 1 << 23;
+       private static final int DV_II_50_2_bit = 1 << 24;
+       private static final int DV_II_51_0_bit = 1 << 25;
+       private static final int DV_II_51_2_bit = 1 << 26;
+       private static final int DV_II_52_0_bit = 1 << 27;
+       private static final int DV_II_53_0_bit = 1 << 28;
+       private static final int DV_II_54_0_bit = 1 << 29;
+       private static final int DV_II_55_0_bit = 1 << 30;
+       private static final int DV_II_56_0_bit = 1 << 31;
+
+       static int check(int[] w) {
+               int mask = ~0;
+               mask &= (((((w[44] ^ w[45]) >>> 29) & 1) - 1) | ~(DV_I_48_0_bit
+                               | DV_I_51_0_bit | DV_I_52_0_bit | DV_II_45_0_bit
+                               | DV_II_46_0_bit | DV_II_50_0_bit | DV_II_51_0_bit));
+               mask &= (((((w[49] ^ w[50]) >>> 29) & 1) - 1)
+                               | ~(DV_I_46_0_bit | DV_II_45_0_bit | DV_II_50_0_bit
+                                               | DV_II_51_0_bit | DV_II_55_0_bit | DV_II_56_0_bit));
+               mask &= (((((w[48] ^ w[49]) >>> 29) & 1) - 1)
+                               | ~(DV_I_45_0_bit | DV_I_52_0_bit | DV_II_49_0_bit
+                                               | DV_II_50_0_bit | DV_II_54_0_bit | DV_II_55_0_bit));
+               mask &= ((((w[47] ^ (w[50] >>> 25)) & (1 << 4)) - (1 << 4))
+                               | ~(DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit
+                                               | DV_II_45_0_bit | DV_II_51_0_bit | DV_II_56_0_bit));
+               mask &= (((((w[47] ^ w[48]) >>> 29) & 1) - 1)
+                               | ~(DV_I_44_0_bit | DV_I_51_0_bit | DV_II_48_0_bit
+                                               | DV_II_49_0_bit | DV_II_53_0_bit | DV_II_54_0_bit));
+               mask &= (((((w[46] >>> 4) ^ (w[49] >>> 29)) & 1) - 1)
+                               | ~(DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit
+                                               | DV_I_52_0_bit | DV_II_50_0_bit | DV_II_55_0_bit));
+               mask &= (((((w[46] ^ w[47]) >>> 29) & 1) - 1)
+                               | ~(DV_I_43_0_bit | DV_I_50_0_bit | DV_II_47_0_bit
+                                               | DV_II_48_0_bit | DV_II_52_0_bit | DV_II_53_0_bit));
+               mask &= (((((w[45] >>> 4) ^ (w[48] >>> 29)) & 1) - 1)
+                               | ~(DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit
+                                               | DV_I_51_0_bit | DV_II_49_0_bit | DV_II_54_0_bit));
+               mask &= (((((w[45] ^ w[46]) >>> 29) & 1) - 1)
+                               | ~(DV_I_49_0_bit | DV_I_52_0_bit | DV_II_46_0_bit
+                                               | DV_II_47_0_bit | DV_II_51_0_bit | DV_II_52_0_bit));
+               mask &= (((((w[44] >>> 4) ^ (w[47] >>> 29)) & 1) - 1)
+                               | ~(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit
+                                               | DV_I_50_0_bit | DV_II_48_0_bit | DV_II_53_0_bit));
+               mask &= (((((w[43] >>> 4) ^ (w[46] >>> 29)) & 1) - 1)
+                               | ~(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit
+                                               | DV_I_49_0_bit | DV_II_47_0_bit | DV_II_52_0_bit));
+               mask &= (((((w[43] ^ w[44]) >>> 29) & 1) - 1)
+                               | ~(DV_I_47_0_bit | DV_I_50_0_bit | DV_I_51_0_bit
+                                               | DV_II_45_0_bit | DV_II_49_0_bit | DV_II_50_0_bit));
+               mask &= (((((w[42] >>> 4) ^ (w[45] >>> 29)) & 1) - 1)
+                               | ~(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit
+                                               | DV_I_52_0_bit | DV_II_46_0_bit | DV_II_51_0_bit));
+               mask &= (((((w[41] >>> 4) ^ (w[44] >>> 29)) & 1) - 1)
+                               | ~(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit
+                                               | DV_I_51_0_bit | DV_II_45_0_bit | DV_II_50_0_bit));
+               mask &= (((((w[40] ^ w[41]) >>> 29) & 1) - 1)
+                               | ~(DV_I_44_0_bit | DV_I_47_0_bit | DV_I_48_0_bit
+                                               | DV_II_46_0_bit | DV_II_47_0_bit | DV_II_56_0_bit));
+               mask &= (((((w[54] ^ w[55]) >>> 29) & 1) - 1)
+                               | ~(DV_I_51_0_bit | DV_II_47_0_bit | DV_II_50_0_bit
+                                               | DV_II_55_0_bit | DV_II_56_0_bit));
+               mask &= (((((w[53] ^ w[54]) >>> 29) & 1) - 1)
+                               | ~(DV_I_50_0_bit | DV_II_46_0_bit | DV_II_49_0_bit
+                                               | DV_II_54_0_bit | DV_II_55_0_bit));
+               mask &= (((((w[52] ^ w[53]) >>> 29) & 1) - 1)
+                               | ~(DV_I_49_0_bit | DV_II_45_0_bit | DV_II_48_0_bit
+                                               | DV_II_53_0_bit | DV_II_54_0_bit));
+               mask &= ((((w[50] ^ (w[53] >>> 25)) & (1 << 4)) - (1 << 4))
+                               | ~(DV_I_50_0_bit | DV_I_52_0_bit | DV_II_46_0_bit
+                                               | DV_II_48_0_bit | DV_II_54_0_bit));
+               mask &= (((((w[50] ^ w[51]) >>> 29) & 1) - 1)
+                               | ~(DV_I_47_0_bit | DV_II_46_0_bit | DV_II_51_0_bit
+                                               | DV_II_52_0_bit | DV_II_56_0_bit));
+               mask &= ((((w[49] ^ (w[52] >>> 25)) & (1 << 4)) - (1 << 4))
+                               | ~(DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit
+                                               | DV_II_47_0_bit | DV_II_53_0_bit));
+               mask &= ((((w[48] ^ (w[51] >>> 25)) & (1 << 4)) - (1 << 4))
+                               | ~(DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit
+                                               | DV_II_46_0_bit | DV_II_52_0_bit));
+               mask &= (((((w[42] ^ w[43]) >>> 29) & 1) - 1)
+                               | ~(DV_I_46_0_bit | DV_I_49_0_bit | DV_I_50_0_bit
+                                               | DV_II_48_0_bit | DV_II_49_0_bit));
+               mask &= (((((w[41] ^ w[42]) >>> 29) & 1) - 1)
+                               | ~(DV_I_45_0_bit | DV_I_48_0_bit | DV_I_49_0_bit
+                                               | DV_II_47_0_bit | DV_II_48_0_bit));
+               mask &= (((((w[40] >>> 4) ^ (w[43] >>> 29)) & 1) - 1)
+                               | ~(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_50_0_bit
+                                               | DV_II_49_0_bit | DV_II_56_0_bit));
+               mask &= (((((w[39] >>> 4) ^ (w[42] >>> 29)) & 1) - 1)
+                               | ~(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_49_0_bit
+                                               | DV_II_48_0_bit | DV_II_55_0_bit));
+               if ((mask & (DV_I_44_0_bit | DV_I_48_0_bit | DV_II_47_0_bit
+                               | DV_II_54_0_bit | DV_II_56_0_bit)) != 0)
+                       mask &= (((((w[38] >>> 4) ^ (w[41] >>> 29)) & 1) - 1)
+                                       | ~(DV_I_44_0_bit | DV_I_48_0_bit | DV_II_47_0_bit
+                                                       | DV_II_54_0_bit | DV_II_56_0_bit));
+               mask &= (((((w[37] >>> 4) ^ (w[40] >>> 29)) & 1) - 1)
+                               | ~(DV_I_43_0_bit | DV_I_47_0_bit | DV_II_46_0_bit
+                                               | DV_II_53_0_bit | DV_II_55_0_bit));
+               if ((mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_51_0_bit
+                               | DV_II_56_0_bit)) != 0)
+                       mask &= (((((w[55] ^ w[56]) >>> 29) & 1) - 1) | ~(DV_I_52_0_bit
+                                       | DV_II_48_0_bit | DV_II_51_0_bit | DV_II_56_0_bit));
+               if ((mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_50_0_bit
+                               | DV_II_56_0_bit)) != 0)
+                       mask &= ((((w[52] ^ (w[55] >>> 25)) & (1 << 4)) - (1 << 4))
+                                       | ~(DV_I_52_0_bit | DV_II_48_0_bit | DV_II_50_0_bit
+                                                       | DV_II_56_0_bit));
+               if ((mask & (DV_I_51_0_bit | DV_II_47_0_bit | DV_II_49_0_bit
+                               | DV_II_55_0_bit)) != 0)
+                       mask &= ((((w[51] ^ (w[54] >>> 25)) & (1 << 4)) - (1 << 4))
+                                       | ~(DV_I_51_0_bit | DV_II_47_0_bit | DV_II_49_0_bit
+                                                       | DV_II_55_0_bit));
+               if ((mask & (DV_I_48_0_bit | DV_II_47_0_bit | DV_II_52_0_bit
+                               | DV_II_53_0_bit)) != 0)
+                       mask &= (((((w[51] ^ w[52]) >>> 29) & 1) - 1) | ~(DV_I_48_0_bit
+                                       | DV_II_47_0_bit | DV_II_52_0_bit | DV_II_53_0_bit));
+               if ((mask & (DV_I_46_0_bit | DV_I_49_0_bit | DV_II_45_0_bit
+                               | DV_II_48_0_bit)) != 0)
+                       mask &= (((((w[36] >>> 4) ^ (w[40] >>> 29)) & 1) - 1)
+                                       | ~(DV_I_46_0_bit | DV_I_49_0_bit | DV_II_45_0_bit
+                                                       | DV_II_48_0_bit));
+               if ((mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_49_0_bit)) != 0)
+                       mask &= ((0 - (((w[53] ^ w[56]) >>> 29) & 1))
+                                       | ~(DV_I_52_0_bit | DV_II_48_0_bit | DV_II_49_0_bit));
+               if ((mask & (DV_I_50_0_bit | DV_II_46_0_bit | DV_II_47_0_bit)) != 0)
+                       mask &= ((0 - (((w[51] ^ w[54]) >>> 29) & 1))
+                                       | ~(DV_I_50_0_bit | DV_II_46_0_bit | DV_II_47_0_bit));
+               if ((mask & (DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit)) != 0)
+                       mask &= ((0 - (((w[50] ^ w[52]) >>> 29) & 1))
+                                       | ~(DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit));
+               if ((mask & (DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit)) != 0)
+                       mask &= ((0 - (((w[49] ^ w[51]) >>> 29) & 1))
+                                       | ~(DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit));
+               if ((mask & (DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit)) != 0)
+                       mask &= ((0 - (((w[48] ^ w[50]) >>> 29) & 1))
+                                       | ~(DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit));
+               if ((mask & (DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit)) != 0)
+                       mask &= ((0 - (((w[47] ^ w[49]) >>> 29) & 1))
+                                       | ~(DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit));
+               if ((mask & (DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit)) != 0)
+                       mask &= ((0 - (((w[46] ^ w[48]) >>> 29) & 1))
+                                       | ~(DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit));
+               mask &= ((((w[45] ^ w[47]) & (1 << 6)) - (1 << 6))
+                               | ~(DV_I_47_2_bit | DV_I_49_2_bit | DV_I_51_2_bit));
+               if ((mask & (DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit)) != 0)
+                       mask &= ((0 - (((w[45] ^ w[47]) >>> 29) & 1))
+                                       | ~(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit));
+               mask &= (((((w[44] ^ w[46]) >>> 6) & 1) - 1)
+                               | ~(DV_I_46_2_bit | DV_I_48_2_bit | DV_I_50_2_bit));
+               if ((mask & (DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit)) != 0)
+                       mask &= ((0 - (((w[44] ^ w[46]) >>> 29) & 1))
+                                       | ~(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit));
+               mask &= ((0 - ((w[41] ^ (w[42] >>> 5)) & (1 << 1)))
+                               | ~(DV_I_48_2_bit | DV_II_46_2_bit | DV_II_51_2_bit));
+               mask &= ((0 - ((w[40] ^ (w[41] >>> 5)) & (1 << 1)))
+                               | ~(DV_I_47_2_bit | DV_I_51_2_bit | DV_II_50_2_bit));
+               if ((mask & (DV_I_44_0_bit | DV_I_46_0_bit | DV_II_56_0_bit)) != 0)
+                       mask &= ((0 - (((w[40] ^ w[42]) >>> 4) & 1))
+                                       | ~(DV_I_44_0_bit | DV_I_46_0_bit | DV_II_56_0_bit));
+               mask &= ((0 - ((w[39] ^ (w[40] >>> 5)) & (1 << 1)))
+                               | ~(DV_I_46_2_bit | DV_I_50_2_bit | DV_II_49_2_bit));
+               if ((mask & (DV_I_43_0_bit | DV_I_45_0_bit | DV_II_55_0_bit)) != 0)
+                       mask &= ((0 - (((w[39] ^ w[41]) >>> 4) & 1))
+                                       | ~(DV_I_43_0_bit | DV_I_45_0_bit | DV_II_55_0_bit));
+               if ((mask & (DV_I_44_0_bit | DV_II_54_0_bit | DV_II_56_0_bit)) != 0)
+                       mask &= ((0 - (((w[38] ^ w[40]) >>> 4) & 1))
+                                       | ~(DV_I_44_0_bit | DV_II_54_0_bit | DV_II_56_0_bit));
+               if ((mask & (DV_I_43_0_bit | DV_II_53_0_bit | DV_II_55_0_bit)) != 0)
+                       mask &= ((0 - (((w[37] ^ w[39]) >>> 4) & 1))
+                                       | ~(DV_I_43_0_bit | DV_II_53_0_bit | DV_II_55_0_bit));
+               mask &= ((0 - ((w[36] ^ (w[37] >>> 5)) & (1 << 1)))
+                               | ~(DV_I_47_2_bit | DV_I_50_2_bit | DV_II_46_2_bit));
+               if ((mask & (DV_I_45_0_bit | DV_I_48_0_bit | DV_II_47_0_bit)) != 0)
+                       mask &= (((((w[35] >>> 4) ^ (w[39] >>> 29)) & 1) - 1)
+                                       | ~(DV_I_45_0_bit | DV_I_48_0_bit | DV_II_47_0_bit));
+               if ((mask & (DV_I_48_0_bit | DV_II_48_0_bit)) != 0)
+                       mask &= ((0 - ((w[63] ^ (w[64] >>> 5)) & (1 << 0)))
+                                       | ~(DV_I_48_0_bit | DV_II_48_0_bit));
+               if ((mask & (DV_I_45_0_bit | DV_II_45_0_bit)) != 0)
+                       mask &= ((0 - ((w[63] ^ (w[64] >>> 5)) & (1 << 1)))
+                                       | ~(DV_I_45_0_bit | DV_II_45_0_bit));
+               if ((mask & (DV_I_47_0_bit | DV_II_47_0_bit)) != 0)
+                       mask &= ((0 - ((w[62] ^ (w[63] >>> 5)) & (1 << 0)))
+                                       | ~(DV_I_47_0_bit | DV_II_47_0_bit));
+               if ((mask & (DV_I_46_0_bit | DV_II_46_0_bit)) != 0)
+                       mask &= ((0 - ((w[61] ^ (w[62] >>> 5)) & (1 << 0)))
+                                       | ~(DV_I_46_0_bit | DV_II_46_0_bit));
+               mask &= ((0 - ((w[61] ^ (w[62] >>> 5)) & (1 << 2)))
+                               | ~(DV_I_46_2_bit | DV_II_46_2_bit));
+               if ((mask & (DV_I_45_0_bit | DV_II_45_0_bit)) != 0)
+                       mask &= ((0 - ((w[60] ^ (w[61] >>> 5)) & (1 << 0)))
+                                       | ~(DV_I_45_0_bit | DV_II_45_0_bit));
+               if ((mask & (DV_II_51_0_bit | DV_II_54_0_bit)) != 0)
+                       mask &= (((((w[58] ^ w[59]) >>> 29) & 1) - 1)
+                                       | ~(DV_II_51_0_bit | DV_II_54_0_bit));
+               if ((mask & (DV_II_50_0_bit | DV_II_53_0_bit)) != 0)
+                       mask &= (((((w[57] ^ w[58]) >>> 29) & 1) - 1)
+                                       | ~(DV_II_50_0_bit | DV_II_53_0_bit));
+               if ((mask & (DV_II_52_0_bit | DV_II_54_0_bit)) != 0)
+                       mask &= ((((w[56] ^ (w[59] >>> 25)) & (1 << 4)) - (1 << 4))
+                                       | ~(DV_II_52_0_bit | DV_II_54_0_bit));
+               if ((mask & (DV_II_51_0_bit | DV_II_52_0_bit)) != 0)
+                       mask &= ((0 - (((w[56] ^ w[59]) >>> 29) & 1))
+                                       | ~(DV_II_51_0_bit | DV_II_52_0_bit));
+               if ((mask & (DV_II_49_0_bit | DV_II_52_0_bit)) != 0)
+                       mask &= (((((w[56] ^ w[57]) >>> 29) & 1) - 1)
+                                       | ~(DV_II_49_0_bit | DV_II_52_0_bit));
+               if ((mask & (DV_II_51_0_bit | DV_II_53_0_bit)) != 0)
+                       mask &= ((((w[55] ^ (w[58] >>> 25)) & (1 << 4)) - (1 << 4))
+                                       | ~(DV_II_51_0_bit | DV_II_53_0_bit));
+               if ((mask & (DV_II_50_0_bit | DV_II_52_0_bit)) != 0)
+                       mask &= ((((w[54] ^ (w[57] >>> 25)) & (1 << 4)) - (1 << 4))
+                                       | ~(DV_II_50_0_bit | DV_II_52_0_bit));
+               if ((mask & (DV_II_49_0_bit | DV_II_51_0_bit)) != 0)
+                       mask &= ((((w[53] ^ (w[56] >>> 25)) & (1 << 4)) - (1 << 4))
+                                       | ~(DV_II_49_0_bit | DV_II_51_0_bit));
+               mask &= ((((w[51] ^ (w[50] >>> 5)) & (1 << 1)) - (1 << 1))
+                               | ~(DV_I_50_2_bit | DV_II_46_2_bit));
+               mask &= ((((w[48] ^ w[50]) & (1 << 6)) - (1 << 6))
+                               | ~(DV_I_50_2_bit | DV_II_46_2_bit));
+               if ((mask & (DV_I_51_0_bit | DV_I_52_0_bit)) != 0)
+                       mask &= ((0 - (((w[48] ^ w[55]) >>> 29) & 1))
+                                       | ~(DV_I_51_0_bit | DV_I_52_0_bit));
+               mask &= ((((w[47] ^ w[49]) & (1 << 6)) - (1 << 6))
+                               | ~(DV_I_49_2_bit | DV_I_51_2_bit));
+               mask &= ((((w[48] ^ (w[47] >>> 5)) & (1 << 1)) - (1 << 1))
+                               | ~(DV_I_47_2_bit | DV_II_51_2_bit));
+               mask &= ((((w[46] ^ w[48]) & (1 << 6)) - (1 << 6))
+                               | ~(DV_I_48_2_bit | DV_I_50_2_bit));
+               mask &= ((((w[47] ^ (w[46] >>> 5)) & (1 << 1)) - (1 << 1))
+                               | ~(DV_I_46_2_bit | DV_II_50_2_bit));
+               mask &= ((0 - ((w[44] ^ (w[45] >>> 5)) & (1 << 1)))
+                               | ~(DV_I_51_2_bit | DV_II_49_2_bit));
+               mask &= ((((w[43] ^ w[45]) & (1 << 6)) - (1 << 6))
+                               | ~(DV_I_47_2_bit | DV_I_49_2_bit));
+               mask &= (((((w[42] ^ w[44]) >>> 6) & 1) - 1)
+                               | ~(DV_I_46_2_bit | DV_I_48_2_bit));
+               mask &= ((((w[43] ^ (w[42] >>> 5)) & (1 << 1)) - (1 << 1))
+                               | ~(DV_II_46_2_bit | DV_II_51_2_bit));
+               mask &= ((((w[42] ^ (w[41] >>> 5)) & (1 << 1)) - (1 << 1))
+                               | ~(DV_I_51_2_bit | DV_II_50_2_bit));
+               mask &= ((((w[41] ^ (w[40] >>> 5)) & (1 << 1)) - (1 << 1))
+                               | ~(DV_I_50_2_bit | DV_II_49_2_bit));
+               if ((mask & (DV_I_52_0_bit | DV_II_51_0_bit)) != 0)
+                       mask &= ((((w[39] ^ (w[43] >>> 25)) & (1 << 4)) - (1 << 4))
+                                       | ~(DV_I_52_0_bit | DV_II_51_0_bit));
+               if ((mask & (DV_I_51_0_bit | DV_II_50_0_bit)) != 0)
+                       mask &= ((((w[38] ^ (w[42] >>> 25)) & (1 << 4)) - (1 << 4))
+                                       | ~(DV_I_51_0_bit | DV_II_50_0_bit));
+               if ((mask & (DV_I_48_2_bit | DV_I_51_2_bit)) != 0)
+                       mask &= ((0 - ((w[37] ^ (w[38] >>> 5)) & (1 << 1)))
+                                       | ~(DV_I_48_2_bit | DV_I_51_2_bit));
+               if ((mask & (DV_I_50_0_bit | DV_II_49_0_bit)) != 0)
+                       mask &= ((((w[37] ^ (w[41] >>> 25)) & (1 << 4)) - (1 << 4))
+                                       | ~(DV_I_50_0_bit | DV_II_49_0_bit));
+               if ((mask & (DV_II_52_0_bit | DV_II_54_0_bit)) != 0)
+                       mask &= ((0 - ((w[36] ^ w[38]) & (1 << 4)))
+                                       | ~(DV_II_52_0_bit | DV_II_54_0_bit));
+               mask &= ((0 - ((w[35] ^ (w[36] >>> 5)) & (1 << 1)))
+                               | ~(DV_I_46_2_bit | DV_I_49_2_bit));
+               if ((mask & (DV_I_51_0_bit | DV_II_47_0_bit)) != 0)
+                       mask &= ((((w[35] ^ (w[39] >>> 25)) & (1 << 3)) - (1 << 3))
+                                       | ~(DV_I_51_0_bit | DV_II_47_0_bit));
+
+               if (mask == 0) {
+                       return mask;
+               }
+
+               if ((mask & DV_I_43_0_bit) != 0)
+                       if (0 == ((w[61] ^ (w[62] >>> 5)) & (1 << 1))
+                                       || 0 != ((w[59] ^ (w[63] >>> 25)) & (1 << 5))
+                                       || 0 == ((w[58] ^ (w[63] >>> 30)) & (1 << 0)))
+                               mask &= ~DV_I_43_0_bit;
+               if ((mask & DV_I_44_0_bit) != 0)
+                       if (0 == ((w[62] ^ (w[63] >>> 5)) & (1 << 1))
+                                       || 0 != ((w[60] ^ (w[64] >>> 25)) & (1 << 5))
+                                       || 0 == ((w[59] ^ (w[64] >>> 30)) & (1 << 0)))
+                               mask &= ~DV_I_44_0_bit;
+               if ((mask & DV_I_46_2_bit) != 0)
+                       mask &= ((~((w[40] ^ w[42]) >>> 2)) | ~DV_I_46_2_bit);
+               if ((mask & DV_I_47_2_bit) != 0)
+                       if (0 == ((w[62] ^ (w[63] >>> 5)) & (1 << 2))
+                                       || 0 != ((w[41] ^ w[43]) & (1 << 6)))
+                               mask &= ~DV_I_47_2_bit;
+               if ((mask & DV_I_48_2_bit) != 0)
+                       if (0 == ((w[63] ^ (w[64] >>> 5)) & (1 << 2))
+                                       || 0 != ((w[48] ^ (w[49] << 5)) & (1 << 6)))
+                               mask &= ~DV_I_48_2_bit;
+               if ((mask & DV_I_49_2_bit) != 0)
+                       if (0 != ((w[49] ^ (w[50] << 5)) & (1 << 6))
+                                       || 0 == ((w[42] ^ w[50]) & (1 << 1))
+                                       || 0 != ((w[39] ^ (w[40] << 5)) & (1 << 6))
+                                       || 0 == ((w[38] ^ w[40]) & (1 << 1)))
+                               mask &= ~DV_I_49_2_bit;
+               if ((mask & DV_I_50_0_bit) != 0)
+                       mask &= ((((w[36] ^ w[37]) << 7)) | ~DV_I_50_0_bit);
+               if ((mask & DV_I_50_2_bit) != 0)
+                       mask &= ((((w[43] ^ w[51]) << 11)) | ~DV_I_50_2_bit);
+               if ((mask & DV_I_51_0_bit) != 0)
+                       mask &= ((((w[37] ^ w[38]) << 9)) | ~DV_I_51_0_bit);
+               if ((mask & DV_I_51_2_bit) != 0)
+                       if (0 != ((w[51] ^ (w[52] << 5)) & (1 << 6))
+                                       || 0 != ((w[49] ^ w[51]) & (1 << 6))
+                                       || 0 != ((w[37] ^ (w[37] >>> 5)) & (1 << 1))
+                                       || 0 != ((w[35] ^ (w[39] >>> 25)) & (1 << 5)))
+                               mask &= ~DV_I_51_2_bit;
+               if ((mask & DV_I_52_0_bit) != 0)
+                       mask &= ((((w[38] ^ w[39]) << 11)) | ~DV_I_52_0_bit);
+               if ((mask & DV_II_46_2_bit) != 0)
+                       mask &= ((((w[47] ^ w[51]) << 17)) | ~DV_II_46_2_bit);
+               if ((mask & DV_II_48_0_bit) != 0)
+                       if (0 != ((w[36] ^ (w[40] >>> 25)) & (1 << 3))
+                                       || 0 == ((w[35] ^ (w[40] << 2)) & (1 << 30)))
+                               mask &= ~DV_II_48_0_bit;
+               if ((mask & DV_II_49_0_bit) != 0)
+                       if (0 != ((w[37] ^ (w[41] >>> 25)) & (1 << 3))
+                                       || 0 == ((w[36] ^ (w[41] << 2)) & (1 << 30)))
+                               mask &= ~DV_II_49_0_bit;
+               if ((mask & DV_II_49_2_bit) != 0)
+                       if (0 != ((w[53] ^ (w[54] << 5)) & (1 << 6))
+                                       || 0 != ((w[51] ^ w[53]) & (1 << 6))
+                                       || 0 == ((w[50] ^ w[54]) & (1 << 1))
+                                       || 0 != ((w[45] ^ (w[46] << 5)) & (1 << 6))
+                                       || 0 != ((w[37] ^ (w[41] >>> 25)) & (1 << 5))
+                                       || 0 == ((w[36] ^ (w[41] >>> 30)) & (1 << 0)))
+                               mask &= ~DV_II_49_2_bit;
+               if ((mask & DV_II_50_0_bit) != 0)
+                       if (0 == ((w[55] ^ w[58]) & (1 << 29))
+                                       || 0 != ((w[38] ^ (w[42] >>> 25)) & (1 << 3))
+                                       || 0 == ((w[37] ^ (w[42] << 2)) & (1 << 30)))
+                               mask &= ~DV_II_50_0_bit;
+               if ((mask & DV_II_50_2_bit) != 0)
+                       if (0 != ((w[54] ^ (w[55] << 5)) & (1 << 6))
+                                       || 0!=((w[52] ^ w[54]) & (1 << 6))
+                                       || 0==((w[51] ^ w[55]) & (1 << 1))
+                                       || 0==((w[45] ^ w[47]) & (1 << 1))
+                                       || 0!=((w[38] ^ (w[42] >>> 25)) & (1 << 5))
+                                       || 0==((w[37] ^ (w[42] >>> 30)) & (1 << 0)))
+                               mask &= ~DV_II_50_2_bit;
+               if ((mask & DV_II_51_0_bit) != 0)
+                       if (0 != ((w[39] ^ (w[43] >>> 25)) & (1 << 3))
+                                       || 0 == ((w[38] ^ (w[43] << 2)) & (1 << 30)))
+                               mask &= ~DV_II_51_0_bit;
+               if ((mask & DV_II_51_2_bit) != 0)
+                       if (0 != ((w[55] ^ (w[56] << 5)) & (1 << 6))
+                                       || 0 != ((w[53] ^ w[55]) & (1 << 6))
+                                       || 0 == ((w[52] ^ w[56]) & (1 << 1))
+                                       || 0 == ((w[46] ^ w[48]) & (1 << 1))
+                                       || 0 != ((w[39] ^ (w[43] >>> 25)) & (1 << 5))
+                                       || 0 == ((w[38] ^ (w[43] >>> 30)) & (1 << 0)))
+                               mask &= ~DV_II_51_2_bit;
+               if ((mask & DV_II_52_0_bit) != 0)
+                       if (0 != ((w[59] ^ w[60]) & (1 << 29))
+                                       || 0 != ((w[40] ^ (w[44] >>> 25)) & (1 << 3))
+                                       || 0 != ((w[40] ^ (w[44] >>> 25)) & (1 << 4))
+                                       || 0==((w[39] ^ (w[44] << 2)) & (1 << 30)))
+                               mask &= ~DV_II_52_0_bit;
+               if ((mask & DV_II_53_0_bit) != 0)
+                       if (0==((w[58] ^ w[61]) & (1 << 29))
+                                       || 0!=((w[57] ^ (w[61] >>> 25)) & (1 << 4))
+                                       || 0!=((w[41] ^ (w[45] >>> 25)) & (1 << 3))
+                                       || 0!=((w[41] ^ (w[45] >>> 25)) & (1 << 4)))
+                               mask &= ~DV_II_53_0_bit;
+               if ((mask & DV_II_54_0_bit) != 0)
+                       if (0 != ((w[58] ^ (w[62] >>> 25)) & (1 << 4))
+                                       || 0 != ((w[42] ^ (w[46] >>> 25)) & (1 << 3))
+                                       || 0 != ((w[42] ^ (w[46] >>> 25)) & (1 << 4)))
+                               mask &= ~DV_II_54_0_bit;
+               if ((mask & DV_II_55_0_bit) != 0)
+                       if (0 != ((w[59] ^ (w[63] >>> 25)) & (1 << 4))
+                                       || 0 != ((w[57] ^ (w[59] >>> 25)) & (1 << 4))
+                                       || 0 != ((w[43] ^ (w[47] >>> 25)) & (1 << 3))
+                                       || 0 != ((w[43] ^ (w[47] >>> 25)) & (1 << 4)))
+                               mask &= ~DV_II_55_0_bit;
+               if ((mask & DV_II_56_0_bit) != 0)
+                       if (0 != ((w[60] ^ (w[64] >>> 25)) & (1 << 4))
+                                       || 0 != ((w[44] ^ (w[48] >>> 25)) & (1 << 3))
+                                       || 0 != ((w[44] ^ (w[48] >>> 25)) & (1 << 4)))
+                               mask &= ~DV_II_56_0_bit;
+               return mask;
+       }
+
+       private UbcCheck() {
+       }
+
+       static final class DvInfo {
+               final int testt;
+               final int maskb;
+               final int[] dm;
+
+               @SuppressWarnings("unused")
+               DvInfo(int dvType, int dvK, int dvB, int testt, int maskb, int[] dm) {
+                       this.testt = testt;
+                       this.maskb = maskb;
+                       this.dm = dm;
+
+                       // Only states 58 and 65 are saved.
+                       if (testt != 58 && testt != 65) {
+                               throw new IllegalArgumentException();
+                       }
+               }
+       }
+
+       static final DvInfo[] DV = new DvInfo[] {
+                       new DvInfo(1, 43, 0, 58, 0, new int[] { 0x08000000, 0x9800000c,
+                                       0xd8000010, 0x08000010, 0xb8000010, 0x98000000, 0x60000000,
+                                       0x00000008, 0xc0000000, 0x90000014, 0x10000010, 0xb8000014,
+                                       0x28000000, 0x20000010, 0x48000000, 0x08000018, 0x60000000,
+                                       0x90000010, 0xf0000010, 0x90000008, 0xc0000000, 0x90000010,
+                                       0xf0000010, 0xb0000008, 0x40000000, 0x90000000, 0xf0000010,
+                                       0x90000018, 0x60000000, 0x90000010, 0x90000010, 0x90000000,
+                                       0x80000000, 0x00000010, 0xa0000000, 0x20000000, 0xa0000000,
+                                       0x20000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010,
+                                       0x20000000, 0x00000010, 0xa0000000, 0x00000000, 0x20000000,
+                                       0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002,
+                                       0x40000040, 0x40000002, 0x80000004, 0x80000080, 0x80000006,
+                                       0x00000049, 0x00000103, 0x80000009, 0x80000012, 0x80000202,
+                                       0x00000018, 0x00000164, 0x00000408, 0x800000e6, 0x8000004c,
+                                       0x00000803, 0x80000161, 0x80000599 }),
+                       new DvInfo(1, 44, 0, 58, 1, new int[] { 0xb4000008, 0x08000000,
+                                       0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, 0x98000000,
+                                       0x60000000, 0x00000008, 0xc0000000, 0x90000014, 0x10000010,
+                                       0xb8000014, 0x28000000, 0x20000010, 0x48000000, 0x08000018,
+                                       0x60000000, 0x90000010, 0xf0000010, 0x90000008, 0xc0000000,
+                                       0x90000010, 0xf0000010, 0xb0000008, 0x40000000, 0x90000000,
+                                       0xf0000010, 0x90000018, 0x60000000, 0x90000010, 0x90000010,
+                                       0x90000000, 0x80000000, 0x00000010, 0xa0000000, 0x20000000,
+                                       0xa0000000, 0x20000010, 0x00000000, 0x20000010, 0x20000000,
+                                       0x00000010, 0x20000000, 0x00000010, 0xa0000000, 0x00000000,
+                                       0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001,
+                                       0x40000002, 0x40000040, 0x40000002, 0x80000004, 0x80000080,
+                                       0x80000006, 0x00000049, 0x00000103, 0x80000009, 0x80000012,
+                                       0x80000202, 0x00000018, 0x00000164, 0x00000408, 0x800000e6,
+                                       0x8000004c, 0x00000803, 0x80000161 }),
+                       new DvInfo(1, 45, 0, 58, 2, new int[] { 0xf4000014, 0xb4000008,
+                                       0x08000000, 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010,
+                                       0x98000000, 0x60000000, 0x00000008, 0xc0000000, 0x90000014,
+                                       0x10000010, 0xb8000014, 0x28000000, 0x20000010, 0x48000000,
+                                       0x08000018, 0x60000000, 0x90000010, 0xf0000010, 0x90000008,
+                                       0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, 0x40000000,
+                                       0x90000000, 0xf0000010, 0x90000018, 0x60000000, 0x90000010,
+                                       0x90000010, 0x90000000, 0x80000000, 0x00000010, 0xa0000000,
+                                       0x20000000, 0xa0000000, 0x20000010, 0x00000000, 0x20000010,
+                                       0x20000000, 0x00000010, 0x20000000, 0x00000010, 0xa0000000,
+                                       0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020,
+                                       0x00000001, 0x40000002, 0x40000040, 0x40000002, 0x80000004,
+                                       0x80000080, 0x80000006, 0x00000049, 0x00000103, 0x80000009,
+                                       0x80000012, 0x80000202, 0x00000018, 0x00000164, 0x00000408,
+                                       0x800000e6, 0x8000004c, 0x00000803 }),
+                       new DvInfo(1, 46, 0, 58, 3, new int[] { 0x2c000010, 0xf4000014,
+                                       0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, 0x08000010,
+                                       0xb8000010, 0x98000000, 0x60000000, 0x00000008, 0xc0000000,
+                                       0x90000014, 0x10000010, 0xb8000014, 0x28000000, 0x20000010,
+                                       0x48000000, 0x08000018, 0x60000000, 0x90000010, 0xf0000010,
+                                       0x90000008, 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008,
+                                       0x40000000, 0x90000000, 0xf0000010, 0x90000018, 0x60000000,
+                                       0x90000010, 0x90000010, 0x90000000, 0x80000000, 0x00000010,
+                                       0xa0000000, 0x20000000, 0xa0000000, 0x20000010, 0x00000000,
+                                       0x20000010, 0x20000000, 0x00000010, 0x20000000, 0x00000010,
+                                       0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
+                                       0x00000020, 0x00000001, 0x40000002, 0x40000040, 0x40000002,
+                                       0x80000004, 0x80000080, 0x80000006, 0x00000049, 0x00000103,
+                                       0x80000009, 0x80000012, 0x80000202, 0x00000018, 0x00000164,
+                                       0x00000408, 0x800000e6, 0x8000004c }),
+                       new DvInfo(1, 46, 2, 58, 4, new int[] { 0xb0000040, 0xd0000053,
+                                       0xd0000022, 0x20000000, 0x60000032, 0x60000043, 0x20000040,
+                                       0xe0000042, 0x60000002, 0x80000001, 0x00000020, 0x00000003,
+                                       0x40000052, 0x40000040, 0xe0000052, 0xa0000000, 0x80000040,
+                                       0x20000001, 0x20000060, 0x80000001, 0x40000042, 0xc0000043,
+                                       0x40000022, 0x00000003, 0x40000042, 0xc0000043, 0xc0000022,
+                                       0x00000001, 0x40000002, 0xc0000043, 0x40000062, 0x80000001,
+                                       0x40000042, 0x40000042, 0x40000002, 0x00000002, 0x00000040,
+                                       0x80000002, 0x80000000, 0x80000002, 0x80000040, 0x00000000,
+                                       0x80000040, 0x80000000, 0x00000040, 0x80000000, 0x00000040,
+                                       0x80000002, 0x00000000, 0x80000000, 0x80000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004,
+                                       0x00000080, 0x00000004, 0x00000009, 0x00000101, 0x00000009,
+                                       0x00000012, 0x00000202, 0x0000001a, 0x00000124, 0x0000040c,
+                                       0x00000026, 0x0000004a, 0x0000080a, 0x00000060, 0x00000590,
+                                       0x00001020, 0x0000039a, 0x00000132 }),
+                       new DvInfo(1, 47, 0, 58, 5, new int[] { 0xc8000010, 0x2c000010,
+                                       0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010,
+                                       0x08000010, 0xb8000010, 0x98000000, 0x60000000, 0x00000008,
+                                       0xc0000000, 0x90000014, 0x10000010, 0xb8000014, 0x28000000,
+                                       0x20000010, 0x48000000, 0x08000018, 0x60000000, 0x90000010,
+                                       0xf0000010, 0x90000008, 0xc0000000, 0x90000010, 0xf0000010,
+                                       0xb0000008, 0x40000000, 0x90000000, 0xf0000010, 0x90000018,
+                                       0x60000000, 0x90000010, 0x90000010, 0x90000000, 0x80000000,
+                                       0x00000010, 0xa0000000, 0x20000000, 0xa0000000, 0x20000010,
+                                       0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x20000000,
+                                       0x00000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000040,
+                                       0x40000002, 0x80000004, 0x80000080, 0x80000006, 0x00000049,
+                                       0x00000103, 0x80000009, 0x80000012, 0x80000202, 0x00000018,
+                                       0x00000164, 0x00000408, 0x800000e6 }),
+                       new DvInfo(1, 47, 2, 58, 6, new int[] { 0x20000043, 0xb0000040,
+                                       0xd0000053, 0xd0000022, 0x20000000, 0x60000032, 0x60000043,
+                                       0x20000040, 0xe0000042, 0x60000002, 0x80000001, 0x00000020,
+                                       0x00000003, 0x40000052, 0x40000040, 0xe0000052, 0xa0000000,
+                                       0x80000040, 0x20000001, 0x20000060, 0x80000001, 0x40000042,
+                                       0xc0000043, 0x40000022, 0x00000003, 0x40000042, 0xc0000043,
+                                       0xc0000022, 0x00000001, 0x40000002, 0xc0000043, 0x40000062,
+                                       0x80000001, 0x40000042, 0x40000042, 0x40000002, 0x00000002,
+                                       0x00000040, 0x80000002, 0x80000000, 0x80000002, 0x80000040,
+                                       0x00000000, 0x80000040, 0x80000000, 0x00000040, 0x80000000,
+                                       0x00000040, 0x80000002, 0x00000000, 0x80000000, 0x80000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000004, 0x00000080, 0x00000004, 0x00000009, 0x00000101,
+                                       0x00000009, 0x00000012, 0x00000202, 0x0000001a, 0x00000124,
+                                       0x0000040c, 0x00000026, 0x0000004a, 0x0000080a, 0x00000060,
+                                       0x00000590, 0x00001020, 0x0000039a }),
+                       new DvInfo(1, 48, 0, 58, 7, new int[] { 0xb800000a, 0xc8000010,
+                                       0x2c000010, 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c,
+                                       0xd8000010, 0x08000010, 0xb8000010, 0x98000000, 0x60000000,
+                                       0x00000008, 0xc0000000, 0x90000014, 0x10000010, 0xb8000014,
+                                       0x28000000, 0x20000010, 0x48000000, 0x08000018, 0x60000000,
+                                       0x90000010, 0xf0000010, 0x90000008, 0xc0000000, 0x90000010,
+                                       0xf0000010, 0xb0000008, 0x40000000, 0x90000000, 0xf0000010,
+                                       0x90000018, 0x60000000, 0x90000010, 0x90000010, 0x90000000,
+                                       0x80000000, 0x00000010, 0xa0000000, 0x20000000, 0xa0000000,
+                                       0x20000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010,
+                                       0x20000000, 0x00000010, 0xa0000000, 0x00000000, 0x20000000,
+                                       0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002,
+                                       0x40000040, 0x40000002, 0x80000004, 0x80000080, 0x80000006,
+                                       0x00000049, 0x00000103, 0x80000009, 0x80000012, 0x80000202,
+                                       0x00000018, 0x00000164, 0x00000408 }),
+                       new DvInfo(1, 48, 2, 58, 8, new int[] { 0xe000002a, 0x20000043,
+                                       0xb0000040, 0xd0000053, 0xd0000022, 0x20000000, 0x60000032,
+                                       0x60000043, 0x20000040, 0xe0000042, 0x60000002, 0x80000001,
+                                       0x00000020, 0x00000003, 0x40000052, 0x40000040, 0xe0000052,
+                                       0xa0000000, 0x80000040, 0x20000001, 0x20000060, 0x80000001,
+                                       0x40000042, 0xc0000043, 0x40000022, 0x00000003, 0x40000042,
+                                       0xc0000043, 0xc0000022, 0x00000001, 0x40000002, 0xc0000043,
+                                       0x40000062, 0x80000001, 0x40000042, 0x40000042, 0x40000002,
+                                       0x00000002, 0x00000040, 0x80000002, 0x80000000, 0x80000002,
+                                       0x80000040, 0x00000000, 0x80000040, 0x80000000, 0x00000040,
+                                       0x80000000, 0x00000040, 0x80000002, 0x00000000, 0x80000000,
+                                       0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000004, 0x00000080, 0x00000004, 0x00000009,
+                                       0x00000101, 0x00000009, 0x00000012, 0x00000202, 0x0000001a,
+                                       0x00000124, 0x0000040c, 0x00000026, 0x0000004a, 0x0000080a,
+                                       0x00000060, 0x00000590, 0x00001020 }),
+                       new DvInfo(1, 49, 0, 58, 9, new int[] { 0x18000000, 0xb800000a,
+                                       0xc8000010, 0x2c000010, 0xf4000014, 0xb4000008, 0x08000000,
+                                       0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, 0x98000000,
+                                       0x60000000, 0x00000008, 0xc0000000, 0x90000014, 0x10000010,
+                                       0xb8000014, 0x28000000, 0x20000010, 0x48000000, 0x08000018,
+                                       0x60000000, 0x90000010, 0xf0000010, 0x90000008, 0xc0000000,
+                                       0x90000010, 0xf0000010, 0xb0000008, 0x40000000, 0x90000000,
+                                       0xf0000010, 0x90000018, 0x60000000, 0x90000010, 0x90000010,
+                                       0x90000000, 0x80000000, 0x00000010, 0xa0000000, 0x20000000,
+                                       0xa0000000, 0x20000010, 0x00000000, 0x20000010, 0x20000000,
+                                       0x00000010, 0x20000000, 0x00000010, 0xa0000000, 0x00000000,
+                                       0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001,
+                                       0x40000002, 0x40000040, 0x40000002, 0x80000004, 0x80000080,
+                                       0x80000006, 0x00000049, 0x00000103, 0x80000009, 0x80000012,
+                                       0x80000202, 0x00000018, 0x00000164 }),
+                       new DvInfo(1, 49, 2, 58, 10, new int[] { 0x60000000, 0xe000002a,
+                                       0x20000043, 0xb0000040, 0xd0000053, 0xd0000022, 0x20000000,
+                                       0x60000032, 0x60000043, 0x20000040, 0xe0000042, 0x60000002,
+                                       0x80000001, 0x00000020, 0x00000003, 0x40000052, 0x40000040,
+                                       0xe0000052, 0xa0000000, 0x80000040, 0x20000001, 0x20000060,
+                                       0x80000001, 0x40000042, 0xc0000043, 0x40000022, 0x00000003,
+                                       0x40000042, 0xc0000043, 0xc0000022, 0x00000001, 0x40000002,
+                                       0xc0000043, 0x40000062, 0x80000001, 0x40000042, 0x40000042,
+                                       0x40000002, 0x00000002, 0x00000040, 0x80000002, 0x80000000,
+                                       0x80000002, 0x80000040, 0x00000000, 0x80000040, 0x80000000,
+                                       0x00000040, 0x80000000, 0x00000040, 0x80000002, 0x00000000,
+                                       0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000004, 0x00000080, 0x00000004,
+                                       0x00000009, 0x00000101, 0x00000009, 0x00000012, 0x00000202,
+                                       0x0000001a, 0x00000124, 0x0000040c, 0x00000026, 0x0000004a,
+                                       0x0000080a, 0x00000060, 0x00000590 }),
+                       new DvInfo(1, 50, 0, 65, 11, new int[] { 0x0800000c, 0x18000000,
+                                       0xb800000a, 0xc8000010, 0x2c000010, 0xf4000014, 0xb4000008,
+                                       0x08000000, 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010,
+                                       0x98000000, 0x60000000, 0x00000008, 0xc0000000, 0x90000014,
+                                       0x10000010, 0xb8000014, 0x28000000, 0x20000010, 0x48000000,
+                                       0x08000018, 0x60000000, 0x90000010, 0xf0000010, 0x90000008,
+                                       0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, 0x40000000,
+                                       0x90000000, 0xf0000010, 0x90000018, 0x60000000, 0x90000010,
+                                       0x90000010, 0x90000000, 0x80000000, 0x00000010, 0xa0000000,
+                                       0x20000000, 0xa0000000, 0x20000010, 0x00000000, 0x20000010,
+                                       0x20000000, 0x00000010, 0x20000000, 0x00000010, 0xa0000000,
+                                       0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020,
+                                       0x00000001, 0x40000002, 0x40000040, 0x40000002, 0x80000004,
+                                       0x80000080, 0x80000006, 0x00000049, 0x00000103, 0x80000009,
+                                       0x80000012, 0x80000202, 0x00000018 }),
+                       new DvInfo(1, 50, 2, 65, 12, new int[] { 0x20000030, 0x60000000,
+                                       0xe000002a, 0x20000043, 0xb0000040, 0xd0000053, 0xd0000022,
+                                       0x20000000, 0x60000032, 0x60000043, 0x20000040, 0xe0000042,
+                                       0x60000002, 0x80000001, 0x00000020, 0x00000003, 0x40000052,
+                                       0x40000040, 0xe0000052, 0xa0000000, 0x80000040, 0x20000001,
+                                       0x20000060, 0x80000001, 0x40000042, 0xc0000043, 0x40000022,
+                                       0x00000003, 0x40000042, 0xc0000043, 0xc0000022, 0x00000001,
+                                       0x40000002, 0xc0000043, 0x40000062, 0x80000001, 0x40000042,
+                                       0x40000042, 0x40000002, 0x00000002, 0x00000040, 0x80000002,
+                                       0x80000000, 0x80000002, 0x80000040, 0x00000000, 0x80000040,
+                                       0x80000000, 0x00000040, 0x80000000, 0x00000040, 0x80000002,
+                                       0x00000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000080,
+                                       0x00000004, 0x00000009, 0x00000101, 0x00000009, 0x00000012,
+                                       0x00000202, 0x0000001a, 0x00000124, 0x0000040c, 0x00000026,
+                                       0x0000004a, 0x0000080a, 0x00000060 }),
+                       new DvInfo(1, 51, 0, 65, 13, new int[] { 0xe8000000, 0x0800000c,
+                                       0x18000000, 0xb800000a, 0xc8000010, 0x2c000010, 0xf4000014,
+                                       0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, 0x08000010,
+                                       0xb8000010, 0x98000000, 0x60000000, 0x00000008, 0xc0000000,
+                                       0x90000014, 0x10000010, 0xb8000014, 0x28000000, 0x20000010,
+                                       0x48000000, 0x08000018, 0x60000000, 0x90000010, 0xf0000010,
+                                       0x90000008, 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008,
+                                       0x40000000, 0x90000000, 0xf0000010, 0x90000018, 0x60000000,
+                                       0x90000010, 0x90000010, 0x90000000, 0x80000000, 0x00000010,
+                                       0xa0000000, 0x20000000, 0xa0000000, 0x20000010, 0x00000000,
+                                       0x20000010, 0x20000000, 0x00000010, 0x20000000, 0x00000010,
+                                       0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
+                                       0x00000020, 0x00000001, 0x40000002, 0x40000040, 0x40000002,
+                                       0x80000004, 0x80000080, 0x80000006, 0x00000049, 0x00000103,
+                                       0x80000009, 0x80000012, 0x80000202 }),
+                       new DvInfo(1, 51, 2, 65, 14, new int[] { 0xa0000003, 0x20000030,
+                                       0x60000000, 0xe000002a, 0x20000043, 0xb0000040, 0xd0000053,
+                                       0xd0000022, 0x20000000, 0x60000032, 0x60000043, 0x20000040,
+                                       0xe0000042, 0x60000002, 0x80000001, 0x00000020, 0x00000003,
+                                       0x40000052, 0x40000040, 0xe0000052, 0xa0000000, 0x80000040,
+                                       0x20000001, 0x20000060, 0x80000001, 0x40000042, 0xc0000043,
+                                       0x40000022, 0x00000003, 0x40000042, 0xc0000043, 0xc0000022,
+                                       0x00000001, 0x40000002, 0xc0000043, 0x40000062, 0x80000001,
+                                       0x40000042, 0x40000042, 0x40000002, 0x00000002, 0x00000040,
+                                       0x80000002, 0x80000000, 0x80000002, 0x80000040, 0x00000000,
+                                       0x80000040, 0x80000000, 0x00000040, 0x80000000, 0x00000040,
+                                       0x80000002, 0x00000000, 0x80000000, 0x80000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004,
+                                       0x00000080, 0x00000004, 0x00000009, 0x00000101, 0x00000009,
+                                       0x00000012, 0x00000202, 0x0000001a, 0x00000124, 0x0000040c,
+                                       0x00000026, 0x0000004a, 0x0000080a }),
+                       new DvInfo(1, 52, 0, 65, 15, new int[] { 0x04000010, 0xe8000000,
+                                       0x0800000c, 0x18000000, 0xb800000a, 0xc8000010, 0x2c000010,
+                                       0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010,
+                                       0x08000010, 0xb8000010, 0x98000000, 0x60000000, 0x00000008,
+                                       0xc0000000, 0x90000014, 0x10000010, 0xb8000014, 0x28000000,
+                                       0x20000010, 0x48000000, 0x08000018, 0x60000000, 0x90000010,
+                                       0xf0000010, 0x90000008, 0xc0000000, 0x90000010, 0xf0000010,
+                                       0xb0000008, 0x40000000, 0x90000000, 0xf0000010, 0x90000018,
+                                       0x60000000, 0x90000010, 0x90000010, 0x90000000, 0x80000000,
+                                       0x00000010, 0xa0000000, 0x20000000, 0xa0000000, 0x20000010,
+                                       0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x20000000,
+                                       0x00000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000040,
+                                       0x40000002, 0x80000004, 0x80000080, 0x80000006, 0x00000049,
+                                       0x00000103, 0x80000009, 0x80000012 }),
+                       new DvInfo(2, 45, 0, 58, 16, new int[] { 0xec000014, 0x0c000002,
+                                       0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010,
+                                       0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014,
+                                       0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010,
+                                       0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010,
+                                       0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000,
+                                       0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010,
+                                       0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010,
+                                       0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010,
+                                       0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000,
+                                       0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000,
+                                       0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020,
+                                       0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005,
+                                       0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089,
+                                       0x00000014, 0x8000024b, 0x0000011b, 0x8000016d, 0x8000041a,
+                                       0x000002e4, 0x80000054, 0x00000967 }),
+                       new DvInfo(2, 46, 0, 58, 17, new int[] { 0x2400001c, 0xec000014,
+                                       0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018,
+                                       0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010,
+                                       0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004,
+                                       0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010,
+                                       0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000,
+                                       0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000,
+                                       0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000,
+                                       0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000,
+                                       0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000,
+                                       0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000,
+                                       0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
+                                       0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022,
+                                       0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107,
+                                       0x00000089, 0x00000014, 0x8000024b, 0x0000011b, 0x8000016d,
+                                       0x8000041a, 0x000002e4, 0x80000054 }),
+                       new DvInfo(2, 46, 2, 58, 18, new int[] { 0x90000070, 0xb0000053,
+                                       0x30000008, 0x00000043, 0xd0000072, 0xb0000010, 0xf0000062,
+                                       0xc0000042, 0x00000030, 0xe0000042, 0x20000060, 0xe0000041,
+                                       0x20000050, 0xc0000041, 0xe0000072, 0xa0000003, 0xc0000012,
+                                       0x60000041, 0xc0000032, 0x20000001, 0xc0000002, 0xe0000042,
+                                       0x60000042, 0x80000002, 0x00000000, 0x00000000, 0x80000000,
+                                       0x00000002, 0x00000040, 0x00000000, 0x80000040, 0x80000000,
+                                       0x00000040, 0x80000001, 0x00000060, 0x80000003, 0x40000002,
+                                       0xc0000040, 0xc0000002, 0x80000000, 0x80000000, 0x80000002,
+                                       0x00000040, 0x00000002, 0x80000000, 0x80000000, 0x80000000,
+                                       0x00000002, 0x00000040, 0x00000000, 0x80000040, 0x80000002,
+                                       0x00000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004,
+                                       0x00000080, 0x00000004, 0x00000009, 0x00000105, 0x00000089,
+                                       0x00000016, 0x0000020b, 0x0000011b, 0x0000012d, 0x0000041e,
+                                       0x00000224, 0x00000050, 0x0000092e, 0x0000046c, 0x000005b6,
+                                       0x0000106a, 0x00000b90, 0x00000152 }),
+                       new DvInfo(2, 47, 0, 58, 19, new int[] { 0x20000010, 0x2400001c,
+                                       0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004,
+                                       0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018,
+                                       0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000,
+                                       0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000,
+                                       0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000,
+                                       0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010,
+                                       0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000,
+                                       0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000,
+                                       0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000,
+                                       0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010,
+                                       0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041,
+                                       0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b,
+                                       0x80000107, 0x00000089, 0x00000014, 0x8000024b, 0x0000011b,
+                                       0x8000016d, 0x8000041a, 0x000002e4 }),
+                       new DvInfo(2, 48, 0, 58, 20, new int[] { 0xbc00001a, 0x20000010,
+                                       0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c,
+                                       0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010,
+                                       0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c,
+                                       0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000,
+                                       0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000,
+                                       0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000,
+                                       0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018,
+                                       0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000,
+                                       0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000,
+                                       0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000,
+                                       0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002,
+                                       0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046,
+                                       0x4000004b, 0x80000107, 0x00000089, 0x00000014, 0x8000024b,
+                                       0x0000011b, 0x8000016d, 0x8000041a }),
+                       new DvInfo(2, 49, 0, 58, 21, new int[] { 0x3c000004, 0xbc00001a,
+                                       0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010,
+                                       0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c,
+                                       0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010,
+                                       0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c,
+                                       0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000,
+                                       0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010,
+                                       0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000,
+                                       0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000,
+                                       0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000,
+                                       0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010,
+                                       0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000,
+                                       0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001,
+                                       0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082,
+                                       0xc0000046, 0x4000004b, 0x80000107, 0x00000089, 0x00000014,
+                                       0x8000024b, 0x0000011b, 0x8000016d }),
+                       new DvInfo(2, 49, 2, 58, 22, new int[] { 0xf0000010, 0xf000006a,
+                                       0x80000040, 0x90000070, 0xb0000053, 0x30000008, 0x00000043,
+                                       0xd0000072, 0xb0000010, 0xf0000062, 0xc0000042, 0x00000030,
+                                       0xe0000042, 0x20000060, 0xe0000041, 0x20000050, 0xc0000041,
+                                       0xe0000072, 0xa0000003, 0xc0000012, 0x60000041, 0xc0000032,
+                                       0x20000001, 0xc0000002, 0xe0000042, 0x60000042, 0x80000002,
+                                       0x00000000, 0x00000000, 0x80000000, 0x00000002, 0x00000040,
+                                       0x00000000, 0x80000040, 0x80000000, 0x00000040, 0x80000001,
+                                       0x00000060, 0x80000003, 0x40000002, 0xc0000040, 0xc0000002,
+                                       0x80000000, 0x80000000, 0x80000002, 0x00000040, 0x00000002,
+                                       0x80000000, 0x80000000, 0x80000000, 0x00000002, 0x00000040,
+                                       0x00000000, 0x80000040, 0x80000002, 0x00000000, 0x80000000,
+                                       0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000004, 0x00000080, 0x00000004,
+                                       0x00000009, 0x00000105, 0x00000089, 0x00000016, 0x0000020b,
+                                       0x0000011b, 0x0000012d, 0x0000041e, 0x00000224, 0x00000050,
+                                       0x0000092e, 0x0000046c, 0x000005b6 }),
+                       new DvInfo(2, 50, 0, 65, 23, new int[] { 0xb400001c, 0x3c000004,
+                                       0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002,
+                                       0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010,
+                                       0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014,
+                                       0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010,
+                                       0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010,
+                                       0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000,
+                                       0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010,
+                                       0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010,
+                                       0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010,
+                                       0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000,
+                                       0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000,
+                                       0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020,
+                                       0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005,
+                                       0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089,
+                                       0x00000014, 0x8000024b, 0x0000011b }),
+                       new DvInfo(2, 50, 2, 65, 24, new int[] { 0xd0000072, 0xf0000010,
+                                       0xf000006a, 0x80000040, 0x90000070, 0xb0000053, 0x30000008,
+                                       0x00000043, 0xd0000072, 0xb0000010, 0xf0000062, 0xc0000042,
+                                       0x00000030, 0xe0000042, 0x20000060, 0xe0000041, 0x20000050,
+                                       0xc0000041, 0xe0000072, 0xa0000003, 0xc0000012, 0x60000041,
+                                       0xc0000032, 0x20000001, 0xc0000002, 0xe0000042, 0x60000042,
+                                       0x80000002, 0x00000000, 0x00000000, 0x80000000, 0x00000002,
+                                       0x00000040, 0x00000000, 0x80000040, 0x80000000, 0x00000040,
+                                       0x80000001, 0x00000060, 0x80000003, 0x40000002, 0xc0000040,
+                                       0xc0000002, 0x80000000, 0x80000000, 0x80000002, 0x00000040,
+                                       0x00000002, 0x80000000, 0x80000000, 0x80000000, 0x00000002,
+                                       0x00000040, 0x00000000, 0x80000040, 0x80000002, 0x00000000,
+                                       0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000080,
+                                       0x00000004, 0x00000009, 0x00000105, 0x00000089, 0x00000016,
+                                       0x0000020b, 0x0000011b, 0x0000012d, 0x0000041e, 0x00000224,
+                                       0x00000050, 0x0000092e, 0x0000046c }),
+                       new DvInfo(2, 51, 0, 65, 25, new int[] { 0xc0000010, 0xb400001c,
+                                       0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014,
+                                       0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018,
+                                       0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010,
+                                       0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004,
+                                       0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010,
+                                       0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000,
+                                       0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000,
+                                       0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000,
+                                       0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000,
+                                       0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000,
+                                       0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000,
+                                       0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
+                                       0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022,
+                                       0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107,
+                                       0x00000089, 0x00000014, 0x8000024b }),
+                       new DvInfo(2, 51, 2, 65, 26, new int[] { 0x00000043, 0xd0000072,
+                                       0xf0000010, 0xf000006a, 0x80000040, 0x90000070, 0xb0000053,
+                                       0x30000008, 0x00000043, 0xd0000072, 0xb0000010, 0xf0000062,
+                                       0xc0000042, 0x00000030, 0xe0000042, 0x20000060, 0xe0000041,
+                                       0x20000050, 0xc0000041, 0xe0000072, 0xa0000003, 0xc0000012,
+                                       0x60000041, 0xc0000032, 0x20000001, 0xc0000002, 0xe0000042,
+                                       0x60000042, 0x80000002, 0x00000000, 0x00000000, 0x80000000,
+                                       0x00000002, 0x00000040, 0x00000000, 0x80000040, 0x80000000,
+                                       0x00000040, 0x80000001, 0x00000060, 0x80000003, 0x40000002,
+                                       0xc0000040, 0xc0000002, 0x80000000, 0x80000000, 0x80000002,
+                                       0x00000040, 0x00000002, 0x80000000, 0x80000000, 0x80000000,
+                                       0x00000002, 0x00000040, 0x00000000, 0x80000040, 0x80000002,
+                                       0x00000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004,
+                                       0x00000080, 0x00000004, 0x00000009, 0x00000105, 0x00000089,
+                                       0x00000016, 0x0000020b, 0x0000011b, 0x0000012d, 0x0000041e,
+                                       0x00000224, 0x00000050, 0x0000092e }),
+                       new DvInfo(2, 52, 0, 65, 27, new int[] { 0x0c000002, 0xc0000010,
+                                       0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c,
+                                       0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004,
+                                       0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018,
+                                       0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000,
+                                       0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000,
+                                       0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000,
+                                       0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010,
+                                       0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000,
+                                       0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000,
+                                       0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000,
+                                       0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010,
+                                       0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041,
+                                       0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b,
+                                       0x80000107, 0x00000089, 0x00000014 }),
+                       new DvInfo(2, 53, 0, 65, 28, new int[] { 0xcc000014, 0x0c000002,
+                                       0xc0000010, 0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010,
+                                       0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c,
+                                       0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010,
+                                       0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c,
+                                       0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000,
+                                       0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000,
+                                       0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000,
+                                       0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018,
+                                       0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000,
+                                       0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000,
+                                       0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000,
+                                       0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002,
+                                       0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046,
+                                       0x4000004b, 0x80000107, 0x00000089 }),
+                       new DvInfo(2, 54, 0, 65, 29, new int[] { 0x0400001c, 0xcc000014,
+                                       0x0c000002, 0xc0000010, 0xb400001c, 0x3c000004, 0xbc00001a,
+                                       0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010,
+                                       0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c,
+                                       0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010,
+                                       0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c,
+                                       0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000,
+                                       0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010,
+                                       0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000,
+                                       0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000,
+                                       0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000,
+                                       0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010,
+                                       0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000,
+                                       0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001,
+                                       0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082,
+                                       0xc0000046, 0x4000004b, 0x80000107 }),
+                       new DvInfo(2, 55, 0, 65, 30, new int[] { 0x00000010, 0x0400001c,
+                                       0xcc000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x3c000004,
+                                       0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002,
+                                       0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010,
+                                       0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014,
+                                       0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010,
+                                       0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010,
+                                       0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000,
+                                       0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010,
+                                       0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010,
+                                       0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010,
+                                       0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000,
+                                       0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000,
+                                       0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020,
+                                       0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005,
+                                       0xc0000082, 0xc0000046, 0x4000004b }),
+                       new DvInfo(2, 56, 0, 65, 31, new int[] { 0x2600001a, 0x00000010,
+                                       0x0400001c, 0xcc000014, 0x0c000002, 0xc0000010, 0xb400001c,
+                                       0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014,
+                                       0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018,
+                                       0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010,
+                                       0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004,
+                                       0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010,
+                                       0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000,
+                                       0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000,
+                                       0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000,
+                                       0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000,
+                                       0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000,
+                                       0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000,
+                                       0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000,
+                                       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
+                                       0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022,
+                                       0x80000005, 0xc0000082, 0xc0000046 }), };
+
+       static {
+               // Assert the DV array is indexed by maskb; that is DV block using
+               // maskb = N must be at array index N.
+               for (int i = 0; i < DV.length; i++) {
+                       if (i != DV[i].maskb) {
+                               throw new IllegalStateException("must be indexed by maskb"); //$NON-NLS-1$
+                       }
+               }
+       }
+}