Skip to content

Commit

Permalink
Upgrade bitcoin-kmp
Browse files Browse the repository at this point in the history
It now provides different types for individual and aggregated musig2 nonces.
  • Loading branch information
sstone committed Dec 5, 2023
1 parent b825d1a commit fe20db0
Show file tree
Hide file tree
Showing 10 changed files with 33 additions and 35 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ kotlin {

val commonMain by sourceSets.getting {
dependencies {
api("fr.acinq.bitcoin:bitcoin-kmp:0.15.0-MUSIG2-SNAPSHOT") // when upgrading, keep secp256k1-kmp-jni-jvm in sync below
api("fr.acinq.bitcoin:bitcoin-kmp:0.15.0-SNAPSHOT") // when upgrading, keep secp256k1-kmp-jni-jvm in sync below
api("org.kodein.log:canard:0.18.0")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVersion")
api("org.jetbrains.kotlinx:kotlinx-serialization-core:$serializationVersion")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package fr.acinq.lightning.channel

import fr.acinq.bitcoin.*
import fr.acinq.bitcoin.Script.tail
import fr.acinq.bitcoin.musig2.PublicNonce
import fr.acinq.bitcoin.musig2.IndividualNonce
import fr.acinq.bitcoin.musig2.SecretNonce
import fr.acinq.lightning.Lightning.randomBytes32
import fr.acinq.lightning.MilliSatoshi
Expand Down Expand Up @@ -410,7 +410,7 @@ data class SharedTransaction(
val previousOutputs = unsignedTx.txIn.map { previousOutputsMap[it.outPoint]!! }.toList()

// nonces that we've received for all musig2 swap-in
val receivedNonces: Map<Long, PublicNonce> = when (session.txCompleteReceived) {
val receivedNonces: Map<Long, IndividualNonce> = when (session.txCompleteReceived) {
null -> mapOf()
else -> (localInputs.filterIsInstance<InteractiveTxInput.LocalMusig2SwapIn>() + remoteInputs.filterIsInstance<InteractiveTxInput.RemoteSwapInMusig2>())
.sortedBy { it.serialId }
Expand All @@ -437,7 +437,7 @@ data class SharedTransaction(
require(session.txCompleteReceived != null)
val serverNonce = receivedNonces[input.serialId]
require(serverNonce != null) { "missing server nonce for input ${input.serialId}" }
val commonNonce = PublicNonce.aggregate(listOf(userNonce.publicNonce(), serverNonce))
val commonNonce = IndividualNonce.aggregate(listOf(userNonce.publicNonce(), serverNonce))
TxSignatures.Companion.PartialSignature(keyManager.swapInOnChainWallet.signSwapInputUserMusig2(unsignedTx, i, previousOutputs, userNonce, serverNonce), commonNonce)
}
}.filterNotNull()
Expand Down Expand Up @@ -465,7 +465,7 @@ data class SharedTransaction(
require(session.txCompleteReceived != null)
val serverNonce = receivedNonces[input.serialId]
require(serverNonce != null) { "missing server nonce for input ${input.serialId}" }
val commonNonce = PublicNonce.aggregate(listOf(userNonce.publicNonce(), serverNonce))
val commonNonce = IndividualNonce.aggregate(listOf(userNonce.publicNonce(), serverNonce))
val swapInProtocol = SwapInProtocolMusig2(input.swapInParams.userKey, serverKey.publicKey(), input.swapInParams.userRefundKey, input.swapInParams.refundDelay)
TxSignatures.Companion.PartialSignature(swapInProtocol.signSwapInputServer(unsignedTx, i, previousOutputs, serverNonce, serverKey, userNonce), commonNonce)
}
Expand Down
4 changes: 2 additions & 2 deletions src/commonMain/kotlin/fr/acinq/lightning/crypto/KeyManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package fr.acinq.lightning.crypto
import fr.acinq.bitcoin.*
import fr.acinq.bitcoin.DeterministicWallet.hardened
import fr.acinq.bitcoin.io.ByteArrayInput
import fr.acinq.bitcoin.musig2.PublicNonce
import fr.acinq.bitcoin.musig2.IndividualNonce
import fr.acinq.bitcoin.musig2.SecretNonce
import fr.acinq.lightning.DefaultSwapInParams
import fr.acinq.lightning.NodeParams
Expand Down Expand Up @@ -155,7 +155,7 @@ interface KeyManager {
return swapInProtocol.signSwapInputUser(fundingTx, index, parentTxOuts[fundingTx.txIn[index].outPoint.index.toInt()] , userPrivateKey)
}

fun signSwapInputUserMusig2(fundingTx: Transaction, index: Int, parentTxOuts: List<TxOut>, userNonce: SecretNonce, serverNonce: PublicNonce): ByteVector32 {
fun signSwapInputUserMusig2(fundingTx: Transaction, index: Int, parentTxOuts: List<TxOut>, userNonce: SecretNonce, serverNonce: IndividualNonce): ByteVector32 {
return swapInProtocolMusig2.signSwapInputUser(fundingTx, index, parentTxOuts, userPrivateKey, userNonce, serverNonce)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package fr.acinq.lightning.serialization.v4
import fr.acinq.bitcoin.*
import fr.acinq.bitcoin.io.ByteArrayInput
import fr.acinq.bitcoin.io.Input
import fr.acinq.bitcoin.musig2.PublicNonce
import fr.acinq.bitcoin.musig2.IndividualNonce
import fr.acinq.bitcoin.musig2.SecretNonce
import fr.acinq.lightning.CltvExpiryDelta
import fr.acinq.lightning.Features
Expand Down Expand Up @@ -599,7 +599,7 @@ object Deserialization {

private fun Input.readTxId(): TxId = TxId(readByteVector32())

private fun Input.readPublicNonce() = PublicNonce.fromBin(ByteArray(66).also { read(it, 0, it.size) })
private fun Input.readPublicNonce() = IndividualNonce.fromBin(ByteArray(66).also { read(it, 0, it.size) })

private fun Input.readDelimitedByteArray(): ByteArray {
val size = readNumber().toInt()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package fr.acinq.lightning.serialization.v4
import fr.acinq.bitcoin.*
import fr.acinq.bitcoin.io.ByteArrayOutput
import fr.acinq.bitcoin.io.Output
import fr.acinq.bitcoin.musig2.PublicNonce
import fr.acinq.bitcoin.musig2.IndividualNonce
import fr.acinq.lightning.FeatureSupport
import fr.acinq.lightning.Features
import fr.acinq.lightning.channel.*
Expand Down Expand Up @@ -655,7 +655,7 @@ object Serialization {

private fun Output.writeTxId(o: TxId) = write(o.value.toByteArray())

private fun Output.writePublicNonce(o: PublicNonce) = write(o.toByteArray())
private fun Output.writePublicNonce(o: IndividualNonce) = write(o.toByteArray())

private fun Output.writeDelimited(o: ByteArray) {
writeNumber(o.size)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package fr.acinq.lightning.transactions

import fr.acinq.bitcoin.*
import fr.acinq.bitcoin.musig2.Musig2
import fr.acinq.bitcoin.musig2.PublicNonce
import fr.acinq.bitcoin.musig2.SecretNonce
import fr.acinq.bitcoin.musig2.SessionCtx
import fr.acinq.bitcoin.musig2.*
import fr.acinq.lightning.NodeParams
import fr.acinq.lightning.wire.TxAddInputTlv

Expand Down Expand Up @@ -86,10 +83,10 @@ class SwapInProtocolMusig2(val userPublicKey: PublicKey, val serverPublicKey: Pu

fun witnessRefund(userSig: ByteVector64): ScriptWitness = ScriptWitness.empty.push(userSig).push(redeemScript).push(controlBlock)

fun signSwapInputUser(fundingTx: Transaction, index: Int, parentTxOuts: List<TxOut>, userPrivateKey: PrivateKey, userNonce: SecretNonce, serverNonce: PublicNonce): ByteVector32 {
fun signSwapInputUser(fundingTx: Transaction, index: Int, parentTxOuts: List<TxOut>, userPrivateKey: PrivateKey, userNonce: SecretNonce, serverNonce: IndividualNonce): ByteVector32 {
require(userPrivateKey.publicKey() == userPublicKey)
val txHash = Transaction.hashForSigningSchnorr(fundingTx, index, parentTxOuts, SigHash.SIGHASH_DEFAULT, SigVersion.SIGVERSION_TAPROOT)
val commonNonce = PublicNonce.aggregate(listOf(userNonce.publicNonce(), serverNonce))
val commonNonce = IndividualNonce.aggregate(listOf(userNonce.publicNonce(), serverNonce))
val ctx = SessionCtx(
commonNonce,
listOf(userPrivateKey.publicKey(), serverPublicKey),
Expand All @@ -104,9 +101,9 @@ class SwapInProtocolMusig2(val userPublicKey: PublicKey, val serverPublicKey: Pu
return Crypto.signSchnorr(txHash, userPrivateKey, Crypto.SchnorrTweak.NoTweak)
}

fun signSwapInputServer(fundingTx: Transaction, index: Int, parentTxOuts: List<TxOut>, userNonce: PublicNonce, serverPrivateKey: PrivateKey, serverNonce: SecretNonce): ByteVector32 {
fun signSwapInputServer(fundingTx: Transaction, index: Int, parentTxOuts: List<TxOut>, userNonce: IndividualNonce, serverPrivateKey: PrivateKey, serverNonce: SecretNonce): ByteVector32 {
val txHash = Transaction.hashForSigningSchnorr(fundingTx, index, parentTxOuts, SigHash.SIGHASH_DEFAULT, SigVersion.SIGVERSION_TAPROOT)
val commonNonce = PublicNonce.aggregate(listOf(userNonce, serverNonce.publicNonce()))
val commonNonce = IndividualNonce.aggregate(listOf(userNonce, serverNonce.publicNonce()))
val ctx = SessionCtx(
commonNonce,
listOf(userPublicKey, serverPrivateKey.publicKey()),
Expand All @@ -116,7 +113,7 @@ class SwapInProtocolMusig2(val userPublicKey: PublicKey, val serverPublicKey: Pu
return ctx.sign(serverNonce, serverPrivateKey)
}

fun signingCtx(fundingTx: Transaction, index: Int, parentTxOuts: List<TxOut>, commonNonce: PublicNonce): SessionCtx {
fun signingCtx(fundingTx: Transaction, index: Int, parentTxOuts: List<TxOut>, commonNonce: AggregatedNonce): SessionCtx {
val txHash = Transaction.hashForSigningSchnorr(fundingTx, index, parentTxOuts, SigHash.SIGHASH_DEFAULT, SigVersion.SIGVERSION_TAPROOT)
return SessionCtx(
commonNonce,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ package fr.acinq.lightning.wire
import fr.acinq.bitcoin.*
import fr.acinq.bitcoin.io.Input
import fr.acinq.bitcoin.io.Output
import fr.acinq.bitcoin.musig2.PublicNonce
import fr.acinq.bitcoin.musig2.AggregatedNonce
import fr.acinq.bitcoin.musig2.IndividualNonce
import fr.acinq.lightning.utils.sat
import fr.acinq.lightning.utils.toByteVector
import fr.acinq.lightning.utils.toByteVector64
Expand Down Expand Up @@ -72,7 +73,7 @@ sealed class TxRemoveOutputTlv : Tlv

sealed class TxCompleteTlv : Tlv {
/** nonces for all Musig2 swap-in inputs, ordered by serial id */
data class Nonces(val nonces: List<PublicNonce>): TxCompleteTlv() {
data class Nonces(val nonces: List<IndividualNonce>): TxCompleteTlv() {
override val tag: Long get() = Nonces.tag

override fun write(out: Output) {
Expand All @@ -83,7 +84,7 @@ sealed class TxCompleteTlv : Tlv {
const val tag: Long = 101
override fun read(input: Input): Nonces {
val count = input.availableBytes / 66
val nonces = (0 until count).map { PublicNonce.fromBin(LightningCodecs.bytes(input, 66)) }
val nonces = (0 until count).map { IndividualNonce.fromBin(LightningCodecs.bytes(input, 66)) }
return Nonces(nonces)
}
}
Expand Down Expand Up @@ -145,7 +146,7 @@ sealed class TxSignaturesTlv : Tlv {
val count = input.availableBytes / (32 + 66)
val psigs = (0 until count).map {
val sig = LightningCodecs.bytes(input, 32).byteVector32()
val nonce = PublicNonce.fromBin(LightningCodecs.bytes(input, 66))
val nonce = AggregatedNonce.fromBin(LightningCodecs.bytes(input, 66))
TxSignatures.Companion.PartialSignature(sig, nonce)
}
return SwapInUserPartialSigs(psigs)
Expand All @@ -166,7 +167,7 @@ sealed class TxSignaturesTlv : Tlv {
val count = input.availableBytes / (32 + 66)
val psigs = (0 until count).map {
val sig = LightningCodecs.bytes(input, 32).byteVector32()
val nonce = PublicNonce.fromBin(LightningCodecs.bytes(input, 66))
val nonce = AggregatedNonce.fromBin(LightningCodecs.bytes(input, 66))
TxSignatures.Companion.PartialSignature(sig, nonce)
}
return SwapInServerPartialSigs(psigs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import fr.acinq.bitcoin.io.ByteArrayInput
import fr.acinq.bitcoin.io.ByteArrayOutput
import fr.acinq.bitcoin.io.Input
import fr.acinq.bitcoin.io.Output
import fr.acinq.bitcoin.musig2.PublicNonce
import fr.acinq.bitcoin.musig2.IndividualNonce
import fr.acinq.bitcoin.musig2.AggregatedNonce
import fr.acinq.lightning.*
import fr.acinq.lightning.blockchain.fee.FeeratePerKw
import fr.acinq.lightning.channel.ChannelType
Expand Down Expand Up @@ -451,9 +452,9 @@ data class TxComplete(
) : InteractiveTxConstructionMessage(), HasChannelId {
override val type: Long get() = TxComplete.type

val publicNonces: List<PublicNonce> = tlvs.get<TxCompleteTlv.Nonces>()?.nonces ?: listOf()
val publicNonces: List<IndividualNonce> = tlvs.get<TxCompleteTlv.Nonces>()?.nonces ?: listOf()

constructor(channelId: ByteVector32, publicNonces: List<PublicNonce>) : this(channelId, TlvStream(TxCompleteTlv.Nonces(publicNonces)))
constructor(channelId: ByteVector32, publicNonces: List<IndividualNonce>) : this(channelId, TlvStream(TxCompleteTlv.Nonces(publicNonces)))

override fun write(out: Output) {
LightningCodecs.writeBytes(channelId.toByteArray(), out)
Expand Down Expand Up @@ -518,7 +519,7 @@ data class TxSignatures(
companion object : LightningMessageReader<TxSignatures> {
const val type: Long = 71

data class PartialSignature(val sig: ByteVector32, val aggregatedPublicNonce: PublicNonce)
data class PartialSignature(val sig: ByteVector32, val aggregatedPublicNonce: AggregatedNonce)

@Suppress("UNCHECKED_CAST")
val readers = mapOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@ import fr.acinq.bitcoin.Script.pay2wsh
import fr.acinq.bitcoin.Script.write
import fr.acinq.bitcoin.crypto.Pack
import fr.acinq.bitcoin.musig2.Musig2
import fr.acinq.bitcoin.musig2.PublicNonce
import fr.acinq.bitcoin.musig2.IndividualNonce
import fr.acinq.bitcoin.musig2.SecretNonce
import fr.acinq.lightning.CltvExpiry
import fr.acinq.lightning.CltvExpiryDelta
import fr.acinq.lightning.Lightning.randomBytes32
import fr.acinq.lightning.Lightning.randomKey
import fr.acinq.lightning.NodeParams
import fr.acinq.lightning.blockchain.fee.FeeratePerKw
import fr.acinq.lightning.channel.Commitments
import fr.acinq.lightning.channel.Helpers.Funding
Expand Down Expand Up @@ -588,7 +587,7 @@ class TransactionsTestsCommon : LightningTestSuite() {

val userSig = swapInProtocolMusig2.signSwapInputUser(tx, 0, swapInTx.txOut, userPrivateKey, userNonce, serverNonce.publicNonce())
val serverSig = swapInProtocolMusig2.signSwapInputServer(tx, 0, swapInTx.txOut, userNonce.publicNonce(), serverPrivateKey, serverNonce)
val ctx = swapInProtocolMusig2.signingCtx(tx, 0, swapInTx.txOut, PublicNonce.aggregate(listOf(userNonce.publicNonce(), serverNonce.publicNonce())))
val ctx = swapInProtocolMusig2.signingCtx(tx, 0, swapInTx.txOut, IndividualNonce.aggregate(listOf(userNonce.publicNonce(), serverNonce.publicNonce())))
val commonSig = ctx.partialSigAgg(listOf(userSig, serverSig))
val signedTx = tx.updateWitness(0, swapInProtocolMusig2.witness(commonSig))
Transaction.correctlySpends(signedTx, swapInTx, ScriptFlags.STANDARD_SCRIPT_VERIFY_FLAGS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package fr.acinq.lightning.wire
import fr.acinq.bitcoin.*
import fr.acinq.bitcoin.io.ByteArrayInput
import fr.acinq.bitcoin.io.ByteArrayOutput
import fr.acinq.bitcoin.musig2.PublicNonce
import fr.acinq.bitcoin.musig2.AggregatedNonce
import fr.acinq.lightning.*
import fr.acinq.lightning.Lightning.randomBytes
import fr.acinq.lightning.Lightning.randomBytes32
Expand Down Expand Up @@ -378,8 +378,8 @@ class LightningCodecsTestsCommon : LightningTestSuite() {
val pubKey1 = PrivateKey.fromHex("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").publicKey()
val pubKey2 = PrivateKey.fromHex("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb").publicKey()
val swapInPartialSignatures = listOf(
TxSignatures.Companion.PartialSignature(ByteVector32("cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"), PublicNonce(pubKey1, pubKey2)),
TxSignatures.Companion.PartialSignature(ByteVector32("dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"), PublicNonce(pubKey1, pubKey2))
TxSignatures.Companion.PartialSignature(ByteVector32("cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"), AggregatedNonce(pubKey1, pubKey2)),
TxSignatures.Companion.PartialSignature(ByteVector32("dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"), AggregatedNonce(pubKey1, pubKey2))
)
val signature = ByteVector64("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
// This is a random mainnet transaction.
Expand Down

0 comments on commit fe20db0

Please sign in to comment.