Skip to content

Commit 7cfdb96

Browse files
Rename blinding to pathKey (#735)
Rename some variable to align with the spec.
1 parent 97b1525 commit 7cfdb96

21 files changed

+213
-213
lines changed

modules/core/src/commonMain/kotlin/fr/acinq/lightning/NodeParams.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,13 +262,13 @@ data class NodeParams(
262262
* @return the default offer and the private key that will sign invoices for this offer.
263263
*/
264264
fun defaultOffer(trampolineNodeId: PublicKey): Pair<OfferTypes.Offer, PrivateKey> {
265-
// We generate a deterministic blindingSecret based on:
265+
// We generate a deterministic session key based on:
266266
// - a custom tag indicating that this is used in the Bolt 12 context
267267
// - our trampoline node, which is used as an introduction node for the offer's blinded path
268-
// - our private key, which ensures that nobody else can generate the same blindingSecret
269-
val blindingSecret = PrivateKey(Crypto.sha256("bolt 12 default offer".toByteArray(Charsets.UTF_8).byteVector() + trampolineNodeId.value + nodePrivateKey.value).byteVector32())
268+
// - our private key, which ensures that nobody else can generate the same path key secret
269+
val sessionKey = PrivateKey(Crypto.sha256("bolt 12 default offer".toByteArray(Charsets.UTF_8).byteVector() + trampolineNodeId.value + nodePrivateKey.value).byteVector32())
270270
// We don't use our currently activated features, otherwise the offer would change when we add support for new features.
271271
// If we add a new feature that we would like to use by default, we will need to explicitly create a new offer.
272-
return OfferTypes.Offer.createBlindedOffer(amount = null, description = null, this, trampolineNodeId, Features.empty, blindingSecret)
272+
return OfferTypes.Offer.createBlindedOffer(amount = null, description = null, this, trampolineNodeId, Features.empty, sessionKey)
273273
}
274274
}

modules/core/src/commonMain/kotlin/fr/acinq/lightning/crypto/RouteBlinding.kt

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,68 +14,68 @@ import fr.acinq.lightning.wire.OnionPaymentPayloadTlv
1414
object RouteBlinding {
1515

1616
/**
17-
* @param nodeId introduction node's id (which cannot be blinded since the sender need to find a route to it).
17+
* @param nodeId first node's id (which cannot be blinded since the sender need to find a route to it).
1818
* @param blindedPublicKey blinded public key, which hides the real public key.
19-
* @param blindingEphemeralKey blinding tweak that can be used by the receiving node to derive the private key that matches the blinded public key.
20-
* @param encryptedPayload encrypted payload that can be decrypted with the introduction node's private key and the blinding ephemeral key.
19+
* @param pathKey blinding tweak that can be used by the receiving node to derive the private key that matches the blinded public key.
20+
* @param encryptedPayload encrypted payload that can be decrypted with the introduction node's private key and the path key.
2121
*/
22-
data class IntroductionNode(
22+
data class FirstHop(
2323
val nodeId: EncodedNodeId,
2424
val blindedPublicKey: PublicKey,
25-
val blindingEphemeralKey: PublicKey,
25+
val pathKey: PublicKey,
2626
val encryptedPayload: ByteVector
2727
)
2828

2929
/**
3030
* @param blindedPublicKey blinded public key, which hides the real public key.
31-
* @param encryptedPayload encrypted payload that can be decrypted with the receiving node's private key and the blinding ephemeral key.
31+
* @param encryptedPayload encrypted payload that can be decrypted with the receiving node's private key and the path key.
3232
*/
33-
data class BlindedNode(val blindedPublicKey: PublicKey, val encryptedPayload: ByteVector)
33+
data class BlindedHop(val blindedPublicKey: PublicKey, val encryptedPayload: ByteVector)
3434

3535
/**
36-
* @param introductionNodeId the first node, not blinded so that the sender can locate it.
37-
* @param blindingKey blinding tweak that can be used by the introduction node to derive the private key that matches the blinded public key.
38-
* @param blindedNodes blinded nodes (including the introduction node).
36+
* @param firstNodeId the first node, not blinded so that the sender can locate it.
37+
* @param firstPathKey blinding tweak that can be used by the introduction node to derive the private key that matches the blinded public key.
38+
* @param blindedHops blinded nodes (including the introduction node).
3939
*/
4040
data class BlindedRoute(
41-
val introductionNodeId: EncodedNodeId,
42-
val blindingKey: PublicKey,
43-
val blindedNodes: List<BlindedNode>
41+
val firstNodeId: EncodedNodeId,
42+
val firstPathKey: PublicKey,
43+
val blindedHops: List<BlindedHop>
4444
) {
45-
val introductionNode: IntroductionNode = IntroductionNode(
46-
introductionNodeId,
47-
blindedNodes.first().blindedPublicKey,
48-
blindingKey,
49-
blindedNodes.first().encryptedPayload
45+
val firstHop: FirstHop = FirstHop(
46+
firstNodeId,
47+
blindedHops.first().blindedPublicKey,
48+
firstPathKey,
49+
blindedHops.first().encryptedPayload
5050
)
51-
val subsequentNodes: List<BlindedNode> = blindedNodes.drop(1)
52-
val blindedNodeIds: List<PublicKey> = blindedNodes.map { it.blindedPublicKey }
53-
val encryptedPayloads: List<ByteVector> = blindedNodes.map { it.encryptedPayload }
51+
val subsequentHops: List<BlindedHop> = blindedHops.drop(1)
52+
val blindedNodeIds: List<PublicKey> = blindedHops.map { it.blindedPublicKey }
53+
val encryptedPayloads: List<ByteVector> = blindedHops.map { it.encryptedPayload }
5454
}
5555

5656
/**
5757
* @param route blinded route.
58-
* @param lastBlinding blinding point for the last node, which can be used to derive the blinded private key.
58+
* @param lastPathKey path key for the last node, which can be used to derive the blinded private key.
5959
*/
60-
data class BlindedRouteDetails(val route: BlindedRoute, val lastBlinding: PublicKey) {
60+
data class BlindedRouteDetails(val route: BlindedRoute, val lastPathKey: PublicKey) {
6161
/** @param nodeKey private key associated with our non-blinded node_id. */
62-
fun blindedPrivateKey(nodeKey: PrivateKey): PrivateKey = derivePrivateKey(nodeKey, lastBlinding)
62+
fun blindedPrivateKey(nodeKey: PrivateKey): PrivateKey = derivePrivateKey(nodeKey, lastPathKey)
6363
}
6464

6565
/**
6666
* Blind the provided route and encrypt intermediate nodes' payloads.
6767
*
68-
* @param sessionKey this node's session key.
68+
* @param sessionKey session key of the blinded path, the corresponding public key will be the first path key.
6969
* @param publicKeys public keys of each node on the route, starting from the introduction point.
7070
* @param payloads payloads that should be encrypted for each node on the route.
7171
* @return a blinded route.
7272
*/
7373
fun create(sessionKey: PrivateKey, publicKeys: List<PublicKey>, payloads: List<ByteVector>): BlindedRouteDetails {
7474
require(publicKeys.size == payloads.size) { "a payload must be provided for each node in the blinded path" }
7575
var e = sessionKey
76-
val (blindedHops, blindingKeys) = publicKeys.zip(payloads).map { pair ->
76+
val (blindedHops, pathKeys) = publicKeys.zip(payloads).map { pair ->
7777
val (publicKey, payload) = pair
78-
val blindingKey = e.publicKey()
78+
val pathKey = e.publicKey()
7979
val sharedSecret = Sphinx.computeSharedSecret(publicKey, e)
8080
val blindedPublicKey = Sphinx.blind(publicKey, Sphinx.generateKey("blinded_node_id", sharedSecret))
8181
val rho = Sphinx.generateKey("rho", sharedSecret)
@@ -85,38 +85,38 @@ object RouteBlinding {
8585
payload.toByteArray(),
8686
byteArrayOf()
8787
)
88-
e *= PrivateKey(Crypto.sha256(blindingKey.value.toByteArray() + sharedSecret.toByteArray()))
89-
Pair(BlindedNode(blindedPublicKey, ByteVector(encryptedPayload + mac)), blindingKey)
88+
e *= PrivateKey(Crypto.sha256(pathKey.value.toByteArray() + sharedSecret.toByteArray()))
89+
Pair(BlindedHop(blindedPublicKey, ByteVector(encryptedPayload + mac)), pathKey)
9090
}.unzip()
91-
return BlindedRouteDetails(BlindedRoute(EncodedNodeId(publicKeys.first()), blindingKeys.first(), blindedHops), blindingKeys.last())
91+
return BlindedRouteDetails(BlindedRoute(EncodedNodeId(publicKeys.first()), pathKeys.first(), blindedHops), pathKeys.last())
9292
}
9393

9494
/**
9595
* Compute the blinded private key that must be used to decrypt an incoming blinded onion.
9696
*
9797
* @param privateKey this node's private key.
98-
* @param blindingEphemeralKey unblinding ephemeral key.
98+
* @param pathKey unblinding ephemeral key.
9999
* @return this node's blinded private key.
100100
*/
101-
fun derivePrivateKey(privateKey: PrivateKey, blindingEphemeralKey: PublicKey): PrivateKey {
102-
val sharedSecret = Sphinx.computeSharedSecret(blindingEphemeralKey, privateKey)
101+
fun derivePrivateKey(privateKey: PrivateKey, pathKey: PublicKey): PrivateKey {
102+
val sharedSecret = Sphinx.computeSharedSecret(pathKey, privateKey)
103103
return privateKey * PrivateKey(Sphinx.generateKey("blinded_node_id", sharedSecret))
104104
}
105105

106106
/**
107107
* Decrypt the encrypted payload (usually found in the onion) that contains instructions to locate the next node.
108108
*
109109
* @param privateKey this node's private key.
110-
* @param blindingEphemeralKey unblinding ephemeral key.
110+
* @param pathKey unblinding ephemeral key.
111111
* @param encryptedPayload encrypted payload for this node.
112112
* @return a tuple (decrypted payload, unblinding ephemeral key for the next node)
113113
*/
114114
fun decryptPayload(
115115
privateKey: PrivateKey,
116-
blindingEphemeralKey: PublicKey,
116+
pathKey: PublicKey,
117117
encryptedPayload: ByteVector
118118
): Either<InvalidTlvPayload, Pair<ByteVector, PublicKey>> {
119-
val sharedSecret = Sphinx.computeSharedSecret(blindingEphemeralKey, privateKey)
119+
val sharedSecret = Sphinx.computeSharedSecret(pathKey, privateKey)
120120
val rho = Sphinx.generateKey("rho", sharedSecret)
121121
return try {
122122
val decrypted = ChaCha20Poly1305.decrypt(
@@ -126,8 +126,8 @@ object RouteBlinding {
126126
byteArrayOf(),
127127
encryptedPayload.takeRight(16).toByteArray()
128128
)
129-
val nextBlindingEphemeralKey = Sphinx.blind(blindingEphemeralKey, Sphinx.computeBlindingFactor(blindingEphemeralKey, sharedSecret))
130-
Either.Right(Pair(ByteVector(decrypted), nextBlindingEphemeralKey))
129+
val nextPathKey = Sphinx.blind(pathKey, Sphinx.computeBlindingFactor(pathKey, sharedSecret))
130+
Either.Right(Pair(ByteVector(decrypted), nextPathKey))
131131
} catch (_: Throwable) {
132132
Either.Left(CannotDecodeTlv(OnionPaymentPayloadTlv.EncryptedRecipientData.tag))
133133
}

modules/core/src/commonMain/kotlin/fr/acinq/lightning/json/JsonSerializers.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
JsonSerializers.FundingSignedSerializer::class,
5050
JsonSerializers.UpdateAddHtlcSerializer::class,
5151
JsonSerializers.UpdateAddHtlcTlvSerializer::class,
52-
JsonSerializers.UpdateAddHtlcTlvBlindingSerializer::class,
52+
JsonSerializers.UpdateAddHtlcTlvPathKeySerializer::class,
5353
JsonSerializers.UpdateFulfillHtlcSerializer::class,
5454
JsonSerializers.UpdateFailHtlcSerializer::class,
5555
JsonSerializers.UpdateFailMalformedHtlcSerializer::class,
@@ -98,7 +98,7 @@
9898
JsonSerializers.Bolt11UnknownTagSerializer::class,
9999
JsonSerializers.Bolt11InvalidTagSerializer::class,
100100
JsonSerializers.EncodedNodeIdSerializer::class,
101-
JsonSerializers.BlindedNodeSerializer::class,
101+
JsonSerializers.BlindedHopSerializer::class,
102102
JsonSerializers.BlindedRouteSerializer::class,
103103
)
104104
@file:UseContextualSerialization(
@@ -209,7 +209,7 @@ object JsonSerializers {
209209
subclass(CommitSigTlv.Batch::class, CommitSigTlvBatchSerializer)
210210
subclass(ShutdownTlv.ChannelData::class, ShutdownTlvChannelDataSerializer)
211211
subclass(ClosingSignedTlv.FeeRange::class, ClosingSignedTlvFeeRangeSerializer)
212-
subclass(UpdateAddHtlcTlv.Blinding::class, UpdateAddHtlcTlvBlindingSerializer)
212+
subclass(UpdateAddHtlcTlv.PathKey::class, UpdateAddHtlcTlvPathKeySerializer)
213213
}
214214
// TODO The following declarations are required because serializers for [TransactionWithInputInfo]
215215
// depend themselves on @Contextual serializers. Once we get rid of v2/v3 serialization and we
@@ -476,8 +476,8 @@ object JsonSerializers {
476476
@Serializer(forClass = EncryptedChannelData::class)
477477
object EncryptedChannelDataSerializer
478478

479-
@Serializer(forClass = UpdateAddHtlcTlv.Blinding::class)
480-
object UpdateAddHtlcTlvBlindingSerializer
479+
@Serializer(forClass = UpdateAddHtlcTlv.PathKey::class)
480+
object UpdateAddHtlcTlvPathKeySerializer
481481

482482
@Serializer(forClass = UpdateAddHtlcTlv::class)
483483
object UpdateAddHtlcTlvSerializer
@@ -649,8 +649,8 @@ object JsonSerializers {
649649
delegateSerializer = EncodedNodeIdSurrogate.serializer()
650650
)
651651

652-
@Serializer(forClass = RouteBlinding.BlindedNode::class)
653-
object BlindedNodeSerializer
652+
@Serializer(forClass = RouteBlinding.BlindedHop::class)
653+
object BlindedHopSerializer
654654

655655
@Serializer(forClass = RouteBlinding.BlindedRoute::class)
656656
object BlindedRouteSerializer

0 commit comments

Comments
 (0)