Main step of GOST 28147-89: Difference between revisions

m
m (missing r32() call)
 
(24 intermediate revisions by 12 users not shown)
Line 1:
{{task|Encryption}}
 
[[wphttps:GOST (block//tools.ietf.org/html/rfc5830 cipher)|GOST 28147-89]] is a standard symmetric encryption based on a [[wphttp:Feistel//cryptowiki.net/index.php?title=Generalized_Feistel_networks cipher|Feistel network]].
 
 
Line 16:
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> DIM table&(7,15), test%(1)
table&() = 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, \
Line 46:
WHILE v>&7FFFFFFF : v-=2^32 : ENDWHILE
WHILE v<&80000000 : v+=2^32 : ENDWHILE
= v</langsyntaxhighlight>
'''Output:'''
<pre>
Line 55:
Version with packed replacement table.
 
<langsyntaxhighlight Clang="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 };
Line 87:
k43[x>> 8 & 255] << 8 | k21[x & 255];
return x<<11 | x>>(32-11);
}</langsyntaxhighlight>
 
=={{header|C#}}==
{{trans|Go}}
<syntaxhighlight lang="C#">
using System;
 
class Gost
{
private byte[,] sBox = new byte[8, 16];
private byte[] k87 = new byte[256];
private byte[] k65 = new byte[256];
private byte[] k43 = new byte[256];
private byte[] k21 = new byte[256];
private byte[] enc = new byte[8];
 
public Gost(byte[,] s)
{
sBox = s;
for (int i = 0; i < 256; i++)
{
k87[i] = (byte)((sBox[7, i >> 4] << 4) | sBox[6, i & 15]);
k65[i] = (byte)((sBox[5, i >> 4] << 4) | sBox[4, i & 15]);
k43[i] = (byte)((sBox[3, i >> 4] << 4) | sBox[2, i & 15]);
k21[i] = (byte)((sBox[1, i >> 4] << 4) | sBox[0, i & 15]);
}
}
 
private uint F(uint x)
{
x = (uint)(k87[x >> 24 & 255] << 24) | (uint)(k65[x >> 16 & 255] << 16) |
(uint)(k43[x >> 8 & 255] << 8) | (uint)(k21[x & 255]);
return x << 11 | x >> (32 - 11);
}
 
private static uint U32(byte[] b)
{
return (uint)(b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24);
}
 
private static void B4(uint u, byte[] b)
{
b[0] = (byte)u;
b[1] = (byte)(u >> 8);
b[2] = (byte)(u >> 16);
b[3] = (byte)(u >> 24);
}
 
public void MainStep(byte[] input, byte[] key)
{
uint key32 = U32(key);
uint input1 = U32(input, 0);
uint input2 = U32(input, 4);
B4(F(key32 + input1) ^ input2, enc, 0);
Array.Copy(input, 0, enc, 4, 4);
}
 
public byte[] Enc => enc;
 
private static uint U32(byte[] b, int index)
{
return (uint)(b[index] | b[index + 1] << 8 | b[index + 2] << 16 | b[index + 3] << 24);
}
 
private static void B4(uint u, byte[] b, int index)
{
b[index] = (byte)u;
b[index + 1] = (byte)(u >> 8);
b[index + 2] = (byte)(u >> 16);
b[index + 3] = (byte)(u >> 24);
}
}
 
class Program
{
static void Main(string[] args)
{
byte[,] cbrf = {
{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},
};
 
byte[] input = { 0x21, 0x04, 0x3B, 0x04, 0x30, 0x04, 0x32, 0x04 };
byte[] key = { 0xF9, 0x04, 0xC1, 0xE2 };
 
Gost g = new Gost(cbrf);
g.MainStep(input, key);
 
foreach (var b in g.Enc)
{
Console.Write("[{0:x2}]", b);
}
Console.WriteLine();
}
}
</syntaxhighlight>
{{out}}
<pre>
[1f][88][cf][07][21][04][3b][04]
 
</pre>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">UINT_64 TGost::SWAP32(UINT_32 N1, UINT_32 N2)
{
UINT_64 N;
Line 123 ⟶ 229:
N1 = S;
return SWAP32(N2,N1);
}</langsyntaxhighlight>
 
Variable "BS" is the replacement table.
Line 130 ⟶ 236:
{{trans|C}}
{{trans|Go}}
<langsyntaxhighlight lang="d">import std.stdio, std.range, std.algorithm;
 
/// Rotate uint left.
Line 200 ⟶ 306:
g.mainStep(input, key);
writefln("%(%08X %)", g.buffer);
}</langsyntaxhighlight>
{{out}}
<pre>07CF881F 043B0421</pre>
 
=={{header|JavaScriptFreeBASIC}}==
{{trans|Python}}
<lang JavaScript>var Таблица_замен = [
<syntaxhighlight lang="freebasic">Dim Shared As Ubyte k87(255), k65(255), k43(255), k21(255)
[ 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]];
 
Sub kboxinit()
function ОсновнойШаг(блок_текста, элемент_ключа) {
Dim As Ubyte k8(15) = {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}
var N = блок_текста.slice(0);
Dim As Ubyte k7(15) = {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}
var X = элемент_ключа;
Dim As Ubyte k6(15) = {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}
var S = (N[0] + X) & 0xFFFFFFFF;
Dim As Ubyte k5(15) = { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}
var ячейка; var нов_S = 0;
Dim As Ubyte k4(15) = { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}
for (var сч = 0; сч < 4; сч++) {
Dim As Ubyte k3(15) = {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}
ячейка = (S >>> (сч << 3)) & 0xFF;
Dim As Ubyte k2(15) = { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}
нов_S += (Таблица_замен[сч*2][ячейка & 0x0F] + (Таблица_замен[сч*2+1][ячейка >>> 4] << 4)) << (сч << 3);
Dim As Ubyte k1(15) = {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}
}
S = (((нов_S << 11) + (нов_S >>> 21)) & 0xFFFFFFFF) ^ N[1];
N[1] = N[0];For N[0]i As Uinteger = S;0 To 255
k87(i) = k8(i Shr 4) Shl 4 Or k7(i And 15)
return N;
k65(i) = k6(i Shr 4) Shl 4 Or k5(i And 15)
}</lang>
k43(i) = k4(i Shr 4) Shl 4 Or k3(i And 15)
k21(i) = k2(i Shr 4) Shl 4 Or k1(i And 15)
Next i
End Sub
 
Function f(x As Integer) As Integer
x = k87(x Shr 24 And 255) Shl 24 Or k65(x Shr 16 And 255) Shl 16 Or _
k43(x Shr 8 And 255) Shl 8 Or k21(x And 255)
Return x Shl 11 Or x Shr (32-11)
End Function</syntaxhighlight>
 
Note: the variable "блок_текста" is an array of two 32-bit values that make up the block.
 
=={{header|Glagol}}==
Line 292 ⟶ 400:
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 366 ⟶ 474:
}
fmt.Println()
}</langsyntaxhighlight>
{{out}}
<pre>
[1f][88][cf][07][21][04][3b][04]
</pre>
 
=={{header|Java}}==
<syntaxhighlight lang="java">
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.function.IntUnaryOperator;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
 
/**
* Encrypt and decrypt messages in unicode characters using the GOST 28147-89 (Magma) algorithm.
*
* For further information visit https://en.wikipedia.org/wiki/GOST_(block_cipher)
*/
public final class MainStepGOST28147_89 {
 
public static void main(String[] aArgs) {
// Initialisation
String plainText = "The spy 我 lives in Iž";
GOST28147_89 gost = new GOST28147_89(plainText);
// Display the plain text and the plain text bytes
System.out.println("The plain text is: \"" + plainText + "\"" + System.lineSeparator());
String plainTextBinary = gost.getPlainTextBinary();
displayBytesFromBinary("The plain text bytes are: ", plainTextBinary);
// Encryption
String encryptedBinary = gost.gostAlgorithm(plainTextBinary, Cryptation.ENCRYPT);
// Display the encrypted text bytes and the encrypted text
List<Character> encryptedChars = displayBytesFromBinary("The encrypted text bytes are: ", encryptedBinary);
String encryptedText = encryptedChars.stream().map(String::valueOf).collect(Collectors.joining());
System.out.println("The encrypted text is: \"" + encryptedText + "\"" + System.lineSeparator());
// Decryption
String decryptedBinary = gost.gostAlgorithm(encryptedBinary, Cryptation.DECRYPT);
// Display the decrypted text bytes and the decrypted text
List<Character> decryptedChars = displayBytesFromBinary("The decrypted text bytes are: ", decryptedBinary);
byte[] bytes = new byte[decryptedChars.size()];
IntStream.range(0, decryptedChars.size()).forEach( i -> bytes[i] = (byte) decryptedChars.get(i).charValue() );
System.out.println("The decrypted text is: \"" + new String(bytes) + "\"" + System.lineSeparator());
}
/**
* Display the given tile string together with a list of bytes obtained from the given binary string.
* Return a list of characters obtained from the given binary string.
*/
private static List<Character> displayBytesFromBinary(String aTitle, String aBinaryBlock) {
List<Character> chars = new ArrayList<Character>();
List<String> bytes = new ArrayList<String>();
for ( int i = 0; i < aBinaryBlock.length(); i += 8 ) {
char ch = (char) Integer.parseInt(aBinaryBlock.substring(i, i + 8), 2);
chars.add(ch);
bytes.add(String.format("%2s", Integer.toHexString(ch)).replace(" ", "0"));
}
System.out.println(aTitle);
for ( int i = 0; i < bytes.size(); i += 8 ) {
System.out.print(bytes.subList(i, i + 8));
}
System.out.println(System.lineSeparator());
return chars;
}
}
 
enum Cryptation { ENCRYPT, DECRYPT }
 
final class GOST28147_89 {
public GOST28147_89(String aPlainText) {
createSbox();
createKeys();
plainTextBinary = convertCharactersToBinary(aPlainText, StandardCharsets.UTF_8);
}
/**
* Encrypt or decrypt the given binary string according to the value of the given enum,
* using the GOST 28147-89 (Magma) algorithm.
*/
public String gostAlgorithm(String aBinaryBlock, Cryptation aCryptation) {
StringBuilder stringBuilder = new StringBuilder();
for ( int i = 0; i < aBinaryBlock.length(); i += 64 ) {
String one = reverse(aBinaryBlock.substring(i, i + 32));
String two = reverse(aBinaryBlock.substring(i + 32, i + 64));
List<String> pair;
switch ( aCryptation ) {
case ENCRYPT -> { pair = mainStep(one, two, 24, k -> k % 8);
pair = mainStep(pair.get(0), pair.get(1), 8, k -> 7 - k);
stringBuilder.append(reverse(pair.get(0)));
stringBuilder.append(reverse(pair.get(1)));
}
case DECRYPT -> { pair = mainStep(two, one, 8, k -> k);
pair = mainStep(pair.get(0), pair.get(1), 24, k -> 7 - k % 8);
stringBuilder.append(reverse(pair.get(1)));
stringBuilder.append(reverse(pair.get(0)));
}
};
}
return stringBuilder.toString();
}
public String getPlainTextBinary() {
return plainTextBinary;
}
// PRIVATE //
 
/**
* Perform the main step of the GOST 28147-89 (Magma) algorithm.
*/
private List<String> mainStep(String aLeft, String aRight, int aIterations, IntUnaryOperator aOperator) {
for ( int i = 0; i < aIterations; i++ ) {
long sum = Long.parseLong(aRight, 2) + Integer.parseInt(keys.get(aOperator.applyAsInt(i)), 2);
sum %= Math.pow(2, 32);
String newSum = String.format("%32s", Long.toBinaryString(sum)).replace(" ", "0");
newSum = shiftLeft(sBoxFunction(newSum));
String temp = aLeft;
aLeft = aRight;
long xor = Long.parseLong(newSum, 2) ^ Long.parseLong(temp, 2);
aRight = String.format("%32s", Long.toBinaryString(xor)).replace(" ", "0");
}
return List.of(aLeft, aRight);
}
/**
* Convert each byte in the given string to its ASCII code value as a binary number,
* and concatenate these binary numbers into a single string.
* Pad the resulting string so that its length is a multiple of 8 bytes which is 64 bits.
*/
private String convertCharactersToBinary(String aBytes, Charset aCharset) {
StringBuilder stringBuilder = new StringBuilder();
for ( byte bbyte : aBytes.getBytes(aCharset) ) {
String binary = String.format("%8s", Integer.toBinaryString(bbyte & 0xff)).replace(" ", "0");
stringBuilder.append(binary);
}
String binaryBlock = stringBuilder.toString();
while ( binaryBlock.length() % 64 > 0 ) {
binaryBlock += "00100000"; // The ASCII code for the space character as a binary number.
}
return binaryBlock;
}
/**
* Left shift the given string by 11 bits.
*/
private String shiftLeft(String aBinaryBlock) {
return aBinaryBlock.substring(11) + aBinaryBlock.substring(0, 11);
}
/**
* Return the reverse of the given string.
*/
private String reverse(String aText) {
return new StringBuilder(aText).reverse().toString();
}
/**
* Convert the 32 character KEY_TEXT into a 256 bit binary string.
* Then convert this string into 8 keys each consisting of a 32 bit string.
*/
private void createKeys() {
if ( KEY_TEXT.length() != 32 ) {
throw new AssertionError("The KEY_TEXT must contain exactly 32 characters");
}
String binaryKey = convertCharactersToBinary(KEY_TEXT, StandardCharsets.UTF_8);
keys = new ArrayList<String>();
for ( int i = 0; i < 256; i += 32 ) {
keys.add( new String(binaryKey.substring(i, i + 32)) );
}
}
/**
* Split the given 32 bit string into 8 parts,
* and replace each part with its respective hexadecimal number from the sBox.
*/
private String sBoxFunction(String aBinaryBlock) {
StringBuilder result = new StringBuilder();
for ( int i = 0; i < 32; i += 4 ) {
int number = Integer.parseInt(aBinaryBlock.substring(i, i + 4), 2);
int boxNumber = Integer.parseInt(sBox.get(i / 4).substring(number, number + 1), 16);
String binary = Integer.toBinaryString(boxNumber).replace(" ", "0");
result.append(binary);
}
return result.toString();
}
/**
* Create a list of strings of hexadecimal digits.
*/
private void createSbox() {
sBox = List.of(
"4A92D80E6B1C7F53",
"EB4C6DFA23810759",
"581DA342EFC7609B",
"7DA1089FE46CB253",
"6C715FD84A9E03B2",
"4BA0721D36859CFE",
"DB413F590AE7682C",
"1FD057A4923E6B8C");
}
private List<String> sBox;
private List<String> keys;
private String plainTextBinary;
// The KEY_TEXT must contain exactly 32 characters.
private final String KEY_TEXT = "Kriptografi Metode GOST, Andysah";
}
</syntaxhighlight>
{{ out }}
<pre>
The plain text is: "The spy 我 lives in Iž"
 
The plain text bytes are:
[54, 68, 65, 20, 73, 70, 79, 20][e6, 88, 91, 20, 6c, 69, 76, 65][73, 20, 69, 6e, 20, 49, c5, be]
 
The encrypted text bytes are:
[aa, 67, e0, 72, 66, 3a, 97, 42][7b, 9f, e6, 88, f3, d0, 70, 25][27, 3f, 2c, 40, 43, 59, e0, 9e]
 
The encrypted text is: "ªgàrf:—B{ŸæˆóÐp%'?,@CYàž"
 
The decrypted text bytes are:
[54, 68, 65, 20, 73, 70, 79, 20][e6, 88, 91, 20, 6c, 69, 76, 65][73, 20, 69, 6e, 20, 49, c5, be]
 
The decrypted text is: "The spy 我 lives in Iž"
</pre>
 
=={{header|JavaScript}}==
<syntaxhighlight lang="javascript">
const Таблица_замен = [
[ 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]
];
 
const Основной_шаг = (блок_текста, элемент_ключа, ТЗ) => {
const
N = блок_текста.slice(0),
S = N[0] + элемент_ключа & 0xFFFFFFFF;
let нов_S = 0;
for (let сч = 0; сч < 4; сч++) {
const яч = (S >>> (сч << 3)) & 0xFF;
нов_S += ТЗ[сч * 2][яч & 0x0F] + (ТЗ[сч * 2 + 1][яч >>> 4] << 4) << (сч << 3);
}
нов_S = (нов_S << 11) + (нов_S >>> 21) & 0xFFFFFFFF ^ N[1];
N[1] = N[0]; N[0] = нов_S;
return N;
};
</syntaxhighlight>
 
Note: the variable "блок_текста" is an array of two 32-bit values that make up the block.
 
=={{header|Julia}}==
{{trans|Kotlin}}
<langsyntaxhighlight lang="julia">
const k8 = [ 4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3]
const k7 = [14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9]
Line 402 ⟶ 780:
end
 
bytes2int(arr) = arr[1] + reinterpret(UInt32(arr[2]), << 8) + (UInt32(arr[3]) << 16) + (UInt32(arr[4begin])) << 24
int2bytes(x) = [UInt8reinterpret(x&0xff), UInt8((x&0xff00)>>8), UInt8(([x&0xff0000])>>16), UInt8(x>>24)]
 
function mainstep(inputbytes, keybytes)
Line 416 ⟶ 794:
const key = [0xF9, 0x04, 0xC1, 0xE2]
println("The encoded bytes are $(mainstep(input, key))")
</syntaxhighlight>
</lang>
{{output}}<pre>
The encoded bytes are UInt8[0x1f, 0x88, 0xcf, 0x07, 0x21, 0x04, 0x3b, 0x04]</pre>
Line 422 ⟶ 800:
=={{header|Kotlin}}==
{{trans|Go}}
<langsyntaxhighlight lang="scala">// version 1.1.4-3
 
fun Byte.toUInt() = java.lang.Byte.toUnsignedInt(this)
Line 498 ⟶ 876:
for (b in g.enc) print("[%02X]".format(b))
println()
}</langsyntaxhighlight>
 
