Skip to content

Commit

Permalink
fix(secp256k1): Exposing EC Secp256K1
Browse files Browse the repository at this point in the history
  • Loading branch information
hamada147 committed Aug 14, 2023
1 parent 2865b24 commit d936a8a
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,27 @@ class KMMECSecp256k1PrivateKey : Encodable {
return raw
}

/**
* Sign the provided data with EC Secp256K1
* @param data data that you want to sign
* @return signature
*/
fun sign(data: ByteArray): ByteArray {
val secp256k1Lib = Secp256k1Lib()
return secp256k1Lib.sign(raw, data)
}

/**
* Verify provided signature with the public key that is generated using the private key
* @param signature that we need to verify
* @param data that was used in signature
* @return true when valid, false when invalid
*/
fun verify(signature: ByteArray, data: ByteArray): Boolean {
val secp256k1Lib = Secp256k1Lib()
return secp256k1Lib.verify(getPublicKey().raw, signature, data)
}

companion object : KMMECSecp256k1PrivateKeyCommonStaticInterface {
override fun secp256k1FromByteArray(d: ByteArray): KMMECSecp256k1PrivateKey {
return KMMECSecp256k1PrivateKey(d)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.iohk.atala.prism.apollo.utils

import com.ionspin.kotlin.bignum.integer.BigInteger
import com.ionspin.kotlin.bignum.integer.Sign
import io.iohk.atala.prism.apollo.secp256k1.Secp256k1Lib
import kotlin.js.ExperimentalJsExport
import kotlin.js.JsExport
import kotlin.js.JsName
Expand Down Expand Up @@ -55,8 +56,6 @@ class KMMECSecp256k1PublicKey {
this.raw = raw
}

companion object : KMMECSecp256k1PublicKeyCommonStaticInterface

fun getCurvePoint(): KMMECPoint {
if (raw.size != 65) {
throw IllegalArgumentException("Public key should be 65 bytes long")
Expand All @@ -69,4 +68,17 @@ class KMMECSecp256k1PublicKey {

return KMMECPoint(x, y)
}

/**
* Verify provided signature
* @param signature that we need to verify
* @param data that was used in signature
* @return true when valid, false when invalid
*/
fun verify(signature: ByteArray, data: ByteArray): Boolean {
val secp256k1Lib = Secp256k1Lib()
return secp256k1Lib.verify(raw, signature, data)
}

companion object : KMMECSecp256k1PublicKeyCommonStaticInterface
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package io.iohk.atala.prism.apollo.utils

import io.iohk.atala.prism.apollo.base64.base64UrlDecodedBytes
import io.iohk.atala.prism.apollo.base64.base64UrlEncoded
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue

class KMMECSecp256k1KeysTests {
@Test
fun testSigning() {
val privateKeyBase64 = "N_JFgvYaReyRXwassz5FHg33A4I6dczzdXrjdHGksmg"
val base64ByteArray = privateKeyBase64.base64UrlDecodedBytes
val privateKey = KMMECSecp256k1PrivateKey.secp256k1FromByteArray(base64ByteArray)
val message = "Test"
val signature = privateKey.sign(message.encodeToByteArray())
assertEquals("MEUCIQCFeGlhJrH-9R70X4JzrurWs52SwuxCnJ8ky6riFwMOrwIgT7zlLo7URMHW5tiMgG73IOw2Dm3XyLl1iqW1-t5NFWQ", signature.base64UrlEncoded)
}

@Test
fun testVerifyingFromPrivateKey() {
val privateKeyBase64 = "N_JFgvYaReyRXwassz5FHg33A4I6dczzdXrjdHGksmg"
val base64ByteArray = privateKeyBase64.base64UrlDecodedBytes
val privateKey = KMMECSecp256k1PrivateKey.secp256k1FromByteArray(base64ByteArray)
val message = "Test"
val signature = privateKey.sign(message.encodeToByteArray())
assertEquals("MEUCIQCFeGlhJrH-9R70X4JzrurWs52SwuxCnJ8ky6riFwMOrwIgT7zlLo7URMHW5tiMgG73IOw2Dm3XyLl1iqW1-t5NFWQ", signature.base64UrlEncoded)
assertTrue(privateKey.verify(signature, message.encodeToByteArray()))
}

@Test
fun testVerifyingFromPublicKey() {
val privateKeyBase64 = "N_JFgvYaReyRXwassz5FHg33A4I6dczzdXrjdHGksmg"
val base64ByteArray = privateKeyBase64.base64UrlDecodedBytes
val privateKey = KMMECSecp256k1PrivateKey.secp256k1FromByteArray(base64ByteArray)
val message = "Test"
val signature = privateKey.sign(message.encodeToByteArray())
assertEquals("MEUCIQCFeGlhJrH-9R70X4JzrurWs52SwuxCnJ8ky6riFwMOrwIgT7zlLo7URMHW5tiMgG73IOw2Dm3XyLl1iqW1-t5NFWQ", signature.base64UrlEncoded)
val publicKey = privateKey.getPublicKey()
assertTrue(publicKey.verify(signature, message.encodeToByteArray()))
}

@Test
fun getPublicKeyFromPrivateKey() {
val privateKeyBase64 = "N_JFgvYaReyRXwassz5FHg33A4I6dczzdXrjdHGksmg"
val base64ByteArray = privateKeyBase64.base64UrlDecodedBytes
val privateKey = KMMECSecp256k1PrivateKey.secp256k1FromByteArray(base64ByteArray)
assertEquals("BD-l4lrQ6Go-oN5XtdpY6o5dyf2V2v5EbMAvRjVGJpE1gYVURJfxKMpNPnKlLr4MOLNVaYvBNOoy9L50E8jVx8Q", privateKey.getPublicKey().raw.base64UrlEncoded)
}

@Test
fun testIsPointOnSecp256k1Curve() {
val point = KMMECPoint(
"P6XiWtDoaj6g3le12ljqjl3J_ZXa_kRswC9GNUYmkTU".base64UrlDecodedBytes,
"gYVURJfxKMpNPnKlLr4MOLNVaYvBNOoy9L50E8jVx8Q".base64UrlDecodedBytes
)
assertTrue(KMMECSecp256k1PublicKey.isPointOnSecp256k1Curve(point))
}

@Test
fun testGetCurvePoint() {
val publicKey = KMMECSecp256k1PublicKey("BD-l4lrQ6Go-oN5XtdpY6o5dyf2V2v5EbMAvRjVGJpE1gYVURJfxKMpNPnKlLr4MOLNVaYvBNOoy9L50E8jVx8Q".base64UrlDecodedBytes)
val point = publicKey.getCurvePoint()
assertEquals("P6XiWtDoaj6g3le12ljqjl3J_ZXa_kRswC9GNUYmkTU", point.x.base64UrlEncoded)
assertEquals("gYVURJfxKMpNPnKlLr4MOLNVaYvBNOoy9L50E8jVx8Q", point.y.base64UrlEncoded)
}

@Test
fun testECSecp256K1FromByteCoordinates() {
val publicKey = KMMECSecp256k1PublicKey.secp256k1FromByteCoordinates(
"P6XiWtDoaj6g3le12ljqjl3J_ZXa_kRswC9GNUYmkTU".base64UrlDecodedBytes,
"gYVURJfxKMpNPnKlLr4MOLNVaYvBNOoy9L50E8jVx8Q".base64UrlDecodedBytes
)
assertTrue(KMMECSecp256k1PublicKey.isPointOnSecp256k1Curve(publicKey.getCurvePoint()))
}
}

0 comments on commit d936a8a

Please sign in to comment.