@@ -521,20 +521,48 @@ func (r *Router) Stop() {
521521 r .log .Stop ()
522522}
523523
524+ // processOnionCfg is a set of config values that can be used to modify how an
525+ // onion is processed.
526+ type processOnionCfg struct {
527+ blindingPoint * btcec.PublicKey
528+ }
529+
530+ // ProcessOnionOpt defines the signature of a function option that can be used
531+ // to modify how an onion is processed.
532+ type ProcessOnionOpt func (cfg * processOnionCfg )
533+
534+ // WithBlindingPoint is a function option that can be used to set the blinding
535+ // point to be used when processing an onion.
536+ func WithBlindingPoint (point * btcec.PublicKey ) ProcessOnionOpt {
537+ return func (cfg * processOnionCfg ) {
538+ cfg .blindingPoint = point
539+ }
540+ }
541+
524542// ProcessOnionPacket processes an incoming onion packet which has been forward
525543// to the target Sphinx router. If the encoded ephemeral key isn't on the
526544// target Elliptic Curve, then the packet is rejected. Similarly, if the
527- // derived shared secret has been seen before the packet is rejected. Finally
528- // if the MAC doesn't check the packet is again rejected.
545+ // derived shared secret has been seen before the packet is rejected. If the
546+ // blinded point is specified, then it will be used along with the ephemeral key
547+ // in the onion packet to derive the shared secret. Finally, if the MAC doesn't
548+ // check the packet is again rejected.
529549//
530550// In the case of a successful packet processing, and ProcessedPacket struct is
531551// returned which houses the newly parsed packet, along with instructions on
532552// what to do next.
533- func (r * Router ) ProcessOnionPacket (onionPkt * OnionPacket ,
534- assocData []byte , incomingCltv uint32 ) (* ProcessedPacket , error ) {
553+ func (r * Router ) ProcessOnionPacket (onionPkt * OnionPacket , assocData []byte ,
554+ incomingCltv uint32 , opts ... ProcessOnionOpt ) (* ProcessedPacket ,
555+ error ) {
556+
557+ cfg := & processOnionCfg {}
558+ for _ , o := range opts {
559+ o (cfg )
560+ }
535561
536562 // Compute the shared secret for this onion packet.
537- sharedSecret , err := r .generateSharedSecret (onionPkt .EphemeralKey )
563+ sharedSecret , err := r .generateSharedSecret (
564+ onionPkt .EphemeralKey , cfg .blindingPoint ,
565+ )
538566 if err != nil {
539567 return nil , err
540568 }
@@ -546,7 +574,7 @@ func (r *Router) ProcessOnionPacket(onionPkt *OnionPacket,
546574 // Continue to optimistically process this packet, deferring replay
547575 // protection until the end to reduce the penalty of multiple IO
548576 // operations.
549- packet , err := processOnionPacket (onionPkt , & sharedSecret , assocData , r )
577+ packet , err := processOnionPacket (onionPkt , & sharedSecret , assocData )
550578 if err != nil {
551579 return nil , err
552580 }
@@ -564,16 +592,23 @@ func (r *Router) ProcessOnionPacket(onionPkt *OnionPacket,
564592//
565593// NOTE: This method does not do any sort of replay protection, and should only
566594// be used to reconstruct packets that were successfully processed previously.
567- func (r * Router ) ReconstructOnionPacket (onionPkt * OnionPacket ,
568- assocData []byte ) (* ProcessedPacket , error ) {
595+ func (r * Router ) ReconstructOnionPacket (onionPkt * OnionPacket , assocData []byte ,
596+ opts ... ProcessOnionOpt ) (* ProcessedPacket , error ) {
597+
598+ cfg := & processOnionCfg {}
599+ for _ , o := range opts {
600+ o (cfg )
601+ }
569602
570603 // Compute the shared secret for this onion packet.
571- sharedSecret , err := r .generateSharedSecret (onionPkt .EphemeralKey )
604+ sharedSecret , err := r .generateSharedSecret (
605+ onionPkt .EphemeralKey , cfg .blindingPoint ,
606+ )
572607 if err != nil {
573608 return nil , err
574609 }
575610
576- return processOnionPacket (onionPkt , & sharedSecret , assocData , r )
611+ return processOnionPacket (onionPkt , & sharedSecret , assocData )
577612}
578613
579614// unwrapPacket wraps a layer of the passed onion packet using the specified
@@ -640,8 +675,7 @@ func unwrapPacket(onionPkt *OnionPacket, sharedSecret *Hash256,
640675// packets. The processed packets returned from this method should only be used
641676// if the packet was not flagged as a replayed packet.
642677func processOnionPacket (onionPkt * OnionPacket , sharedSecret * Hash256 ,
643- assocData []byte ,
644- sharedSecretGen sharedSecretGenerator ) (* ProcessedPacket , error ) {
678+ assocData []byte ) (* ProcessedPacket , error ) {
645679
646680 // First, we'll unwrap an initial layer of the onion packet. Typically,
647681 // we'll only have a single layer to unwrap, However, if the sender has
@@ -721,18 +755,25 @@ func (r *Router) BeginTxn(id []byte, nels int) *Tx {
721755// ProcessOnionPacket processes an incoming onion packet which has been forward
722756// to the target Sphinx router. If the encoded ephemeral key isn't on the
723757// target Elliptic Curve, then the packet is rejected. Similarly, if the
724- // derived shared secret has been seen before the packet is rejected. Finally
725- // if the MAC doesn't check the packet is again rejected.
758+ // derived shared secret has been seen before the packet is rejected. If the
759+ // blinded point is specified, then it will be used along with the ephemeral key
760+ // in the onion packet to derive the shared secret. Finally, if the MAC doesn't
761+ // check the packet is again rejected.
726762//
727763// In the case of a successful packet processing, and ProcessedPacket struct is
728764// returned which houses the newly parsed packet, along with instructions on
729765// what to do next.
730766func (t * Tx ) ProcessOnionPacket (seqNum uint16 , onionPkt * OnionPacket ,
731- assocData []byte , incomingCltv uint32 ) error {
767+ assocData []byte , incomingCltv uint32 , opts ... ProcessOnionOpt ) error {
768+
769+ cfg := & processOnionCfg {}
770+ for _ , o := range opts {
771+ o (cfg )
772+ }
732773
733774 // Compute the shared secret for this onion packet.
734775 sharedSecret , err := t .router .generateSharedSecret (
735- onionPkt .EphemeralKey ,
776+ onionPkt .EphemeralKey , cfg . blindingPoint ,
736777 )
737778 if err != nil {
738779 return err
@@ -745,9 +786,7 @@ func (t *Tx) ProcessOnionPacket(seqNum uint16, onionPkt *OnionPacket,
745786 // Continue to optimistically process this packet, deferring replay
746787 // protection until the end to reduce the penalty of multiple IO
747788 // operations.
748- packet , err := processOnionPacket (
749- onionPkt , & sharedSecret , assocData , t .router ,
750- )
789+ packet , err := processOnionPacket (onionPkt , & sharedSecret , assocData )
751790 if err != nil {
752791 return err
753792 }
0 commit comments