{{out}}
Line 509 ⟶ 887:
 
Code for the first module:
<syntaxhighlight lang="text">ИП6 С/П + П6 ИП7 С/П + П7 ИПE -
x>=0 14 П7 КИП6 ИП6 ИПE - x>=0 20 П6
8 П2 П3 2 П1 4 П0 0 П8 1
Line 519 ⟶ 897:
П5 ИП4 ИП6 П4 <-> П6 ИП5 ИП7 П5 <->
П7 БП 00 ИПC / [x] КП0 Вx {x} ИПC
* ИПD * В/О</langsyntaxhighlight>
 
Code for the second module:
<syntaxhighlight lang="text">П1 <-> П2 Сx П3 1 П4 19 П0 ИП1
2 / [x] П1 Вx {x} ИП2 2 / [x]
П2 Вx {x} <-> -> - x#0 33 ИП4 ИП3
+ П3 ИП4 ^ + П4 L0 10 ИП3 С/П
БП 00</langsyntaxhighlight>
 
<u>Instruction</u>:
Line 539 ⟶ 917:
 
=={{header|Nim}}==
Algorithm inspired from C, Go, etc.
{{trans|C}}
The Sboxes are computed at compile time.
<lang nim>var
<syntaxhighlight lang="nim">import sequtils, strutils
k8 = [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7]
k7 = [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10]
k6 = [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8]
k5 = [ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15]
k4 = [ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9]
k3 = [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11]
k2 = [ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1]
k1 = [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7]
 
