From 0a9fd0ca7575e96c7eac5a80dacedd074e568226 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Thu, 21 Aug 2014 18:22:25 +0200 Subject: beginning on support for partial bytes, c implemention is not working correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- java-c-jni/SHA3.c | 69 ++++++++++++----- java-c-jni/SHA3.java | 201 +++++++++++++++++++++++++++++++++++++++++++++--- java-c-jni/sha3sum.java | 14 ++-- 3 files changed, 247 insertions(+), 37 deletions(-) (limited to 'java-c-jni') diff --git a/java-c-jni/SHA3.c b/java-c-jni/SHA3.c index eea5dbe..1735099 100644 --- a/java-c-jni/SHA3.c +++ b/java-c-jni/SHA3.c @@ -407,19 +407,22 @@ inline llong toLane64(byte* message, long msglen, long rr, long off) * @param msg The message to pad * @param len The length of the message * @param r The bitrate + * @param bits The number of bits in the end of the message that does not make a whole byte * @param outlen The length of the padded message (out parameter) * @return The message padded */ -inline byte* pad10star1(byte* msg, long len, long r, long* outlen) +inline byte* pad10star1(byte* msg, long len, long r, long bits, long* outlen) { byte* message; + byte b; + long i, ll, nbrf, nrf; - long nrf = (len <<= 3) >> 3; - long nbrf = len & 7; - long ll = len % r; - long i; + len = ((len - (bits + 7) / 8) << 3) + bits; + nrf = len >> 3; + nbrf = len & 7; + ll = len % r; - byte b = (byte)(nbrf == 0 ? 1 : ((msg[nrf] >> (8 - nbrf)) | (1 << nbrf))); + b = (byte)(nbrf == 0 ? 1 : (msg[nrf] | (1 << nbrf))); if ((r - 8 <= ll) && (ll <= r - 2)) { @@ -620,10 +623,13 @@ void update(byte* msg, long msglen) * * @param msg The rest of the message, may be {@code null} * @param msglen The length of the partial message + * @param bits The number of bits at the end of the message not covered by msglen + * @param suffix The suffix concatenate to the message + * @param suffix_len The length of the suffix * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null} * @return The hash sum, or {@code null} if withReturn is {@code false} */ -byte* digest(byte* msg, long msglen, boolean withReturn) +byte* digest(byte* msg, long msglen, long bits, int* suffix, long suffix_len, boolean withReturn) { byte* message; byte* _msg; @@ -634,20 +640,37 @@ byte* digest(byte* msg, long msglen, boolean withReturn) long i, j = 0, ptr = 0, _; long nnn; - if ((msg == null) || (msglen == 0)) - message = pad10star1(M, mptr, r, &len); - else + if (msg == null) + msglen = bits = 0; + + msglen += bits >> 3; + if ((bits &= 7)) { - if (mptr + msglen > mlen) + msg[msglen] &= (1 << bits) - 1; + msg = (byte*)realloc(msg, msglen + ((suffix_len + bits + 7) >> 3)); + for (i = 0; i < suffix_len; i++) { - byte* buf = (byte*)malloc(mlen += msglen); - arraycopy(M, 0, buf, 0, mptr); - free(M); - M = buf; - } - arraycopy(msg, 0, M, mptr, msglen); - message = pad10star1(M, mptr + msglen, r, &len); + msg[msglen] |= suffix[i] << bits; + if (bits == 8) + { + bits = 0; + msglen++; + } + } + if (bits) + msglen++; + } + + if (mptr + msglen > mlen) + { + byte* buf = (byte*)malloc(mlen += msglen); + arraycopy(M, 0, buf, 0, mptr); + free(M); + M = buf; } + arraycopy(msg, 0, M, mptr, msglen); + message = pad10star1(M, mptr + msglen, r, bits, &len); + free(M); M = null; rc = (byte*)malloc((n + 7) >> 3); @@ -814,16 +837,20 @@ JNIEXPORT void JNICALL Java_SHA3_update(JNIEnv* env, jclass class, jbyteArray ms } -JNIEXPORT jbyteArray JNICALL Java_SHA3_digest(JNIEnv* env, jclass class, jbyteArray msg, jint msglen, jboolean withReturn) +JNIEXPORT jbyteArray JNICALL Java_SHA3_digest(JNIEnv* env, jclass class, jbyteArray msg, jint msglen, jint bits, jintArray suffix, jboolean withReturn) { jbyte* rcn; jbyteArray rcj = null; + int* suffix_elems = (int*)((*env)->GetIntArrayElements(env, suffix, 0)); + long suffix_len = (long)((*env)->GetArrayLength(env, suffix)); + (void) class; if ((msg != null) && (msglen != 0)) - rcn = (jbyte*)digest((byte*)((*env)->GetByteArrayElements(env, msg, 0)), msglen, withReturn); + rcn = (jbyte*)digest((byte*)((*env)->GetByteArrayElements(env, msg, 0)), msglen, + bits, suffix_elems, suffix_len, withReturn); else - rcn = (jbyte*)digest(null, 0, withReturn); + rcn = (jbyte*)digest(null, 0, 0, suffix_elems, suffix_len, withReturn); if (withReturn) { rcj = (*env)->NewByteArray(env, (n + 7) >> 3); diff --git a/java-c-jni/SHA3.java b/java-c-jni/SHA3.java index 1a4067b..4be013e 100644 --- a/java-c-jni/SHA3.java +++ b/java-c-jni/SHA3.java @@ -27,6 +27,28 @@ import java.util.*; */ public class SHA3 { + /** + * Suffix the message when calculating the Keccak hash sum + */ + public static final String KECCAK_SUFFIX = ""; + + /** + * Suffix the message when calculating the SHA-3 hash sum + */ + public static final String SHA3_SUFFIX = "01"; + + /** + * Suffix the message when calculating the RawSHAKE hash sum + */ + public static final String RawSHAKE_SUFFIX = "11"; + + /** + * Suffix the message when calculating the SHAKE hash sum + */ + public static final String SHAKE_SUFFIX = "1111"; + + + /** * Hidden constructor */ @@ -91,19 +113,44 @@ public class SHA3 */ public static byte[] digest() { - return digest(null, 0, true); + return digest(null, 0, 0, SHA3.SHA3_SUFFIX, true); } /** * Squeeze the Keccak sponge * - * @paran withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null} + * @param suffix The suffix concatenate to the message + * @return The hash sum + */ + public static byte[] digest(String suffix) + { + return digest(null, 0, 0, suffix, true); + } + + + /** + * Squeeze the Keccak sponge + * + * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null} * @return The hash sum, or {@code null} if withReturn is {@code false} */ public static byte[] digest(boolean withReturn) { - return digest(null, 0, withReturn); + return digest(null, 0, 0, SHA3.SHA3_SUFFIX, withReturn); + } + + + /** + * Squeeze the Keccak sponge + * + * @param suffix The suffix concatenate to the message + * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null} + * @return The hash sum, or {@code null} if withReturn is {@code false} + */ + public static byte[] digest(String suffix, boolean withReturn) + { + return digest(null, 0, 0, suffix, withReturn); } @@ -115,7 +162,20 @@ public class SHA3 */ public static byte[] digest(byte[] msg) { - return digest(msg, msg == null ? 0 : msg.length, true); + return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, true); + } + + + /** + * Absorb the last part of the message and squeeze the Keccak sponge + * + * @param msg The rest of the message + * @param suffix The suffix concatenate to the message + * @return The hash sum + */ + public static byte[] digest(byte[] msg, String suffix) + { + return digest(msg, msg == null ? 0 : msg.length, 0, suffix, true); } @@ -123,12 +183,26 @@ public class SHA3 * Absorb the last part of the message and squeeze the Keccak sponge * * @param msg The rest of the message - * @paran withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null} + * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null} * @return The hash sum, or {@code null} if withReturn is {@code false} */ public static byte[] digest(byte[] msg, boolean withReturn) { - return digest(msg, msg == null ? 0 : msg.length, withReturn); + return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, withReturn); + } + + + /** + * Absorb the last part of the message and squeeze the Keccak sponge + * + * @param msg The rest of the message + * @param suffix The suffix concatenate to the message + * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null} + * @return The hash sum, or {@code null} if withReturn is {@code false} + */ + public static byte[] digest(byte[] msg, String suffix, boolean withReturn) + { + return digest(msg, msg == null ? 0 : msg.length, 0, suffix, withReturn); } @@ -136,12 +210,119 @@ public class SHA3 * Absorb the last part of the message and squeeze the Keccak sponge * * @param msg The rest of the message - * @param msglen The length of the partial message + * @param msglen The length of the partial message in while bytes * @return The hash sum */ public static byte[] digest(byte[] msg, int msglen) { - return digest(msg, msg == null ? 0 : msg.length, true); + return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, true); + } + + + /** + * Absorb the last part of the message and squeeze the Keccak sponge + * + * @param msg The rest of the message + * @param msglen The length of the partial message in while bytes + * @param suffix The suffix concatenate to the message + * @return The hash sum + */ + public static byte[] digest(byte[] msg, int msglen, String suffix) + { + return digest(msg, msg == null ? 0 : msg.length, 0, suffix, true); + } + + + /** + * Absorb the last part of the message and squeeze the Keccak sponge + * + * @param msg The rest of the message + * @param msglen The length of the partial message in while bytes + * @param bits The number of bits at the end of the message not covered by msglen + * @return The hash sum + */ + public static byte[] digest(byte[] msg, int msglen, int bits) + { + return digest(msg, msg == null ? 0 : msg.length, bits, SHA3.SHA3_SUFFIX, true); + } + + + /** + * Absorb the last part of the message and squeeze the Keccak sponge + * + * @param msg The rest of the message + * @param msglen The length of the partial message in while bytes + * @param bits The number of bits at the end of the message not covered by msglen + * @param suffix The suffix concatenate to the message + * @return The hash sum + */ + public static byte[] digest(byte[] msg, int msglen, int bits, String suffix) + { + return digest(msg, msg == null ? 0 : msg.length, bits, suffix, true); + } + + + /** + * Absorb the last part of the message and squeeze the Keccak sponge + * + * @param msg The rest of the message + * @param msglen The length of the partial message in while bytes + * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null} + * @return The hash sum, or {@code null} if withReturn is {@code false} + */ + public static byte[] digest(byte[] msg, int msglen, boolean withReturn) + { + return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, withReturn); + } + + + /** + * Absorb the last part of the message and squeeze the Keccak sponge + * + * @param msg The rest of the message + * @param msglen The length of the partial message in while bytes + * @param suffix The suffix concatenate to the message + * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null} + * @return The hash sum, or {@code null} if withReturn is {@code false} + */ + public static byte[] digest(byte[] msg, int msglen, String suffix, boolean withReturn) + { + return digest(msg, msg == null ? 0 : msg.length, 0, suffix, withReturn); + } + + + /** + * Absorb the last part of the message and squeeze the Keccak sponge + * + * @param msg The rest of the message + * @param msglen The length of the partial message in while bytes + * @param bits The number of bits at the end of the message not covered by msglen + * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null} + * @return The hash sum, or {@code null} if withReturn is {@code false} + */ + public static byte[] digest(byte[] msg, int msglen, int bits, boolean withReturn) + { + return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, withReturn); + } + + + /** + * Absorb the last part of the message and squeeze the Keccak sponge + * + * @param msg The rest of the message + * @param msglen The length of the partial message + * @param bits The number of bits at the end of the message not covered by msglen + * @param suffix The suffix concatenate to the message + * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null} + * @return The hash sum, or {@code null} if withReturn is {@code false} + */ + public static byte[] digest(byte[] msg, int msglen, int bits, String suffix, boolean withReturn) + { + int[] suffix_ = new int[suffix.length()]; + for (int i = 0, n = suffix_.length; i < n; i++) + suffix_[i] = suffix.charAt(i) == '1' ? 1 : 0; + + return digest(msg, msglen, bits, suffix_, withReturn); } @@ -150,10 +331,12 @@ public class SHA3 * * @param msg The rest of the message * @param msglen The length of the partial message + * @param bits The number of bits at the end of the message not covered by msglen + * @param suffix The suffix concatenate to the message * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null} * @return The hash sum, or {@code null} if withReturn is {@code false} */ - public static native byte[] digest(byte[] msg, int msglen, boolean withReturn); + public static native byte[] digest(byte[] msg, int msglen, int bits, int[] suffix, boolean withReturn); /** diff --git a/java-c-jni/sha3sum.java b/java-c-jni/sha3sum.java index a7abd07..c3c63a5 100644 --- a/java-c-jni/sha3sum.java +++ b/java-c-jni/sha3sum.java @@ -355,9 +355,9 @@ public class sha3sum else { int n = read >> 1; - for (int _ = 0; _ < n; _++) - { byte a = chunk[_ << 1], b = chunk[(_ << 1) | 1]; - chunk[_] = (byte)((((a & 15) + (a <= '9' ? 0 : 9)) << 4) | ((b & 15) + (b <= '9' ? 0 : 9))); + for (int k = 0; k < n; k++) + { byte a = chunk[k << 1], b = chunk[(k << 1) | 1]; + chunk[k] = (byte)((((a & 15) + (a <= '9' ? 0 : 9)) << 4) | ((b & 15) + (b <= '9' ? 0 : 9))); } SHA3.update(chunk, n); } @@ -374,7 +374,7 @@ public class sha3sum bs = stdin; if (multi == 0) { - for (int _ = 1; _ < i; _++) + for (int k = 1; k < i; k++) { SHA3.initialise(r, c, o); bs = SHA3.digest(bs, j == 1); @@ -409,7 +409,7 @@ public class sha3sum out[out.length - 1] = '\n'; System.out.write(out); } - for (int _ = 1; _ < i; _++) + for (int k = 1; k < i; k++) { SHA3.initialise(r, c, o); bs = SHA3.digest(bs, j == 1); @@ -434,9 +434,9 @@ public class sha3sum HashSet got = new HashSet(); String loop = null; byte[] out = new byte[(bs.length << 1)]; - for (int _ = 0; _ < i; _++) + for (int k = 0; k < i; k++) { - if (_ > 0) + if (k > 0) { SHA3.initialise(r, c, o); bs = SHA3.digest(bs, j == 1); if (j > 2) -- cgit v1.2.3-70-g09d2