From ab215e26df9eae26883f678d7979ea905aa0f5ab Mon Sep 17 00:00:00 2001 From: benthecarman Date: Sat, 11 Jun 2022 09:36:19 -0500 Subject: [PATCH] Set recovery id properly for buildLnInvoiceSignature (#4379) --- .../core/protocol/ln/LnInvoiceUnitTest.scala | 14 +++++++++++++- .../org/bitcoins/core/protocol/ln/LnInvoice.scala | 5 ++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/core-test/src/test/scala/org/bitcoins/core/protocol/ln/LnInvoiceUnitTest.scala b/core-test/src/test/scala/org/bitcoins/core/protocol/ln/LnInvoiceUnitTest.scala index ca2fb146be..a0a24600e7 100644 --- a/core-test/src/test/scala/org/bitcoins/core/protocol/ln/LnInvoiceUnitTest.scala +++ b/core-test/src/test/scala/org/bitcoins/core/protocol/ln/LnInvoiceUnitTest.scala @@ -5,6 +5,7 @@ import org.bitcoins.core.protocol.ln.LnParams.{ LnBitcoinMainNet, LnBitcoinTestNet } +import org.bitcoins.core.protocol.ln.LnTag.{DescriptionTag, PaymentHashTag} import org.bitcoins.core.protocol.ln.channel.ShortChannelId import org.bitcoins.core.protocol.ln.currency.{ MicroBitcoins, @@ -22,7 +23,7 @@ import org.bitcoins.core.util.Bech32 import org.bitcoins.crypto._ import org.bitcoins.testkitcore.gen.ln.LnInvoiceGen import org.bitcoins.testkitcore.util.BitcoinSUnitTest -import scodec.bits.ByteVector +import scodec.bits._ class LnInvoiceUnitTest extends BitcoinSUnitTest { behavior of "LnInvoice" @@ -565,4 +566,15 @@ class LnInvoiceUnitTest extends BitcoinSUnitTest { "lntbs42949672960n1p3qavpxpp59mdvu0tw0mzf2kl96ddfcm0597nuxwp42tzsehrn66jrmlg7nu8sdqqcqzpgxqyz5vqsp5y70pg45suf546mses9cp54fk4uke2rmppk9dy4926prhe5v54g4s9qyyssqmtpasu8map7hegdxfzmgusuqnkrssy6m34wcup3lmu0mae3xtht5d49204a3wm9wpklalx49g33cer5gqfractwt79vrc8p7wlpsdlqp296km0" assert(LnInvoice.fromStringT(str).isSuccess) } + + it must "build an invoice with a recoverable pub key" in { + val priv = ECPrivateKey.fromBytes( + hex"deeb3f23a850090b9033e3400584923a281d3c7d914a6d1587369abe2071d8c5") + val hrp = LnHumanReadablePart.fromLnParams(LnParams.LnBitcoinRegTest) + val tags = LnTaggedFields( + Vector(PaymentHashTag(Sha256Digest.empty), DescriptionTag("test"))) + val invoice = LnInvoice.build(hrp, tags, priv) + + assert(invoice.nodeId == NodeId(priv.publicKey)) + } } diff --git a/core/src/main/scala/org/bitcoins/core/protocol/ln/LnInvoice.scala b/core/src/main/scala/org/bitcoins/core/protocol/ln/LnInvoice.scala index f9e7a5b98d..c36e7703af 100644 --- a/core/src/main/scala/org/bitcoins/core/protocol/ln/LnInvoice.scala +++ b/core/src/main/scala/org/bitcoins/core/protocol/ln/LnInvoice.scala @@ -275,7 +275,10 @@ object LnInvoice extends StringFactory[LnInvoice] { val sigHash = buildSigHashData(hrp, timestamp, lnTags) val sig = privateKey.sign(sigHash) - LnInvoiceSignature(recoverId = UInt8.zero, signature = sig) + val (pub1, _) = CryptoUtil.recoverPublicKey(sig, sigHash.bytes) + val recoveryId = if (privateKey.publicKey == pub1) UInt8.zero else UInt8.one + + LnInvoiceSignature(recoverId = recoveryId, signature = sig) } /** The easiest way to create a [[org.bitcoins.core.protocol.ln.LnInvoice LnInvoice]]