Skip to content

Commit 1e4209f

Browse files
guggeromatheusd
authored andcommitted
multi: hide long-term private key behind interface
To be able to eventually extract the private keys out of the node itself into a hardware wallet or HSM, we need to abstract the ECDH operation against the long-term key behind an interface.
1 parent 5b732fe commit 1e4209f

File tree

4 files changed

+13
-29
lines changed

4 files changed

+13
-29
lines changed

cmd/main.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,11 @@ func main() {
136136
}
137137

138138
privkey := secp256k1.PrivKeyFromBytes(binKey)
139+
privKeyECDH := &sphinx.PrivKeyECDH{PrivKey: privkey}
139140
replayLog := sphinx.NewMemoryReplayLog()
140-
s := sphinx.NewRouter(privkey, chaincfg.TestNet3Params(), replayLog)
141+
s := sphinx.NewRouter(
142+
privKeyECDH, chaincfg.TestNet3Params(), replayLog,
143+
)
141144

142145
replayLog.Start()
143146
defer replayLog.Stop()

crypto.go

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -228,29 +228,7 @@ func (r *Router) generateSharedSecret(dhKey *secp256k1.PublicKey) (Hash256, erro
228228
}
229229

230230
// Compute our shared secret.
231-
return generateSharedSecret(dhKey, r.onionKey)
232-
}
233-
234-
// generateSharedSecret generates the shared secret for a particular hop. The
235-
// shared secret is generated by taking the group element contained in the
236-
// mix-header, and performing an ECDH operation with the node's long term onion
237-
// key. We then take the _entire_ point generated by the ECDH operation,
238-
// serialize that using a compressed format, then feed the raw bytes through a
239-
// single SHA256 invocation. The resulting value is the shared secret.
240-
func generateSharedSecret(pub *secp256k1.PublicKey, priv *secp256k1.PrivateKey) (Hash256,
241-
error) {
242-
var modNScalar secp256k1.ModNScalar
243-
modNScalar.SetByteSlice(priv.ToECDSA().D.Bytes())
244-
245-
var point secp256k1.JacobianPoint
246-
pub.AsJacobian(&point)
247-
248-
var result secp256k1.JacobianPoint
249-
secp256k1.ScalarMultNonConst(&modNScalar, &point, &result)
250-
result.ToAffine()
251-
252-
s := secp256k1.NewPublicKey(&result.X, &result.Y)
253-
return sha256.Sum256(s.SerializeCompressed()), nil
231+
return r.onionKey.ECDH(dhKey)
254232
}
255233

256234
// onionEncrypt obfuscates the data with compliance with BOLT#4. As we use a

sphinx.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ func generateSharedSecrets(paymentPath []*secp256k1.PublicKey,
131131
// Within the loop each new triplet will be computed recursively based
132132
// off of the blinding factor of the last hop.
133133
lastEphemeralPubKey := sessionKey.PubKey()
134-
sharedSecret, err := generateSharedSecret(paymentPath[0], sessionKey)
134+
sessionKeyECDH := &PrivKeyECDH{PrivKey: sessionKey}
135+
sharedSecret, err := sessionKeyECDH.ECDH(paymentPath[0])
135136
if err != nil {
136137
return nil, err
137138
}
@@ -488,14 +489,14 @@ type Router struct {
488489
nodeID [AddressSize]byte
489490
nodeAddr *dcrutil.AddressPubKeyHash
490491

491-
onionKey *secp256k1.PrivateKey
492+
onionKey SingleKeyECDH
492493

493494
log ReplayLog
494495
}
495496

496497
// NewRouter creates a new instance of a Sphinx onion Router given the node's
497498
// currently advertised onion private key, and the target Bitcoin network.
498-
func NewRouter(nodeKey *secp256k1.PrivateKey, net dcrutil.AddressParams, log ReplayLog) *Router {
499+
func NewRouter(nodeKey SingleKeyECDH, net dcrutil.AddressParams, log ReplayLog) *Router {
499500
var nodeID [AddressSize]byte
500501
copy(nodeID[:], dcrutil.Hash160(nodeKey.PubKey().SerializeCompressed()))
501502

sphinx_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ func newTestRoute(numHops int) ([]*Router, *PaymentPath, *[]HopData, *OnionPacke
5252
}
5353

5454
nodes[i] = NewRouter(
55-
privKey, netParams, NewMemoryReplayLog(),
55+
&PrivKeyECDH{PrivKey: privKey}, netParams,
56+
NewMemoryReplayLog(),
5657
)
5758
}
5859

@@ -494,7 +495,8 @@ func newEOBRoute(numHops uint32,
494495
}
495496

496497
nodes[i] = NewRouter(
497-
privKey, netParams, NewMemoryReplayLog(),
498+
&PrivKeyECDH{PrivKey: privKey}, netParams,
499+
NewMemoryReplayLog(),
498500
)
499501
}
500502

0 commit comments

Comments
 (0)