const
k87, k65, k43, k21 = newSeq[int64](256)
K1 = [byte 4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3]
K2 = [byte 14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9]
K3 = [byte 5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11]
K4 = [byte 7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3]
K5 = [byte 6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2]
K6 = [byte 4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14]
K7 = [byte 13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12]
K8 = [byte 1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12]
 
 
proc kboxInit =
proc kboxInit: tuple[k87, k65, k43, k21: array[256, byte]] {.compileTime.} =
for i in 0 .. 255:
result.k87[i] = k8K8[i shr 4] shl 4 or k7K7[i and 15]
result.k65[i] = k6K6[i shr 4] shl 4 or k5K5[i and 15]
result.k43[i] = k4K4[i shr 4] shl 4 or k3K3[i and 15]
result.k21[i] = k2K2[i shr 4] shl 4 or k1K1[i and 15]
 
const (K87, K65, K43, K21) = kboxInit()
proc f(x): int64 =
 
let x = k87[x shr 24 and 255] shl 24 or k65[x shr 16 and 255] shl 16 or
template rol(x: uint32; n: typed): uint32 =
k43[x shr 8 and 255] shl 8 or k21[x and 255]
x shl 11n or x shr (32 - 11n)</lang>
 
proc f(x: uint32): uint32 =
let x = K87[x shr 24 and 255].uint32 shl 24 or K65[x shr 16 and 255].uint32 shl 16 or
K43[x shr 8 and 255].uint32 shl 8 or K21[x and 255].uint32
result = x.rol(11)
 
