Task: Main step of GOST 28147-89

C: static unsigned char const k8[16] = {	14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7 }; 
static unsigned char const k7[16] = {	15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10 };
static unsigned char const k6[16] = {	10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8 };
static unsigned char const k5[16] = {	 7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15 };
static unsigned char const k4[16] = {	 2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9 };
static unsigned char const k3[16] = {	12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11 };
static unsigned char const k2[16] = {	 4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1 };
static unsigned char const k1[16] = {	13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7 };

static unsigned char k87[256];
static unsigned char k65[256];
static unsigned char k43[256];
static unsigned char k21[256];

void
kboxinit(void)
{
	int i;
	for (i = 0; i < 256; i++) {
		k87[i] = k8[i >> 4] << 4 | k7[i & 15];
		k65[i] = k6[i >> 4] << 4 | k5[i & 15];
		k43[i] = k4[i >> 4] << 4 | k3[i & 15];
		k21[i] = k2[i >> 4] << 4 | k1[i & 15];
	}
}

static word32
f(word32 x)
{
	x = k87[x>>24 & 255] << 24 | k65[x>>16 & 255] << 16 |
	    k43[x>> 8 & 255] <<  8 | k21[x & 255];
	return x<<11 | x>>(32-11);
}




Go: 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)
}






var cbrf = sBox{
    {4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3},
    {14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9},
    {5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11},
    {7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3},
    {6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2},
    {4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14},
    {13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12},
    {1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12},
}

func u32(b []byte) uint32 {
    return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
}

func b4(u uint32, b []byte) {
    b[0] = byte(u)
    b[1] = byte(u >> 8)
    b[2] = byte(u >> 16)
    b[3] = byte(u >> 24)
}

func (g *gost) mainStep(input []byte, key []byte) {
    key32 := u32(key)
    input1 := u32(input[:4])
    input2 := u32(input[4:])
    b4(g.f(key32+input1)^input2, g.enc[:4])
    copy(g.enc[4:], input[:4])
}

func main() {
    input := []byte{0x21, 0x04, 0x3B, 0x04, 0x30, 0x04, 0x32, 0x04}
    key := []byte{0xF9, 0x04, 0xC1, 0xE2}

    g := newGost(&cbrf)
    g.mainStep(input, key)
    for _, b := range g.enc {
        fmt.Printf("[%02x]", b)
    }
    fmt.Println()
}