package yu_tencent import ( yu_bytes "gogs.qqck.cn/s/tools/bytes" yu_rand "gogs.qqck.cn/s/tools/rand" ) type Tea struct { key [4]uint32 } func NewTea() (t *Tea) { t = &Tea{} return } func (t *Tea) SetKey(key [16]byte) *Tea { t.key[3] = uint32(key[15]) | uint32(key[14])<<8 | uint32(key[13])<<16 | uint32(key[12])<<24 t.key[2] = uint32(key[11]) | uint32(key[10])<<8 | uint32(key[9])<<16 | uint32(key[8])<<24 t.key[1] = uint32(key[7]) | uint32(key[6])<<8 | uint32(key[5])<<16 | uint32(key[4])<<24 t.key[0] = uint32(key[3]) | uint32(key[2])<<8 | uint32(key[1])<<16 | uint32(key[0])<<24 return t } func (t *Tea) SetKeyB(key []byte) *Tea { var j_key [16]byte copy(j_key[:], key) return t.SetKey(j_key) } func (t *Tea) GetKey() (key [16]byte) { key[0] = byte(t.key[0] >> 24) key[1] = byte(t.key[0] >> 16) key[2] = byte(t.key[0] >> 8) key[3] = byte(t.key[0]) key[4] = byte(t.key[1] >> 24) key[5] = byte(t.key[1] >> 16) key[6] = byte(t.key[1] >> 8) key[7] = byte(t.key[1]) key[8] = byte(t.key[2] >> 24) key[9] = byte(t.key[2] >> 16) key[10] = byte(t.key[2] >> 8) key[11] = byte(t.key[2]) key[12] = byte(t.key[3] >> 24) key[13] = byte(t.key[3] >> 16) key[14] = byte(t.key[3] >> 8) key[15] = byte(t.key[3]) return } func (t *Tea) GetKeyB() []byte { j_key := t.GetKey() return j_key[:] } func (t *Tea) rand() byte { return byte(yu_rand.Uint32()) } func (t *Tea) En(data []byte) []byte { j_fill := 0x0a - (len(data)+1)%8 // 计算头部填充字节数 j_encode := make([]byte, j_fill+len(data)+7) // 计算输出的密文长度 // 这里的操作把 j_fill 存到了 j_encode 的第一个字节里面 // 0xF8 后面三位是空的,正好留给 j_fill 因为 j_fill 是 0 到 7 的值,表示文本开始的字节位置 j_encode[0] = byte(j_fill-3) | (t.rand() & 0xf8) // 存储pad长度 // 这里用随机产生的数填充 j_encode[1] 到 j_encode[j_fill] 之间的内容 for j_i := 1; j_i < j_fill; j_i++ { j_encode[j_i] = t.rand() } copy(j_encode[j_fill:], data) var j_iv1, j_iv2, j_holder uint64 for j_i := 0; j_i < len(j_encode); j_i += 8 { j_holder = (uint64(j_encode[j_i+7]) | uint64(j_encode[j_i+6])<<8 | uint64(j_encode[j_i+5])<<16 | uint64(j_encode[j_i+4])<<24 | uint64(j_encode[j_i+3])<<32 | uint64(j_encode[j_i+2])<<40 | uint64(j_encode[j_i+1])<<48 | uint64(j_encode[j_i])<<56) ^ j_iv1 j_iv1 = t.encode(j_holder) j_iv1 ^= j_iv2 j_iv2 = j_holder j_encode[j_i] = byte(j_iv1 >> 56) j_encode[j_i+1] = byte(j_iv1 >> 48) j_encode[j_i+2] = byte(j_iv1 >> 40) j_encode[j_i+3] = byte(j_iv1 >> 32) j_encode[j_i+4] = byte(j_iv1 >> 24) j_encode[j_i+5] = byte(j_iv1 >> 16) j_encode[j_i+6] = byte(j_iv1 >> 8) j_encode[j_i+7] = byte(j_iv1) } return j_encode } //go:nosplit func (t *Tea) encode(n uint64) uint64 { v0, v1 := uint32(n>>32), uint32(n) v0 += (v1 + 0x9e3779b9) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 += (v0 + 0x9e3779b9) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 += (v1 + 0x3c6ef372) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 += (v0 + 0x3c6ef372) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 += (v1 + 0xdaa66d2b) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 += (v0 + 0xdaa66d2b) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 += (v1 + 0x78dde6e4) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 += (v0 + 0x78dde6e4) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 += (v1 + 0x1715609d) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 += (v0 + 0x1715609d) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 += (v1 + 0xb54cda56) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 += (v0 + 0xb54cda56) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 += (v1 + 0x5384540f) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 += (v0 + 0x5384540f) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 += (v1 + 0xf1bbcdc8) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 += (v0 + 0xf1bbcdc8) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 += (v1 + 0x8ff34781) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 += (v0 + 0x8ff34781) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 += (v1 + 0x2e2ac13a) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 += (v0 + 0x2e2ac13a) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 += (v1 + 0xcc623af3) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 += (v0 + 0xcc623af3) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 += (v1 + 0x6a99b4ac) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 += (v0 + 0x6a99b4ac) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 += (v1 + 0x08d12e65) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 += (v0 + 0x08d12e65) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 += (v1 + 0xa708a81e) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 += (v0 + 0xa708a81e) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 += (v1 + 0x454021d7) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 += (v0 + 0x454021d7) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 += (v1 + 0xe3779b90) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 += (v0 + 0xe3779b90) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) return uint64(v0)<<32 | uint64(v1) } func (t *Tea) De(data []byte) []byte { j_data_len := len(data) if j_data_len < 9 || j_data_len%8 != 0 { return nil } j_decode := make([]byte, j_data_len) var j_iv1, j_iv2, j_holder uint64 for j_i := 0; j_i < j_data_len; j_i += 8 { j_iv1 = uint64(data[j_i+7]) | uint64(data[j_i+6])<<8 | uint64(data[j_i+5])<<16 | uint64(data[j_i+4])<<24 | uint64(data[j_i+3])<<32 | uint64(data[j_i+2])<<40 | uint64(data[j_i+1])<<48 | uint64(data[j_i])<<56 j_iv2 = t.decode(j_iv2 ^ j_iv1) j_holder ^= j_iv2 j_decode[j_i] = byte(j_holder >> 56) j_decode[j_i+1] = byte(j_holder >> 48) j_decode[j_i+2] = byte(j_holder >> 40) j_decode[j_i+3] = byte(j_holder >> 32) j_decode[j_i+4] = byte(j_holder >> 24) j_decode[j_i+5] = byte(j_holder >> 16) j_decode[j_i+6] = byte(j_holder >> 8) j_decode[j_i+7] = byte(j_holder) j_holder = j_iv1 } j_iv2_bytes := make([]byte, 8) j_iv2_bytes[0] = byte(j_iv2 >> 56) j_iv2_bytes[1] = byte(j_iv2 >> 48) j_iv2_bytes[2] = byte(j_iv2 >> 40) j_iv2_bytes[3] = byte(j_iv2 >> 32) j_iv2_bytes[4] = byte(j_iv2 >> 24) j_iv2_bytes[5] = byte(j_iv2 >> 16) j_iv2_bytes[6] = byte(j_iv2 >> 8) j_iv2_bytes[7] = byte(j_iv2) if !yu_bytes.Equals(j_iv2_bytes[1:8], data[j_data_len-15:j_data_len-8]) { return nil } return j_decode[j_decode[0]&7+3 : j_data_len-7] } //go:nosplit func (t *Tea) decode(n uint64) uint64 { v0, v1 := uint32(n>>32), uint32(n) v1 -= (v0 + 0xe3779b90) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 -= (v1 + 0xe3779b90) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 -= (v0 + 0x454021d7) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 -= (v1 + 0x454021d7) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 -= (v0 + 0xa708a81e) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 -= (v1 + 0xa708a81e) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 -= (v0 + 0x08d12e65) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 -= (v1 + 0x08d12e65) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 -= (v0 + 0x6a99b4ac) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 -= (v1 + 0x6a99b4ac) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 -= (v0 + 0xcc623af3) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 -= (v1 + 0xcc623af3) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 -= (v0 + 0x2e2ac13a) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 -= (v1 + 0x2e2ac13a) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 -= (v0 + 0x8ff34781) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 -= (v1 + 0x8ff34781) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 -= (v0 + 0xf1bbcdc8) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 -= (v1 + 0xf1bbcdc8) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 -= (v0 + 0x5384540f) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 -= (v1 + 0x5384540f) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 -= (v0 + 0xb54cda56) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 -= (v1 + 0xb54cda56) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 -= (v0 + 0x1715609d) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 -= (v1 + 0x1715609d) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 -= (v0 + 0x78dde6e4) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 -= (v1 + 0x78dde6e4) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 -= (v0 + 0xdaa66d2b) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 -= (v1 + 0xdaa66d2b) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 -= (v0 + 0x3c6ef372) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 -= (v1 + 0x3c6ef372) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) v1 -= (v0 + 0x9e3779b9) ^ (v0<<4 + t.key[2]) ^ (v0>>5 + t.key[3]) v0 -= (v1 + 0x9e3779b9) ^ (v1<<4 + t.key[0]) ^ (v1>>5 + t.key[1]) return uint64(v0)<<32 | uint64(v1) }