8259498: Reduce overhead of MD5 and SHA digests

Reviewed-by: valeriep
This commit is contained in:
Claes Redestad 2021-01-20 23:45:55 +00:00
parent 27cc62a5c7
commit 35c9da7031
8 changed files with 305 additions and 576 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,24 +25,14 @@
package sun.security.provider;
import static java.lang.Integer.reverseBytes;
import static java.lang.Long.reverseBytes;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.nio.ByteOrder;
import jdk.internal.misc.Unsafe;
/**
* Optimized methods for converting between byte[] and int[]/long[], both for
* big endian and little endian byte orders.
*
* Currently, it includes a default code path plus two optimized code paths.
* One is for little endian architectures that support full speed int/long
* access at unaligned addresses (i.e. x86/amd64). The second is for big endian
* architectures (that only support correctly aligned access), such as SPARC.
* These are the only platforms we currently support, but other optimized
* variants could be added as needed.
*
* NOTE that ArrayIndexOutOfBoundsException will be thrown if the bounds checks
* failed.
*
@ -59,408 +49,128 @@ final class ByteArrayAccess {
// empty
}
private static final Unsafe unsafe = Unsafe.getUnsafe();
static final class LE {
static final VarHandle INT_ARRAY
= MethodHandles.byteArrayViewVarHandle(int[].class,
ByteOrder.LITTLE_ENDIAN).withInvokeExactBehavior();
// whether to use the optimized path for little endian platforms that
// support full speed unaligned memory access.
private static final boolean littleEndianUnaligned;
// whether to use the optimzied path for big endian platforms that
// support only correctly aligned full speed memory access.
// (Note that on SPARC unaligned memory access is possible, but it is
// implemented using a software trap and therefore very slow)
private static final boolean bigEndian;
private static final int byteArrayOfs = unsafe.arrayBaseOffset(byte[].class);
static {
boolean scaleOK = ((unsafe.arrayIndexScale(byte[].class) == 1)
&& (unsafe.arrayIndexScale(int[].class) == 4)
&& (unsafe.arrayIndexScale(long[].class) == 8)
&& ((byteArrayOfs & 3) == 0));
ByteOrder byteOrder = ByteOrder.nativeOrder();
littleEndianUnaligned =
scaleOK && unaligned() && (byteOrder == ByteOrder.LITTLE_ENDIAN);
bigEndian =
scaleOK && (byteOrder == ByteOrder.BIG_ENDIAN);
static final VarHandle LONG_ARRAY
= MethodHandles.byteArrayViewVarHandle(long[].class,
ByteOrder.LITTLE_ENDIAN).withInvokeExactBehavior();
}
// Return whether this platform supports full speed int/long memory access
// at unaligned addresses.
private static boolean unaligned() {
return unsafe.unalignedAccess();
}
static final class BE {
static final VarHandle INT_ARRAY
= MethodHandles.byteArrayViewVarHandle(int[].class,
ByteOrder.BIG_ENDIAN).withInvokeExactBehavior();
/**
* byte[] to int[] conversion, little endian byte order.
*/
static void b2iLittle(byte[] in, int inOfs, int[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len) ||
(outOfs < 0) || ((out.length - outOfs) < len/4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
len += inOfs;
while (inOfs < len) {
out[outOfs++] = unsafe.getInt(in, (long)inOfs);
inOfs += 4;
}
} else if (bigEndian && ((inOfs & 3) == 0)) {
inOfs += byteArrayOfs;
len += inOfs;
while (inOfs < len) {
out[outOfs++] = reverseBytes(unsafe.getInt(in, (long)inOfs));
inOfs += 4;
}
} else {
len += inOfs;
while (inOfs < len) {
out[outOfs++] = ((in[inOfs ] & 0xff) )
| ((in[inOfs + 1] & 0xff) << 8)
| ((in[inOfs + 2] & 0xff) << 16)
| ((in[inOfs + 3] ) << 24);
inOfs += 4;
}
}
}
// Special optimization of b2iLittle(in, inOfs, out, 0, 64)
static void b2iLittle64(byte[] in, int inOfs, int[] out) {
if ((inOfs < 0) || ((in.length - inOfs) < 64) ||
(out.length < 16)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
out[ 0] = unsafe.getInt(in, (long)(inOfs ));
out[ 1] = unsafe.getInt(in, (long)(inOfs + 4));
out[ 2] = unsafe.getInt(in, (long)(inOfs + 8));
out[ 3] = unsafe.getInt(in, (long)(inOfs + 12));
out[ 4] = unsafe.getInt(in, (long)(inOfs + 16));
out[ 5] = unsafe.getInt(in, (long)(inOfs + 20));
out[ 6] = unsafe.getInt(in, (long)(inOfs + 24));
out[ 7] = unsafe.getInt(in, (long)(inOfs + 28));
out[ 8] = unsafe.getInt(in, (long)(inOfs + 32));
out[ 9] = unsafe.getInt(in, (long)(inOfs + 36));
out[10] = unsafe.getInt(in, (long)(inOfs + 40));
out[11] = unsafe.getInt(in, (long)(inOfs + 44));
out[12] = unsafe.getInt(in, (long)(inOfs + 48));
out[13] = unsafe.getInt(in, (long)(inOfs + 52));
out[14] = unsafe.getInt(in, (long)(inOfs + 56));
out[15] = unsafe.getInt(in, (long)(inOfs + 60));
} else if (bigEndian && ((inOfs & 3) == 0)) {
inOfs += byteArrayOfs;
out[ 0] = reverseBytes(unsafe.getInt(in, (long)(inOfs )));
out[ 1] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 4)));
out[ 2] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 8)));
out[ 3] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 12)));
out[ 4] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 16)));
out[ 5] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 20)));
out[ 6] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 24)));
out[ 7] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 28)));
out[ 8] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 32)));
out[ 9] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 36)));
out[10] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 40)));
out[11] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 44)));
out[12] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 48)));
out[13] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 52)));
out[14] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 56)));
out[15] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 60)));
} else {
b2iLittle(in, inOfs, out, 0, 64);
}
static final VarHandle LONG_ARRAY
= MethodHandles.byteArrayViewVarHandle(long[].class,
ByteOrder.BIG_ENDIAN).withInvokeExactBehavior();
}
/**
* int[] to byte[] conversion, little endian byte order.
*/
static void i2bLittle(int[] in, int inOfs, byte[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len/4) ||
(outOfs < 0) || ((out.length - outOfs) < len)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
outOfs += byteArrayOfs;
len += outOfs;
while (outOfs < len) {
unsafe.putInt(out, (long)outOfs, in[inOfs++]);
outOfs += 4;
}
} else if (bigEndian && ((outOfs & 3) == 0)) {
outOfs += byteArrayOfs;
len += outOfs;
while (outOfs < len) {
unsafe.putInt(out, (long)outOfs, reverseBytes(in[inOfs++]));
outOfs += 4;
}
} else {
len += outOfs;
while (outOfs < len) {
int i = in[inOfs++];
out[outOfs++] = (byte)(i );
out[outOfs++] = (byte)(i >> 8);
out[outOfs++] = (byte)(i >> 16);
out[outOfs++] = (byte)(i >> 24);
}
len += outOfs;
while (outOfs < len) {
LE.INT_ARRAY.set(out, outOfs, in[inOfs++]);
outOfs += 4;
}
}
// Store one 32-bit value into out[outOfs..outOfs+3] in little endian order.
static void i2bLittle4(int val, byte[] out, int outOfs) {
if ((outOfs < 0) || ((out.length - outOfs) < 4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
unsafe.putInt(out, (long)(byteArrayOfs + outOfs), val);
} else if (bigEndian && ((outOfs & 3) == 0)) {
unsafe.putInt(out, (long)(byteArrayOfs + outOfs), reverseBytes(val));
} else {
out[outOfs ] = (byte)(val );
out[outOfs + 1] = (byte)(val >> 8);
out[outOfs + 2] = (byte)(val >> 16);
out[outOfs + 3] = (byte)(val >> 24);
}
LE.INT_ARRAY.set(out, outOfs, val);
}
/**
* byte[] to int[] conversion, big endian byte order.
*/
static void b2iBig(byte[] in, int inOfs, int[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len) ||
(outOfs < 0) || ((out.length - outOfs) < len/4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
len += inOfs;
while (inOfs < len) {
out[outOfs++] = reverseBytes(unsafe.getInt(in, (long)inOfs));
inOfs += 4;
}
} else if (bigEndian && ((inOfs & 3) == 0)) {
inOfs += byteArrayOfs;
len += inOfs;
while (inOfs < len) {
out[outOfs++] = unsafe.getInt(in, (long)inOfs);
inOfs += 4;
}
} else {
len += inOfs;
while (inOfs < len) {
out[outOfs++] = ((in[inOfs + 3] & 0xff) )
| ((in[inOfs + 2] & 0xff) << 8)
| ((in[inOfs + 1] & 0xff) << 16)
| ((in[inOfs ] ) << 24);
inOfs += 4;
}
len += inOfs;
while (inOfs < len) {
out[outOfs++] = (int) BE.INT_ARRAY.get(in, inOfs);
inOfs += 4;
}
}
// Special optimization of b2iBig(in, inOfs, out, 0, 64)
static void b2iBig64(byte[] in, int inOfs, int[] out) {
if ((inOfs < 0) || ((in.length - inOfs) < 64) ||
(out.length < 16)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
out[ 0] = reverseBytes(unsafe.getInt(in, (long)(inOfs )));
out[ 1] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 4)));
out[ 2] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 8)));
out[ 3] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 12)));
out[ 4] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 16)));
out[ 5] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 20)));
out[ 6] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 24)));
out[ 7] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 28)));
out[ 8] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 32)));
out[ 9] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 36)));
out[10] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 40)));
out[11] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 44)));
out[12] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 48)));
out[13] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 52)));
out[14] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 56)));
out[15] = reverseBytes(unsafe.getInt(in, (long)(inOfs + 60)));
} else if (bigEndian && ((inOfs & 3) == 0)) {
inOfs += byteArrayOfs;
out[ 0] = unsafe.getInt(in, (long)(inOfs ));
out[ 1] = unsafe.getInt(in, (long)(inOfs + 4));
out[ 2] = unsafe.getInt(in, (long)(inOfs + 8));
out[ 3] = unsafe.getInt(in, (long)(inOfs + 12));
out[ 4] = unsafe.getInt(in, (long)(inOfs + 16));
out[ 5] = unsafe.getInt(in, (long)(inOfs + 20));
out[ 6] = unsafe.getInt(in, (long)(inOfs + 24));
out[ 7] = unsafe.getInt(in, (long)(inOfs + 28));
out[ 8] = unsafe.getInt(in, (long)(inOfs + 32));
out[ 9] = unsafe.getInt(in, (long)(inOfs + 36));
out[10] = unsafe.getInt(in, (long)(inOfs + 40));
out[11] = unsafe.getInt(in, (long)(inOfs + 44));
out[12] = unsafe.getInt(in, (long)(inOfs + 48));
out[13] = unsafe.getInt(in, (long)(inOfs + 52));
out[14] = unsafe.getInt(in, (long)(inOfs + 56));
out[15] = unsafe.getInt(in, (long)(inOfs + 60));
} else {
b2iBig(in, inOfs, out, 0, 64);
}
out[ 0] = (int) BE.INT_ARRAY.get(in, inOfs );
out[ 1] = (int) BE.INT_ARRAY.get(in, inOfs + 4);
out[ 2] = (int) BE.INT_ARRAY.get(in, inOfs + 8);
out[ 3] = (int) BE.INT_ARRAY.get(in, inOfs + 12);
out[ 4] = (int) BE.INT_ARRAY.get(in, inOfs + 16);
out[ 5] = (int) BE.INT_ARRAY.get(in, inOfs + 20);
out[ 6] = (int) BE.INT_ARRAY.get(in, inOfs + 24);
out[ 7] = (int) BE.INT_ARRAY.get(in, inOfs + 28);
out[ 8] = (int) BE.INT_ARRAY.get(in, inOfs + 32);
out[ 9] = (int) BE.INT_ARRAY.get(in, inOfs + 36);
out[10] = (int) BE.INT_ARRAY.get(in, inOfs + 40);
out[11] = (int) BE.INT_ARRAY.get(in, inOfs + 44);
out[12] = (int) BE.INT_ARRAY.get(in, inOfs + 48);
out[13] = (int) BE.INT_ARRAY.get(in, inOfs + 52);
out[14] = (int) BE.INT_ARRAY.get(in, inOfs + 56);
out[15] = (int) BE.INT_ARRAY.get(in, inOfs + 60);
}
/**
* int[] to byte[] conversion, big endian byte order.
*/
static void i2bBig(int[] in, int inOfs, byte[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len/4) ||
(outOfs < 0) || ((out.length - outOfs) < len)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
outOfs += byteArrayOfs;
len += outOfs;
while (outOfs < len) {
unsafe.putInt(out, (long)outOfs, reverseBytes(in[inOfs++]));
outOfs += 4;
}
} else if (bigEndian && ((outOfs & 3) == 0)) {
outOfs += byteArrayOfs;
len += outOfs;
while (outOfs < len) {
unsafe.putInt(out, (long)outOfs, in[inOfs++]);
outOfs += 4;
}
} else {
len += outOfs;
while (outOfs < len) {
int i = in[inOfs++];
out[outOfs++] = (byte)(i >> 24);
out[outOfs++] = (byte)(i >> 16);
out[outOfs++] = (byte)(i >> 8);
out[outOfs++] = (byte)(i );
}
len += outOfs;
while (outOfs < len) {
BE.INT_ARRAY.set(out, outOfs, in[inOfs++]);
outOfs += 4;
}
}
// Store one 32-bit value into out[outOfs..outOfs+3] in big endian order.
static void i2bBig4(int val, byte[] out, int outOfs) {
if ((outOfs < 0) || ((out.length - outOfs) < 4)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
unsafe.putInt(out, (long)(byteArrayOfs + outOfs), reverseBytes(val));
} else if (bigEndian && ((outOfs & 3) == 0)) {
unsafe.putInt(out, (long)(byteArrayOfs + outOfs), val);
} else {
out[outOfs ] = (byte)(val >> 24);
out[outOfs + 1] = (byte)(val >> 16);
out[outOfs + 2] = (byte)(val >> 8);
out[outOfs + 3] = (byte)(val );
}
BE.INT_ARRAY.set(out, outOfs, val);
}
/**
* byte[] to long[] conversion, big endian byte order.
*/
static void b2lBig(byte[] in, int inOfs, long[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len) ||
(outOfs < 0) || ((out.length - outOfs) < len/8)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
len += inOfs;
while (inOfs < len) {
out[outOfs++] = reverseBytes(unsafe.getLong(in, (long)inOfs));
inOfs += 8;
}
} else if (bigEndian && ((inOfs & 3) == 0)) {
// In the current HotSpot memory layout, the first element of a
// byte[] is only 32-bit aligned, not 64-bit.
// That means we could use getLong() only for offset 4, 12, etc.,
// which would rarely occur in practice. Instead, we use an
// optimization that uses getInt() so that it works for offset 0.
inOfs += byteArrayOfs;
len += inOfs;
while (inOfs < len) {
out[outOfs++] =
((long)unsafe.getInt(in, (long)inOfs) << 32)
| (unsafe.getInt(in, (long)(inOfs + 4)) & 0xffffffffL);
inOfs += 8;
}
} else {
len += inOfs;
while (inOfs < len) {
int i1 = ((in[inOfs + 3] & 0xff) )
| ((in[inOfs + 2] & 0xff) << 8)
| ((in[inOfs + 1] & 0xff) << 16)
| ((in[inOfs ] ) << 24);
inOfs += 4;
int i2 = ((in[inOfs + 3] & 0xff) )
| ((in[inOfs + 2] & 0xff) << 8)
| ((in[inOfs + 1] & 0xff) << 16)
| ((in[inOfs ] ) << 24);
out[outOfs++] = ((long)i1 << 32) | (i2 & 0xffffffffL);
inOfs += 4;
}
len += inOfs;
while (inOfs < len) {
out[outOfs++] = (long) BE.LONG_ARRAY.get(in, inOfs);
inOfs += 8;
}
}
// Special optimization of b2lBig(in, inOfs, out, 0, 128)
static void b2lBig128(byte[] in, int inOfs, long[] out) {
if ((inOfs < 0) || ((in.length - inOfs) < 128) ||
(out.length < 16)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
out[ 0] = reverseBytes(unsafe.getLong(in, (long)(inOfs )));
out[ 1] = reverseBytes(unsafe.getLong(in, (long)(inOfs + 8)));
out[ 2] = reverseBytes(unsafe.getLong(in, (long)(inOfs + 16)));
out[ 3] = reverseBytes(unsafe.getLong(in, (long)(inOfs + 24)));
out[ 4] = reverseBytes(unsafe.getLong(in, (long)(inOfs + 32)));
out[ 5] = reverseBytes(unsafe.getLong(in, (long)(inOfs + 40)));
out[ 6] = reverseBytes(unsafe.getLong(in, (long)(inOfs + 48)));
out[ 7] = reverseBytes(unsafe.getLong(in, (long)(inOfs + 56)));
out[ 8] = reverseBytes(unsafe.getLong(in, (long)(inOfs + 64)));
out[ 9] = reverseBytes(unsafe.getLong(in, (long)(inOfs + 72)));
out[10] = reverseBytes(unsafe.getLong(in, (long)(inOfs + 80)));
out[11] = reverseBytes(unsafe.getLong(in, (long)(inOfs + 88)));
out[12] = reverseBytes(unsafe.getLong(in, (long)(inOfs + 96)));
out[13] = reverseBytes(unsafe.getLong(in, (long)(inOfs + 104)));
out[14] = reverseBytes(unsafe.getLong(in, (long)(inOfs + 112)));
out[15] = reverseBytes(unsafe.getLong(in, (long)(inOfs + 120)));
} else {
// no optimization for big endian, see comments in b2lBig
b2lBig(in, inOfs, out, 0, 128);
}
out[ 0] = (long) BE.LONG_ARRAY.get(in, inOfs );
out[ 1] = (long) BE.LONG_ARRAY.get(in, inOfs + 8);
out[ 2] = (long) BE.LONG_ARRAY.get(in, inOfs + 16);
out[ 3] = (long) BE.LONG_ARRAY.get(in, inOfs + 24);
out[ 4] = (long) BE.LONG_ARRAY.get(in, inOfs + 32);
out[ 5] = (long) BE.LONG_ARRAY.get(in, inOfs + 40);
out[ 6] = (long) BE.LONG_ARRAY.get(in, inOfs + 48);
out[ 7] = (long) BE.LONG_ARRAY.get(in, inOfs + 56);
out[ 8] = (long) BE.LONG_ARRAY.get(in, inOfs + 64);
out[ 9] = (long) BE.LONG_ARRAY.get(in, inOfs + 72);
out[10] = (long) BE.LONG_ARRAY.get(in, inOfs + 80);
out[11] = (long) BE.LONG_ARRAY.get(in, inOfs + 88);
out[12] = (long) BE.LONG_ARRAY.get(in, inOfs + 96);
out[13] = (long) BE.LONG_ARRAY.get(in, inOfs + 104);
out[14] = (long) BE.LONG_ARRAY.get(in, inOfs + 112);
out[15] = (long) BE.LONG_ARRAY.get(in, inOfs + 120);
}
/**
* long[] to byte[] conversion, big endian byte order.
*/
static void l2bBig(long[] in, int inOfs, byte[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len/8) ||
(outOfs < 0) || ((out.length - outOfs) < len)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
outOfs += byteArrayOfs;
len += outOfs;
while (outOfs < len) {
unsafe.putLong(out, (long)outOfs, reverseBytes(in[inOfs++]));
outOfs += 8;
}
} else {
len += outOfs;
while (outOfs < len) {
long i = in[inOfs++];
out[outOfs++] = (byte)(i >> 56);
out[outOfs++] = (byte)(i >> 48);
out[outOfs++] = (byte)(i >> 40);
out[outOfs++] = (byte)(i >> 32);
out[outOfs++] = (byte)(i >> 24);
out[outOfs++] = (byte)(i >> 16);
out[outOfs++] = (byte)(i >> 8);
out[outOfs++] = (byte)(i );
}
len += outOfs;
while (outOfs < len) {
BE.LONG_ARRAY.set(out, outOfs, in[inOfs++]);
outOfs += 8;
}
}
@ -468,30 +178,10 @@ final class ByteArrayAccess {
* byte[] to long[] conversion, little endian byte order
*/
static void b2lLittle(byte[] in, int inOfs, long[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len) ||
((outOfs < 0) || (out.length - outOfs) < len/8)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
inOfs += byteArrayOfs;
len += inOfs;
while (inOfs < len) {
out[outOfs++] = unsafe.getLong(in, (long)inOfs);
inOfs += 8;
}
} else {
len += inOfs;
while (inOfs < len) {
out[outOfs++] = ((in[inOfs ] & 0xffL)
| ((in[inOfs + 1] & 0xffL) << 8)
| ((in[inOfs + 2] & 0xffL) << 16)
| ((in[inOfs + 3] & 0xffL) << 24)
| ((in[inOfs + 4] & 0xffL) << 32)
| ((in[inOfs + 5] & 0xffL) << 40)
| ((in[inOfs + 6] & 0xffL) << 48)
| ((in[inOfs + 7] & 0xffL) << 56));
inOfs += 8;
}
len += inOfs;
while (inOfs < len) {
out[outOfs++] = (long) LE.LONG_ARRAY.get(in, inOfs);
inOfs += 8;
}
}
@ -500,30 +190,10 @@ final class ByteArrayAccess {
* long[] to byte[] conversion, little endian byte order
*/
static void l2bLittle(long[] in, int inOfs, byte[] out, int outOfs, int len) {
if ((inOfs < 0) || ((in.length - inOfs) < len/8) ||
(outOfs < 0) || ((out.length - outOfs) < len)) {
throw new ArrayIndexOutOfBoundsException();
}
if (littleEndianUnaligned) {
outOfs += byteArrayOfs;
len += outOfs;
while (outOfs < len) {
unsafe.putLong(out, (long)outOfs, in[inOfs++]);
outOfs += 8;
}
} else {
len += outOfs;
while (outOfs < len) {
long i = in[inOfs++];
out[outOfs++] = (byte)(i );
out[outOfs++] = (byte)(i >> 8);
out[outOfs++] = (byte)(i >> 16);
out[outOfs++] = (byte)(i >> 24);
out[outOfs++] = (byte)(i >> 32);
out[outOfs++] = (byte)(i >> 40);
out[outOfs++] = (byte)(i >> 48);
out[outOfs++] = (byte)(i >> 56);
}
len += outOfs;
while (outOfs < len) {
LE.LONG_ARRAY.set(out, outOfs, in[inOfs++]);
outOfs += 8;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -47,8 +47,6 @@ public final class MD4 extends DigestBase {
// state of this object
private int[] state;
// temporary buffer, used by implCompress()
private int[] x;
// rotation constants
private static final int S11 = 3;
@ -93,7 +91,6 @@ public final class MD4 extends DigestBase {
public MD4() {
super("MD4", 16, 64);
state = new int[4];
x = new int[16];
resetHashes();
}
@ -101,7 +98,6 @@ public final class MD4 extends DigestBase {
public Object clone() throws CloneNotSupportedException {
MD4 copy = (MD4) super.clone();
copy.state = copy.state.clone();
copy.x = new int[16];
return copy;
}
@ -111,8 +107,6 @@ public final class MD4 extends DigestBase {
void implReset() {
// Load magic initialization constants.
resetHashes();
// clear out old data
Arrays.fill(x, 0);
}
private void resetHashes() {
@ -162,7 +156,22 @@ public final class MD4 extends DigestBase {
* bytes from the buffer, beginning at the specified offset.
*/
void implCompress(byte[] buf, int ofs) {
b2iLittle64(buf, ofs, x);
int x0 = (int) LE.INT_ARRAY.get(buf, ofs);
int x1 = (int) LE.INT_ARRAY.get(buf, ofs + 4);
int x2 = (int) LE.INT_ARRAY.get(buf, ofs + 8);
int x3 = (int) LE.INT_ARRAY.get(buf, ofs + 12);
int x4 = (int) LE.INT_ARRAY.get(buf, ofs + 16);
int x5 = (int) LE.INT_ARRAY.get(buf, ofs + 20);
int x6 = (int) LE.INT_ARRAY.get(buf, ofs + 24);
int x7 = (int) LE.INT_ARRAY.get(buf, ofs + 28);
int x8 = (int) LE.INT_ARRAY.get(buf, ofs + 32);
int x9 = (int) LE.INT_ARRAY.get(buf, ofs + 36);
int x10 = (int) LE.INT_ARRAY.get(buf, ofs + 40);
int x11 = (int) LE.INT_ARRAY.get(buf, ofs + 44);
int x12 = (int) LE.INT_ARRAY.get(buf, ofs + 48);
int x13 = (int) LE.INT_ARRAY.get(buf, ofs + 52);
int x14 = (int) LE.INT_ARRAY.get(buf, ofs + 56);
int x15 = (int) LE.INT_ARRAY.get(buf, ofs + 60);
int a = state[0];
int b = state[1];
@ -170,58 +179,58 @@ public final class MD4 extends DigestBase {
int d = state[3];
/* Round 1 */
a = FF (a, b, c, d, x[ 0], S11); /* 1 */
d = FF (d, a, b, c, x[ 1], S12); /* 2 */
c = FF (c, d, a, b, x[ 2], S13); /* 3 */
b = FF (b, c, d, a, x[ 3], S14); /* 4 */
a = FF (a, b, c, d, x[ 4], S11); /* 5 */
d = FF (d, a, b, c, x[ 5], S12); /* 6 */
c = FF (c, d, a, b, x[ 6], S13); /* 7 */
b = FF (b, c, d, a, x[ 7], S14); /* 8 */
a = FF (a, b, c, d, x[ 8], S11); /* 9 */
d = FF (d, a, b, c, x[ 9], S12); /* 10 */
c = FF (c, d, a, b, x[10], S13); /* 11 */
b = FF (b, c, d, a, x[11], S14); /* 12 */
a = FF (a, b, c, d, x[12], S11); /* 13 */
d = FF (d, a, b, c, x[13], S12); /* 14 */
c = FF (c, d, a, b, x[14], S13); /* 15 */
b = FF (b, c, d, a, x[15], S14); /* 16 */
a = FF (a, b, c, d, x0, S11); /* 1 */
d = FF (d, a, b, c, x1, S12); /* 2 */
c = FF (c, d, a, b, x2, S13); /* 3 */
b = FF (b, c, d, a, x3, S14); /* 4 */
a = FF (a, b, c, d, x4, S11); /* 5 */
d = FF (d, a, b, c, x5, S12); /* 6 */
c = FF (c, d, a, b, x6, S13); /* 7 */
b = FF (b, c, d, a, x7, S14); /* 8 */
a = FF (a, b, c, d, x8, S11); /* 9 */
d = FF (d, a, b, c, x9, S12); /* 10 */
c = FF (c, d, a, b, x10, S13); /* 11 */
b = FF (b, c, d, a, x11, S14); /* 12 */
a = FF (a, b, c, d, x12, S11); /* 13 */
d = FF (d, a, b, c, x13, S12); /* 14 */
c = FF (c, d, a, b, x14, S13); /* 15 */
b = FF (b, c, d, a, x15, S14); /* 16 */
/* Round 2 */
a = GG (a, b, c, d, x[ 0], S21); /* 17 */
d = GG (d, a, b, c, x[ 4], S22); /* 18 */
c = GG (c, d, a, b, x[ 8], S23); /* 19 */
b = GG (b, c, d, a, x[12], S24); /* 20 */
a = GG (a, b, c, d, x[ 1], S21); /* 21 */
d = GG (d, a, b, c, x[ 5], S22); /* 22 */
c = GG (c, d, a, b, x[ 9], S23); /* 23 */
b = GG (b, c, d, a, x[13], S24); /* 24 */
a = GG (a, b, c, d, x[ 2], S21); /* 25 */
d = GG (d, a, b, c, x[ 6], S22); /* 26 */
c = GG (c, d, a, b, x[10], S23); /* 27 */
b = GG (b, c, d, a, x[14], S24); /* 28 */
a = GG (a, b, c, d, x[ 3], S21); /* 29 */
d = GG (d, a, b, c, x[ 7], S22); /* 30 */
c = GG (c, d, a, b, x[11], S23); /* 31 */
b = GG (b, c, d, a, x[15], S24); /* 32 */
a = GG (a, b, c, d, x0, S21); /* 17 */
d = GG (d, a, b, c, x4, S22); /* 18 */
c = GG (c, d, a, b, x8, S23); /* 19 */
b = GG (b, c, d, a, x12, S24); /* 20 */
a = GG (a, b, c, d, x1, S21); /* 21 */
d = GG (d, a, b, c, x5, S22); /* 22 */
c = GG (c, d, a, b, x9, S23); /* 23 */
b = GG (b, c, d, a, x13, S24); /* 24 */
a = GG (a, b, c, d, x2, S21); /* 25 */
d = GG (d, a, b, c, x6, S22); /* 26 */
c = GG (c, d, a, b, x10, S23); /* 27 */
b = GG (b, c, d, a, x14, S24); /* 28 */
a = GG (a, b, c, d, x3, S21); /* 29 */
d = GG (d, a, b, c, x7, S22); /* 30 */
c = GG (c, d, a, b, x11, S23); /* 31 */
b = GG (b, c, d, a, x15, S24); /* 32 */
/* Round 3 */
a = HH (a, b, c, d, x[ 0], S31); /* 33 */
d = HH (d, a, b, c, x[ 8], S32); /* 34 */
c = HH (c, d, a, b, x[ 4], S33); /* 35 */
b = HH (b, c, d, a, x[12], S34); /* 36 */
a = HH (a, b, c, d, x[ 2], S31); /* 37 */
d = HH (d, a, b, c, x[10], S32); /* 38 */
c = HH (c, d, a, b, x[ 6], S33); /* 39 */
b = HH (b, c, d, a, x[14], S34); /* 40 */
a = HH (a, b, c, d, x[ 1], S31); /* 41 */
d = HH (d, a, b, c, x[ 9], S32); /* 42 */
c = HH (c, d, a, b, x[ 5], S33); /* 43 */
b = HH (b, c, d, a, x[13], S34); /* 44 */
a = HH (a, b, c, d, x[ 3], S31); /* 45 */
d = HH (d, a, b, c, x[11], S32); /* 46 */
c = HH (c, d, a, b, x[ 7], S33); /* 47 */
b = HH (b, c, d, a, x[15], S34); /* 48 */
a = HH (a, b, c, d, x0, S31); /* 33 */
d = HH (d, a, b, c, x8, S32); /* 34 */
c = HH (c, d, a, b, x4, S33); /* 35 */
b = HH (b, c, d, a, x12, S34); /* 36 */
a = HH (a, b, c, d, x2, S31); /* 37 */
d = HH (d, a, b, c, x10, S32); /* 38 */
c = HH (c, d, a, b, x6, S33); /* 39 */
b = HH (b, c, d, a, x14, S34); /* 40 */
a = HH (a, b, c, d, x1, S31); /* 41 */
d = HH (d, a, b, c, x9, S32); /* 42 */
c = HH (c, d, a, b, x5, S33); /* 43 */
b = HH (b, c, d, a, x13, S34); /* 44 */
a = HH (a, b, c, d, x3, S31); /* 45 */
d = HH (d, a, b, c, x11, S32); /* 46 */
c = HH (c, d, a, b, x7, S33); /* 47 */
b = HH (b, c, d, a, x15, S34); /* 48 */
state[0] += a;
state[1] += b;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,9 @@
package sun.security.provider;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.Objects;
@ -44,8 +47,6 @@ public final class MD5 extends DigestBase {
// state of this object
private int[] state;
// temporary buffer, used by implCompress()
private int[] x;
// rotation constants
private static final int S11 = 7;
@ -69,15 +70,13 @@ public final class MD5 extends DigestBase {
public MD5() {
super("MD5", 16, 64);
state = new int[4];
x = new int[16];
resetHashes();
implReset();
}
// clone this object
public Object clone() throws CloneNotSupportedException {
MD5 copy = (MD5) super.clone();
copy.state = copy.state.clone();
copy.x = new int[16];
return copy;
}
@ -86,12 +85,6 @@ public final class MD5 extends DigestBase {
*/
void implReset() {
// Load magic initialization constants.
resetHashes();
// clear out old data
Arrays.fill(x, 0);
}
private void resetHashes() {
state[0] = 0x67452301;
state[1] = 0xefcdab89;
state[2] = 0x98badcfe;
@ -156,11 +149,12 @@ public final class MD5 extends DigestBase {
private void implCompressCheck(byte[] buf, int ofs) {
Objects.requireNonNull(buf);
// The checks performed by the method 'b2iBig64'
// are sufficient for the case when the method
// These checks are sufficient for the case when the method
// 'implCompressImpl' is replaced with a compiler
// intrinsic.
b2iLittle64(buf, ofs, x);
if ((ofs < 0) || ((buf.length - ofs) < 64)) {
throw new ArrayIndexOutOfBoundsException();
}
}
// The method 'implCompress0 seems not to use its parameters.
@ -175,77 +169,94 @@ public final class MD5 extends DigestBase {
int c = state[2];
int d = state[3];
int x0 = (int) LE.INT_ARRAY.get(buf, ofs);
int x1 = (int) LE.INT_ARRAY.get(buf, ofs + 4);
int x2 = (int) LE.INT_ARRAY.get(buf, ofs + 8);
int x3 = (int) LE.INT_ARRAY.get(buf, ofs + 12);
int x4 = (int) LE.INT_ARRAY.get(buf, ofs + 16);
int x5 = (int) LE.INT_ARRAY.get(buf, ofs + 20);
int x6 = (int) LE.INT_ARRAY.get(buf, ofs + 24);
int x7 = (int) LE.INT_ARRAY.get(buf, ofs + 28);
int x8 = (int) LE.INT_ARRAY.get(buf, ofs + 32);
int x9 = (int) LE.INT_ARRAY.get(buf, ofs + 36);
int x10 = (int) LE.INT_ARRAY.get(buf, ofs + 40);
int x11 = (int) LE.INT_ARRAY.get(buf, ofs + 44);
int x12 = (int) LE.INT_ARRAY.get(buf, ofs + 48);
int x13 = (int) LE.INT_ARRAY.get(buf, ofs + 52);
int x14 = (int) LE.INT_ARRAY.get(buf, ofs + 56);
int x15 = (int) LE.INT_ARRAY.get(buf, ofs + 60);
/* Round 1 */
a = FF ( a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
d = FF ( d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
c = FF ( c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
b = FF ( b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
a = FF ( a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
d = FF ( d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
c = FF ( c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
b = FF ( b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
a = FF ( a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
d = FF ( d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
c = FF ( c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
b = FF ( b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
a = FF ( a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
d = FF ( d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
c = FF ( c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
b = FF ( b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
a = FF ( a, b, c, d, x0, S11, 0xd76aa478); /* 1 */
d = FF ( d, a, b, c, x1, S12, 0xe8c7b756); /* 2 */
c = FF ( c, d, a, b, x2, S13, 0x242070db); /* 3 */
b = FF ( b, c, d, a, x3, S14, 0xc1bdceee); /* 4 */
a = FF ( a, b, c, d, x4, S11, 0xf57c0faf); /* 5 */
d = FF ( d, a, b, c, x5, S12, 0x4787c62a); /* 6 */
c = FF ( c, d, a, b, x6, S13, 0xa8304613); /* 7 */
b = FF ( b, c, d, a, x7, S14, 0xfd469501); /* 8 */
a = FF ( a, b, c, d, x8, S11, 0x698098d8); /* 9 */
d = FF ( d, a, b, c, x9, S12, 0x8b44f7af); /* 10 */
c = FF ( c, d, a, b, x10, S13, 0xffff5bb1); /* 11 */
b = FF ( b, c, d, a, x11, S14, 0x895cd7be); /* 12 */
a = FF ( a, b, c, d, x12, S11, 0x6b901122); /* 13 */
d = FF ( d, a, b, c, x13, S12, 0xfd987193); /* 14 */
c = FF ( c, d, a, b, x14, S13, 0xa679438e); /* 15 */
b = FF ( b, c, d, a, x15, S14, 0x49b40821); /* 16 */
/* Round 2 */
a = GG ( a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
d = GG ( d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
c = GG ( c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
b = GG ( b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
a = GG ( a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
d = GG ( d, a, b, c, x[10], S22, 0x2441453); /* 22 */
c = GG ( c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
b = GG ( b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
a = GG ( a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
d = GG ( d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
c = GG ( c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
b = GG ( b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
a = GG ( a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
d = GG ( d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
c = GG ( c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
b = GG ( b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
a = GG ( a, b, c, d, x1, S21, 0xf61e2562); /* 17 */
d = GG ( d, a, b, c, x6, S22, 0xc040b340); /* 18 */
c = GG ( c, d, a, b, x11, S23, 0x265e5a51); /* 19 */
b = GG ( b, c, d, a, x0, S24, 0xe9b6c7aa); /* 20 */
a = GG ( a, b, c, d, x5, S21, 0xd62f105d); /* 21 */
d = GG ( d, a, b, c, x10, S22, 0x2441453); /* 22 */
c = GG ( c, d, a, b, x15, S23, 0xd8a1e681); /* 23 */
b = GG ( b, c, d, a, x4, S24, 0xe7d3fbc8); /* 24 */
a = GG ( a, b, c, d, x9, S21, 0x21e1cde6); /* 25 */
d = GG ( d, a, b, c, x14, S22, 0xc33707d6); /* 26 */
c = GG ( c, d, a, b, x3, S23, 0xf4d50d87); /* 27 */
b = GG ( b, c, d, a, x8, S24, 0x455a14ed); /* 28 */
a = GG ( a, b, c, d, x13, S21, 0xa9e3e905); /* 29 */
d = GG ( d, a, b, c, x2, S22, 0xfcefa3f8); /* 30 */
c = GG ( c, d, a, b, x7, S23, 0x676f02d9); /* 31 */
b = GG ( b, c, d, a, x12, S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
a = HH ( a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
d = HH ( d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
c = HH ( c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
b = HH ( b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
a = HH ( a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
d = HH ( d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
c = HH ( c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
b = HH ( b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
a = HH ( a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
d = HH ( d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
c = HH ( c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
b = HH ( b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
a = HH ( a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
d = HH ( d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
c = HH ( c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
b = HH ( b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
a = HH ( a, b, c, d, x5, S31, 0xfffa3942); /* 33 */
d = HH ( d, a, b, c, x8, S32, 0x8771f681); /* 34 */
c = HH ( c, d, a, b, x11, S33, 0x6d9d6122); /* 35 */
b = HH ( b, c, d, a, x14, S34, 0xfde5380c); /* 36 */
a = HH ( a, b, c, d, x1, S31, 0xa4beea44); /* 37 */
d = HH ( d, a, b, c, x4, S32, 0x4bdecfa9); /* 38 */
c = HH ( c, d, a, b, x7, S33, 0xf6bb4b60); /* 39 */
b = HH ( b, c, d, a, x10, S34, 0xbebfbc70); /* 40 */
a = HH ( a, b, c, d, x13, S31, 0x289b7ec6); /* 41 */
d = HH ( d, a, b, c, x0, S32, 0xeaa127fa); /* 42 */
c = HH ( c, d, a, b, x3, S33, 0xd4ef3085); /* 43 */
b = HH ( b, c, d, a, x6, S34, 0x4881d05); /* 44 */
a = HH ( a, b, c, d, x9, S31, 0xd9d4d039); /* 45 */
d = HH ( d, a, b, c, x12, S32, 0xe6db99e5); /* 46 */
c = HH ( c, d, a, b, x15, S33, 0x1fa27cf8); /* 47 */
b = HH ( b, c, d, a, x2, S34, 0xc4ac5665); /* 48 */
/* Round 4 */
a = II ( a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
d = II ( d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
c = II ( c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
b = II ( b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
a = II ( a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
d = II ( d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
c = II ( c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
b = II ( b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
a = II ( a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
d = II ( d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
c = II ( c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
b = II ( b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
a = II ( a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
d = II ( d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
c = II ( c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
b = II ( b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
a = II ( a, b, c, d, x0, S41, 0xf4292244); /* 49 */
d = II ( d, a, b, c, x7, S42, 0x432aff97); /* 50 */
c = II ( c, d, a, b, x14, S43, 0xab9423a7); /* 51 */
b = II ( b, c, d, a, x5, S44, 0xfc93a039); /* 52 */
a = II ( a, b, c, d, x12, S41, 0x655b59c3); /* 53 */
d = II ( d, a, b, c, x3, S42, 0x8f0ccc92); /* 54 */
c = II ( c, d, a, b, x10, S43, 0xffeff47d); /* 55 */
b = II ( b, c, d, a, x1, S44, 0x85845dd1); /* 56 */
a = II ( a, b, c, d, x8, S41, 0x6fa87e4f); /* 57 */
d = II ( d, a, b, c, x15, S42, 0xfe2ce6e0); /* 58 */
c = II ( c, d, a, b, x6, S43, 0xa3014314); /* 59 */
b = II ( b, c, d, a, x13, S44, 0x4e0811a1); /* 60 */
a = II ( a, b, c, d, x4, S41, 0xf7537e82); /* 61 */
d = II ( d, a, b, c, x11, S42, 0xbd3af235); /* 62 */
c = II ( c, d, a, b, x2, S43, 0x2ad7d2bb); /* 63 */
b = II ( b, c, d, a, x9, S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -62,7 +62,6 @@ public final class SHA extends DigestBase {
public SHA() {
super("SHA-1", 20, 64);
state = new int[5];
W = new int[80];
resetHashes();
}
@ -72,7 +71,7 @@ public final class SHA extends DigestBase {
public Object clone() throws CloneNotSupportedException {
SHA copy = (SHA) super.clone();
copy.state = copy.state.clone();
copy.W = new int[80];
copy.W = null;
return copy;
}
@ -83,7 +82,9 @@ public final class SHA extends DigestBase {
// Load magic initialization constants.
resetHashes();
// clear out old data
Arrays.fill(W, 0);
if (W != null) {
Arrays.fill(W, 0);
}
}
private void resetHashes() {
@ -132,11 +133,12 @@ public final class SHA extends DigestBase {
private void implCompressCheck(byte[] buf, int ofs) {
Objects.requireNonNull(buf);
// The checks performed by the method 'b2iBig64'
// are sufficient for the case when the method
// 'implCompress0' is replaced with a compiler
// intrinsic.
b2iBig64(buf, ofs, W);
// Checks similar to those performed by the method 'b2iBig64'
// are sufficient for the case when the method 'implCompress0' is
// replaced with a compiler intrinsic.
if (ofs < 0 || (buf.length - ofs) < 64) {
throw new ArrayIndexOutOfBoundsException();
}
}
// The method 'implCompress0 seems not to use its parameters.
@ -146,6 +148,10 @@ public final class SHA extends DigestBase {
// must be passed as parameter to the method.
@IntrinsicCandidate
private void implCompress0(byte[] buf, int ofs) {
if (W == null) {
W = new int[80];
}
b2iBig64(buf, ofs, W);
// The first 16 ints have the byte stream, compute the rest of
// the buffer
for (int t = 16; t <= 79; t++) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -83,7 +83,6 @@ abstract class SHA2 extends DigestBase {
super(name, digestLength, 64);
this.initialHashes = initialHashes;
state = new int[8];
W = new int[64];
resetHashes();
}
@ -92,7 +91,9 @@ abstract class SHA2 extends DigestBase {
*/
void implReset() {
resetHashes();
Arrays.fill(W, 0);
if (W != null) {
Arrays.fill(W, 0);
}
}
private void resetHashes() {
@ -124,11 +125,12 @@ abstract class SHA2 extends DigestBase {
private void implCompressCheck(byte[] buf, int ofs) {
Objects.requireNonNull(buf);
// The checks performed by the method 'b2iBig64'
// are sufficient for the case when the method
// 'implCompressImpl' is replaced with a compiler
// intrinsic.
b2iBig64(buf, ofs, W);
// Checks similar to those performed by the method 'b2iBig64'
// are sufficient for the case when the method 'implCompress0' is
// replaced with a compiler intrinsic.
if (ofs < 0 || (buf.length - ofs) < 64) {
throw new ArrayIndexOutOfBoundsException();
}
}
// The method 'implCompressImpl' seems not to use its parameters.
@ -138,6 +140,10 @@ abstract class SHA2 extends DigestBase {
// must be passed as parameter to the method.
@IntrinsicCandidate
private void implCompress0(byte[] buf, int ofs) {
if (W == null) {
W = new int[64];
}
b2iBig64(buf, ofs, W);
// The first 16 ints are from the byte stream, compute the rest of
// the W[]'s
for (int t = 16; t < ITERATION; t++) {
@ -220,7 +226,7 @@ abstract class SHA2 extends DigestBase {
public Object clone() throws CloneNotSupportedException {
SHA2 copy = (SHA2) super.clone();
copy.state = copy.state.clone();
copy.W = new int[64];
copy.W = null;
return copy;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -98,13 +98,14 @@ abstract class SHA5 extends DigestBase {
super(name, digestLength, 128);
this.initialHashes = initialHashes;
state = new long[8];
W = new long[80];
resetHashes();
}
final void implReset() {
resetHashes();
Arrays.fill(W, 0L);
if (W != null) {
Arrays.fill(W, 0L);
}
}
private void resetHashes() {
@ -225,11 +226,12 @@ abstract class SHA5 extends DigestBase {
private void implCompressCheck(byte[] buf, int ofs) {
Objects.requireNonNull(buf);
// The checks performed by the method 'b2iBig128'
// are sufficient for the case when the method
// 'implCompressImpl' is replaced with a compiler
// intrinsic.
b2lBig128(buf, ofs, W);
// Checks similar to those performed by the method 'b2lBig128'
// are sufficient for the case when the method 'implCompress0' is
// replaced with a compiler intrinsic.
if (ofs < 0 || (buf.length - ofs) < 128) {
throw new ArrayIndexOutOfBoundsException();
}
}
// The method 'implCompressImpl' seems not to use its parameters.
@ -239,6 +241,10 @@ abstract class SHA5 extends DigestBase {
// must be passed as parameter to the method.
@IntrinsicCandidate
private final void implCompress0(byte[] buf, int ofs) {
if (W == null) {
W = new long[80];
}
b2lBig128(buf, ofs, W);
// The first 16 longs are from the byte stream, compute the rest of
// the W[]'s
for (int t = 16; t < ITERATION; t++) {
@ -280,7 +286,7 @@ abstract class SHA5 extends DigestBase {
public Object clone() throws CloneNotSupportedException {
SHA5 copy = (SHA5) super.clone();
copy.state = copy.state.clone();
copy.W = new long[80];
copy.W = null;
return copy;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -45,8 +45,8 @@ import org.openjdk.jmh.annotations.Warmup;
*/
@State(Scope.Thread)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Warmup(iterations = 5)
@Measurement(iterations = 10)
@Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
@Fork(jvmArgsAppend = {"-Xms1024m", "-Xmx1024m", "-Xmn768m", "-XX:+UseParallelGC"}, value = 5)
public class MessageDigests {
@ -77,4 +77,15 @@ public class MessageDigests {
public byte[] digest() throws DigestException {
return digester.digest(inputBytes);
}
@Benchmark
public byte[] getAndDigest() throws DigestException, NoSuchAlgorithmException, NoSuchProviderException {
MessageDigest md;
if ("DEFAULT".equals(provider)) {
md = MessageDigest.getInstance(digesterName);
} else {
md = MessageDigest.getInstance(digesterName, provider);
}
return md.digest(inputBytes);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -37,6 +37,8 @@ public class UUIDBench {
@Param("20000")
private int size;
private byte[][] uuidBytes;
private UUID[] uuids;
private String[] uuidStrings;
@ -45,11 +47,14 @@ public class UUIDBench {
@Setup
public void setup() {
uuidBytes = new byte[size][];
uuids = new UUID[size];
uuidStrings = new String[size];
java.util.Random r = new java.util.Random(0);
for (int i = 0; i < this.uuidStrings.length; i++) {
final UUID uuid = UUID.randomUUID();
this.uuidBytes[i] = new byte[16];
r.nextBytes(this.uuidBytes[i]);
this.uuids[i] = uuid;
this.uuidStrings[i] = uuid.toString();
}
@ -72,4 +77,9 @@ public class UUIDBench {
public String toString() {
return uuids[index].toString();
}
@Benchmark
public UUID fromType3Bytes() {
return UUID.nameUUIDFromBytes(uuidBytes[index]);
}
}