mc root source folder cleanup

This commit is contained in:
adman
2026-06-27 13:54:54 +02:00
parent b2784574bd
commit 666f250b3e
480 changed files with 325 additions and 325 deletions
+40
View File
@@ -0,0 +1,40 @@
package crypto
import (
"crypto/sha1"
"encoding/hex"
"strings"
)
func twosComplement(p []byte) []byte {
carry := true
for i := len(p) - 1; i >= 0; i-- {
p[i] = byte(^p[i])
if carry {
carry = p[i] == 0xff
p[i]++
}
}
return p
}
// AuthDigest stolen from https://gist.github.com/toqueteos/5372776
func AuthDigest(elems ...[]byte) string {
h := sha1.New()
for _, elem := range elems {
h.Write(elem)
}
hash := h.Sum(nil)
negative := (hash[0] & 0x80) == 0x80
if negative {
hash = twosComplement(hash)
}
res := strings.TrimLeft(hex.EncodeToString(hash), "0")
if negative {
res = "-" + res
}
return res
}
+165
View File
@@ -0,0 +1,165 @@
package crypto
// https://github.com/Tnze/go-mc/blob/master/net/CFB8/cfb8.go
// Package CFB8 implements CFB8 block cipher mode of operation used by Minecraft protocol.
// MIT License
//
//Copyright (c) 2019 Tnze
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in all
//copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.
import (
"crypto/cipher"
"crypto/subtle"
"sync"
"unsafe"
)
type CFB8 struct {
c cipher.Block
blockSize int
ivPos int
iv []byte
de bool
mutex sync.Mutex
}
func NewCFB8Decrypt(c cipher.Block, iv []byte) *CFB8 {
return newCFB8(c, iv, true)
}
func NewCFB8Encrypt(c cipher.Block, iv []byte) *CFB8 {
return newCFB8(c, iv, false)
}
func newCFB8(c cipher.Block, iv []byte, de bool) *CFB8 {
cp := make([]byte, len(iv)*3)
copy(cp, iv)
return &CFB8{
c: c,
blockSize: c.BlockSize(),
iv: cp,
de: de,
}
}
func (cf *CFB8) XORKeyStream(dst, src []byte) {
cf.mutex.Lock()
defer cf.mutex.Unlock()
if len(src) == 0 {
return
}
if len(dst) < len(src) {
panic("cfb8: output smaller than input")
}
// If dst and src does not overlap in first block size,
// and the length of src is greater than 2*blockSize,
// we can use an optimized implementation.
if len(src) > cf.blockSize<<1 &&
(uintptr(unsafe.Pointer(&dst[0]))+uintptr(cf.blockSize) <= uintptr(unsafe.Pointer(&src[0])) ||
uintptr(unsafe.Pointer(&src[0]))+uintptr(len(src)) <= uintptr(unsafe.Pointer(&dst[0]))) {
// encrypt/decrypt first blockSize bytes
// After this, the IV will come to the same as
// the last blockSize of ciphertext, so
// we can reuse them without copy.
cf.xorKeyStream(dst, src[:cf.blockSize])
var ciphertext []byte
if cf.de {
ciphertext = src
} else {
ciphertext = dst
}
dst = dst[cf.blockSize:]
src = src[cf.blockSize:]
iv := cf.iv
_ = iv[0] // bounds check hint to compiler; see golang.org/issue/14808
var (
i int
val byte
)
dst = dst[:len(src)]
if cf.de && // and requires to be non-overlapping at all
uintptr(unsafe.Pointer(&dst[0])) <= uintptr(unsafe.Pointer(&src[len(src)-1])) &&
uintptr(unsafe.Pointer(&src[0])) <= uintptr(unsafe.Pointer(&dst[len(dst)-1])) {
for i = 0; i < len(src)-cf.blockSize; i += 1 {
cf.c.Encrypt(dst[i:], ciphertext[i:])
}
subtle.XORBytes(dst, src[:i], dst)
for ; i < len(src); i += 1 {
cf.c.Encrypt(iv, ciphertext[i:])
dst[i] = src[i] ^ iv[0]
}
} else {
_ = ciphertext[len(src)]
for i, val = range src {
cf.c.Encrypt(iv, ciphertext[i:])
dst[i] = val ^ iv[0]
}
// for-range does not increase i in the last loop,
// compared to the classic for clause
i += 1
}
// copy the current IV for next operation
copy(iv, ciphertext[i:i+cf.blockSize])
cf.ivPos = 0
return
}
cf.xorKeyStream(dst, src)
}
func (cf *CFB8) xorKeyStream(dst, src []byte) {
dst = dst[:len(src)] // remove bounds check in loop
for i, val := range src {
posPlusBlockSize := cf.ivPos + cf.blockSize
// fast mod; 2*blockSize must be a non-negative integer power of 2
tempPos := posPlusBlockSize & (cf.blockSize<<1 - 1)
// reuse space to store encrypted block
cf.c.Encrypt(cf.iv[tempPos:], cf.iv[cf.ivPos:])
// Only the first byte of the encrypted block is used
// for encryption/decryption, other bytes are ignored.
val ^= cf.iv[tempPos]
if cf.ivPos == cf.blockSize<<1 {
// bound reached; move to next round for next operation
// copy next block to the start of the ring buffer
copy(cf.iv, cf.iv[cf.ivPos+1:])
// insert the encrypted byte to the end of IV
if cf.de {
cf.iv[cf.blockSize-1] = src[i]
} else {
cf.iv[cf.blockSize-1] = val
}
cf.ivPos = 0
} else {
// insert the encrypted byte to the end of IV
if cf.de {
cf.iv[posPlusBlockSize] = src[i]
} else {
cf.iv[posPlusBlockSize] = val
}
// move to next block
cf.ivPos += 1
}
dst[i] = val
}
}
+26
View File
@@ -0,0 +1,26 @@
package crypto
import (
"crypto/md5"
"github.com/google/uuid"
)
// UUIDv3 Variation of google.uuid.NewHash
// We need this because we want a 14-byte namespace and Google forces 16
func UUIDv3(space []byte, data []byte) uuid.UUID {
h := md5.New()
h.Reset()
h.Write(space) //nolint:errcheck
h.Write(data) //nolint:errcheck
s := h.Sum(nil)
var u uuid.UUID
copy(u[:], s)
u[6] = (u[6] & 0x0f) | uint8((3&0xf)<<4) // Version 3
u[8] = (u[8] & 0x3f) | 0x80 // RFC 4122 variant
return u
}
func FromOfflinePlayer(displayName string) uuid.UUID {
return UUIDv3([]byte("OfflinePlayer:"), []byte(displayName))
}