Fix toHexByteArray
Add tests.
This commit is contained in:
parent
df4f48122f
commit
fc07abc894
@ -15,8 +15,11 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(kotlin("stdlib-jdk8"))
|
implementation(kotlin("stdlib-jdk8"))
|
||||||
testCompile("junit", "junit", "4.12")
|
|
||||||
implementation ("cafe.cryptography:ed25519-elisabeth:0.1.0")
|
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")
|
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.9.1")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package it.unisannio.assd.tkn
|
package it.unisannio.assd.tkn
|
||||||
|
|
||||||
import java.math.BigInteger
|
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import java.nio.ByteOrder
|
import java.nio.ByteOrder
|
||||||
|
|
||||||
@ -21,7 +20,15 @@ fun ByteArray.toHexString(): String {
|
|||||||
return builder.toString()
|
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 {
|
fun ByteBuffer.read(n: Int): ByteArray {
|
||||||
val bytes = ByteArray(n)
|
val bytes = ByteArray(n)
|
||||||
|
@ -4,6 +4,7 @@ import cafe.cryptography.ed25519.Ed25519PrivateKey
|
|||||||
import cafe.cryptography.ed25519.Ed25519PublicKey
|
import cafe.cryptography.ed25519.Ed25519PublicKey
|
||||||
import it.unisannio.assd.tkn.Const
|
import it.unisannio.assd.tkn.Const
|
||||||
import it.unisannio.assd.tkn.toHexByteArray
|
import it.unisannio.assd.tkn.toHexByteArray
|
||||||
|
import it.unisannio.assd.tkn.toHexString
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
|
|
||||||
@ -32,6 +33,8 @@ class ReportAuthorizationKey private constructor(private val key: Ed25519Private
|
|||||||
|
|
||||||
fun toByteArray(): ByteArray = key.toByteArray()
|
fun toByteArray(): ByteArray = key.toByteArray()
|
||||||
|
|
||||||
|
fun toHexString() = toByteArray().toHexString()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun createFromByteArray(bytes: ByteArray): ReportAuthorizationKey =
|
fun createFromByteArray(bytes: ByteArray): ReportAuthorizationKey =
|
||||||
ReportAuthorizationKey(
|
ReportAuthorizationKey(
|
||||||
|
@ -3,6 +3,7 @@ package it.unisannio.assd.tkn.key
|
|||||||
import cafe.cryptography.ed25519.Ed25519PrivateKey
|
import cafe.cryptography.ed25519.Ed25519PrivateKey
|
||||||
import cafe.cryptography.ed25519.Ed25519PublicKey
|
import cafe.cryptography.ed25519.Ed25519PublicKey
|
||||||
import cafe.cryptography.ed25519.Ed25519Signature
|
import cafe.cryptography.ed25519.Ed25519Signature
|
||||||
|
import it.unisannio.assd.tkn.toHexByteArray
|
||||||
import it.unisannio.assd.tkn.toHexString
|
import it.unisannio.assd.tkn.toHexString
|
||||||
|
|
||||||
class ReportVerificationKey private constructor(private val key: Ed25519PublicKey) {
|
class ReportVerificationKey private constructor(private val key: Ed25519PublicKey) {
|
||||||
@ -32,5 +33,10 @@ class ReportVerificationKey private constructor(private val key: Ed25519PublicKe
|
|||||||
ReportVerificationKey(
|
ReportVerificationKey(
|
||||||
Ed25519PublicKey.fromByteArray(bytes)
|
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.Const
|
||||||
import it.unisannio.assd.tkn.report.Memo
|
import it.unisannio.assd.tkn.report.Memo
|
||||||
import it.unisannio.assd.tkn.report.Report
|
import it.unisannio.assd.tkn.report.Report
|
||||||
|
import it.unisannio.assd.tkn.toHexByteArray
|
||||||
import it.unisannio.assd.tkn.toHexString
|
import it.unisannio.assd.tkn.toHexString
|
||||||
import it.unisannio.assd.tkn.toLeByteArray
|
import it.unisannio.assd.tkn.toLeByteArray
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
@ -71,5 +72,11 @@ class TemporaryContactKey private constructor(
|
|||||||
bytes,
|
bytes,
|
||||||
index
|
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 it.unisannio.assd.tkn.toHexString
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import java.util.*
|
import java.util.UUID
|
||||||
|
|
||||||
class TemporaryContactNumber(
|
class TemporaryContactNumber(
|
||||||
private val number: ByteArray,
|
private val number: ByteArray,
|
||||||
|
@ -8,7 +8,7 @@ import java.nio.ByteOrder
|
|||||||
|
|
||||||
class SignedReport private constructor(
|
class SignedReport private constructor(
|
||||||
val report: Report,
|
val report: Report,
|
||||||
private val sign: ByteArray
|
val sign: ByteArray
|
||||||
) {
|
) {
|
||||||
fun verify(): Boolean = report.getVerificationKey()
|
fun verify(): Boolean = report.getVerificationKey()
|
||||||
.verify(report.toByteArray(), sign)
|
.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