@ -16,7 +16,9 @@ package org.hyperledger.besu.crypto;
import java.security.MessageDigest ;
import java.security.NoSuchAlgorithmException ;
import java.util.function.Supplier ;
import com.google.common.base.Suppliers ;
import org.apache.tuweni.bytes.Bytes ;
import org.apache.tuweni.bytes.Bytes32 ;
@ -25,24 +27,41 @@ public abstract class Hash {
private Hash ( ) { }
public static final String KECCAK256_ALG = "KECCAK-256" ;
private static final String SHA256_ALG = "SHA-256" ;
private static final String RIPEMD160 = "RIPEMD160" ;
private static final String RIPEMD160_ALG = "RIPEMD160" ;
private static final String BLAKE2BF_ALG = "BLAKE2BF" ;
private static final Supplier < MessageDigest > KECCAK256_SUPPLIER =
Suppliers . memoize ( ( ) - > messageDigest ( KECCAK256_ALG ) ) ;
private static final Supplier < MessageDigest > SHA256_SUPPLIER =
Suppliers . memoize ( ( ) - > messageDigest ( SHA256_ALG ) ) ;
private static final Supplier < MessageDigest > RIPEMD160_SUPPLIER =
Suppliers . memoize ( ( ) - > messageDigest ( RIPEMD160_ALG ) ) ;
private static final Supplier < MessageDigest > BLAKE2BF_SUPPLIER =
Suppliers . memoize ( ( ) - > messageDigest ( BLAKE2BF_ALG ) ) ;
private static MessageDigest messageDigest ( final String algorithm ) {
try {
return MessageDigestFactory . create ( algorithm ) ;
} catch ( final NoSuchAlgorithmException e ) {
throw new RuntimeException ( e ) ;
}
}
/ * *
* Helper method to generate a digest using the provided algorithm .
*
* @param input The input bytes to produce the digest for .
* @param alg The name of the digest algorithm to use .
* @param digestSupplier the digest supplier to use
* @return A digest .
* /
private static byte [ ] digestUsingAlgorithm ( final Bytes input , final String alg ) {
private static byte [ ] digestUsingAlgorithm (
final Bytes input , final Supplier < MessageDigest > digestSupplier ) {
try {
final MessageDigest digest = MessageDigestFactory . create ( alg ) ;
final MessageDigest digest = ( MessageDigest ) digestSupplier . get ( ) . clone ( ) ;
input . update ( digest ) ;
return digest . digest ( ) ;
} catch ( final NoSuchAlgorithmException e ) {
} catch ( final CloneNotSupported Exception e ) {
throw new RuntimeException ( e ) ;
}
}
@ -54,7 +73,7 @@ public abstract class Hash {
* @return A digest .
* /
public static Bytes32 sha256 ( final Bytes input ) {
return Bytes32 . wrap ( digestUsingAlgorithm ( input , SHA256_ALG ) ) ;
return Bytes32 . wrap ( digestUsingAlgorithm ( input , SHA256_SUPPLIER ) ) ;
}
/ * *
@ -64,7 +83,7 @@ public abstract class Hash {
* @return A digest .
* /
public static Bytes32 keccak256 ( final Bytes input ) {
return Bytes32 . wrap ( digestUsingAlgorithm ( input , KECCAK256_ALG ) ) ;
return Bytes32 . wrap ( digestUsingAlgorithm ( input , KECCAK256_SUPPLIER ) ) ;
}
/ * *
@ -74,7 +93,7 @@ public abstract class Hash {
* @return A digest .
* /
public static Bytes ripemd160 ( final Bytes input ) {
return Bytes . wrap ( digestUsingAlgorithm ( input , RIPEMD160 ) ) ;
return Bytes . wrap ( digestUsingAlgorithm ( input , RIPEMD160_SUPPLIER ) ) ;
}
/ * *
@ -84,6 +103,6 @@ public abstract class Hash {
* @return A digest .
* /
public static Bytes blake2bf ( final Bytes input ) {
return Bytes . wrap ( digestUsingAlgorithm ( input , BLAKE2BF_ALG ) ) ;
return Bytes . wrap ( digestUsingAlgorithm ( input , BLAKE2BF_SUPPLIER ) ) ;
}
}