mirror of
https://github.com/corda/corda.git
synced 2025-01-29 15:43:55 +00:00
NodeAndWeight deterministic comparator (#1003)
NodeAndWeight deterministic ordering by comparing hashes of public keys when required.
This commit is contained in:
parent
5b78863e57
commit
d52b0e5db9
@ -4,6 +4,7 @@ import net.corda.core.crypto.CompositeKey.NodeAndWeight
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import org.bouncycastle.asn1.*
|
||||
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
|
||||
import java.nio.ByteBuffer
|
||||
import java.security.PublicKey
|
||||
import java.util.*
|
||||
|
||||
@ -109,11 +110,11 @@ class CompositeKey private constructor (val threshold: Int,
|
||||
// We don't allow zero or negative weights. Minimum weight = 1.
|
||||
require (weight > 0) { "A non-positive weight was detected. Node info: $this" }
|
||||
}
|
||||
|
||||
override fun compareTo(other: NodeAndWeight): Int {
|
||||
if (weight == other.weight) {
|
||||
return node.hashCode().compareTo(other.node.hashCode())
|
||||
}
|
||||
else return weight.compareTo(other.weight)
|
||||
return if (weight == other.weight) {
|
||||
ByteBuffer.wrap(node.toSHA256Bytes()).compareTo(ByteBuffer.wrap(other.node.toSHA256Bytes()))
|
||||
} else weight.compareTo(other.weight)
|
||||
}
|
||||
|
||||
override fun toASN1Primitive(): ASN1Primitive {
|
||||
|
@ -65,4 +65,4 @@ fun String.hexToBase64(): String = hexToByteArray().toBase64()
|
||||
// structure, e.g. mapping a PublicKey to a condition with the specific feature (ED25519).
|
||||
fun parsePublicKeyBase58(base58String: String): PublicKey = base58String.base58ToByteArray().deserialize<PublicKey>()
|
||||
fun PublicKey.toBase58String(): String = this.serialize().bytes.toBase58()
|
||||
fun PublicKey.toSHA256Bytes(): ByteArray = this.serialize().bytes.sha256().bytes
|
||||
fun PublicKey.toSHA256Bytes(): ByteArray = this.serialize().bytes.sha256().bytes // TODO: decide on the format of hashed key (encoded Vs serialised).
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.corda.core.crypto
|
||||
|
||||
import net.corda.core.utilities.OpaqueBytes
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.core.utilities.OpaqueBytes
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
@ -259,4 +259,22 @@ class CompositeKeyTests {
|
||||
val signaturesWithoutRSA = listOf(K1Signature, R1Signature, EdSignature, SPSignature)
|
||||
assertFalse { compositeKey.isFulfilledBy(signaturesWithoutRSA.byKeys()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `CompositeKey deterministic children sorting`() {
|
||||
val (_, pub1) = Crypto.generateKeyPair(Crypto.EDDSA_ED25519_SHA512)
|
||||
val (_, pub2) = Crypto.generateKeyPair(Crypto.ECDSA_SECP256K1_SHA256)
|
||||
val (_, pub3) = Crypto.generateKeyPair(Crypto.RSA_SHA256)
|
||||
val (_, pub4) = Crypto.generateKeyPair(Crypto.EDDSA_ED25519_SHA512)
|
||||
val (_, pub5) = Crypto.generateKeyPair(Crypto.ECDSA_SECP256R1_SHA256)
|
||||
val (_, pub6) = Crypto.generateKeyPair(Crypto.SPHINCS256_SHA256)
|
||||
val (_, pub7) = Crypto.generateKeyPair(Crypto.ECDSA_SECP256K1_SHA256)
|
||||
|
||||
// Using default weight = 1, thus all weights are equal.
|
||||
val composite1 = CompositeKey.Builder().addKeys(pub1, pub2, pub3, pub4, pub5, pub6, pub7).build() as CompositeKey
|
||||
// Store in reverse order.
|
||||
val composite2 = CompositeKey.Builder().addKeys(pub7, pub6, pub5, pub4, pub3, pub2, pub1).build() as CompositeKey
|
||||
// There are 7! = 5040 permutations, but as sorting is deterministic the following should never fail.
|
||||
assertEquals(composite1.children, composite2.children)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user