proc mainStep(input: array[8, byte]; key: array[4, byte]): array[8, byte] =
let input32 = cast[array[2, uint32]](input)
let key = cast[uint32](key)
let val = f(key + input32[0]) xor input32[1]
result[0..3] = cast[array[4, byte]](val)
result[4..7] = input[0..3]
 
when isMainModule:
const
Input = [byte 0x21, 0x04, 0x3B, 0x04, 0x30, 0x04, 0x32, 0x04]
Key = [byte 0xF9, 0x04, 0xC1, 0xE2]
 
let output = mainStep(Input, Key)
echo mapIt(output, it.toHex).join(" ")</syntaxhighlight>
 
{{out}}
<pre>1F 88 CF 07 21 04 3B 04</pre>
 
=={{header|Perl}}==
{{trans|Perl 6Raku}}
{{libheader|ntheory}}
<langsyntaxhighlight lang="perl">use strict;
use warnings;
use ntheory 'fromdigits';
Line 610 ⟶ 1,013:
 
printf '%02X ', (($L << 32) + $R >> (8*$_))%256 for 0..7;
print "\n";</langsyntaxhighlight>
{{out}}
<pre>1F 88 CF 07 21 04 3B 04</pre>
 
=={{header|Perl 6}}==
{{works with|rakudo|2012-10-30}}
Implemented to match explanation on Discussion page:
 
