Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "encoding/binary"
- "fmt"
- "strconv"
- )
- func crc32v(idx int) int {
- POLY := 0x04c11db7
- c := idx << 24 & 0xFFFFFFFF
- for i := 0; i < 8; i++ {
- if c&0x80000000 > 0 {
- c = c<<1 ^ POLY
- } else {
- c = c << 1 & 0xFFFFFFFF
- }
- }
- return c
- }
- func adler32(bs []byte) int {
- s1 := 4
- s2 := 0
- for _, x := range bs {
- s1 = (s1 + int(x)) % 65521
- s2 = (s2 + s1) % 65521
- }
- res := (s2 << 16) | s1
- return res
- }
- func prepareSubs(key []int) [][]int {
- table1 := make([]int, 256)
- for i := range table1 {
- table1[i] = i
- }
- s := 0
- for i := range table1 {
- s += table1[i]
- s += key[i%len(key)]
- s &= 0xFF
- table1[i] = table1[s]
- }
- table2 := make([]int, 256)
- for i, v := range table1 {
- table2[i] = v
- }
- s = 0
- for i := range table2 {
- if i > 0 {
- s = (table2[i] + s) & 0xFF
- table2[i] = table2[s]
- }
- }
- out := [][]int{table1, table2}
- return out
- }
- // Reverse a string
- func Reverse(s string) (result string) {
- for _, v := range s {
- result = string(v) + result
- }
- return
- }
- // Takes an int and width, converts to base 2,
- // then left pads it with a total of (width - len(base2_result)) zeros.
- // as a string, then reverses it and converts it back to an integer.
- // The resulting int is then assigned to "x" in the main Leviathan function
- // and has some bitwise operations performed on it.
- func rbit(x int, width int) int {
- x2 := strconv.FormatInt(int64(x), 2)
- orig := len(x2)
- for i := 0; i < width-orig; i++ {
- x2 = fmt.Sprintf("0%s", x2)
- }
- x3, _ := strconv.ParseInt(Reverse(x2), 2, 32)
- return int(x3)
- }
- // Leviathan
- func Leviathan(srcData []byte, timestamp uint64) string {
- ldsBytes := []byte{0x0D, 0xC0, 0xA0, 0xE1, 0xF0, 0x00, 0x2D, 0xE9, 0xE9, 0x00, 0x40, 0xE2, 0x00, 0x70, 0xA0, 0xE1, 0x01, 0x00, 0xA0, 0xE1, 0x02, 0x10, 0xA0, 0xE1, 0x03, 0x20, 0xA0, 0xE1, 0x78, 0x00, 0x9C, 0xE8}
- stackCrc := crc32v(0x63)
- inpbs := []byte{}
- for i := 0; i < 4; i++ {
- next := srcData[i*16 : i*16+4]
- for _, b := range next {
- inpbs = append(inpbs, b)
- }
- }
- // Append timestamp bytes to inpbs
- tsBytes := make([]byte, 4)
- binary.BigEndian.PutUint32(tsBytes, uint32(timestamp))
- for _, b := range tsBytes {
- inpbs = append(inpbs, b)
- }
- ldsChecksum := adler32(ldsBytes)
- crcbs := 0
- for i := 0; i < 4; i++ {
- crcbs = (crcbs << 4) + (ldsChecksum & 0xff)
- ldsChecksum >>= 8
- }
- crcbs = (crc32v(crcbs&0xFF) ^ crc32v((crcbs>>8)&0xFF))
- key := []int{
- crcbs & 0xFF,
- 0,
- (crcbs >> 8) & 0xFF,
- (stackCrc >> 8) & 0xFF,
- (crcbs >> 16) & 0xFF,
- (crcbs >> 24) & 0xFF,
- 0,
- stackCrc & 0xFF,
- }
- // Returns multi-dimensional int array
- sbox := prepareSubs(key)
- result := make([]int, len(inpbs)) // It prepends like 6 bytes before the return
- for r, i := range inpbs {
- result[r] = int(i)
- }
- for i := range result {
- result[i] ^= sbox[0][(sbox[1][i+1]<<1)&0xFF]
- }
- for i := range result {
- x := ((result[i] << 4) & 0xF0) | ((result[i] >> 4) & 0xF)
- x ^= result[(i+1)%len(result)]
- x = rbit(x, 8)
- x ^= 0xFF
- x ^= 0x14
- result[i] = x
- }
- pre := make([]int, len(result)+6)
- pre[0] = 0x03
- pre[1] = 0x6F
- pre[2] = key[7]
- pre[3] = key[3]
- pre[4] = 0
- pre[5] = 0
- for r, v := range result {
- pre[r+6] = v
- }
- str := ""
- for _, p := range pre {
- str = fmt.Sprintf("%s%02x", str, p)
- }
- fmt.Println("As []int: \t", pre)
- fmt.Printf("As hex:\t\t%02x\n", pre)
- fmt.Printf("As hex string:\t%v\n", str)
- return str
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement