package algos import ( "crypto/md5" "crypto/rand" "encoding/base64" "encoding/binary" "encoding/hex" "fmt" ) // validate 验证并限制在64位范围内 func validate(num uint64) uint64 { return num & 0xFFFFFFFFFFFFFFFF } // ror 右循环移位 func ror(value uint64, count int) uint64 { nbits := 64 count %= nbits low := (value << (nbits - count)) value = (value >> count) value = value | low return value } // encryptLadonInput 加密Ladon输入 func encryptLadonInput(hashTable []byte, inputData []byte) []byte { data0 := binary.LittleEndian.Uint64(inputData[:8]) data1 := binary.LittleEndian.Uint64(inputData[8:]) for i := 0; i < 0x22; i++ { hash := binary.LittleEndian.Uint64(hashTable[i*8 : (i+1)*8]) data1 = validate(hash ^ (data0 + ((data1 >> 8) | (data1 << (64 - 8))))) data0 = validate(data1 ^ ((data0 >> 0x3D) | (data0 << (64 - 0x3D)))) } outputData := make([]byte, 26) binary.LittleEndian.PutUint64(outputData[:8], data0) binary.LittleEndian.PutUint64(outputData[8:], data1) return outputData } // encryptLadon 加密Ladon func encryptLadon(md5Hex []byte, data []byte, size int) []byte { hashTable := make([]byte, 272+16) copy(hashTable[:32], md5Hex) temp := make([]uint64, 0) for i := 0; i < 4; i++ { temp = append(temp, binary.LittleEndian.Uint64(hashTable[i*8:(i+1)*8])) } bufferB0 := temp[0] bufferB8 := temp[1] temp = temp[2:] for i := 0; i < 0x22; i++ { x9 := bufferB0 x8 := bufferB8 x8 = validate(ror(x8, 8)) x8 = validate(x8 + x9) x8 = validate(x8 ^ uint64(i)) temp = append(temp, x8) x8 = validate(x8 ^ ror(x9, 61)) binary.LittleEndian.PutUint64(hashTable[(i+1)*8:], x8) bufferB0 = x8 bufferB8 = temp[0] temp = temp[1:] } newSize := PaddingSize(size) input := make([]byte, newSize) copy(input[:size], data) PKCS7PadBuffer(input, size, newSize, 16) output := make([]byte, newSize) for i := 0; i < newSize/16; i++ { result := encryptLadonInput(hashTable, input[i*16:(i+1)*16]) copy(output[i*16:(i+1)*16], result) } return output } // LadonEncrypt Ladon加密主函数 func LadonEncrypt(khronos int64, lcID int, aid int, randomBytes []byte) string { data := fmt.Sprintf("%d-%d-%d", khronos, lcID, aid) if randomBytes == nil { randomBytes = make([]byte, 4) rand.Read(randomBytes) } keygen := append(randomBytes, []byte(fmt.Sprintf("%d", aid))...) hasher := md5.New() hasher.Write(keygen) md5Hex := hex.EncodeToString(hasher.Sum(nil)) size := len(data) newSize := PaddingSize(size) output := make([]byte, newSize+4) copy(output[:4], randomBytes) encrypted := encryptLadon([]byte(md5Hex), []byte(data), size) copy(output[4:], encrypted) return base64.StdEncoding.EncodeToString(output) } // Ladon Ladon加密器 type Ladon struct{} // Encrypt Ladon加密 func (l *Ladon) Encrypt(xKhronos int64, lcID int, aid int) string { return LadonEncrypt(xKhronos, lcID, aid, nil) }