





















































































by Nata Drachinskaya
This part of the photobook recreates the life I remember, the one I lived with my parents and sister. It was the life of an ordinary Soviet family.
As a child, I was surrounded by propaganda and grew up in “the best country in the world,”. I was a young pioneer - a member of youth communist organization. I didn’t have the chance to join the Komsomol because the USSR collapsed. I ask myself: how was it that most people living in the USSR seemed blind to the events happening around them? Military actions in Czechoslovakia, Afghanistan, and Chechen wars were not secrets. The Communist Party’s double standards were also obvious for the people. By the 1980s, it seemed no one truly believed in the Communist Party anymore. Yet everyone carried on ignoring it. Leaving the USSR was practically impossible, and this parallel existence became the norm.
The first decade of a free Russia after the USSR’s collapse—the 1990s—is often referred to as “the wild ‘90s.” It was a challenging time: inflation wiped out earnings, and money was never enough for basic needs. Long lines formed for the simplest products, like eggs or cheese, due to shortages in stores. A new capitalist market was being established, accompanied by power struggles between various criminal groups. However, it was also a decade with the taste of freedom. The old world was destroyed, and we had a chance to build a new one.
During this decade, my parents’ goal was survival: earning enough to feed the family and paying for preparatory courses so my sister and I could attend university. Our goal, as children, was to study so we could later find good jobs. Now I see that our family, like most Russian families, continued living a parallel life “outside of politics.” The reasons were different—survival and securing a future—but the habit remained the same.
As I delved into readings for the project and reflected on the duality of human nature, it struck me that many Soviet individuals and families lived a parallel, hidden life. This could be connected to secret services or dissident movements. To some extent, this duality became the norm within society. Many Russians still hold on to this habit today. I believe it is one of the main factors contributing to the current passivity among Russians, not to mention the influence of propaganda.
While working on this project, I showed the book’s prototype to various artists and asked for feedback. One American artist, whos parants came to the USA many years ago from India, asked me, “Why are you so harsh about your father?” For him, respect for older generations, especially parents, was essential. Another American artist, who emigrated from the USSR 30 years ago, asked me, “Why are you justifying your father?” She knew what it was like to live in the USSR. I’m neither trying to judge my father nor express my disrespect. My project has a different aim. I want to show how the story of one family can reflect the story of a big country and how vital it is to know your family’s history in order to think critically. The larger history of nations is woven from family stories, individual lives, and the choices people make.
#familyhistory #bighistory
I want to say thank you to my Mom Vera for everything, for supporting me in making this book, and for being the most attentive proofreader of the English texts.
I’m grateful to my sister Ira for being so close to me and for helping me obtain some images from our father’s archive for this book.
Photo archives: Andrey Shtepa
Photos, drawings, texts, translations: Nata Drachinskaya (Shtepa)
Concept, edit and art-direction developed in the 2022 Photobook as Object workshop by Yumi Goto and Jan Rosseel in collaboration with Reminders Photography Stronghold
Any commercial use, reproduction, resale, or reprint of this book requires the explicit agreement of Natalia Drachinskaya, REMINDERS PHOTOGRAPHY STRONGHOLD (RPS), and Yumi Goto. All rights to the content and design of this book remain with the original creators.
Copyright © Nata Drachinskaya2025
Characteristic to graduate of secondary school No. 52 with in-depth study of mathematics Oktyabrsky district of Moscow
Shtepa Andrey Borisovich
Andrey Shtepa, born in 1954 and a member of the Komsomol, has studied at this school since 1969. During this time, Andrey has shown himself to be a capable student who takes his studies seriously and conscientiously. He studied only with “good” and “excellent.” He showed a particular interest in mathematics. During the two years of study at this school, Andrey took part in all school and regional mathematical and physical Olympiads. He earned second place in mathematics at the district Olympiad in 1971. He participated in the Physics and Mathematics Olympiad at MAI.
Simultaneously with successful studies at school, Andrey graduated from the evening physics and mathematics school at the Moscow Aviation Institute. Andrey was seriously engaged in coding. He received the qualification of a computer coder of the highest category. The internship was held at the Computer Center of Moscow State University.
Andrey is an active member of the Komsomol. Politically literate, he was a political informant of the class and an active member of the school society’s “Knowledge” lecture group.
A sensitive, sympathetic friend, always ready to help his classmates, Andrey won the love of the students of the class and the respect of the entire teaching staff. He completed the program of the Lenin testament. The pedagogical council of the school recommends Andrey Shtepa to a university with a mathematical profile.
June 19, 1971
Principal Class teacher
Secretary of the Komsomol organization
August 1968, the Czechoslovak Socialist Republic was invaded by the Soviet Union and other three Warsaw Pact contries.
December 1979, the Soviet Union sent troops into Afghanistan.
Communist Party of the USSR membership card
Congratulations on the wedding from the State Security Committee (KGB)
// Including dependancies #include <iostream> #include <string> using namespace std;
// Array to hold the 16 keys string round_keys[16];
// Function to do a circular left shift by 1 string shift_left_once(string key_chunk){
string shifted=””; for(int i = 1; i < 28; i++){ shifted += key_chunk[i];
}
shifted += key_chunk[0]; return shifted;
}
// Function to do a circular left shift by 2 string shift_left_twice(string key_chunk){
string shifted=””; for(int i = 0; i < 2; i++){ for(int j = 1; j < 28; j++){ shifted += key_chunk[j];
}
shifted += key_chunk[0]; key_chunk= shifted; shifted =””; }
return key_chunk;
void generate_keys(string key){
// The PC1 table int pc1[56] = { 57,49,41,33,25,17,9, 1,58,50,42,34,26,18, 10,2,59,51,43,35,27, 19,11,3,60,52,44,36, 63,55,47,39,31,23,15, 7,62,54,46,38,30,22, 14,6,61,53,45,37,29, 21,13,5,28,20,12,4
// The PC2 table
12.05.1980 № 902-А Central Committee of
The main measures to ensure safety in preparation and holding the Games of the XXII Olympiad 1980
Summary. The State Security Committee has developed and is implementing measures to ensure the security of the Games of the XXII Olympiad. All operational and organizational work is carried out in close cooperation with the USSR Ministry of Internal Affairs bodies. Interaction has been established with the security agencies of the socialist commonwealth.
As already reported (No. 1213-A dated 16.IV.78, 819-A dated 25.IV.1979, 1455-A dated 30.VII.1979), enemy secret services and foreign anti-Soviet organizations actively developed plans for the implementation of subversive actions during the preparation and holding of the XXII Olympic Games in 1980.
This hostile activity was especially intensified in connection with the unprecedented antiOlympic campaign unleashed by the Carter administration. The refusal of the United States to participate in the Games of the XXII Olympiad may push extremist elements to commit subversive actions on the territory of the USSR.
Taking into account the available materials on the subversive plans of the enemy, the State Security Committee has developed. It is implementing measures to ensure the security of the Olympic Games, identifying and disrupting hostile actions that are being prepared. The main attention is paid to countering the extremist aspirations of the enemy. For this purpose, in particular, an album was prepared with reference data for 3000 well-known members of international terrorist organizations, which was sent to all engaged KGB bodies, to checkpoints for the entry of foreigners into the USSR, as well as to the security agencies of the countries of the socialist commonwealth in order to prevent the entry of these persons into our country.
Entry into the Soviet Union was closed to 6000 foreigners who posed a danger from the point of view of the possible implementation of hostile actions during the Olympics. Work on identifying foreigners of this category and closing their entry into the USSR continues. Through the Consular Department of the USSR Ministry of Foreign Affairs, a temporary procedure for issuing visas has been introduced, which guarantees the verification of persons wishing to enter the USSR, according to operational records of the KGB, two months before entry.
On our recommendation, the 0lympiad-80 Organising Committee adopted the decision by the International Olympic Committee, according to which the participants of the Olympics-80, when entering our country, will present not only accreditation certificates but also national passports.
Special means of protection against forgery of Olympic certificates and other accreditation documents have been introduced.
A full customs inspection of foreigners is being introduced, and measures of control over their movement to the country are being strengthened.
In order to prevent the illegal transportation of weapons, explosive devices, other means of sabotage, and anti-Soviet and other politically harmful materials, the checkpoints of the border troops are equipped with modern technology, and special training has been carried out for the personnel of the checkpoint. Measures are being taken to strengthen the overall protection of the state border of the USSR.
The State Security Committee organized enhanced control over persons suspected of committing especially dangerous state crimes, as well as those who tried to illegally acquire firearms, explosives, and poisonous substances, who expressed intentions to commit especially dangerous state crimes. Together with the Ministry of Internal Affairs of the USSR, control over the state of registration and storage of firearms, explosives, and radioactive and poisonous substances has been strengthened, and measures to search for stolen weapons have been intensified.
In order to prevent possible impudent antisocial manifestations on the part of mentally ill persons bearing aggressive intentions, together with the Ministry of Internal Affairs and health authorities, measures are being taken to preventively isolate such persons for the period of the Olympics-80.
The main measures to ensure the safety of participants and guests of the XXII Olympic Games include the following:
- development of a technical system for detecting explosive devices in the mail;
- acceptance of parcels and parcels from citizens during the Olympics with the obligatory presentation of their contents to employees of postal services;
- special security measures at the places of residence of participants and guests of the Moscow Olympics, at sports facilities;
- protection of participants and guests of the Olympic Games, following the country by rail;
- strengthening the protection of life support facilities and especially regime-protected objects;
- special inspection of Soviet citizens involved in servicing participants and guests of the Olympics.
In addition, special measures are provided for the protection of the Israeli delegation, as well as the delegations of China, Chile, and some other countries, in case they arrive at the Olympic Games.
In developing measures to ensure the security of the XXII Olympic Games, much attention was paid to forecasting possible emergencies and other undesirable manifestations, various options for their prevention and localization were identified, and special task forces were trained to act in such situations.
To manage and coordinate the activities of the KGB bodies and troops to ensure the security of the XXII Olympic Games, the Operational Headquarters of the KGB of the USSR “0lympics-80” was created, which included the heads of all the main departments of the State Security Committee. The operational headquarters of the “Olympic Games-80” was also created by the KGB of the Ukrainian SSR, the KGB of the BSSR, the KGB of the ESSR, the KGB of the USSR in Moscow, and the Moscow region, the KGB of the USSR in the Leningrad region, in the KGB bodies along the route of the Olympic torch relay and other territorial bodies and special departments of the KGB of the USSR.
The State Security Committee and local KGB bodies carry out all operational and organizational work to ensure security during the preparation and holding of the Moscow Olympics in close cooperation with the bodies of the USSR Ministry of Internal Affairs. For the purpose of practical guidance and coordination of operational activities, joint operational headquarters of the KGB-MVD have been created at all Olympic venues. The leaders of the joint headquarters organize and direct the work to ensure security and public order at the facilities entrusted to them.
In the interests of ensuring security during the Olympic Games, the KGB of the USSR has established interaction with the security agencies of the countries of the socialist commonwealth. April 7-10 this year, a working meeting of representatives of the security services of the NRB, Hungary, East Germany, Poland, Czechoslovakia, Vietnam, Mongolian People’s Republic, and the Republic of Cuba at the level of deputy ministers, during which practical issues related to ensuring security at the final stage of preparation and during the Moscow Olympics were discussed.
With the consent of the Central Committee of the CPSU, on the initiative of the Committee of State Security, the USSR Ministry of Foreign Affairs made corresponding appeals to the leaders of a number of Arab states with a request to render all possible assistance to our country in holding the XXII Olympic Games in the spirit of the principles of humanism and peace among peoples, taking the necessary measures to prevent entry into the Soviet Union of persons involved in terrorist and extremist organizations.
At the same time, the KGB of the USSR made appeals to the heads of the security agencies of some developing countries with a request to receive and transmit information about the subversive plans of the special services of the imperialist states in relation to the Moscow Olympics.
Work on identifying and disrupting the hostile plans of the enemy and improving the system of security measures during the preparation and holding of the Olympics-80 continues, taking into account the changing situation in the world.
Reported in order to inform.
Chairman of the Committee. Yu. Andropov
30,40,51,45,33,48, 44,49,39,56,34,53, 46,42,50,36,29,32
// 1. Compressing the key using the PC1 table
string perm_key =””; for(int i = 0; i < 56; i++){ perm_key+= key[pc1[i]-1];
}
// 2. Dividing the result into two equal halves string left= perm_key.substr(0, 28); string right= perm_key.substr(28, 28); // Generating 16 keys for(int i=0; i<16; i++){
// 3.1. For rounds 1, 2, 9, 16 the key_chunks // are shifted by one.
if(i == 0 || i == 1 || i==8 || i==15 ){
left= shift_left_once(left); right= shift_left_once(right);
}
// 3.2. For other rounds, the key_chunks // are shifted by two else{
left= shift_left_twice(left); right= shift_left_twice(right);
// 4. The chunks are combined string combined_key = left + right; string round_key = “”; // 5. Finally, the PC2 table is used to transpose // the key bits for(int i = 0; i < 48; i++){ round_key += combined_key[pc2[i]-1]; } round_keys[i] = round_key; cout<<”Key “<<i+1<<”: “<<round_keys[i]<<endl; }
int main(){
string key = “10101010101110110000100100011000001001110011
}
return shifted;
// Function to do a circular left shift by 2 string shift_left_twice(string key_chunk){ string shifted=””; for(int i = 0; i < 2; i++){ for(int j = 1; j < 28; j++){ shifted += key_chunk[j]; } shifted += key_chunk[0]; key_chunk= shifted; shifted =””;
} return key_chunk;
} // Function to compute xor between two strings string Xor(string a, string b){ string result = “”; int size = b.size(); for(int i = 0; i < size; i++){ if(a[i] != b[i]){ result += “1”; } else{ result += “0”; } } return result;
} // Function to generate the 16 keys. void generate_keys(string key){ // The PC1 table int pc1[56] = { 57,49,41,33,25,17,9, 1,58,50,42,34,26,18, 10,2,59,51,43,35,27, 19,11,3,60,52,44,36, 63,55,47,39,31,23,15, 7,62,54,46,38,30,22, 14,6,61,53,45,37,29, 21,13,5,28,20,12,4 };
#include <iostream>
#include <string>
#include <cmath> using namespace std;
// Array to hold 16 keys string round_keys[16];
// String to hold the plain text string pt;
// Function to convert a number in decimal to binary string convertDecimalToBinary(int decimal)
{ string binary; while(decimal != 0) { binary = (decimal % 2 == 0 ? “0” : “1”) + binary; decimal = decimal/2; } while(binary.length() < 4){ binary = “0” + binary; } return binary;
}
// Function to convert a number in binary to decimal int convertBinaryToDecimal(string binary)
{ int decimal = 0; int counter = 0; int size = binary.length(); for(int i = size-1; i >= 0; i--)
{ if(binary[i] == ‘1’){ decimal += pow(2, counter); } counter++; } return decimal;
}
// Function to do a circular left shift by 1 string shift_left_once(string key_chunk){ string shifted=””; for(int i = 1; i < 28; i++){ shifted += key_chunk[i];
}
STATEMENT
of the Heads of State of the Republic of Belarus, the RSFSR, and Ukraine
We, the leaders of the Republic of Belarus, the RSFSR, Ukraine, - noting that negotiations for a new union agreement have reached an impasse, and that the objective process of the republics’ withdrawal from the USSR and the formation of independent states has become an established fact;
- statingthat the short-sighted policies of the central government have led to a deep economic and political crisis, the collapse of industry, and a catastrophic decline in the living standards of nearly all segments of society;
- taking into account the rise in social tensions across many regions of the former USSR, which has resulted in interethnic conflicts and numerous casualties;
- our responsibility to our peoples, the international community, and the urgent need for the practical implementation of political and economic reforms, we hereby declare the formation of the Commonwealth of Independent States, as formalized by the agreement signed by the parties on December 8, 1991.
The Commonwealth of Independent States, consisting of the Republic of Belarus, the RSFSR, and Ukraine, is open for accession by all member states of the USSR and other states that share the goals and principles of this agreement.
he member states of the Commonwealth intend to pursue a policy aimed at strengthening international peace and security. They guarantee the fulfillment of international obligations arising from the treaties and agreements of the former Soviet Union and will ensure unified control over nuclear weapons and their non-proliferation.
Chairman of the Supreme Council of the Republic of Belarus
S. Shushkevich
President of the RSFSR
B. Yeltsin
President of Ukraine
L. Kravchuk
December 8, 1991
Minsk
December 1994, First Chechen war started.
// 2. Dividing the result into two equal halves
string left = perm.substr(0, 32);
string right = perm.substr(32, 32);
// The plain text is encrypted 16 times for(int i=0; i<16; i++) {
string right_expanded = “”;
// 3.1. The right half of the plain text is expanded for(int i = 0; i < 48; i++) { right_expanded += right[expansion_table[i]-1];
44,49,39,56,34,53, 46,42,50,36,29,32
};
// 1. Compressing the key using the PC1 table string perm_key =””; for(int i = 0; i < 56; i++){ perm_key+= key[pc1[i]-1];
}
}; // 3.3. The result is xored with a key string xored = Xor(round_keys[i], right_expanded);
string res = “”;
// 3.4. The result is divided into 8 equal parts and passed // through 8 substitution boxes. After passing through a // substituion box, each box is reduces from 6 to 4 bits.
for(int i=0;i<8; i++){
// Finding row and column indices to lookup the // substituition box
string row1= xored.substr(i*6,1) + xored.substr(i*6 + 5,1);
int row = convertBinaryToDecimal(row1);
string col1 = xored.substr(i*6 + 1,1) + xored.substr(i*6 + 2,1) + xored.substr(i*6 + 3,1) + xored.substr(i*6 + 4,1);; int col = convertBinaryToDecimal(col1); int val = substition_boxes[i][row][col]; res += convertDecimalToBinary(val);
}
// 3.5. Another permutation is applied string perm2 =””; for(int i = 0; i < 32; i++){ perm2 += res[permutation_tab[i]-1];
}
// 3.6. The result is xored with the left half xored = Xor(perm2, left);
// 3.7. The left and the right parts of the plain text are swapped left = xored;
if(i < 15){
string temp = right; right = xored; left = temp; shifted += key_chunk[i];
}
// 2. Dividing the key into two equal halves string left= perm_key.substr(0, 28); string right= perm_key.substr(28, 28); for(int i=0; i<16; i++){
// 3.1. For rounds 1, 2, 9, 16 the key_chunks // are shifted by one.
if(i == 0 || i == 1 || i==8 || i==15 ){ left= shift_left_once(left); right= shift_left_once(right);
}
// 3.2. For other rounds, the key_chunks // are shifted by two else{ left= shift_left_twice(left); right= shift_left_twice(right);
}
// Combining the two chunks string combined_key = left + right; string round_key = “”;
// Finally, using the PC2 table to transpose the key bits for(int i = 0; i < 48; i++){ round_key += combined_key[pc2[i]-1];
} round_keys[i] = round_key;
}
using namespace std;
// Array to hold 16 keys string round_keys[16];
// String to hold the plain text string pt;
// Function to convert a number in decimal to binary string convertDecimalToBinary(int decimal) { string binary; while(decimal != 0) { binary = (decimal % 2 == 0 ? “0” : “1”) + binary; decimal = decimal/2; } while(binary.length() < 4){ binary = “0” + binary; } return binary;
}
// Function to convert a number in binary to decimal int convertBinaryToDecimal(string binary)
{ int decimal = 0; int counter = 0; int size = binary.length(); for(int i = size-1; i >= 0; i--) { if(binary[i] == ‘1’){ decimal += pow(2, counter); } counter++; } return decimal;
}
// Function to do a circular left shift by 1 string shift_left_once(string key_chunk){ string shifted=””;
for(int i = 1; i < 28; i++){ shifted += key_chunk[i]; } shifted += key_chunk[0]; return shifted;
for(int i=0; i<16; i++) { string right_expanded = “”;
// 3.1. The right half of the plain text is expanded for(int i = 0; i < 48; i++) { right_expanded += right[expansion_table[i]-1];
}; // 3.3. The result is xored with a key string xored = Xor(round_keys[i], right_expanded); string res = “”; // 3.4. The result is divided into 8 equal parts and passed // through 8 substitution boxes. After passing through a // substituion box, each box is reduces from 6 to 4 bits. for(int i=0;i<8; i++){
// Finding row and column indices to lookup the // substituition box
string row1= xored.substr(i*6,1) + xored.substr(i*6 + 5,1); int row = convertBinaryToDecimal(row1);
string col1 = xored.substr(i*6 + 1,1) + xored.substr(i*6 + 2,1) + xored.substr(i*6 + 3,1) + xored.substr(i*6 + 4,1);; int col = convertBinaryToDecimal(col1); int val = substition_boxes[i][row][col]; res += convertDecimalToBinary(val);
} // 3.5. Another permutation is applied string perm2 =””; for(int i = 0; i < 32; i++){ perm2 += res[permutation_tab[i]-1];
}
// 3.6. The result is xored with the left half xored = Xor(perm2, left);
// 3.7. The left and the right parts of the plain text are swapped left = xored; if(i < 15){ string temp = right; right = xored; left = temp;
}
} // 4. The halves of the plain text are applied string combined_text = left + right; string ciphertext =””; // The inverse of the initial permuttaion is applied
}
}
using namespace std;
using namespace std;
using namespace std;
#include <iostream>
// Array to hold 16 keys string round_keys[16];
// Array to hold 16 keys string round_keys[16];
#include <iostream>
// Array to hold 16 keys string round_keys[16];
// String to hold the plain text string pt;
#include <string> using namespace std;
// String to hold the plain text string pt;
#include <string>
#include <cmath> using namespace std;
// String to hold the plain text string pt;
// String to hold the plain text string pt;
// Array to hold the 16 keys string round_keys[16];
// Function to convert a number in binary to decimal int convertBinaryToDecimal(string binary) { int decimal = 0, counter = 0, size = binary.length(); for (int i = size - 1; i >= 0; i--) { if (binary[i] == ‘1’) { decimal += pow(2, counter);
using namespace std;
for(int i=0; i<16; i++) { string right_expanded = “”;
// Array to hold 16 keys string round_keys[16];
string round_key = “”; for (int j = 0; j < 48; j++) { round_key += combined_key[pc2[j] - 1]; } round_keys[i] = round_key;
// 3.1. The right half of the plain text is expanded for(int i = 0; i < 48; i++) { right_expanded += right[expansion_table[i]-1];
// String to hold the plain text string pt;
// Function to convert a number in decimal to binary string convertDecimalToBinary(int decimal)
} counter++;
// Array to hold 16 keys string round_keys[16];
// Function to convert a number in decimal to binary string convertDecimalToBinary(int decimal) { string binary; while (decimal != 0) { binary = (decimal % 2 == 0 ? “0” : “1”) + binary; decimal /= 2;
}
} return decimal;
// Function to convert a number in decimal to binary string convertDecimalToBinary(int decimal) { string binary; while(decimal != 0) { binary = (decimal % 2 == 0 ? “0” : “1”) + binary; decimal = decimal/2;
// Function to convert a number in decimal to binary string convertDecimalToBinary(int decimal)
{ string binary; while(decimal != 0) { binary = (decimal % 2 == 0 ? “0” : “1”) + binary; decimal = decimal/2;
while (binary.length() < 4) { binary = “0” + binary;
} while(binary.length() < 4){ binary = “0” + binary;
return binary;
} return binary;
}
} return binary;
// String to hold the plain text string pt;
while(binary.length() < 4){ binary = “0” + binary;
}
// Function to convert a number in decimal to binary string convertDecimalToBinary(int decimal)
// Function to do a circular left shift by 1 string shift_left_once(string key_chunk) { string shifted = “”; for (int i = 1; i < 28; i++) { shifted += key_chunk[i]; } shifted += key_chunk[0]; return shifted;
{ string binary; while(decimal != 0) { binary = (decimal % 2 == 0 ? “0” : “1”) + binary; decimal = decimal/2; } while(binary.length() < 4){ binary = “0” + binary; } return binary; }
// Function to do a circular left shift by 1 string shift_left_once(string key_chunk) { return key_chunk.substr(1) + key_chunk[0];
// Function to convert a number in decimal to binary string convertDecimalToBinary(int decimal) { string binary; while (decimal != 0) { binary = (decimal % 2 == 0 ? “0” : “1”) + binary; decimal = decimal / 2; } while (binary.length() < 4) { binary = “0” + binary; }
// Function to convert a number in binary to decimal int convertBinaryToDecimal(string binary)
// Function to convert a number in binary to decimal int convertBinaryToDecimal(string binary)
}
// Function to convert a number in binary to decimal int convertBinaryToDecimal(string binary) { int decimal = 0, counter = 0, size = binary.length(); for (int i = size - 1; i >= 0; i--) { if (binary[i] == ‘1’) { decimal += pow(2, counter); } counter++;
}
// Function to convert a number in binary to decimal int convertBinaryToDecimal(string binary)
{ int decimal = 0; int counter = 0; int size = binary.length(); for(int i = size-1; i >= 0; i--) { if(binary[i] == ‘1’){ decimal += pow(2, counter); } counter++; } return decimal;
return binary; }
{ int decimal = 0; int counter = 0; int size = binary.length(); for(int i = size-1; i >= 0; i--)
return decimal;
{ if(binary[i] == ‘1’){ decimal += pow(2, counter);
} counter++;
}
} // Function to do a circular left shift by 2 string shift_left_twice(string key_chunk) { return shift_left_once(shift_left_once(key_chunk));
{ int decimal = 0; int counter = 0; int size = binary.length(); for(int i = size-1; i >= 0; i--) { if(binary[i] == ‘1’){ decimal += pow(2, counter); } counter++; } return decimal; }
// Function to do a circular left shift by 1 string shift_left_once(string key_chunk) { return key_chunk.substr(1) + key_chunk[0];
} return decimal;
// Function to do a circular left shift by 1 string shift_left_once(string key_chunk){ string shifted=””; for(int i = 1; i < 28; i++){ shifted += key_chunk[i]; } shifted += key_chunk[0]; return shifted;
// Function to do a circular left shift by 1 string shift_left_once(string key_chunk){ string shifted=””; for(int i = 1; i < 28; i++){ shifted += key_chunk[i];
// Function to compute XOR between two strings string Xor(string a, string b) { string result = “”; int size = b.size(); for (int i = 0; i < size; i++) { result += (a[i] != b[i]) ? “1” : “0”; } return result;
// Function to do a circular left shift by 2 string shift_left_twice(string key_chunk) { string shifted = “”; for (int i = 0; i < 2; i++) { for (int j = 1; j < 28; j++) { shifted += key_chunk[j]; } shifted += key_chunk[0]; key_chunk = shifted; shifted = “”; } return key_chunk; } void generate_keys(string key) {
// Function to convert a number in binary to decimal int convertBinaryToDecimal(string binary) { int decimal = 0, counter = 0; int size = binary.length(); for (int i = size - 1; i >= 0; i--) { if (binary[i] == ‘1’) { decimal += pow(2, counter); } counter++; } return decimal; }
// Function to do a circular left shift by 2 string shift_left_twice(string key_chunk) { return shift_left_once(shift_left_once(key_chunk));
} // Function to generate the 16 keys void generate_keys(string key) { int pc1[56] = { 57,49,41,33,25,17,9, 1,58,50,42,34,26,18, 10,2,59,51,43,35,27, 19,11,3,60,52,44,36, 63,55,47,39,31,23,15, 7,62,54,46,38,30,22, 14,6,61,53,45,37,29, 21,13,5,28,20,12,4
} shifted += key_chunk[0];
// Function to do a circular left shift by 1 string shift_left_once(string key_chunk){ string shifted=””; for(int i = 1; i < 28; i++){ shifted += key_chunk[i]; } shifted += key_chunk[0]; return shifted; string round_keys[16];
// The PC1 table int pc1[56] = { 57,49,41,33,25,17,9, 1,58,50,42,34,26,18, 10,2,59,51,43,35,27, 19,11,3,60,52,44,36, 63,55,47,39,31,23,15, 7,62,54,46,38,30,22, 14,6,61,53,45,37,29, 21,13,5,28,20,12,4
// Function to compute XOR between two strings string Xor(string a, string b) {
// Function to do a circular left shift by 1 string shift_left_once(string key_chunk) { string shifted = “”; for (int i = 1; i < 28; i++) { shifted += key_chunk[i];
}; int pc2[48] = {
}; // 3.3. The result is xored with a key string xored = Xor(round_keys[i], right_expanded); string res = “”;
{ string binary; while(decimal != 0) { binary = (decimal % 2 == 0 ? “0” : “1”) + binary; decimal = decimal/2; } while(binary.length() < 4){ binary = “0” + binary; } return binary; }
// 3.4. The result is divided into 8 equal parts and passed // through 8 substitution boxes. After passing through a // substituion box, each box is reduces from 6 to 4 bits. for(int i=0;i<8; i++){
string Xor(string a, string b) { string result = “”; int size = b.size(); for (int i = 0; i < size; i++) { result += (a[i] != b[i]) ? “1” : “0”; } return result; } // Function to generate the 16 keys void generate_keys(string key) { int pc1[56] = { 57,49,41,33,25,17,9, 1,58,50,42,34,26,18, 10,2,59,51,43,35,27, 19,11,3,60,52,44,36, 63,55,47,39,31,23,15, 7,62,54,46,38,30,22, 14,6,61,53,45,37,29, 21,13,5,28,20,12,4
} } int main() { string key = “00010011001101000101011101111001100110111011110011011 11111110001”; generate_keys(key); for (int i = 0; i < 16; i++) { cout << “Round “ << i + 1 << “ Key: “ << round_keys[i] << endl; } return 0; }
// 3.4. The result is divided into 8 equal parts and passed // through 8 substitution boxes. After passing through a // substituion box, each box is reduces from 6 to 4 bits. for(int i=0;i<8; i++){
// Finding row and column indices to lookup the // substituition box
// Finding row and column indices to lookup the // substituition box
string row1= xored.substr(i*6,1) + xored.substr(i*6 + 5,1); int row = convertBinaryToDecimal(row1);
string row1= xored.substr(i*6,1) + xored.substr(i*6 + 5,1); int row = convertBinaryToDecimal(row1);
#include <iostream>
string col1 = xored.substr(i*6 + 1,1) + xored.substr(i*6 + 2,1) + xored.substr(i*6 + 3,1) + xored.substr(i*6 + 4,1);; int col = convertBinaryToDecimal(col1); int val = substition_boxes[i][row][col]; res += convertDecimalToBinary(val);
#include <string> #include <cmath> using namespace std;
// Function to convert a number in binary to decimal int convertBinaryToDecimal(string binary)
}
int pc2[48] = { 14,17,11,24,1,5, 3,28,15,6,21,10, 23,19,12,4,26,8, 16,7,27,20,13,2, 41,52,31,37,47,55, 30,40,51,45,33,48, 44,49,39,56,34,53, 46,42,50,36,29,32
string col1 = xored.substr(i*6 + 1,1) + xored.substr(i*6 + 2,1) + xored.substr(i*6 + 3,1) + xored.substr(i*6 + 4,1);; int col = convertBinaryToDecimal(col1); int val = substition_boxes[i][row][col]; res += convertDecimalToBinary(val);
}
}
{ int decimal = 0; int counter = 0; int size = binary.length(); for(int i = size-1; i >= 0; i--) { if(binary[i] == ‘1’){ decimal += pow(2, counter); } counter++; } return decimal;
}
// Function to convert a number in decimal to binary string convertDecimalToBinary(int decimal) { string binary; while (decimal != 0) { binary = (decimal % 2 == 0 ? “0” : “1”) + binary; decimal /= 2; } while (binary.length() < 4) { binary = “0” + binary; } return binary; } for(int i=0; i<16; i++) { string right_expanded = “”; // 3.1. The right half of the plain text is expanded for(int i = 0; i < 48; i++) { right_expanded += right[expansion_table[i]-1]; }; // 3.3. The result is xored with a key string xored = Xor(round_keys[i], right_expanded); string res = “”;
}
// 3.5. Another permutation is applied
};
// Array to hold 16 keys string round_keys[16]; // String to hold the plain text string pt;
string perm2 =””; for(int i = 0; i < 32; i++){ perm2 += res[permutation_tab[i]-1];
} // 3.5. Another permutation is applied string perm2 =””; for(int i = 0; i < 32; i++){ perm2 += res[permutation_tab[i]-1];
// 3.6. The result is xored with the left half xored = Xor(perm2, left);
// 3.6. The result is xored with the left half xored = Xor(perm2, left);
// 3.7. The left and the right parts of the plain text are swapped left = xored; if(i < 15){ string temp = right; right = xored; left = temp;
// 3.7. The left and the right parts of the plain text are swapped left = xored; if(i < 15){ string temp = right; right = xored; left = temp;
string perm_key = “”; for (int i = 0; i < 56; i++) { perm_key += key[pc1[i] - 1]; } string left = perm_key.substr(0, 28); string right = perm_key.substr(28, 28); for (int i = 0; i < 16; i++) { if (i == 0 || i == 1 || i == 8 || i == 15) { left = shift_left_once(left); right = shift_left_once(right);
} } // 4. The halves of the plain text are applied string combined_text = left + right; string ciphertext =””;
// Function to do a circular left shift by 1 string shift_left_once(string key_chunk){ string shifted=””; for(int i = 1; i < 28; i++){ shifted += key_chunk[i]; } shifted += key_chunk[0];
} else { left = shift_left_twice(left); right = shift_left_twice(right); }
} // 4. The halves of the plain text are applied string combined_text = left + right; string ciphertext =””; // The inverse of the initial permuttaion is applied
I, Nata Drachinskaya (Shtepa), was born in the USSR, grew up, and lived in the Soviet Union and Russia for more than four decades.
This photobook is the result of my work with the photo archive of my father, who committed suicide in September 2001. He hanged himself one night on the balcony of our family apartment. I was 22 years old. It was only after his death that I began to understand what his job was truly about. Through the story of my father’s life and our family’s history, I came to see from the new prospective how the life in the USSR was organized — and, unfortunately, how it continues in Russia today. Many of the principles of propaganda and social control that were used in the Soviet Union, adapted and expanded by Russia’s security services now. My Dad worked as a coder for the KGB—that was all I knew while he was alive. That’s all I heard from him and my mother, and it was confirmed by the numerous books on mathematics and programming languages in our home. After my father’s death, details began to emerge, forming a picture of the life he had led. Or, rather, the two lives he had led—one of them secret.
I worked with my father’s photographic archive. He loved photography and left behind a box of black-and-white negatives, slides, and prints. I also read books about the USSR, its collapse, the KGB, and its agents, including those who sought political asylum in other countries. I had many conversations with my mother. Gradually, the picture came together—not only of our family’s history but also of the structure of life in the USSR and Russia.
My father was talented in mathematics, he showed up his talent during his school years. In high school, he successfully participated in various math competitions and received glowing recommendations. I believe he could have been admitted to the prestigious Mechanics and Mathematics Faculty at Moscow State University, the best university in the USSR. However, at the time my father graduated school, the KGB’s Higher School (University) had just opened a new 4th Technical department focused on cryptography. They invited mathematically gifted graduates to join without entrance exams. My father’s parents decided to take advantage of this opportunity. The benefits, from their perspective, were clear: no stress of entering exams, guaranteed employment after the University, and the privileges afforded to military personnel.
Thus, my father ended up in the KGB, where he worked for over 25 years in the Government Communications and Information Department as a cryptographer, developing algorithms to cipher governmental communications and architectures for encryption systems. He was forbidden to discuss his work with anyone, including his family. Because he had access to classified information, he was not allowed to travel abroad. My mother, ironically a graduate of the Institute of Foreign Languages and a certified English translator, was also restricted from traveling. My father managed to go abroad only twice, it happened after the collapse of the USSR, to attend computer security conferences in the USA and Germany.
After the end of the USSR, the prestige of government service declined, and salaries became modest compared to those in newly established commercial banks. Many of my father’s colleagues left for security departments in banks. My father did not leave the KGB. His work became more difficult: chaos and a loss of ideological direction after the USSR’s collapse, modest salary, and strained relationships with colleagues, many of whom were “boots” (coarse and poorly educated military personnel). My father started drinking, and communication with him became increasingly difficult. One September morning in 2001, my mother found him hanged on the belt on the balcony of our apartment.
While working with my father’s photo archive, I looked for images that might reveal his secret life—of which I knew nothing. I believe my father was a professional because I found very few such photographs. This part of the book is composed of those images, from his childhood to his final days. I overlaid his life with political events in the USSR and Russia. I was horrified to see how aggressively my country behaved all those years, while propaganda loudly proclaimed that “we stand for peace all over the world.” The invasion of Czechoslovakia, the war in Afghanistan, the first and second Chechen wars—not to mention the internal struggle against dissent and critical thinking.
This photobook is about the beauty and impartiality of mathematics, which serves both the brilliant creators of innovative products and the secret services of severe dictators with equal fidelity. It is about double lives and the destructive power of secrecy, especially when built upon a great lie. It is about the force of propaganda and the learned blindness—the peculiar trait of Soviet and Russian citizens to live parallel domestic lives, detached from politics. And it is about my family and my country, Russia—a love that carries a bitter aftertaste.
#secretiveness #enimiesareallaroundus #fear #doublelives
KGB - is the abbreviation for Komitet Gosudarstvennoy Bezopasnosti, which means ‘Committee for State Security.’ It was the main security agency for the Soviet Union from March 13, 1954, until December 3, 1991. On December 3, 1991, the KGB was officially dissolved. It was later succeeded in Russia by the Foreign Intelligence Service and what would later become the Federal Security Service (FSB).
FAPSI or Federal Agency of Government Communications and Information (FAGCI) - (Russian:
was a Russian government agency, which was responsible for signal intelligence and security of governmental communications.
FAPSI was created from the 8th Main Directorate (Government Communications) and 16th Directorate (Electronic Intelligence) of the KGB.
On March 11, 2003, the agency was reorganized into the Service of Special Communications and Information (Spetssvyaz, Spetssviaz) of the Federal Security Service of the Russian Federation (FSB RF).
- is a short word for binomial. “Bi” is a Latin prefix meaning “two” and “nomial” is the adjective form of nomen, Latin for “name”. A binomial is a polynomial/ algebraic expression with two terms.
The students of the 4th Technical (cryptography) faculty of the High School of KGB, WWWUSSR jokingly called themselves “binomes”. A binomial is a polynomial/ algebraic expression with two terms.
The students of the 4th Technical (cryptography) faculty of the High School of KGB, USSR jokingly called themselves “binomes”.