Skip to content

Commit

Permalink
sphinx: rename obfuscation.go to onion_error.go
Browse files Browse the repository at this point in the history
  • Loading branch information
Roasbeef committed Apr 26, 2019
1 parent 76f6b1e commit c8b47d7
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 15 deletions.
14 changes: 14 additions & 0 deletions crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,17 @@ func generateSharedSecret(pub *btcec.PublicKey, priv *btcec.PrivateKey) Hash256

return sha256.Sum256(s.SerializeCompressed())
}

// onionEncrypt obfuscates the data with compliance with BOLT#4. As we use a
// stream cipher, calling onionEncrypt on an already encrypted piece of data
// will decrypt it.
func onionEncrypt(sharedSecret *Hash256, data []byte) []byte {

p := make([]byte, len(data))

ammagKey := generateKey("ammag", sharedSecret)
streamBytes := generateCipherStream(ammagKey, uint(len(data)))
xor(p, data, streamBytes)

return p
}
26 changes: 12 additions & 14 deletions obfuscation.go → onion_error.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,12 @@ import (
"crypto/hmac"
"crypto/sha256"
"errors"
"fmt"
"io"

"github.com/btcsuite/btcd/btcec"
)

// onionEncrypt obfuscates the data with compliance with BOLT#4. As we use a
// stream cipher, calling onionEncrypt on an already encrypted piece of data
// will decrypt it.
func onionEncrypt(sharedSecret *Hash256, data []byte) []byte {

p := make([]byte, len(data))

ammagKey := generateKey("ammag", sharedSecret)
streamBytes := generateCipherStream(ammagKey, uint(len(data)))
xor(p, data, streamBytes)

return p
}

// OnionErrorEncrypter is a struct that's used to implement onion error
// encryption as defined within BOLT0004.
type OnionErrorEncrypter struct {
Expand Down Expand Up @@ -166,11 +153,22 @@ func NewOnionErrorDecrypter(circuit *Circuit) *OnionErrorDecrypter {
}
}

// onionErrorLength is the expected length of the onion error message.
// Including padding, all messages on the wire should be 256 bytes. We then add
// the size of the sha256 HMAC as well.
const onionErrorLength = 2 + 2 + 256 + sha256.Size

// DecryptError attempts to decrypt the passed encrypted error response. The
// onion failure is encrypted in backward manner, starting from the node where
// error have occurred. As a result, in order to decrypt the error we need get
// all shared secret and apply decryption in the reverse order.
func (o *OnionErrorDecrypter) DecryptError(encryptedData []byte) (*btcec.PublicKey, []byte, error) {
// Ensure the error message length is as expected.
if len(encryptedData) != onionErrorLength {
return nil, nil, fmt.Errorf("invalid error length: "+
"expected %v got %v", onionErrorLength,
len(encryptedData))
}

sharedSecrets := generateSharedSecrets(
o.circuit.PaymentPath,
Expand Down
3 changes: 2 additions & 1 deletion obfuscation_test.go → onion_error_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sphinx

import (
"bytes"
"crypto/sha256"
"encoding/hex"
"reflect"
"testing"
Expand All @@ -28,7 +29,7 @@ func TestOnionFailure(t *testing.T) {
// able to receive the error not only from last hop.
errorPath := paymentPath[:len(paymentPath)-1]

failureData := []byte("some kek-error data")
failureData := bytes.Repeat([]byte{'A'}, onionErrorLength-sha256.Size)
sharedSecrets := generateSharedSecrets(paymentPath, sessionKey)

// Emulate creation of the obfuscator on node where error have occurred.
Expand Down

0 comments on commit c8b47d7

Please sign in to comment.