Fix toHexByteArray
Add tests.
This commit is contained in:
parent
df4f48122f
commit
fc07abc894
@ -15,8 +15,11 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
implementation(kotlin("stdlib-jdk8"))
|
||||
testCompile("junit", "junit", "4.12")
|
||||
implementation ("cafe.cryptography:ed25519-elisabeth:0.1.0")
|
||||
|
||||
testCompile("junit", "junit", "4.12")
|
||||
testImplementation ("org.amshove.kluent:kluent:1.61")
|
||||
|
||||
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.9.1")
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package it.unisannio.assd.tkn
|
||||
|
||||
import java.math.BigInteger
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
|
||||
@ -21,7 +20,15 @@ fun ByteArray.toHexString(): String {
|
||||
return builder.toString()
|
||||
}
|
||||
|
||||
fun String.toHexByteArray(): ByteArray = BigInteger(this, 16).toByteArray()
|
||||
fun String.toHexByteArray(): ByteArray {
|
||||
val b = ByteArray(this.length / 2)
|
||||
for (i in b.indices) {
|
||||
val index = i * 2
|
||||
val v: Int = this.substring(index, index + 2).toInt(16)
|
||||
b[i] = v.toByte()
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
fun ByteBuffer.read(n: Int): ByteArray {
|
||||
val bytes = ByteArray(n)
|
||||
|
@ -4,6 +4,7 @@ import cafe.cryptography.ed25519.Ed25519PrivateKey
|
||||
import cafe.cryptography.ed25519.Ed25519PublicKey
|
||||
import it.unisannio.assd.tkn.Const
|
||||
import it.unisannio.assd.tkn.toHexByteArray
|
||||
import it.unisannio.assd.tkn.toHexString
|
||||
import java.security.MessageDigest
|
||||
import java.security.SecureRandom
|
||||
|
||||
@ -32,6 +33,8 @@ class ReportAuthorizationKey private constructor(private val key: Ed25519Private
|
||||
|
||||
fun toByteArray(): ByteArray = key.toByteArray()
|
||||
|
||||
fun toHexString() = toByteArray().toHexString()
|
||||
|
||||
companion object {
|
||||
fun createFromByteArray(bytes: ByteArray): ReportAuthorizationKey =
|
||||
ReportAuthorizationKey(
|
||||
|
@ -3,6 +3,7 @@ package it.unisannio.assd.tkn.key
|
||||
import cafe.cryptography.ed25519.Ed25519PrivateKey
|
||||
import cafe.cryptography.ed25519.Ed25519PublicKey
|
||||
import cafe.cryptography.ed25519.Ed25519Signature
|
||||
import it.unisannio.assd.tkn.toHexByteArray
|
||||
import it.unisannio.assd.tkn.toHexString
|
||||
|
||||
class ReportVerificationKey private constructor(private val key: Ed25519PublicKey) {
|
||||
@ -32,5 +33,10 @@ class ReportVerificationKey private constructor(private val key: Ed25519PublicKe
|
||||
ReportVerificationKey(
|
||||
Ed25519PublicKey.fromByteArray(bytes)
|
||||
)
|
||||
|
||||
fun createFromHexString(hexString: String): ReportVerificationKey =
|
||||
ReportVerificationKey(
|
||||
Ed25519PublicKey.fromByteArray(hexString.toHexByteArray())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package it.unisannio.assd.tkn.key
|
||||
import it.unisannio.assd.tkn.Const
|
||||
import it.unisannio.assd.tkn.report.Memo
|
||||
import it.unisannio.assd.tkn.report.Report
|
||||
import it.unisannio.assd.tkn.toHexByteArray
|
||||
import it.unisannio.assd.tkn.toHexString
|
||||
import it.unisannio.assd.tkn.toLeByteArray
|
||||
import java.security.MessageDigest
|
||||
@ -71,5 +72,11 @@ class TemporaryContactKey private constructor(
|
||||
bytes,
|
||||
index
|
||||
)
|
||||
|
||||
fun createFromHexString(hexString: String, index: Short): TemporaryContactKey =
|
||||
TemporaryContactKey(
|
||||
hexString.toHexByteArray(),
|
||||
index
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package it.unisannio.assd.tkn.key
|
||||
|
||||
import it.unisannio.assd.tkn.toHexString
|
||||
import java.nio.ByteBuffer
|
||||
import java.util.*
|
||||
import java.util.UUID
|
||||
|
||||
class TemporaryContactNumber(
|
||||
private val number: ByteArray,
|
||||
|
@ -8,7 +8,7 @@ import java.nio.ByteOrder
|
||||
|
||||
class SignedReport private constructor(
|
||||
val report: Report,
|
||||
private val sign: ByteArray
|
||||
val sign: ByteArray
|
||||
) {
|
||||
fun verify(): Boolean = report.getVerificationKey()
|
||||
.verify(report.toByteArray(), sign)
|
||||
|
20
src/test/kotlin/it/unisannio/assd/tkn/TestConst.kt
Normal file
20
src/test/kotlin/it/unisannio/assd/tkn/TestConst.kt
Normal file
@ -0,0 +1,20 @@
|
||||
package it.unisannio.assd.tkn
|
||||
|
||||
/**
|
||||
* These data were derived from the TCN project test vector.
|
||||
* For more information see https://github.com/TCNCoalition/TCN#reporting.
|
||||
*/
|
||||
object TestConst {
|
||||
const val PRIVATE_KEY_STRING_HEX = "577cfdae21fee71579211ab02c418ee0948bacab613cf69d0a4a5ae5a1557dbb"
|
||||
const val PUBLIC_KEY_STRING_HEX = "fd8deb9d91a13e144ca5b0ce14e289532e040fe0bf922c6e3dadb1e4e2333c78"
|
||||
const val TCK_0 = "aeca765f744b47faf1fc297bfcaf802fc6c9a8f2e2c9f2d65a7bdc7f42359164"
|
||||
const val TCK_1 = "df535b90ac99bec8be3a8add45ce77897b1e7cb1906b5cff1097d3cb142fd9d0"
|
||||
const val TCN_1 = "f4350a4a33e30f2f568898fbe4c4cf34"
|
||||
const val TCN_2 = "135eeaa6482b8852fea3544edf6eabf0"
|
||||
const val TCN_3 = "d713ce68cf4127bcebde6874c4991e4b"
|
||||
const val MESSAGE = "test message"
|
||||
const val REPORT_MESSAGE = "fd8deb9d91a13e144ca5b0ce14e289532e040fe0bf922c6e3dadb1e4e2333c78df535b90ac99" +
|
||||
"bec8be3a8add45ce77897b1e7cb1906b5cff1097d3cb142fd9d002000a00000c73796d70746f6d2064617461"
|
||||
const val REPORT_SIGN = "31078ec5367b67a8c793b740626d81ba904789363137b5a313419c0f50b180d8226ecc984bf073ff" +
|
||||
"89cbd9c88fea06bda1f0f368b0e7e88bbe68f15574482904"
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package it.unisannio.assd.tkn.key
|
||||
|
||||
import cafe.cryptography.ed25519.Ed25519PrivateKey
|
||||
import it.unisannio.assd.tkn.TestConst.MESSAGE
|
||||
import it.unisannio.assd.tkn.TestConst.PRIVATE_KEY_STRING_HEX
|
||||
import it.unisannio.assd.tkn.TestConst.PUBLIC_KEY_STRING_HEX
|
||||
import it.unisannio.assd.tkn.TestConst.TCK_0
|
||||
import it.unisannio.assd.tkn.toHexByteArray
|
||||
import org.amshove.kluent.`should be equal to`
|
||||
import org.junit.Test
|
||||
|
||||
class ReportAuthorizationKeyTest {
|
||||
@Test
|
||||
fun createFromByteArray() {
|
||||
val keyBytes = PRIVATE_KEY_STRING_HEX.toHexByteArray()
|
||||
|
||||
val rak = ReportAuthorizationKey.createFromByteArray(keyBytes)
|
||||
|
||||
rak.toHexString() `should be equal to` PRIVATE_KEY_STRING_HEX
|
||||
}
|
||||
|
||||
@Test
|
||||
fun createFromHexString() {
|
||||
val rak = ReportAuthorizationKey.createFromHexString(PRIVATE_KEY_STRING_HEX)
|
||||
|
||||
rak.toHexString() `should be equal to` PRIVATE_KEY_STRING_HEX
|
||||
}
|
||||
|
||||
@Test
|
||||
fun deriveVerificationKey() {
|
||||
val rak = ReportAuthorizationKey.createFromHexString(PRIVATE_KEY_STRING_HEX)
|
||||
|
||||
rak.deriveVerificationKey()
|
||||
.toHexString() `should be equal to` PUBLIC_KEY_STRING_HEX
|
||||
}
|
||||
|
||||
@Test
|
||||
fun deriveTck0() {
|
||||
val rak = ReportAuthorizationKey.createFromHexString(PRIVATE_KEY_STRING_HEX)
|
||||
|
||||
rak.baseTemporaryContactKey()
|
||||
.toHexString() `should be equal to` TCK_0
|
||||
}
|
||||
|
||||
@Test
|
||||
fun sign() {
|
||||
val rak = ReportAuthorizationKey.createFromHexString(PRIVATE_KEY_STRING_HEX)
|
||||
val rvk = rak.deriveVerificationKey()
|
||||
val privateKey = Ed25519PrivateKey.fromByteArray(PRIVATE_KEY_STRING_HEX.toHexByteArray())
|
||||
val publicKey = privateKey.derivePublic()
|
||||
|
||||
val message = MESSAGE.toByteArray()
|
||||
|
||||
rak.sign(message, rvk) `should be equal to` privateKey.expand().sign(message, publicKey).toByteArray()
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package it.unisannio.assd.tkn.key
|
||||
|
||||
import it.unisannio.assd.tkn.TestConst
|
||||
import it.unisannio.assd.tkn.toHexByteArray
|
||||
import org.amshove.kluent.`should be equal to`
|
||||
import org.junit.Test
|
||||
|
||||
class ReportVerificationKeyTest {
|
||||
@Test
|
||||
fun createFromByteArray() {
|
||||
val rvk = ReportVerificationKey
|
||||
.createFromByteArray(TestConst.PUBLIC_KEY_STRING_HEX.toHexByteArray())
|
||||
|
||||
println(rvk.toHexString())
|
||||
|
||||
rvk.toHexString() `should be equal to` TestConst.PUBLIC_KEY_STRING_HEX
|
||||
}
|
||||
|
||||
@Test
|
||||
fun createFromAuthorizationKey() {
|
||||
val rak = ReportAuthorizationKey
|
||||
.createFromHexString(TestConst.PRIVATE_KEY_STRING_HEX)
|
||||
|
||||
ReportVerificationKey
|
||||
.createFromAuthorizationKey(rak)
|
||||
.toHexString() `should be equal to` TestConst.PUBLIC_KEY_STRING_HEX
|
||||
}
|
||||
|
||||
@Test
|
||||
fun createFromHexString() {
|
||||
val rvk = ReportVerificationKey
|
||||
.createFromHexString(TestConst.PUBLIC_KEY_STRING_HEX)
|
||||
|
||||
rvk.toHexString() `should be equal to` TestConst.PUBLIC_KEY_STRING_HEX
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verify() {
|
||||
val rvk = ReportVerificationKey
|
||||
.createFromHexString(TestConst.PUBLIC_KEY_STRING_HEX)
|
||||
|
||||
rvk.verify(
|
||||
TestConst.REPORT_MESSAGE.toHexByteArray(),
|
||||
TestConst.REPORT_SIGN.toHexByteArray()
|
||||
) `should be equal to` true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verifyFalse() {
|
||||
val rvk = ReportVerificationKey
|
||||
.createFromHexString(TestConst.PUBLIC_KEY_STRING_HEX)
|
||||
|
||||
rvk.verify(
|
||||
"not original message".toByteArray(),
|
||||
TestConst.REPORT_SIGN.toHexByteArray()
|
||||
) `should be equal to` false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun contactNumbersBetween() {
|
||||
val rak = ReportAuthorizationKey
|
||||
.createFromHexString(TestConst.PRIVATE_KEY_STRING_HEX)
|
||||
val rvk = ReportVerificationKey
|
||||
.createFromHexString(TestConst.PUBLIC_KEY_STRING_HEX)
|
||||
|
||||
rvk.contactNumbersBetween(
|
||||
rak.baseTemporaryContactKey(),
|
||||
1,
|
||||
4
|
||||
).map {
|
||||
it.toHexString()
|
||||
} `should be equal to` listOf(TestConst.TCN_1, TestConst.TCN_2, TestConst.TCN_3)
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package it.unisannio.assd.tkn.key
|
||||
|
||||
import it.unisannio.assd.tkn.TestConst
|
||||
import it.unisannio.assd.tkn.toHexByteArray
|
||||
import org.amshove.kluent.`should be equal to`
|
||||
import org.junit.Test
|
||||
|
||||
class TemporaryContactKeyTest {
|
||||
@Test
|
||||
fun createFromByteArray() {
|
||||
val tck0 = TemporaryContactKey
|
||||
.createFromByteArray(TestConst.TCK_0.toHexByteArray(), 0)
|
||||
|
||||
tck0.toHexString() `should be equal to` TestConst.TCK_0
|
||||
}
|
||||
|
||||
@Test
|
||||
fun createFromHexString() {
|
||||
val tck0 = TemporaryContactKey
|
||||
.createFromHexString(TestConst.TCK_0, 0)
|
||||
|
||||
tck0.toHexString() `should be equal to` TestConst.TCK_0
|
||||
}
|
||||
|
||||
@Test
|
||||
fun nextTemporaryKey() {
|
||||
val tck0 = TemporaryContactKey
|
||||
.createFromHexString(TestConst.TCK_0, 0)
|
||||
val rvk = ReportVerificationKey
|
||||
.createFromHexString(TestConst.PUBLIC_KEY_STRING_HEX)
|
||||
|
||||
tck0.nextTemporaryContactKey(rvk)
|
||||
.toHexString() `should be equal to` TestConst.TCK_1
|
||||
}
|
||||
|
||||
@Test
|
||||
fun derivateTemporaryContactNumber() {
|
||||
val tck1 = TemporaryContactKey
|
||||
.createFromHexString(TestConst.TCK_1, 1)
|
||||
|
||||
tck1.deriveTemporaryContactNumber()
|
||||
.toHexString() `should be equal to` TestConst.TCN_1
|
||||
}
|
||||
|
||||
@Test
|
||||
fun generateReport() {
|
||||
val tck1 = TemporaryContactKey
|
||||
.createFromHexString(TestConst.TCK_1, 1)
|
||||
val rvk = ReportVerificationKey
|
||||
.createFromHexString(TestConst.PUBLIC_KEY_STRING_HEX)
|
||||
|
||||
tck1.generateReport(rvk, 10, "symptom data")
|
||||
.toHexString() `should be equal to` TestConst.REPORT_MESSAGE
|
||||
}
|
||||
}
|
41
src/test/kotlin/it/unisannio/assd/tkn/report/ReportTest.kt
Normal file
41
src/test/kotlin/it/unisannio/assd/tkn/report/ReportTest.kt
Normal file
@ -0,0 +1,41 @@
|
||||
package it.unisannio.assd.tkn.report
|
||||
|
||||
import it.unisannio.assd.tkn.TestConst
|
||||
import it.unisannio.assd.tkn.key.ReportAuthorizationKey
|
||||
import it.unisannio.assd.tkn.toHexByteArray
|
||||
import it.unisannio.assd.tkn.toHexString
|
||||
import org.amshove.kluent.`should be equal to`
|
||||
import org.junit.Test
|
||||
|
||||
class ReportTest {
|
||||
@Test
|
||||
fun readReportFromByteArray() {
|
||||
val report = Report.readReportFromByteArray(
|
||||
TestConst.REPORT_MESSAGE.toHexByteArray()
|
||||
)
|
||||
|
||||
report.toHexString() `should be equal to` TestConst.REPORT_MESSAGE
|
||||
}
|
||||
|
||||
@Test
|
||||
fun signWith() {
|
||||
val report = Report.readReportFromByteArray(
|
||||
TestConst.REPORT_MESSAGE.toHexByteArray()
|
||||
)
|
||||
val rak = ReportAuthorizationKey
|
||||
.createFromHexString(TestConst.PRIVATE_KEY_STRING_HEX)
|
||||
|
||||
report.signWith(rak).sign
|
||||
.toHexString() `should be equal to` TestConst.REPORT_SIGN
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getVerificationKey() {
|
||||
val report = Report.readReportFromByteArray(
|
||||
TestConst.REPORT_MESSAGE.toHexByteArray()
|
||||
)
|
||||
|
||||
report.getVerificationKey()
|
||||
.toHexString() `should be equal to` TestConst.PUBLIC_KEY_STRING_HEX
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package it.unisannio.assd.tkn.report
|
||||
|
||||
import it.unisannio.assd.tkn.TestConst
|
||||
import it.unisannio.assd.tkn.toHexByteArray
|
||||
import org.amshove.kluent.`should be equal to`
|
||||
import org.junit.Test
|
||||
|
||||
class SignedReportTest {
|
||||
@Test
|
||||
fun readFromByteArray() {
|
||||
val report = TestConst.REPORT_MESSAGE + TestConst.REPORT_SIGN
|
||||
|
||||
SignedReport.readFromByteArray(
|
||||
report.toHexByteArray()
|
||||
).toHexString() `should be equal to` report
|
||||
}
|
||||
|
||||
@Test
|
||||
fun verify() {
|
||||
val report = TestConst.REPORT_MESSAGE + TestConst.REPORT_SIGN
|
||||
|
||||
SignedReport.readFromByteArray(
|
||||
report.toHexByteArray()
|
||||
).verify() `should be equal to` true
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user