You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by dr...@apache.org on 2015/01/12 14:06:44 UTC
[36/50] [abbrv] directory-kerberos git commit: Some clearance
Some clearance
Project: http://git-wip-us.apache.org/repos/asf/directory-kerberos/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-kerberos/commit/d0c6e321
Tree: http://git-wip-us.apache.org/repos/asf/directory-kerberos/tree/d0c6e321
Diff: http://git-wip-us.apache.org/repos/asf/directory-kerberos/diff/d0c6e321
Branch: refs/heads/master
Commit: d0c6e32143b59a6276f9b710b1e5fe6554b4b7ec
Parents: 0d0acfa
Author: Drankye <dr...@gmail.com>
Authored: Fri Dec 26 07:13:52 2014 +0800
Committer: Drankye <dr...@gmail.com>
Committed: Fri Dec 26 07:13:52 2014 +0800
----------------------------------------------------------------------
.../apache/kerberos/kerb/crypto/Camellia.java | 2 +
.../kerberos/kerb/crypto/CamelliaKey.java | 2 +
.../org/apache/kerberos/kerb/crypto/Crc32.java | 120 ++---
.../org/apache/kerberos/kerb/crypto/Md4.java | 490 +++++++++++--------
4 files changed, 324 insertions(+), 290 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/d0c6e321/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/Camellia.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/Camellia.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/Camellia.java
index 232f70c..89db740 100644
--- a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/Camellia.java
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/Camellia.java
@@ -2,6 +2,8 @@ package org.apache.kerberos.kerb.crypto;
/**
* Camellia - based on RFC 3713, about half the size of CamelliaEngine.
+ *
+ * This is based on CamelliaEngine.java from bouncycastle library.
*/
public class Camellia {
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/d0c6e321/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/CamelliaKey.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/CamelliaKey.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/CamelliaKey.java
index 72354a8..f31085e 100644
--- a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/CamelliaKey.java
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/CamelliaKey.java
@@ -2,6 +2,8 @@ package org.apache.kerberos.kerb.crypto;
/**
* Camellia - based on RFC 3713, about half the size of CamelliaEngine.
+ *
+ * This is based on CamelliaEngine.java from bouncycastle library.
*/
public class CamelliaKey {
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/d0c6e321/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/Crc32.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/Crc32.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/Crc32.java
index 52441c8..2c9f600 100644
--- a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/Crc32.java
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/Crc32.java
@@ -1,99 +1,59 @@
package org.apache.kerberos.kerb.crypto;
+/**
+ * Reference: http://introcs.cs.princeton.edu/java/51data/CRC32.java
+ */
public class Crc32 {
- private static long[] crcTable = {
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
- 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
- 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
- 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
- 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
- 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
- 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
- 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
- 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
- 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
- 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
- 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
- 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
- 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
- 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
- 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
- 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
- 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
- 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
- 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
- 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
- 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
- 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
- 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
- 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
- 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
- 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
- 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
- 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
- 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
- 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
- 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
- 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
- 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
- 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
- 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
- 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
- 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
- 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
- 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
- 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
- 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
- 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
- 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
- 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
- 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
- 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
- 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
- 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
- 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
- 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
- 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
- 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
- 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
- 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
- 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
- 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
- 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
- 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
- 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+ private static long[] table = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
};
public static byte[] crc(byte[] data, int start, int size) {
long c = crc(0, data, start, size);
- return convert((int) c);
+ return BytesUtil.int2bytes((int) c, false);
}
- public static long crc(long seed, byte[] data, int start, int len) {
- long c = seed;
+ public static long crc(long initial, byte[] data, int start, int len) {
+ long c = initial;
int idx;
for (int i = 0; i < len; i++) {
idx = (int) ((data[start + i] ^ c) & 0xff);
- c = ((c & 0xffffffffL) >>> 8) ^ crcTable[idx]; // why?
+ c = ((c & 0xffffffffL) >>> 8) ^ table[idx]; // why?
}
return c;
}
-
- private static byte[] convert(int val) {
- byte[] p = new byte[4];
-
- p[3] = (byte) ((val >> 24) & 0xff);
- p[2] = (byte) ((val >> 16) & 0xff);
- p[1] = (byte) ((val >> 8) & 0xff);
- p[0] = (byte) ((val ) & 0xff);
-
- return p;
- }
}
http://git-wip-us.apache.org/repos/asf/directory-kerberos/blob/d0c6e321/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/Md4.java
----------------------------------------------------------------------
diff --git a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/Md4.java b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/Md4.java
index 7f72058..5877234 100644
--- a/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/Md4.java
+++ b/haox-kerb/kerb-crypto/src/main/java/org/apache/kerberos/kerb/crypto/Md4.java
@@ -1,269 +1,339 @@
-package org.apache.kerberos.kerb.crypto;
-
-//http://www.java2s.com/Code/Java/Security/ImplementstheMD4messagedigestalgorithminJava.htm
-
/*
- * Copyright (c) 1997 Systemics Ltd
- * on behalf of the Cryptix Development Team. All rights reserved.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
*/
+package org.apache.kerberos.kerb.crypto;
+import java.security.DigestException;
import java.security.MessageDigest;
+import java.security.MessageDigestSpi;
/**
- * Implements the MD4 message digest algorithm in Java.
- * <p>
- * <b>References:</b>
- * <ol>
- * <li> Ronald L. Rivest,
- * "<a href="http://www.roxen.com/rfc/rfc1320.html">
- * The MD4 Message-Digest Algorithm</a>",
- * IETF RFC-1320 (informational).
- * </ol>
+ * MD4.java - An implementation of Ron Rivest's MD4 message digest algorithm.
+ * The MD4 algorithm is designed to be quite fast on 32-bit machines. In
+ * addition, the MD4 algorithm does not require any large substitution
+ * tables.
+ *
+ * @see The <a href="http://www.ietf.org/rfc/rfc1320.txt">MD4</a> Message-
+ * Digest Algorithm by R. Rivest.
*
- * <p><b>$Revision: 1.2 $</b>
- * @author Raif S. Naffah
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * @since MINA 2.0.0-M3
+ */
+
+/**
+ * Copied from Mina project and modified a bit
*/
-public class Md4 extends MessageDigest implements Cloneable
-{
+public class Md4 extends MessageDigest {
+
/**
- * The size in bytes of the input block to the tranformation algorithm.
+ * The MD4 algorithm message digest length is 16 bytes wide.
*/
- private static final int BLOCK_LENGTH = 64; // = 512 / 8;
+ public static final int BYTE_DIGEST_LENGTH = 16;
/**
- * 4 32-bit words (interim result)
+ * The MD4 algorithm block length is 64 bytes wide.
*/
- private int[] context = new int[4];
+ public static final int BYTE_BLOCK_LENGTH = 64;
/**
- * Number of bytes processed so far mod. 2 power of 64.
+ * The initial values of the four registers. RFC gives the values
+ * in LE so we converted it as JAVA uses BE endianness.
*/
- private long count;
+ private final static int A = 0x67452301;
+
+ private final static int B = 0xefcdab89;
+
+ private final static int C = 0x98badcfe;
+
+ private final static int D = 0x10325476;
/**
- * 512 bits input buffer = 16 x 32-bit words holds until reaches 512 bits.
+ * The four registers initialized with the above IVs.
*/
- private byte[] buffer = new byte[BLOCK_LENGTH];
+ private int a = A;
+
+ private int b = B;
+
+ private int c = C;
+
+ private int d = D;
/**
- * 512 bits work buffer = 16 x 32-bit words
+ * Counts the total length of the data being digested.
*/
- private int[] X = new int[16];
+ private long msgLength;
+ /**
+ * The internal buffer is {@link BLOCK_LENGTH} wide.
+ */
+ private final byte[] buffer = new byte[BYTE_BLOCK_LENGTH];
+
+ /**
+ * Default constructor.
+ */
public Md4() {
super("MD4");
engineReset();
}
/**
- * This constructor is here to implement cloneability of this class.
+ * Returns the digest length in bytes.
+ *
+ * @return the digest length in bytes.
*/
- private Md4(Md4 md) {
- this();
- context = (int[])md.context.clone();
- buffer = (byte[])md.buffer.clone();
- count = md.count;
+ protected int engineGetDigestLength() {
+ return BYTE_DIGEST_LENGTH;
}
/**
- * Returns a copy of this MD object.
- */
- public Object clone() { return new Md4(this); }
-
- /**
- * Resets this object disregarding any temporary data present at the
- * time of the invocation of this call.
+ * {@inheritDoc}
*/
- public void engineReset () {
- // initial values of MD4 i.e. A, B, C, D
- // as per rfc-1320; they are low-order byte first
- context[0] = 0x67452301;
- context[1] = 0xEFCDAB89;
- context[2] = 0x98BADCFE;
- context[3] = 0x10325476;
- count = 0L;
- for (int i = 0; i < BLOCK_LENGTH; i++)
- buffer[i] = 0;
+ protected void engineUpdate(byte b) {
+ int pos = (int) (msgLength % BYTE_BLOCK_LENGTH);
+ buffer[pos] = b;
+ msgLength++;
+
+ // If buffer contains enough data then process it.
+ if (pos == (BYTE_BLOCK_LENGTH - 1)) {
+ process(buffer, 0);
+ }
}
/**
- * Continues an MD4 message digest using the input byte.
+ * {@inheritDoc}
*/
- public void engineUpdate (byte b) {
- // compute number of bytes still unhashed; ie. present in buffer
- int i = (int)(count % BLOCK_LENGTH);
- count++; // update number of bytes
- buffer[i] = b;
- if (i == BLOCK_LENGTH - 1)
- transform(buffer, 0);
+ protected void engineUpdate(byte[] b, int offset, int len) {
+ int pos = (int) (msgLength % BYTE_BLOCK_LENGTH);
+ int nbOfCharsToFillBuf = BYTE_BLOCK_LENGTH - pos;
+ int blkStart = 0;
+
+ msgLength += len;
+
+ // Process each full block
+ if (len >= nbOfCharsToFillBuf) {
+ System.arraycopy(b, offset, buffer, pos, nbOfCharsToFillBuf);
+ process(buffer, 0);
+ for (blkStart = nbOfCharsToFillBuf; blkStart + BYTE_BLOCK_LENGTH - 1 < len; blkStart += BYTE_BLOCK_LENGTH) {
+ process(b, offset + blkStart);
+ }
+ pos = 0;
+ }
+
+ // Fill buffer with the remaining data
+ if (blkStart < len) {
+ System.arraycopy(b, offset + blkStart, buffer, pos, len - blkStart);
+ }
}
/**
- * MD4 block update operation.
- * <p>
- * Continues an MD4 message digest operation, by filling the buffer,
- * transform(ing) data in 512-bit message block(s), updating the variables
- * context and count, and leaving (buffering) the remaining bytes in buffer
- * for the next update or finish.
- *
- * @param input input block
- * @param offset start of meaningful bytes in input
- * @param len count of bytes in input block to consider
+ * {@inheritDoc}
*/
- public void engineUpdate (byte[] input, int offset, int len) {
- // make sure we don't exceed input's allocated size/length
- if (offset < 0 || len < 0 || (long)offset + len > input.length)
- throw new ArrayIndexOutOfBoundsException();
-
- // compute number of bytes still unhashed; ie. present in buffer
- int bufferNdx = (int)(count % BLOCK_LENGTH);
- count += len; // update number of bytes
- int partLen = BLOCK_LENGTH - bufferNdx;
- int i = 0;
- if (len >= partLen) {
- System.arraycopy(input, offset, buffer, bufferNdx, partLen);
+ protected byte[] engineDigest() {
+ byte[] p = pad();
+ engineUpdate(p, 0, p.length);
+ byte[] digest = { (byte) a, (byte) (a >>> 8), (byte) (a >>> 16), (byte) (a >>> 24), (byte) b, (byte) (b >>> 8),
+ (byte) (b >>> 16), (byte) (b >>> 24), (byte) c, (byte) (c >>> 8), (byte) (c >>> 16), (byte) (c >>> 24),
+ (byte) d, (byte) (d >>> 8), (byte) (d >>> 16), (byte) (d >>> 24) };
+ engineReset();
- transform(buffer, 0);
+ return digest;
+ }
- for (i = partLen; i + BLOCK_LENGTH - 1 < len; i+= BLOCK_LENGTH)
- transform(input, offset + i);
- bufferNdx = 0;
+ /**
+ * {@inheritDoc}
+ */
+ protected int engineDigest(byte[] buf, int offset, int len) throws DigestException {
+ if (offset < 0 || offset + len >= buf.length) {
+ throw new DigestException("Wrong offset or not enough space to store the digest");
}
- // buffer remaining input
- if (i < len)
- System.arraycopy(input, offset + i, buffer, bufferNdx, len - i);
+ int destLength = Math.min(len, BYTE_DIGEST_LENGTH);
+ System.arraycopy(engineDigest(), 0, buf, offset, destLength);
+ return destLength;
}
/**
- * Completes the hash computation by performing final operations such
- * as padding. At the return of this engineDigest, the MD engine is
- * reset.
- *
- * @return the array of bytes for the resulting hash value.
+ * {@inheritDoc}
*/
- public byte[] engineDigest () {
- // pad output to 56 mod 64; as RFC1320 puts it: congruent to 448 mod 512
- int bufferNdx = (int)(count % BLOCK_LENGTH);
- int padLen = (bufferNdx < 56) ? (56 - bufferNdx) : (120 - bufferNdx);
-
- // padding is alwas binary 1 followed by binary 0s
- byte[] tail = new byte[padLen + 8];
- tail[0] = (byte)0x80;
-
- // append length before final transform:
- // save number of bits, casting the long to an array of 8 bytes
- // save low-order byte first.
- for (int i = 0; i < 8; i++)
- tail[padLen + i] = (byte)((count * 8) >>> (8 * i));
-
- engineUpdate(tail, 0, tail.length);
-
- byte[] result = new byte[16];
- // cast this MD4's context (array of 4 ints) into an array of 16 bytes.
- for (int i = 0; i < 4; i++)
- for (int j = 0; j < 4; j++)
- result[i * 4 + j] = (byte)(context[i] >>> (8 * j));
-
- // reset the engine
- engineReset();
- return result;
+ protected void engineReset() {
+ a = A;
+ b = B;
+ c = C;
+ d = D;
+ msgLength = 0;
}
/**
- * MD4 basic transformation.
- * <p>
- * Transforms context based on 512 bits from input block starting
- * from the offset'th byte.
- *
- * @param block input sub-array.
- * @param offset starting position of sub-array.
+ * Pads the buffer by appending the byte 0x80, then append as many zero
+ * bytes as necessary to make the buffer length a multiple of 64 bytes.
+ * The last 8 bytes will be filled with the length of the buffer in bits.
+ * If there's no room to store the length in bits in the block i.e the block
+ * is larger than 56 bytes then an additionnal 64-bytes block is appended.
+ *
+ * @see sections 3.1 & 3.2 of the RFC 1320.
+ *
+ * @return the pad byte array
*/
- private void transform (byte[] block, int offset) {
-
- // encodes 64 bytes from input block into an array of 16 32-bit
- // entities. Use A as a temp var.
- for (int i = 0; i < 16; i++)
- X[i] = (block[offset++] & 0xFF) |
- (block[offset++] & 0xFF) << 8 |
- (block[offset++] & 0xFF) << 16 |
- (block[offset++] & 0xFF) << 24;
-
-
- int A = context[0];
- int B = context[1];
- int C = context[2];
- int D = context[3];
-
- A = FF(A, B, C, D, X[ 0], 3);
- D = FF(D, A, B, C, X[ 1], 7);
- C = FF(C, D, A, B, X[ 2], 11);
- B = FF(B, C, D, A, X[ 3], 19);
- A = FF(A, B, C, D, X[ 4], 3);
- D = FF(D, A, B, C, X[ 5], 7);
- C = FF(C, D, A, B, X[ 6], 11);
- B = FF(B, C, D, A, X[ 7], 19);
- A = FF(A, B, C, D, X[ 8], 3);
- D = FF(D, A, B, C, X[ 9], 7);
- C = FF(C, D, A, B, X[10], 11);
- B = FF(B, C, D, A, X[11], 19);
- A = FF(A, B, C, D, X[12], 3);
- D = FF(D, A, B, C, X[13], 7);
- C = FF(C, D, A, B, X[14], 11);
- B = FF(B, C, D, A, X[15], 19);
-
- A = GG(A, B, C, D, X[ 0], 3);
- D = GG(D, A, B, C, X[ 4], 5);
- C = GG(C, D, A, B, X[ 8], 9);
- B = GG(B, C, D, A, X[12], 13);
- A = GG(A, B, C, D, X[ 1], 3);
- D = GG(D, A, B, C, X[ 5], 5);
- C = GG(C, D, A, B, X[ 9], 9);
- B = GG(B, C, D, A, X[13], 13);
- A = GG(A, B, C, D, X[ 2], 3);
- D = GG(D, A, B, C, X[ 6], 5);
- C = GG(C, D, A, B, X[10], 9);
- B = GG(B, C, D, A, X[14], 13);
- A = GG(A, B, C, D, X[ 3], 3);
- D = GG(D, A, B, C, X[ 7], 5);
- C = GG(C, D, A, B, X[11], 9);
- B = GG(B, C, D, A, X[15], 13);
-
- A = HH(A, B, C, D, X[ 0], 3);
- D = HH(D, A, B, C, X[ 8], 9);
- C = HH(C, D, A, B, X[ 4], 11);
- B = HH(B, C, D, A, X[12], 15);
- A = HH(A, B, C, D, X[ 2], 3);
- D = HH(D, A, B, C, X[10], 9);
- C = HH(C, D, A, B, X[ 6], 11);
- B = HH(B, C, D, A, X[14], 15);
- A = HH(A, B, C, D, X[ 1], 3);
- D = HH(D, A, B, C, X[ 9], 9);
- C = HH(C, D, A, B, X[ 5], 11);
- B = HH(B, C, D, A, X[13], 15);
- A = HH(A, B, C, D, X[ 3], 3);
- D = HH(D, A, B, C, X[11], 9);
- C = HH(C, D, A, B, X[ 7], 11);
- B = HH(B, C, D, A, X[15], 15);
-
- context[0] += A;
- context[1] += B;
- context[2] += C;
- context[3] += D;
+ private byte[] pad() {
+ int pos = (int) (msgLength % BYTE_BLOCK_LENGTH);
+ int padLength = (pos < 56) ? (64 - pos) : (128 - pos);
+ byte[] pad = new byte[padLength];
+
+ // First bit of the padding set to 1
+ pad[0] = (byte) 0x80;
+
+ long bits = msgLength << 3;
+ int index = padLength - 8;
+ for (int i = 0; i < 8; i++) {
+ pad[index++] = (byte) (bits >>> (i << 3));
+ }
+
+ return pad;
}
- // The basic MD4 atomic functions.
+ /**
+ * Process one 64-byte block. Algorithm is constituted by three rounds.
+ * Note that F, G and H functions were inlined for improved performance.
+ *
+ * @param in the byte array to process
+ * @param offset the offset at which the 64-byte block is stored
+ */
+ private void process(byte[] in, int offset) {
+ // Save previous state.
+ int aa = a;
+ int bb = b;
+ int cc = c;
+ int dd = d;
+
+ // Copy the block to process into X array
+ int[] X = new int[16];
+ for (int i = 0; i < 16; i++) {
+ X[i] = (in[offset++] & 0xff) | (in[offset++] & 0xff) << 8 | (in[offset++] & 0xff) << 16
+ | (in[offset++] & 0xff) << 24;
+ }
- private int FF (int a, int b, int c, int d, int x, int s) {
- int t = a + ((b & c) | (~b & d)) + x;
- return t << s | t >>> (32 - s);
- }
- private int GG (int a, int b, int c, int d, int x, int s) {
- int t = a + ((b & (c | d)) | (c & d)) + x + 0x5A827999;
- return t << s | t >>> (32 - s);
- }
- private int HH (int a, int b, int c, int d, int x, int s) {
- int t = a + (b ^ c ^ d) + x + 0x6ED9EBA1;
- return t << s | t >>> (32 - s);
+ // Round 1
+ a += ((b & c) | (~b & d)) + X[0];
+ a = a << 3 | a >>> (32 - 3);
+ d += ((a & b) | (~a & c)) + X[1];
+ d = d << 7 | d >>> (32 - 7);
+ c += ((d & a) | (~d & b)) + X[2];
+ c = c << 11 | c >>> (32 - 11);
+ b += ((c & d) | (~c & a)) + X[3];
+ b = b << 19 | b >>> (32 - 19);
+ a += ((b & c) | (~b & d)) + X[4];
+ a = a << 3 | a >>> (32 - 3);
+ d += ((a & b) | (~a & c)) + X[5];
+ d = d << 7 | d >>> (32 - 7);
+ c += ((d & a) | (~d & b)) + X[6];
+ c = c << 11 | c >>> (32 - 11);
+ b += ((c & d) | (~c & a)) + X[7];
+ b = b << 19 | b >>> (32 - 19);
+ a += ((b & c) | (~b & d)) + X[8];
+ a = a << 3 | a >>> (32 - 3);
+ d += ((a & b) | (~a & c)) + X[9];
+ d = d << 7 | d >>> (32 - 7);
+ c += ((d & a) | (~d & b)) + X[10];
+ c = c << 11 | c >>> (32 - 11);
+ b += ((c & d) | (~c & a)) + X[11];
+ b = b << 19 | b >>> (32 - 19);
+ a += ((b & c) | (~b & d)) + X[12];
+ a = a << 3 | a >>> (32 - 3);
+ d += ((a & b) | (~a & c)) + X[13];
+ d = d << 7 | d >>> (32 - 7);
+ c += ((d & a) | (~d & b)) + X[14];
+ c = c << 11 | c >>> (32 - 11);
+ b += ((c & d) | (~c & a)) + X[15];
+ b = b << 19 | b >>> (32 - 19);
+
+ // Round 2
+ a += ((b & (c | d)) | (c & d)) + X[0] + 0x5a827999;
+ a = a << 3 | a >>> (32 - 3);
+ d += ((a & (b | c)) | (b & c)) + X[4] + 0x5a827999;
+ d = d << 5 | d >>> (32 - 5);
+ c += ((d & (a | b)) | (a & b)) + X[8] + 0x5a827999;
+ c = c << 9 | c >>> (32 - 9);
+ b += ((c & (d | a)) | (d & a)) + X[12] + 0x5a827999;
+ b = b << 13 | b >>> (32 - 13);
+ a += ((b & (c | d)) | (c & d)) + X[1] + 0x5a827999;
+ a = a << 3 | a >>> (32 - 3);
+ d += ((a & (b | c)) | (b & c)) + X[5] + 0x5a827999;
+ d = d << 5 | d >>> (32 - 5);
+ c += ((d & (a | b)) | (a & b)) + X[9] + 0x5a827999;
+ c = c << 9 | c >>> (32 - 9);
+ b += ((c & (d | a)) | (d & a)) + X[13] + 0x5a827999;
+ b = b << 13 | b >>> (32 - 13);
+ a += ((b & (c | d)) | (c & d)) + X[2] + 0x5a827999;
+ a = a << 3 | a >>> (32 - 3);
+ d += ((a & (b | c)) | (b & c)) + X[6] + 0x5a827999;
+ d = d << 5 | d >>> (32 - 5);
+ c += ((d & (a | b)) | (a & b)) + X[10] + 0x5a827999;
+ c = c << 9 | c >>> (32 - 9);
+ b += ((c & (d | a)) | (d & a)) + X[14] + 0x5a827999;
+ b = b << 13 | b >>> (32 - 13);
+ a += ((b & (c | d)) | (c & d)) + X[3] + 0x5a827999;
+ a = a << 3 | a >>> (32 - 3);
+ d += ((a & (b | c)) | (b & c)) + X[7] + 0x5a827999;
+ d = d << 5 | d >>> (32 - 5);
+ c += ((d & (a | b)) | (a & b)) + X[11] + 0x5a827999;
+ c = c << 9 | c >>> (32 - 9);
+ b += ((c & (d | a)) | (d & a)) + X[15] + 0x5a827999;
+ b = b << 13 | b >>> (32 - 13);
+
+ // Round 3
+ a += (b ^ c ^ d) + X[0] + 0x6ed9eba1;
+ a = a << 3 | a >>> (32 - 3);
+ d += (a ^ b ^ c) + X[8] + 0x6ed9eba1;
+ d = d << 9 | d >>> (32 - 9);
+ c += (d ^ a ^ b) + X[4] + 0x6ed9eba1;
+ c = c << 11 | c >>> (32 - 11);
+ b += (c ^ d ^ a) + X[12] + 0x6ed9eba1;
+ b = b << 15 | b >>> (32 - 15);
+ a += (b ^ c ^ d) + X[2] + 0x6ed9eba1;
+ a = a << 3 | a >>> (32 - 3);
+ d += (a ^ b ^ c) + X[10] + 0x6ed9eba1;
+ d = d << 9 | d >>> (32 - 9);
+ c += (d ^ a ^ b) + X[6] + 0x6ed9eba1;
+ c = c << 11 | c >>> (32 - 11);
+ b += (c ^ d ^ a) + X[14] + 0x6ed9eba1;
+ b = b << 15 | b >>> (32 - 15);
+ a += (b ^ c ^ d) + X[1] + 0x6ed9eba1;
+ a = a << 3 | a >>> (32 - 3);
+ d += (a ^ b ^ c) + X[9] + 0x6ed9eba1;
+ d = d << 9 | d >>> (32 - 9);
+ c += (d ^ a ^ b) + X[5] + 0x6ed9eba1;
+ c = c << 11 | c >>> (32 - 11);
+ b += (c ^ d ^ a) + X[13] + 0x6ed9eba1;
+ b = b << 15 | b >>> (32 - 15);
+ a += (b ^ c ^ d) + X[3] + 0x6ed9eba1;
+ a = a << 3 | a >>> (32 - 3);
+ d += (a ^ b ^ c) + X[11] + 0x6ed9eba1;
+ d = d << 9 | d >>> (32 - 9);
+ c += (d ^ a ^ b) + X[7] + 0x6ed9eba1;
+ c = c << 11 | c >>> (32 - 11);
+ b += (c ^ d ^ a) + X[15] + 0x6ed9eba1;
+ b = b << 15 | b >>> (32 - 15);
+
+ //Update state.
+ a += aa;
+ b += bb;
+ c += cc;
+ d += dd;
}
}