Skip to content

Commit

Permalink
Fix ECDSA signatures with BTCSigner and cleanup tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ptzianos committed Oct 27, 2019
1 parent 73764b3 commit cb07c83
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 46 deletions.
3 changes: 2 additions & 1 deletion wallet/lib/src/main/kotlin/org/hermes/hd/BaseECDSASigner.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ abstract class BaseECDSASigner: Signer<SecP256K1PrivKey> {
data

val hashed = recDigest(msgBytes, hashRounds, digest)
return key.sign(hashed)
val (r, s, rY) = key.rawSign(hashed)
return ECDSASignature(r, s, rY)
}
}
2 changes: 1 addition & 1 deletion wallet/lib/src/main/kotlin/org/hermes/hd/btc.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ object BTCKeyEncoder: KeyEncoder<ExPrivKey, ExPubKey>() {

object BTCSigner: BaseECDSASigner() {

override fun sign(key: SecP256K1PrivKey, data: ByteArray): ByteArray{
override fun sign(key: SecP256K1PrivKey, data: ByteArray): ByteArray {
val signature = chainSign(
key = key,
prefix = "Bitcoin Signed Message:\n",
Expand Down
1 change: 0 additions & 1 deletion wallet/lib/src/main/kotlin/org/hermes/utils/bytes.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import java.lang.IndexOutOfBoundsException
import java.math.BigInteger
import java.util.*

import org.bouncycastle.pqc.math.linearalgebra.IntegerFunctions.pow
import org.bouncycastle.util.encoders.Base64
import org.bouncycastle.util.encoders.Hex

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,65 +5,25 @@ import org.bouncycastle.util.encoders.Hex
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.Assertions.*

import org.hermes.hd.BTCSigner


internal class SecP256K1PrivKeyTest {

@Test
fun testPrivateKeyImportAndWIF() {
fun privateKeyImportAndWIF() {
val privateKey = SecP256K1PrivKey("0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D")
assertEquals("0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d", Hex.toHexString(privateKey.value.toByteArray()))
assertEquals("5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ", privateKey.toString())
assertTrue(SecP256K1PrivKey.validateWIFCheckSum(privateKey.toString()))
}

@Test
fun testPrivateKeyWith0xImportAndWIF() {
fun privateKeyWith0xImportAndWIF() {
val privateKey = SecP256K1PrivKey("0x0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D")
assertEquals("0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d", Hex.toHexString(privateKey.value.toByteArray()))
assertEquals("5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ", privateKey.toString())
assertTrue(SecP256K1PrivKey.validateWIFCheckSum(privateKey.toString()))
}

@Test
fun signWithPrivateKeyElectrumStyle() {
assertEquals(
"G0orznlzaawDMgoOYJHpeNc70XycJ6V45ktP0aoir1eXG8lIAQ6/44Evyh3jWeYxGtzaSIQ+pPNSzfAtHjU7ei0=",
BTCSigner.sign(SecP256K1PrivKey("0x0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d"),
"blaa".toByteArray())
)
assertEquals(
"HFzue2eFvZYqIGEo1hvQDuk7flI/a6xQ5H5YvOCq/07pYFFyUjCJcrSFUXU79uLw6Vxt3i+Qcotyi7L3UAY2bKc=",
BTCSigner.sign(
SecP256K1PrivKey("0x0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d"),
"""
By signing this with your private key you verify that you are the sole rightful owner of the key pair whose
public key has a SHA3-512 digest that starts with aaaaaaaaaa.
Expires on: 2019-06-27 10:36:07.726093
""".toByteArray())
)
assertEquals(
"GyZWBvo2roM7eKXOTNz0n3keGGQ10isWKouWe1mhaXTJIukPe5d+MuTUTD05bP4NR4f6txCCb1XpF/7RKYQKtII=",
BTCSigner.sign(
SecP256K1PrivKey("0x0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d"),
"""
By signing this with your private key you verify that you are the sole rightful owner of the key pair whose
public key has a SHA3-512 digest that starts with aaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
ccccccccccccccccccccccccccccccccccccddddddddddddddddddddddddddddddddddddddddddddddddddddeeeeeeeeeeeeeeeeeee
fffffffffffffffffffffffffffffffffffffffffffgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
llllllllllllllllllllllllllllllllllllllllllllllmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
.
Expires on: 2019-06-27 10:36:07.726093
""".toByteArray())
)
}

@Test
fun producePublicKey() {
val privateKey = SecP256K1PrivKey("0x0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d")
Expand Down
59 changes: 59 additions & 0 deletions wallet/lib/src/test/kotlin/org/hermes/hd/BTCSignerTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.hermes.hd

import org.bouncycastle.util.Strings

import org.hermes.crypto.SecP256K1PrivKey

import org.junit.jupiter.api.Test
import org.junit.jupiter.api.Assertions.*

internal class BTCSignerTest {

fun sign(keyHex: String, msg: String): String = Strings.fromByteArray(
BTCSigner.sign(SecP256K1PrivKey(keyHex), msg.toByteArray())
)

@Test
fun sign() {
assertEquals(
"G0orznlzaawDMgoOYJHpeNc70XycJ6V45ktP0aoir1eXG8lIAQ6/44Evyh3jWeYxGtzaSIQ+pPNSzfAtHjU7ei0=",
this@BTCSignerTest.sign("0x0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d",
"blaa")
)
}

@Test
fun signLegalText() {
assertEquals(
"HFzue2eFvZYqIGEo1hvQDuk7flI/a6xQ5H5YvOCq/07pYFFyUjCJcrSFUXU79uLw6Vxt3i+Qcotyi7L3UAY2bKc=",
this@BTCSignerTest.sign("0x0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d",
"""
By signing this with your private key you verify that you are the sole rightful owner of the key pair whose
public key has a SHA3-512 digest that starts with aaaaaaaaaa.
Expires on: 2019-06-27 10:36:07.726093
""")
)
}

@Test
fun signLongLegalText() {
assertEquals(
"GyZWBvo2roM7eKXOTNz0n3keGGQ10isWKouWe1mhaXTJIukPe5d+MuTUTD05bP4NR4f6txCCb1XpF/7RKYQKtII=",
this@BTCSignerTest.sign("0x0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d",
"""
By signing this with your private key you verify that you are the sole rightful owner of the key pair whose
public key has a SHA3-512 digest that starts with aaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
ccccccccccccccccccccccccccccccccccccddddddddddddddddddddddddddddddddddddddddddddddddddddeeeeeeeeeeeeeeeeeee
fffffffffffffffffffffffffffffffffffffffffffgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
llllllllllllllllllllllllllllllllllllllllllllllmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
.
Expires on: 2019-06-27 10:36:07.726093
""")
)
}
}
2 changes: 1 addition & 1 deletion wallet/lib/src/test/kotlin/org/hermes/hd/MnemonicTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ class MnemonicTest {

@ParameterizedTest
@MethodSource(value = [ "BIP39TestVectors" ])
fun testBIP39EnglishWord(entropy: String, words: String, seed: String, xPriv: String) {
fun BIP39EnglishWord(entropy: String, words: String, seed: String, xPriv: String) {
val mnemonic = Mnemonic.fromWordList(words.split(' ').toTypedArray(), passphrase)
assertEquals(entropy, Hex.toHexString(mnemonic.entropy))
assertEquals(seed, Hex.toHexString(mnemonic.seed))
Expand Down

0 comments on commit cb07c83

Please sign in to comment.