package main

import "fmt"

type sBox [8][16]byte

type gost struct {
    k87, k65, k43, k21 [256]byte
    enc                []byte
}

func newGost(s *sBox) *gost {
    var g gost
    for i := range g.k87 {
        g.k87[i] = s[7][i>>4]<<4 | s[6][i&15]
        g.k65[i] = s[5][i>>4]<<4 | s[4][i&15]
        g.k43[i] = s[3][i>>4]<<4 | s[2][i&15]
        g.k21[i] = s[1][i>>4]<<4 | s[0][i&15]
    }
    g.enc = make([]byte, 8)
    return &g
}

func (g *gost) f(x uint32) uint32 {
    x = uint32(g.k87[x>>24&255])<<24 | uint32(g.k65[x>>16&255])<<16 |
        uint32(g.k43[x>>8&255])<<8 | uint32(g.k21[x&255])
    return x<<11 | x>>(32-11)
}