github.com/xmplusdev/xmcore@v1.8.11-0.20240412132628-5518b55526af/proxy/vmess/encoding/auth.go (about)

     1  package encoding
     2  
     3  import (
     4  	"crypto/md5"
     5  	"encoding/binary"
     6  	"hash/fnv"
     7  
     8  	"github.com/xmplusdev/xmcore/common"
     9  	"github.com/xmplusdev/xmcore/common/crypto"
    10  	"golang.org/x/crypto/sha3"
    11  )
    12  
    13  // Authenticate authenticates a byte array using Fnv hash.
    14  func Authenticate(b []byte) uint32 {
    15  	fnv1hash := fnv.New32a()
    16  	common.Must2(fnv1hash.Write(b))
    17  	return fnv1hash.Sum32()
    18  }
    19  
    20  // [DEPRECATED 2023-06]
    21  type NoOpAuthenticator struct{}
    22  
    23  func (NoOpAuthenticator) NonceSize() int {
    24  	return 0
    25  }
    26  
    27  func (NoOpAuthenticator) Overhead() int {
    28  	return 0
    29  }
    30  
    31  // Seal implements AEAD.Seal().
    32  func (NoOpAuthenticator) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
    33  	return append(dst[:0], plaintext...)
    34  }
    35  
    36  // Open implements AEAD.Open().
    37  func (NoOpAuthenticator) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
    38  	return append(dst[:0], ciphertext...), nil
    39  }
    40  
    41  // GenerateChacha20Poly1305Key generates a 32-byte key from a given 16-byte array.
    42  func GenerateChacha20Poly1305Key(b []byte) []byte {
    43  	key := make([]byte, 32)
    44  	t := md5.Sum(b)
    45  	copy(key, t[:])
    46  	t = md5.Sum(key[:16])
    47  	copy(key[16:], t[:])
    48  	return key
    49  }
    50  
    51  type ShakeSizeParser struct {
    52  	shake  sha3.ShakeHash
    53  	buffer [2]byte
    54  }
    55  
    56  func NewShakeSizeParser(nonce []byte) *ShakeSizeParser {
    57  	shake := sha3.NewShake128()
    58  	common.Must2(shake.Write(nonce))
    59  	return &ShakeSizeParser{
    60  		shake: shake,
    61  	}
    62  }
    63  
    64  func (*ShakeSizeParser) SizeBytes() int32 {
    65  	return 2
    66  }
    67  
    68  func (s *ShakeSizeParser) next() uint16 {
    69  	common.Must2(s.shake.Read(s.buffer[:]))
    70  	return binary.BigEndian.Uint16(s.buffer[:])
    71  }
    72  
    73  func (s *ShakeSizeParser) Decode(b []byte) (uint16, error) {
    74  	mask := s.next()
    75  	size := binary.BigEndian.Uint16(b)
    76  	return mask ^ size, nil
    77  }
    78  
    79  func (s *ShakeSizeParser) Encode(size uint16, b []byte) []byte {
    80  	mask := s.next()
    81  	binary.BigEndian.PutUint16(b, mask^size)
    82  	return b[:2]
    83  }
    84  
    85  func (s *ShakeSizeParser) NextPaddingLen() uint16 {
    86  	return s.next() % 64
    87  }
    88  
    89  func (s *ShakeSizeParser) MaxPaddingLen() uint16 {
    90  	return 64
    91  }
    92  
    93  type AEADSizeParser struct {
    94  	crypto.AEADChunkSizeParser
    95  }
    96  
    97  func NewAEADSizeParser(auth *crypto.AEADAuthenticator) *AEADSizeParser {
    98  	return &AEADSizeParser{crypto.AEADChunkSizeParser{Auth: auth}}
    99  }