Skip to content

Commit dc6e3c9

Browse files
author
Yao Hsu
committed
Part 2 - Verify Ethereum message signature
1. Convert message to be signed in HEX format 2. Convert message to be verified in EIP-191 format 3. Compare public keys in compressed format
1 parent a8defdf commit dc6e3c9

File tree

3 files changed

+31
-8
lines changed

3 files changed

+31
-8
lines changed

app/build.gradle

+2
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,7 @@ dependencies {
6060
implementation(name:'HtcWalletSDK-Htc_partner1-release', ext:'aar')
6161
implementation 'com.github.komputing.kethereum:model:0.82.4'
6262
implementation 'com.github.komputing.kethereum:crypto:0.82.4'
63+
implementation 'com.github.komputing.kethereum:crypto_api:0.82.4'
6364
implementation 'com.github.komputing.kethereum:crypto_impl_spongycastle:0.82.4'
65+
implementation 'com.github.komputing.kethereum:extensions_kotlin:0.82.4'
6466
}

app/src/main/java/com/htc/zion/demoapp/FirstFragment.kt

+5-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import androidx.fragment.app.Fragment
1212
import com.google.android.material.snackbar.Snackbar
1313
import com.google.gson.Gson
1414
import com.htc.htcwalletsdk.Native.Type.ByteArrayHolder
15+
import com.htc.htcwalletsdk.Utils.GenericUtils
1516
import com.htc.zion.demoapp.Utils.Companion.LOG_TAG
1617
import com.htc.zion.demoapp.Utils.Companion.convertToHex
1718
import com.htc.zion.demoapp.Utils.Companion.sha256
@@ -100,8 +101,9 @@ class FirstFragment : Fragment() {
100101
bitmap.convertToHex()
101102
}?.let { bitmapHex ->
102103
bitmapHex.sha256()
103-
}?.let { bitmapHash ->
104-
val photoData = EthereumJsonTemplate(Message(bitmapHash))
104+
}?.let { msg ->
105+
val msgHex = GenericUtils.byteArrayToHex(msg.toByteArray())
106+
val photoData = EthereumJsonTemplate(Message(msgHex))
105107
Log.i(LOG_TAG, "EthereumJson=$photoData")
106108
val sig = ByteArrayHolder()
107109
val uniqueId = Utils.getZkmaSdkUniqueId(this.requireContext())
@@ -117,7 +119,7 @@ class FirstFragment : Fragment() {
117119
)
118120
val verified = ZkmaSdkHelper.verifyEthMsgSignature(
119121
uniqueId,
120-
bitmapHash,
122+
msg,
121123
sig.byteArray
122124
)
123125
Log.i(

app/src/main/java/com/htc/zion/demoapp/ZkmaSdkHelper.kt

+24-5
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@ import com.htc.htcwalletsdk.Export.HtcWalletSdkManager
77
import com.htc.htcwalletsdk.Export.RESULT
88
import com.htc.htcwalletsdk.Native.Type.ByteArrayHolder
99
import com.htc.htcwalletsdk.Utils.GenericUtils
10+
import org.kethereum.crypto.CURVE
1011
import java.util.concurrent.atomic.AtomicBoolean
1112
import org.kethereum.crypto.signedMessageToKey
13+
import org.kethereum.extensions.toBigInteger
14+
import org.kethereum.extensions.toBytesPadded
15+
import org.kethereum.extensions.toHexStringZeroPadded
16+
import org.kethereum.model.PUBLIC_KEY_SIZE
1217
import org.kethereum.model.SignatureData
13-
import java.lang.NumberFormatException
14-
import java.security.SignatureException
18+
import java.math.BigInteger
1519

1620
class ZkmaSdkHelper {
1721

@@ -96,18 +100,33 @@ class ZkmaSdkHelper {
96100
var verified = false
97101
try {
98102
val signature = GenericUtils.byteArrayToHex(signatureBytes)
103+
Log.d(Utils.LOG_TAG, "signature: $signature")
99104
val r = signature.slice(0..63).toBigInteger(16)
100105
val s = signature.slice(64..127).toBigInteger(16)
101-
val v = signature.slice(128..129).toBigInteger()
106+
val v = signature.slice(128..129).toBigInteger(16)
102107
val signatureData = SignatureData(r, s, v)
103-
val msgPubKey = signedMessageToKey(message.toByteArray(), signatureData).key
108+
val signedMsgBytes = message.toByteArray().let {
109+
"\u0019Ethereum Signed Message:\n${it.size}".toByteArray() + it
110+
}
111+
val msgPubKey = compressKey(signedMessageToKey(signedMsgBytes, signatureData).key)
112+
val msgPubKeyHex = msgPubKey.toHexStringZeroPadded(66, false)
113+
Log.d(Utils.LOG_TAG, "msgPubKey: $msgPubKeyHex")
104114
val tzPubKey = zkmaManager.getSendPublicKey(uniqueId, 60).key
105-
.substringAfter("0x").toBigInteger(16)
115+
.toBigInteger(16)
116+
val tzPubKeyHex = tzPubKey.toHexStringZeroPadded(66, false)
117+
Log.d(Utils.LOG_TAG, "tzPubKey: $tzPubKeyHex")
106118
verified = tzPubKey == msgPubKey
107119
} catch (e: Exception) {
108120
Log.e(Utils.LOG_TAG, e.message, e)
109121
}
110122
return verified
111123
}
124+
125+
fun compressKey(publicKey: BigInteger): BigInteger {
126+
val ret = publicKey.toBytesPadded(PUBLIC_KEY_SIZE + 1)
127+
ret[0] = 4
128+
val point = CURVE.decodePoint(ret)
129+
return point.encoded(true).toBigInteger()
130+
}
112131
}
113132
}

0 commit comments

Comments
 (0)