github.com/metacubex/mihomo@v1.18.5/transport/hysteria/obfs/xplus.go (about)

     1  package obfs
     2  
     3  import (
     4  	"crypto/sha256"
     5  
     6  	"github.com/zhangyunhao116/fastrand"
     7  )
     8  
     9  // [salt][obfuscated payload]
    10  
    11  const saltLen = 16
    12  
    13  type XPlusObfuscator struct {
    14  	Key []byte
    15  }
    16  
    17  func NewXPlusObfuscator(key []byte) *XPlusObfuscator {
    18  	return &XPlusObfuscator{
    19  		Key: key,
    20  	}
    21  }
    22  
    23  func (x *XPlusObfuscator) Deobfuscate(in []byte, out []byte) int {
    24  	pLen := len(in) - saltLen
    25  	if pLen <= 0 || len(out) < pLen {
    26  		// Invalid
    27  		return 0
    28  	}
    29  	key := sha256.Sum256(append(x.Key, in[:saltLen]...))
    30  	// Deobfuscate the payload
    31  	for i, c := range in[saltLen:] {
    32  		out[i] = c ^ key[i%sha256.Size]
    33  	}
    34  	return pLen
    35  }
    36  
    37  func (x *XPlusObfuscator) Obfuscate(in []byte, out []byte) int {
    38  	_, _ = fastrand.Read(out[:saltLen]) // salt
    39  	// Obfuscate the payload
    40  	key := sha256.Sum256(append(x.Key, out[:saltLen]...))
    41  	for i, c := range in {
    42  		out[i+saltLen] = c ^ key[i%sha256.Size]
    43  	}
    44  	return len(in) + saltLen
    45  }