<lang perl6># sboxes from http://en.wikipedia.org/wiki/GOST_(block_cipher)
constant 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];
sub infix:<rol³²>(\y, \n) { (y +< n) % 2**32 +| (y +> (32 - n)) }
sub ГОСТ-round(\R, \K) {
my \a = (R + K) % 2**32;
my \b = :16[ sbox[$_][(a +> (4 * $_)) % 16] for 7...0 ];
b rol³² 11;
}
sub feistel-step(&F, \L, \R, \K) { R, L +^ F(R, K) }
my @input = 0x21, 0x04, 0x3B, 0x04, 0x30, 0x04, 0x32, 0x04;
my @key = 0xF9, 0x04, 0xC1, 0xE2;
my ($L,$R) = @input.reverse.map: { :256[$^a,$^b,$^c,$^d] }
my ($K ) = @key .reverse.map: { :256[$^a,$^b,$^c,$^d] }
($L,$R) = feistel-step(&ГОСТ-round, $L, $R, $K);
 
say [ ($L +< 32 + $R X+> (0, 8 ... 56)) X% 256 ].fmt('%02X');</lang>
 
{{out}}
<pre>1F 88 CF 07 21 04 3B 04</pre>
Line 654 ⟶ 1,019:
=={{header|Phix}}==
{{trans|D}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>constant cbrf = {
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
{ 4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3},
<span style="color: #008080;">constant</span> <span style="color: #000000;">cbrf</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span>
{14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9},
<span style="color: #0000FF;">{</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">13</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">},</span>
{ 5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11},
<span style="color: #0000FF;">{</span><span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">13</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">},</span>
{ 7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3},
<span style="color: #0000FF;">{</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">13</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">},</span>
{ 6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2},
<span style="color: #0000FF;">{</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">13</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">},</span>
{ 4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14},
<span style="color: #0000FF;">{</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">13</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">},</span>
{13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12},
<span style="color: #0000FF;">{</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">13</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">14</span><span style="color: #0000FF;">},</span>
{ 1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12}}
<span style="color: #0000FF;">{</span><span style="color: #000000;">13</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">12</span><span style="color: #0000FF;">},</span>
 
<span style="color: #0000FF;">{</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">13</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">14</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">12</span><span style="color: #0000FF;">}}</span>
function generate(integer k)
sequence res = repeat(0,256)
<span style="color: #008080;">function</span> <span style="color: #000000;">generate</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">)</span>
for i=1 to length(res) do
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">256</span><span style="color: #0000FF;">)</span>
integer hdx = floor((i-1)/16)+1,
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
ldx = and_bits(i-1,#F)+1
<span style="color: #004080;">integer</span> <span style="color: #000000;">hdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">((</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">16</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span>
res[i] = or_bits(cbrf[k][hdx]*#10,cbrf[k-1][ldx])
<span style="color: #000000;">ldx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#F</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
end for
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">or_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cbrf</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">][</span><span style="color: #000000;">hdx</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">#10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cbrf</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">ldx</span><span style="color: #0000FF;">])</span>
return res
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
constant k87 = generate(8),
k65 = generate(6),
<span style="color: #008080;">constant</span> <span style="color: #000000;">k87</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">generate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">8</span><span style="color: #0000FF;">),</span>
k43 = generate(4),
<span style="color: #000000;">k65</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">generate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">6</span><span style="color: #0000FF;">),</span>
k21 = generate(2)
<span style="color: #000000;">k43</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">generate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">4</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">k21</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">generate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
function r32(atom a)
if a<0 then a+=#100000000 end if
<span style="color: #008080;">function</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
return remainder(a,#100000000)
<span style="color: #008080;">if</span> <span style="color: #000000;">a</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">+=</span><span style="color: #000000;">#100000000</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">return</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">#100000000</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function mainstep(sequence input, atom key)
atom s = r32(input[1]+key)
<span style="color: #008080;">function</span> <span style="color: #000000;">mainstep</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">input</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">key</span><span style="color: #0000FF;">)</span>
s = r32(or_all({k87[and_bits(floor(s/#1000000),#FF)+1]*#1000000,
<span style="color: #004080;">atom</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">input</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">key</span><span style="color: #0000FF;">)</span>
k65[and_bits(floor(s/#0010000),#FF)+1]*#0010000,
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">or_all</span><span style="color: #0000FF;">({</span><span style="color: #000000;">k87</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">/</span><span style="color: #000000;">#1000000</span><span style="color: #0000FF;">),</span><span style="color: #000000;">#FF</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">#1000000</span><span style="color: #0000FF;">,</span>
k43[and_bits(floor(s/#0000100),#FF)+1]*#0000100,
<span style="color: #000000;">k65</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">/</span><span style="color: #000000;">#0010000</span><span style="color: #0000FF;">),</span><span style="color: #000000;">#FF</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">#0010000</span><span style="color: #0000FF;">,</span>
k21[and_bits(floor(s/#0000001),#FF)+1]*#0000001}))
<span style="color: #000000;">k43</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">/</span><span style="color: #000000;">#0000100</span><span style="color: #0000FF;">),</span><span style="color: #000000;">#FF</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">#0000100</span><span style="color: #0000FF;">,</span>
s = r32(s*power(2,11))+floor(s/power(2,32-11))
<span style="color: #000000;">k21</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">/</span><span style="color: #000000;">#0000001</span><span style="color: #0000FF;">),</span><span style="color: #000000;">#FF</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">#0000001</span><span style="color: #0000FF;">}))</span>
s = xor_bits(s,input[2])
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r32</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">*</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">11</span><span style="color: #0000FF;">))+</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">/</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">32</span><span style="color: #0000FF;">-</span><span style="color: #000000;">11</span><span style="color: #0000FF;">))</span>
return {s,input[1]}
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">input</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">])</span>
end function
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">input</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
printf(1,"%08x %08x\n",mainstep({#043B0421, #04320430}, #E2C104F9))</lang>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">mainstep</span><span style="color: #0000FF;">({</span><span style="color: #000000;">#043B0421</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#04320430</span><span style="color: #0000FF;">},</span> <span style="color: #000000;">#E2C104F9</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%08x %08x\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">--or, for other-endian:</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%08x"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]),</span>
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%08x"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">])</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">join_by</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" "</span><span style="color: #0000FF;">)))</span>
<span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">join_by</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" "</span><span style="color: #0000FF;">)))</span>
<span style="color: #0000FF;">?{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t</span><span style="color: #0000FF;">}</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
07CF881F 043B0421
{{"1F","88","CF","07"},{"21","04","3B","04"}}
</pre>
 
=={{header|PicoLisp}}==
{{trans|C}}
<langsyntaxhighlight PicoLisplang="picolisp">(setq K1 (13 2 8 4 6 15 11 1 10 9 3 14 5 0 12 7))
(setq K2 ( 4 11 2 14 15 0 8 13 3 12 9 7 5 10 6 1))
(setq K3 (12 1 10 15 9 2 6 8 0 13 3 4 14 7 5 11))
Line 764 ⟶ 1,140:
11 ) )
(bye)</langsyntaxhighlight>
 
=={{header|Python}}==
{{trans|C}}
<langsyntaxhighlight lang="python">
k8 = [ 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 ]
k7 = [ 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 ]
Line 793 ⟶ 1,169:
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)</langsyntaxhighlight>
 
=={{header|Racket}}==
This is a direct translation of the C code, but I have no idea if that code is correct, or a way to test it. (I suspect that it isn't, at least since the table has different numbers than the wikipedia article...)
<langsyntaxhighlight lang="racket">
#lang racket
 
Line 829 ⟶ 1,205:
(bitwise-ior (bitwise-and #xFFFFFFFF (arithmetic-shift x* 11))
(arithmetic-shift x* (- 11 32))))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|rakudo|2012-10-30}}
Implemented to match explanation on Discussion page:
 
<syntaxhighlight lang="raku" line># sboxes from http://en.wikipedia.org/wiki/GOST_(block_cipher)
constant 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];
sub infix:<rol³²>(\y, \n) { (y +< n) % 2**32 +| (y +> (32 - n)) }
sub ГОСТ-round(\R, \K) {
my \a = (R + K) % 2**32;
my \b = :16[ sbox[$_][(a +> (4 * $_)) % 16] for 7...0 ];
b rol³² 11;
}
sub feistel-step(&F, \L, \R, \K) { R, L +^ F(R, K) }
my @input = 0x21, 0x04, 0x3B, 0x04, 0x30, 0x04, 0x32, 0x04;
my @key = 0xF9, 0x04, 0xC1, 0xE2;
my ($L,$R) = @input.reverse.map: { :256[$^a,$^b,$^c,$^d] }
my ($K ) = @key .reverse.map: { :256[$^a,$^b,$^c,$^d] }
($L,$R) = feistel-step(&ГОСТ-round, $L, $R, $K);
 
say [ ($L +< 32 + $R X+> (0, 8 ... 56)) X% 256 ].fmt('%02X');</syntaxhighlight>
 
{{out}}
<pre>1F 88 CF 07 21 04 3B 04</pre>
 
=={{header|REXX}}==
{{trans|BBC BASIC}}
<langsyntaxhighlight lang="rexx">/*REXX program implements main step GOST 28147-89 based on a Feistel network. */
numeric digits 12 /* ┌── a list of 4─bit S─box values used by */
/* ↓ the Central Bank of Russian Federation.*/
Line 858 ⟶ 1,273:
/* [↓] encryption algorithm round. */
k = c2d( bitxor( bitor( d2c(z * 2**11, 4), d2c(z % 2**21, 4) ), d2c(#2, 4) ) )
say center(d2x(k) ' ' d2x(#1), 79) /*stick a fork in it, we're all done. */</langsyntaxhighlight>
{{out|output|:}}
<pre>
7CF881F 43B0421
</pre>
 
=={{header|RPL}}==
{{ trans|Nim}}
« { { 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 } }
« R→B » DOLIST 'K' STO
{ K21 K43 K65 K87 } 1 « { } SWAP STO » DOLIST
0 255 '''FOR''' j
1 4 '''FOR''' n
'K' n 2 * GET j 16 / IP 1 + GET 16 *
'K' n 2 * 1 - GET j 16 MOD 1 + GET OR
'''NEXT'''
4 →LIST { K21 K43 K65 K87 } SWAP STO+
'''NEXT'''
» '<span style="color:blue">KBOXINIT</span>' STO
« { }
'''WHILE''' #0h ≠ '''REPEAT'''
OVER #255d AND SWAP OVER + SWAP SRB
'''END''' SWAP DROP
» '<span style="color:blue">B→LIST</span>' STO
« « SWAP SLB OR » → input key cast
« key REVLIST cast STREAM <span style="color:grey">@ convert key into a little-endian integer</span>
input 1 4 SUB REVLIST cast STREAM + <span style="color:blue">B→LIST</span> <span style="color:grey">@ same for input part 1, then add and back to list format</span>
{ K21 K43 K65 K87 } SWAP B→R 1 ADD GET <span style="color:grey">@ replace bytes according to the table</span>
REVLIST cast STREAM <span style="color:grey">@ back to little-endian format</span>
RLB RL RL RL <span style="color:blue">B→LIST</span> <span style="color:grey">@ roll 11 bits, back to list format</span>
input 5 8 SUB XOR <span style="color:grey">@ add part 2</span>
input 1 4 SUB + <span style="color:grey">@ append part 1</span>
» » '<span style="color:blue">MAINSTEP</span>' STO
« 32 STWS HEX
<span style="color:blue">KBOXINIT</span>
{ #21h #4h #3Bh #4h #30h #4h #32h #4h } { #F9h #4h #C1h #E2h } <span style="color:blue">MAINSTEP</span>
» '<span style="color:blue">TASK</span>' STO
{{out}}
<pre>
1: { # 1Fh # 88h # CFh # 7h # 21h # 4h # 3Bh # 4h }
</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">use std::convert::TryInto;
use std::env;
use std::num::Wrapping;
 
const REPLACEMENT_TABLE: [[u8; 16]; 8] = [
[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],
];
const KEYS: [u32; 8] = [
0xE2C1_04F9,
0xE41D_7CDE,
0x7FE5_E857,
0x0602_65B4,
0x281C_CC85,
0x2E2C_929A,
0x4746_4503,
0xE00_CE510,
];
 
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
let plain_text: Vec<u8> = vec![0x04, 0x3B, 0x04, 0x21, 0x04, 0x32, 0x04, 0x30];
println!(
"Before one step: {}\n",
plain_text
.iter()
.cloned()
.fold("".to_string(), |b, y| b + &format!("{:02X} ", y))
);
let encoded_text = main_step(plain_text, KEYS[0]);
println!(
"After one step : {}\n",
encoded_text
.iter()
.cloned()
.fold("".to_string(), |b, y| b + &format!("{:02X} ", y))
);
} else {
let mut t = args[1].clone(); // "They call him... Баба Яга"
t += &" ".repeat((8 - t.len() % 8) % 8);
let text_bytes = t.bytes().collect::<Vec<_>>();
let plain_text = text_bytes.chunks(8).collect::<Vec<_>>();
println!(
"Plain text : {}\n",
plain_text.iter().cloned().fold("".to_string(), |a, x| a
+ "["
+ &x.iter()
.fold("".to_string(), |b, y| b + &format!("{:02X} ", y))[..23]
+ "]")
);
let encoded_text = plain_text
.iter()
.map(|c| encode(c.to_vec()))
.collect::<Vec<_>>();
println!(
"Encoded text: {}\n",
encoded_text.iter().cloned().fold("".to_string(), |a, x| a
+ "["
+ &x.into_iter()
.fold("".to_string(), |b, y| b + &format!("{:02X} ", y))[..23]
+ "]")
);
let decoded_text = encoded_text
.iter()
.map(|c| decode(c.to_vec()))
.collect::<Vec<_>>();
println!(
"Decoded text: {}\n",
decoded_text.iter().cloned().fold("".to_string(), |a, x| a
+ "["
+ &x.into_iter()
.fold("".to_string(), |b, y| b + &format!("{:02X} ", y))[..23]
+ "]")
);
let recovered_text =
String::from_utf8(decoded_text.iter().cloned().flatten().collect::<Vec<_>>()).unwrap();
println!("Recovered text: {}\n", recovered_text);
}
}
 
fn encode(text_block: Vec<u8>) -> Vec<u8> {
let mut step = text_block;
for i in 0..24 {
step = main_step(step, KEYS[i % 8]);
}
for i in (0..8).rev() {
step = main_step(step, KEYS[i]);
}
step
}
 
fn decode(text_block: Vec<u8>) -> Vec<u8> {
let mut step = text_block[4..].to_vec();
let mut temp = text_block[..4].to_vec();
step.append(&mut temp);
for key in &KEYS {
step = main_step(step, *key);
}
for i in (0..24).rev() {
step = main_step(step, KEYS[i % 8]);
}
let mut ans = step[4..].to_vec();
let mut temp = step[..4].to_vec();
ans.append(&mut temp);
ans
}
 
fn main_step(text_block: Vec<u8>, key_element: u32) -> Vec<u8> {
let mut n = text_block;
let mut s = (Wrapping(
u32::from(n[0]) << 24 | u32::from(n[1]) << 16 | u32::from(n[2]) << 8 | u32::from(n[3]),
) + Wrapping(key_element))
.0;
let mut new_s: u32 = 0;
for mid in 0..4 {
let cell = (s >> (mid << 3)) & 0xFF;
new_s += (u32::from(REPLACEMENT_TABLE[(mid * 2) as usize][(cell & 0x0f) as usize])
+ (u32::from(REPLACEMENT_TABLE[(mid * 2 + 1) as usize][(cell >> 4) as usize]) << 4))
<< (mid << 3);
}
s = ((new_s << 11) + (new_s >> 21))
^ (u32::from(n[4]) << 24 | u32::from(n[5]) << 16 | u32::from(n[6]) << 8 | u32::from(n[7]));
n[4] = n[0];
n[5] = n[1];
n[6] = n[2];
n[7] = n[3];
n[0] = (s >> 24).try_into().unwrap();
n[1] = ((s >> 16) & 0xFF).try_into().unwrap();
n[2] = ((s >> 8) & 0xFF).try_into().unwrap();
n[3] = (s & 0xFF).try_into().unwrap();
n
}</syntaxhighlight>
{{out}}
<pre>
Without parameters:
 
Before one step: 04 3B 04 21 04 32 04 30
 
After one step : 07 CF 88 1F 04 3B 04 21
 
 
With parameter "They call him... Баба Яга"
 
Plain text : [54 68 65 79 20 63 61 6C][6C 20 68 69 6D 2E 2E 2E][20 D0 91 D0 B0 D0 B1 D0][B0 20 D0 AF D0 B3 D0 B0]
 
Encoded text: [D6 7C 52 4A EA 9A 58 2D][D9 81 F7 DA ED 89 46 25][0A 75 2D 89 59 8B 3D C4][53 DC D6 E2 79 B6 68 24]
 
Decoded text: [54 68 65 79 20 63 61 6C][6C 20 68 69 6D 2E 2E 2E][20 D0 91 D0 B0 D0 B1 D0][B0 20 D0 AF D0 B3 D0 B0]
 
Recovered text: They call him... Баба Яга
</pre>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">namespace eval ::GOST {
proc tcl::mathfunc::k {a b} {
variable ::GOST::replacementTable
Line 886 ⟶ 1,507:
return $textBlock
}
}</langsyntaxhighlight>
Note that only the <tt>idx</tt>'th row of the split-up <tt>textBlock</tt> (which contains the two pieces to intermingle/exchange at this step) is altered; it is the responsibility of the caller to iterate over all the steps through the entire plaintext/ciphertext.
 
Line 910 ⟶ 1,531:
* The contents of the segment registers unchanged.
 
<langsyntaxhighlight Asmlang="asm"> .386
.model flat
.code
Line 938 ⟶ 1,559:
ret
_gost32 endp
end</langsyntaxhighlight>
 
=={{header|Wren}}==
{{libheader|Wren-fmt}}
{{trans|Go}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
 
class GOST {
// assumes 's' is an 8 x 16 integer array
construct new(s) {
_k87 = List.filled(256, 0)
_k65 = List.filled(256, 0)
_k43 = List.filled(256, 0)
_k21 = List.filled(256, 0)
_enc = List.filled(8, 0)
for (i in 0..255) {
_k87[i] = s[7][i>>4]<<4 | s[6][i&15]
_k65[i] = s[5][i>>4]<<4 | s[4][i&15]
_k43[i] = s[3][i>>4]<<4 | s[2][i&15]
_k21[i] = s[1][i>>4]<<4 | s[0][i&15]
}
}
 
enc { _enc }
 
f(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)
}
 
mainStep(input, key) {
var key32 = GOST.u32(key)
var input1 = GOST.u32(input[0...4])
var input2 = GOST.u32(input[4..-1])
GOST.b4(f(key32+input1)^input2, enc)
for (i in 0..3) enc[i + 4] = input[i]
}
 
static u32(b) { b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24 }
 
static b4(u, b) {
b[0] = u & 0xff
b[1] = (u >> 8) & 0xff
b[2] = (u >> 16) & 0xff
b[3] = (u >> 24) & 0xff
}
}
 
var cbrf = [
[ 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]
]
 
var input = [0x21, 0x04, 0x3b, 0x04, 0x30, 0x04, 0x32, 0x04]
var key = [0xf9, 0x04, 0xc1, 0xe2]
var g = GOST.new(cbrf)
g.mainStep(input, key)
for (b in g.enc) Fmt.write("[$02x]", b)
System.print()</syntaxhighlight>
 
{{out}}
<pre>
[1f][88][cf][07][21][04][3b][04]
</pre>
 
=={{header|zkl}}==
Line 944 ⟶ 1,634:
{{trans|D}}
This could very well fail on a non-Intel endian-ness.
<langsyntaxhighlight lang="zkl">class GOST{
var [const] // Central Bank of Russian Federation S-Boxes
k8=Data(0,Int, 4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3),
Line 974 ⟶ 1,664:
}
r
}}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl"> // Example from the talk page (little endian byte stream)
input:=Data(0,Int,0x21, 0x04, 0x3B, 0x04, 0x30, 0x04, 0x32, 0x04);
key := 0xE2|C1|04|F9; // big endian
 
GOST.mainStep(input,key).bytes().apply("[%02x]".fmt).concat().println();</langsyntaxhighlight>
{{out}}
<pre>[1f][88][cf][07][21][04][3b][04]</pre>