mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
CORDA-4076: Fix SecureHash compatibility with previous versions (#6801)
This commit is contained in:
parent
d9f905cb81
commit
14e545826c
@ -22,9 +22,7 @@ import java.util.function.Supplier
|
||||
*/
|
||||
@KeepForDJVM
|
||||
@CordaSerializable
|
||||
sealed class SecureHash(val algorithm: String, bytes: ByteArray) : OpaqueBytes(bytes) {
|
||||
constructor(bytes: ByteArray) : this(SHA2_256, bytes)
|
||||
|
||||
sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) {
|
||||
/** SHA-256 is part of the SHA-2 hash function family. Generated hash is fixed size, 256-bits (32-bytes). */
|
||||
class SHA256(bytes: ByteArray) : SecureHash(bytes) {
|
||||
init {
|
||||
@ -52,7 +50,7 @@ sealed class SecureHash(val algorithm: String, bytes: ByteArray) : OpaqueBytes(b
|
||||
}
|
||||
}
|
||||
|
||||
class HASH(algorithm: String, bytes: ByteArray) : SecureHash(algorithm, bytes) {
|
||||
class HASH(val algorithm: String, bytes: ByteArray) : SecureHash(bytes) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return when {
|
||||
this === other -> true
|
||||
@ -63,6 +61,10 @@ sealed class SecureHash(val algorithm: String, bytes: ByteArray) : OpaqueBytes(b
|
||||
|
||||
override fun hashCode() = ByteBuffer.wrap(bytes).int
|
||||
|
||||
override fun toString(): String {
|
||||
return "$algorithm$DELIMITER${toHexString()}"
|
||||
}
|
||||
|
||||
override fun generate(data: ByteArray): SecureHash {
|
||||
return HASH(algorithm, digestAs(algorithm, data))
|
||||
}
|
||||
@ -70,9 +72,7 @@ sealed class SecureHash(val algorithm: String, bytes: ByteArray) : OpaqueBytes(b
|
||||
|
||||
fun toHexString(): String = bytes.toHexString()
|
||||
|
||||
override fun toString(): String {
|
||||
return "$algorithm$DELIMITER${toHexString()}"
|
||||
}
|
||||
override fun toString(): String = bytes.toHexString()
|
||||
|
||||
/**
|
||||
* Returns the first [prefixLen] hexadecimal digits of the [SecureHash] value.
|
||||
@ -354,6 +354,11 @@ fun ByteArray.hashAs(algorithm: String): SecureHash = SecureHash.hashAs(algorith
|
||||
*/
|
||||
fun OpaqueBytes.hashAs(algorithm: String): SecureHash = SecureHash.hashAs(algorithm, bytes)
|
||||
|
||||
/**
|
||||
* Hash algorithm.
|
||||
*/
|
||||
val SecureHash.algorithm: String get() = if (this is SecureHash.HASH) algorithm else SecureHash.SHA2_256
|
||||
|
||||
/**
|
||||
* Hide the [FastThreadLocal] class behind a [Supplier] interface
|
||||
* so that we can remove it for core-deterministic.
|
||||
|
@ -4,6 +4,7 @@ import net.corda.core.KeepForDJVM
|
||||
import net.corda.core.contracts.*
|
||||
import net.corda.core.crypto.DigestService
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.algorithm
|
||||
import net.corda.core.crypto.hashAs
|
||||
import net.corda.core.crypto.internal.DigestAlgorithmFactory
|
||||
import net.corda.core.flows.FlowLogic
|
||||
|
@ -33,20 +33,23 @@ class Blake2s256DigestServiceTest {
|
||||
@Test(timeout = 300_000)
|
||||
fun testBlankHash() {
|
||||
assertEquals(
|
||||
"C59F682376D137F3F255E671E207D1F2374EBE504E9314208A52D9F88D69E8C8",
|
||||
service.hash(byteArrayOf()).toHexString()
|
||||
"BLAKE_TEST:C59F682376D137F3F255E671E207D1F2374EBE504E9314208A52D9F88D69E8C8",
|
||||
service.hash(byteArrayOf()).toString()
|
||||
)
|
||||
assertEquals("C59F682376D137F3F255E671E207D1F2374EBE504E9314208A52D9F88D69E8C8", service.hash(byteArrayOf()).toHexString())
|
||||
}
|
||||
|
||||
@Test(timeout = 300_000)
|
||||
fun testHashBytes() {
|
||||
val hash = service.hash(byteArrayOf(0x64, -0x13, 0x42, 0x3a))
|
||||
assertEquals("BLAKE_TEST:9EEA14092257E759ADAA56539A7A88DA1F68F03ABE3D9552A21D4731F4E6ECA0", hash.toString())
|
||||
assertEquals("9EEA14092257E759ADAA56539A7A88DA1F68F03ABE3D9552A21D4731F4E6ECA0", hash.toHexString())
|
||||
}
|
||||
|
||||
@Test(timeout = 300_000)
|
||||
fun testHashString() {
|
||||
val hash = service.hash("test")
|
||||
assertEquals("BLAKE_TEST:AB76E8F7EEA1968C183D343B756EC812E47D4BC7A3F061F4DDE8948B3E05DAF2", hash.toString())
|
||||
assertEquals("AB76E8F7EEA1968C183D343B756EC812E47D4BC7A3F061F4DDE8948B3E05DAF2", hash.toHexString())
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.SignableData
|
||||
import net.corda.core.crypto.SignatureMetadata
|
||||
import net.corda.core.crypto.TransactionSignature
|
||||
import net.corda.core.crypto.algorithm
|
||||
import net.corda.core.flows.NotaryError
|
||||
import net.corda.core.internal.digestService
|
||||
import net.corda.core.node.ServiceHub
|
||||
|
@ -0,0 +1,45 @@
|
||||
package net.corda.serialization.internal
|
||||
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.SecureHash.Companion.SHA2_256
|
||||
import net.corda.core.crypto.SecureHash.Companion.SHA2_512
|
||||
import net.corda.core.crypto.algorithm
|
||||
import net.corda.core.serialization.SerializationDefaults
|
||||
import net.corda.core.serialization.deserialize
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.testing.core.SerializationEnvironmentRule
|
||||
import org.junit.Assert.assertArrayEquals
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class SecureHashSerializationTest {
|
||||
@Rule
|
||||
@JvmField
|
||||
val testSerialization = SerializationEnvironmentRule()
|
||||
|
||||
@Test(timeout = 300_000)
|
||||
fun `serialize and deserialize SHA-256`() {
|
||||
val before = SecureHash.randomSHA256()
|
||||
val bytes = before.serialize(context = SerializationDefaults.P2P_CONTEXT.withoutReferences()).bytes
|
||||
val after = bytes.deserialize<SecureHash>()
|
||||
assertEquals(before, after)
|
||||
assertArrayEquals(before.bytes, after.bytes)
|
||||
assertEquals(before.algorithm, after.algorithm)
|
||||
assertEquals(after.algorithm, SHA2_256)
|
||||
assertTrue(after is SecureHash.SHA256)
|
||||
}
|
||||
|
||||
@Test(timeout = 300_000)
|
||||
fun `serialize and deserialize SHA-512`() {
|
||||
val before = SecureHash.random(SHA2_512)
|
||||
val bytes = before.serialize(context = SerializationDefaults.P2P_CONTEXT.withoutReferences()).bytes
|
||||
val after = bytes.deserialize<SecureHash>()
|
||||
assertEquals(before, after)
|
||||
assertArrayEquals(before.bytes, after.bytes)
|
||||
assertEquals(before.algorithm, after.algorithm)
|
||||
assertEquals(after.algorithm, SHA2_512)
|
||||
assertTrue(after is SecureHash.HASH)
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package net.corda.tools.shell;
|
||||
|
||||
import net.corda.core.crypto.SecureHash;
|
||||
import net.corda.core.crypto.SecureHashKt;
|
||||
import net.corda.core.internal.VisibleForTesting;
|
||||
import net.corda.core.messaging.CordaRPCOps;
|
||||
import net.corda.core.messaging.StateMachineTransactionMapping;
|
||||
@ -60,7 +61,7 @@ public class HashLookupShellCommand extends CordaRpcOpsShellCommand {
|
||||
Optional<SecureHash> match = mapping.stream()
|
||||
.map(StateMachineTransactionMapping::getTransactionId)
|
||||
.filter(
|
||||
txId -> txId.equals(txIdHashParsed) || SecureHash.hashAs(txIdHashParsed.getAlgorithm(), txId.getBytes()).equals(txIdHashParsed)
|
||||
txId -> txId.equals(txIdHashParsed) || SecureHash.hashAs(SecureHashKt.getAlgorithm(txIdHashParsed), txId.getBytes()).equals(txIdHashParsed)
|
||||
)
|
||||
.findFirst();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user