New Mexico High School
Supercomputing Challenge
Final Report
April 5, 2000
Team 071
Mayfield High School
Team Members
Stephen Miller
Aaron Soto
Teachers
Mrs. Patricia Miller
Mrs. Brenda Hernandez
Table of Contents
Executive Summary 3
Introduction 4
Method 4
Why We Need a Supercomputer 5
Results and Conclusions 5
Future Enhancements 6
Recommendations 6
Acknowledgements 7
Bibliography 8
Appendices 9
A: A Primer on Cryptography 9
B: Sample Output 10
C: Programming Flowchart 11
D. Sample Cube Rotations 12
E: Source Code 13
i. Encode 13
ii. Decode 22
Executive Summary
As inhabitants of the computer world, one quickly realizes the major role security plays in business transactions, personal messages, and other data exchanged across small and large networks, such as the Internet. In light of this consideration, the team quickly set a path to create an encryption program unique to its kind. After much deliberation and research, the Rubik’s cube, invented in the 1970s, seemed to be an unconsidered method of encryption. Using this Rubik’s cube, we quickly determined that by dividing it into 27 smaller pieces, it could be adapted to suit the English alphabet. The cube would then be able to twist and rotate, causing the code to change after each letter. This self-changing code is what previously made other systems, such as the Enigma, so difficult to crack.
After many weeks of diligent work, we completed a C program, which was fully functional. This program can take a message file and a seed value and convert it into an incomprehensible jumble of numbers. It will even cipher the space character, giving the unauthorized decoder no available footholds.
Our results indicate that this method proves to be highly secure. After polling computing resources and reviewing our on-line research, which turned up nothing of its kind, we believe most of the success of our idea is that it has not been widely used. Since most decoders have not seen such a process in the past, they should be unable to find a way to decode it. Assuming that one was to intercept a message encoded with our program, and not have any knowledge of our methods, we believe it would be very difficult to decrypt. Although our methods are unlikely to be adopted for extremely secure data, we believe it would prove an effective method for most businesses and families to use to send and receive secure messages.
Introduction
With the advent of worldwide networks, such as the Internet, data security has become an increasingly important issue. This program is designed to address this problem. Using the mathematical concepts behind the Rubik’s Cube, our team hopes to create a revolutionary data encryption algorithm. We also would like to test our system's security by offering a reward to the person who is able to decipher an encoded message. An additional by-product of this project would be to further our knowledge in both cryptography and programming.
Method
The process is based on the mathematical concept found in the Rubik’s Cube. By dividing the cube into a 3x3x3 matrix, as in the standard Rubik’s Cube, each character in the English alphabet can be assigned to an individual coordinate in a three-dimensional space. The remaining coordinate is dedicated to the "space" character. Once the cube is established, each letter of the message then can be replaced with its coordinate within the cube. For further security, the cube will be rotated and twisted like a Rubik’s Cube after each letter; in this manner, the system is protected against letter frequency analysis. In addition, it was our intent to use RCA encryption to further secure the data. This idea never came to fruition due to the prohibitive difficulty of generating and registering the public and private keys. Instead, a simple character shift will be utilized. The resulting thoroughly encrypted coordinate points are then re-converted to ASCII text and placed in an external data file.
Why Do We Need a Supercomputer?
At this time, for the sake of simplicity, the program does not support advanced functions requiring a supercomputer. Our aim was to create a user friendly, easy-to-use program for home or small business use. However, adding mathematical functions and other types of re-encryption would require a high-end desktop machine or a supercomputer. Without easy access to a supercomputer, development of such software would be quite difficult. Therefore, for the time being, the current program is a simpler version of our methods to allow the program to be tested on standard desktop machines. If development of the program continues, it would be truly enjoyable to add a sophisticated re-encryption process to make the code more secure.
Results and Conclusions
At this time, a working pair of programs has been developed, which utilizes a simplified version of the aforementioned procedures. Thanks to the cryptography teacher at Mayfield High School, Mrs. Joy, we have learned about many types of encryption methods and how they may be “cracked”. This provided us a unique insight with which to develop an extraordinarily robust encryption system, impervious to all methods of “cracking” the team is aware of at this time. Currently it does not support RCA re-encryption. Since this program is written in ANSI standard C, we have the ability to create versions for DOS, Windows 95/98/2000, Macintosh, Linux (and compatible operating systems), and virtually any other operating system.
Future Enhancements
An opportunity to analyze our encryption utility under higher stress would be greatly appreciated; however, we currently have no means to fulfill this wish. As the program stands, we feel it is very secure, but it will not achieve its full effectiveness without a method of re-encryption. Another addition that would enhance our program would be an advanced re-encryption process. RSA was originally considered; however, this style of encryption requires the generation and registration of keys, which would prove very difficult.
Recommendations
To anyone who would like to write a similar encryption program, there is some basic advice to be offered. First, a strong knowledge base of C (or the language of your choice) is recommended. Even if one has a large knowledge of the programming language(s), many books on C and additional documentation are useful during development. Also, a more advanced form of encryption would greatly enhance the security.
Another strong suggestion would be the use of a mentor. Unfortunately, since the Supercomputing Challenge guided program was based on encryption methods, there were many teams using encryption programs and not many mentors. Since we had a large knowledge of C, and had taken a course on cryptography, the team felt that it could work with limited assistance. Belatedly, it was realized that this was a misconception. A mentor would have greatly improved the team’s efficiency.
Acknowledgements
We would like to thank:
The Supercomputing for providing the opportunity to write a program within the auspices of the school
Challenge Team environment
Mr. Ralph Shock for helping the team members learn C, Fortran 90, and the basics of Linux
(Educator)
Mrs. Joy for instructing the team in the basic cryptographic methods
(Educator)
Our Parents for putting up with programming until midnight
Las Cruces Public Schools for purchasing a copy of Visual C++ for use as a development environment
Ms. Comer for assisting with the editing of this report
(Educator)
Bibliography
Aitken & Jones (1998), Teach Yourself C in 21 Days: SAMS Publishing
Rubik’s Cube Solution. [Online] Available http://www.rubiks.com/cubesolution_new.html
January 11, 2000
New Mexico High School Supercomputing Challenge 1999-2000 Finalist Reports
A Primer on Cryptography
This primer is intended to assist the reader in further understanding of the lexicon of cryptography. It provides a brief insight into the basic methods of cryptography from the far past to the present. It also lists the each methods successes and vulnerabilities.
Cesar Shift
This cryptographic method was one of the earliest known forms of encryption. It is a simple substitution cipher that works by replacing one letter with another, located a specified displacement along the alphabet. A Cesar Shift key would look like:
ABCDEFGHIJKLMNOPQRSTUVWXYZ Normal
DEFGHIJKLMNOPQRSTUVWXYZABC Encrypted
In this example, the displacement is four, therefore A would become D, B would become E, and so on.
Affine Transformation
By substituting each letter for a number, we may use mathematical equations in cryptography. This is the basis of the Affine Transformation. The major weakness of this transformation is that it too is a substitution cipher. This means that it is vulnerable to “cracking” by use of frequency analysis. The equation used for this type of cryptography is:
|
C=(a*P)+b(mod n)
RSA Encryption
Through the use of mathematics, a system can be derived that is secure against basic methods of unauthorized encryption. However, this type of encryption requires that each person generate their own personal encoding and decoding keys as well as an easily accessible way in order that users must not personally exchange bulky and complex keys. Therefore, this method was rather difficult to implement, as the program does not have the ability to provide such generation and distribution of keys.
Letter Frequency
Since most basic methods use substitution, frequently, the first line of offense is letter frequency analysis. These faults are visible within the Cesar Shift and Affine Transformation. However, RSA Encryption is not vulnerable to this particular onslaught, since it’s key changes with each individual character. This admirable quality was a key point in our procedure.
Sample Run
C:\>type message.txt
the quick brown fox jumps over the lazy dog
C:\>encode message.txt 314
Message encoded. Refer to code.txt for code.
C:\>type code.txt
0 0 0 1 2 2 1 0 1 2 2 2 2 1 2 0 0 1 2 2 0 0 0 0 1 0 1 0 2 2 2 0 1 2 2 2 2 0 1 2
1 0 0 1 1 0 0 2 2 1 2 2 1 0 1 1 1 0 0 2 0 1 0 0 2 1 0 1 1 1 2 1 2 1 0 2 2 2 0 1
2 1 2 1 1 0 1 2 0 0 2 2 2 0 2 2 2 1 0 1 1 0 2 2 2 0 0 1 2 0 0 2 2 2 2 1 2 0 0 2
0 1 2 1 2 0 0 2 2
C:\>decode code.txt 314
Decoded message reads:
the quick brown fox jumps over the lazy dog
Message decoded. Refer to 'message.txt' for message.
C:\>
Programming Flowchart
Source Code (Encode)
# include<stdio.h>
# include<stdlib.h>
# include<math.h>
# include<ctype.h>
char cube[4][4][4], cuber[4][4][4];
char message[2000000];
int r=1, r2=1, i=0, a=0, length=0, dir=0, clength=0;
char letter;
void FindCoords(char);
void RotateCube(void);
void main(int argc, char *argv[])
{
int x=0, y=0, z=0, help=0, seed=1;
FILE *messdat;
FILE *messcode;
if(argc!=3)
{
printf("Syntax Error:\n");
printf("Correct syntax: ENCODE inputfile [seed]\n\n\n");
exit(EXIT_FAILURE);
}
if((messdat=fopen(argv[1],"r"))==NULL)
{
printf("FATAL ERROR: Cannot open '%s'.\n\n", argv[1]);
exit(EXIT_FAILURE);
}
cube[0][0][0]='a';
cube[1][0][0]='b';
cube[2][0][0]='c';
cube[0][1][0]='d';
cube[1][1][0]='e';
cube[2][1][0]='f';
cube[0][2][0]='g';
cube[1][2][0]='h';
cube[2][2][0]='i';
cube[0][0][1]='j';
cube[1][0][1]='k';
cube[2][0][1]='l';
cube[0][1][1]='m';
cube[1][1][1]='x';
cube[2][1][1]='n';
cube[0][2][1]='o';
cube[1][2][1]='p';
cube[2][2][1]='q';
cube[0][0][2]='r';
cube[1][0][2]='s';
cube[2][0][2]='t';
cube[0][1][2]='u';
cube[1][1][2]='v';
cube[2][1][2]='w';
cube[0][2][2]=' ';
cube[1][2][2]='y';
cube[2][2][2]='z';
i=0;
while (!feof(messdat))
{
fscanf(messdat, "%c", &message[i]);
i++;
}
length=i-1;
if(argc==3)
seed=atoi(argv[2]);
else
seed=length;
//printf("Size Of \"%s\": %d bytes\n\n", argv[1], length-1);
i=0;
while(i<seed)
{
RotateCube();
i++;
}
if((messcode=fopen("code.txt","w"))==0)
{
printf("FATAL ERROR: Cannot create 'code.txt'\n\n");
exit(EXIT_FAILURE);;
}
fclose(messcode);
for(i=0; i<length-1; i++)
{
FindCoords(message[i]);
RotateCube();
}
if((messcode=fopen("code.txt","a"))==0)
{
printf("FATAL ERROR: Cannot open 'code.txt'\n\n");
exit(EXIT_FAILURE);;
}
clength=clength-6;
//printf("%d", clength);
//while((clength % 6) != 0)
//{
// fprintf(messcode," ");
//}
fclose(messcode);
printf("\nMessage encoded. Refer to code.txt for code.\n");
exit(EXIT_SUCCESS);
}
/*----------------------------------------------------------*/
void FindCoords(char letter)
{
int x=0, y=0, z=0;
FILE *messcode;
if((messcode=fopen("code.txt","a"))==0)
{
printf("FATAL ERROR: Cannot create 'code.txt'\n\n");
exit(EXIT_FAILURE);;
}
for(z=0;z<3;z++)
{
for(y=0;y<3;y++)
{
for(x=0;x<3;x++)
{
if(cube[x][y][z]==tolower(letter))
{
fprintf(messcode,"%d %d %d ",x,y,z);
}
}
}
}
fclose(messcode);
clength = clength + 6;
}
/*----------------------------------------------------------*/
void RotateCube()
{
char outcube [4][4][4], incube[4][4][4];
int x,y,z;
for(z=0;z<3;z++)
{
for(y=0;y<3;y++)
{
for(x=0;x<3;x++)
{
incube[x][y][z]=cube[x][y][z];
outcube[x][y][z]=incube[x][y][z];
}
}
}
dir = dir % 12;
switch (dir)
{
case 0:
{
// Rotate whole cube on x axis
outcube[2][0][0] = incube[0][0][0];
outcube[2][0][1] = incube[1][0][0];
outcube[2][0][2] = incube[2][0][0];
outcube[1][0][0] = incube[0][0][1];
outcube[1][0][1] = incube[1][0][1];
outcube[1][0][2] = incube[2][0][1];
outcube[0][0][0] = incube[0][0][2];
outcube[0][0][1] = incube[1][0][2];
outcube[0][0][2] = incube[2][0][2];
outcube[2][1][0] = incube[0][1][0];
outcube[2][1][1] = incube[1][1][0];
outcube[2][1][2] = incube[2][1][0];
outcube[1][1][0] = incube[0][1][1];
outcube[1][1][1] = incube[1][1][1];
outcube[1][1][2] = incube[2][1][1];
outcube[0][1][0] = incube[0][1][2];
outcube[0][1][1] = incube[1][1][2];
outcube[0][1][2] = incube[2][1][2];
outcube[2][2][0] = incube[0][2][0];
outcube[2][2][1] = incube[1][2][0];
outcube[2][2][2] = incube[2][2][0];
outcube[1][2][0] = incube[0][2][1];
outcube[1][2][1] = incube[1][2][1];
outcube[1][2][2] = incube[2][2][1];
outcube[0][2][0] = incube[0][2][2];
outcube[0][2][1] = incube[1][2][2];
outcube[0][2][2] = incube[2][2][2];
break;
}
case 1:
{
// Rotate whole cube on y axis
outcube[0][2][0] = incube[0][0][0];
outcube[0][2][1] = incube[0][1][0];
outcube[0][2][2] = incube[0][2][0];
outcube[0][1][0] = incube[0][0][1];
outcube[0][1][1] = incube[0][1][1];
outcube[0][1][2] = incube[0][2][1];
outcube[0][0][0] = incube[0][0][2];
outcube[0][0][1] = incube[0][1][2];
outcube[0][0][2] = incube[0][2][2];
outcube[1][2][0] = incube[1][0][0];
outcube[1][2][1] = incube[1][1][0];
outcube[1][2][2] = incube[1][2][0];
outcube[1][1][0] = incube[1][0][1];
outcube[1][1][1] = incube[1][1][1];
outcube[1][1][2] = incube[1][2][1];
outcube[1][0][0] = incube[1][0][2];
outcube[1][0][1] = incube[1][1][2];
outcube[1][0][2] = incube[1][2][2];
outcube[2][2][0] = incube[2][0][0];
outcube[2][2][1] = incube[2][1][0];
outcube[2][2][2] = incube[2][2][0];
outcube[2][1][0] = incube[2][0][1];
outcube[2][1][1] = incube[2][1][1];
outcube[2][1][2] = incube[2][2][1];
outcube[2][0][0] = incube[2][0][2];
outcube[2][0][1] = incube[2][1][2];
outcube[2][0][2] = incube[2][2][2];
break;
}
case 2:
{
// Rotate whole cube on z axis
outcube[0][2][0] = incube[0][0][0];
outcube[1][2][0] = incube[0][1][0];
outcube[2][2][0] = incube[0][2][0];
outcube[0][1][0] = incube[1][0][0];
outcube[1][1][0] = incube[1][1][0];
outcube[2][1][0] = incube[1][2][0];
outcube[0][0][0] = incube[2][0][0];
outcube[1][0][0] = incube[2][1][0];
outcube[2][0][0] = incube[2][2][0];
outcube[0][2][1] = incube[0][0][1];
outcube[1][2][1] = incube[0][1][1];
outcube[2][2][1] = incube[0][2][1];
outcube[0][1][1] = incube[1][0][1];
outcube[1][1][1] = incube[1][1][1];
outcube[2][1][1] = incube[1][2][1];
outcube[0][0][1] = incube[2][0][1];
outcube[1][0][1] = incube[2][1][1];
outcube[2][0][1] = incube[2][2][1];
outcube[0][2][2] = incube[0][0][2];
outcube[1][2][2] = incube[0][1][2];
outcube[2][2][2] = incube[0][2][2];
outcube[0][1][2] = incube[1][0][2];
outcube[1][1][2] = incube[1][1][2];
outcube[2][1][2] = incube[1][2][2];
outcube[0][0][2] = incube[2][0][2];
outcube[1][0][2] = incube[2][1][2];
outcube[2][0][2] = incube[2][2][2];
break;
}
case 3:
{
//Twist Layer 1 on x axis
outcube[2][0][0] = incube[0][0][0];
outcube[2][0][1] = incube[1][0][0];
outcube[2][0][2] = incube[2][0][0];
outcube[1][0][0] = incube[0][0][1];
outcube[1][0][1] = incube[1][0][1];
outcube[1][0][2] = incube[2][0][1];
outcube[0][0][0] = incube[0][0][2];
outcube[0][0][1] = incube[1][0][2];
outcube[0][0][2] = incube[2][0][2];
break;
}
case 4:
{
//Twist Layer 1 on y axis
outcube[0][2][0] = incube[0][0][0];
outcube[0][2][1] = incube[0][1][0];
outcube[0][2][2] = incube[0][2][0];
outcube[0][1][0] = incube[0][0][1];
outcube[0][1][1] = incube[0][1][1];
outcube[0][1][2] = incube[0][2][1];
outcube[0][0][0] = incube[0][0][2];
outcube[0][0][1] = incube[0][1][2];
outcube[0][0][2] = incube[0][2][2];
break;
}
case 5:
{
//Twist Layer 1 on z axis
outcube[0][2][0] = incube[0][0][0];
outcube[1][2][0] = incube[0][1][0];
outcube[2][2][0] = incube[0][2][0];
outcube[0][1][0] = incube[1][0][0];
outcube[1][1][0] = incube[1][1][0];
outcube[2][1][0] = incube[1][2][0];
outcube[0][0][0] = incube[2][0][0];
outcube[1][0][0] = incube[2][1][0];
outcube[2][0][0] = incube[2][2][0];
break;
}
case 6:
{
//Twist Layer 2 on x axis
outcube[2][1][0] = incube[0][1][0];
outcube[2][1][1] = incube[1][1][0];
outcube[2][1][2] = incube[2][1][0];
outcube[1][1][0] = incube[0][1][1];
outcube[1][1][1] = incube[1][1][1];
outcube[1][1][2] = incube[2][1][1];
outcube[0][1][0] = incube[0][1][2];
outcube[0][1][1] = incube[1][1][2];
outcube[0][1][2] = incube[2][1][2];
break;
}
case 7:
{
//Twist Layer 2 on y axis
outcube[1][2][0] = incube[1][0][0];
outcube[1][2][1] = incube[1][1][0];
outcube[1][2][2] = incube[1][2][0];
outcube[1][1][0] = incube[1][0][1];
outcube[1][1][1] = incube[1][1][1];
outcube[1][1][2] = incube[1][2][1];
outcube[1][0][0] = incube[1][0][2];
outcube[1][0][1] = incube[1][1][2];
outcube[1][0][2] = incube[1][2][2];
break;
}
case 8:
{
//Twist Layer 2 on z axis
outcube[0][2][1] = incube[0][0][1];
outcube[1][2][1] = incube[0][1][1];
outcube[2][2][1] = incube[0][2][1];
outcube[0][1][1] = incube[1][0][1];
outcube[1][1][1] = incube[1][1][1];
outcube[2][1][1] = incube[1][2][1];
outcube[0][0][1] = incube[2][0][1];
outcube[1][0][1] = incube[2][1][1];
outcube[2][0][1] = incube[2][2][1];
break;
}
case 9:
{
//Twist Layer 3 on x axis
outcube[2][2][0] = incube[0][2][0];
outcube[2][2][1] = incube[1][2][0];
outcube[2][2][2] = incube[2][2][0];
outcube[1][2][0] = incube[0][2][1];
outcube[1][2][1] = incube[1][2][1];
outcube[1][2][2] = incube[2][2][1];
outcube[0][2][0] = incube[0][2][2];
outcube[0][2][1] = incube[1][2][2];
outcube[0][2][2] = incube[2][2][2];
break;
}
case 10:
{
//Twist Layer 3 on y axis
outcube[2][2][0] = incube[2][0][0];
outcube[2][2][1] = incube[2][1][0];
outcube[2][2][2] = incube[2][2][0];
outcube[2][1][0] = incube[2][0][1];
outcube[2][1][1] = incube[2][1][1];
outcube[2][1][2] = incube[2][2][1];
outcube[2][0][0] = incube[2][0][2];
outcube[2][0][1] = incube[2][1][2];
outcube[2][0][2] = incube[2][2][2];
break;
}
case 11:
{
//Twist Layer 3 on z axis
outcube[0][2][2] = incube[0][0][2];
outcube[1][2][2] = incube[0][1][2];
outcube[2][2][2] = incube[0][2][2];
outcube[0][1][2] = incube[1][0][2];
outcube[1][1][2] = incube[1][1][2];
outcube[2][1][2] = incube[1][2][2];
outcube[0][0][2] = incube[2][0][2];
outcube[1][0][2] = incube[2][1][2];
outcube[2][0][2] = incube[2][2][2];
break;
}
default:
printf("Incorrect syntax sent to cube twisting function. Aborting.\n\n");
exit(EXIT_FAILURE);
break;
}
for(z=0;z<3;z++)
{
for(y=0;y<3;y++)
{
for(x=0;x<3;x++)
{
cube[x][y][z]=outcube[x][y][z];
}
}
}
dir++;
}
Source Code (Decode)
# include<stdio.h>
# include<stdlib.h>
# include<math.h>
# include<ctype.h>
char cube[4][4][4], cuber[4][4][4];
char message[2000000], code[384];
int r=1, r2=1, i=0, a=0, seed=0, dir=0, length=0;
char letter, junk;
void RotateCube(void);
void main(int argc, char *argv[])
{
int x=0, y=0, z=0;
FILE *messdat;
FILE *messcode;
FILE *temp;
if(argc!=3)
{
printf("Syntax Error:\n");
printf("Correct syntax: DECODE inputfile [seed]\n\n\n");
exit(EXIT_FAILURE);
}
if((temp=fopen(argv[1],"r"))==NULL)
{
printf("FATAL ERROR: Cannot open '%s'.\n\n", argv[1]);
exit(EXIT_FAILURE);
}
while(!feof(temp))
{
fscanf(temp,"%c", &junk);
length++;
}
fclose(temp);
//printf("Size Of \"%s\": %d bytes\n\n", argv[1], length-1);
if(argc==3)
seed=atoi(argv[2]);
else
seed=(length-1)/6;
if((messcode=fopen(argv[1],"r"))==NULL)
{
printf("FATAL ERROR: Cannot open '%s'.\n\n", argv[1]);
exit(EXIT_FAILURE);
}
cube[0][0][0]='a';
cube[1][0][0]='b';
cube[2][0][0]='c';
cube[0][1][0]='d';
cube[1][1][0]='e';
cube[2][1][0]='f';
cube[0][2][0]='g';
cube[1][2][0]='h';
cube[2][2][0]='i';
cube[0][0][1]='j';
cube[1][0][1]='k';
cube[2][0][1]='l';
cube[0][1][1]='m';
cube[1][1][1]='x';
cube[2][1][1]='n';
cube[0][2][1]='o';
cube[1][2][1]='p';
cube[2][2][1]='q';
cube[0][0][2]='r';
cube[1][0][2]='s';
cube[2][0][2]='t';
cube[0][1][2]='u';
cube[1][1][2]='v';
cube[2][1][2]='w';
cube[0][2][2]=' ';
cube[1][2][2]='y';
cube[2][2][2]='z';
if((messdat=fopen("message.txt","w"))==0)
{
printf("FATAL ERROR: Cannot create 'message.txt'\n\n");
exit(EXIT_FAILURE);
}
i=0;
while(i<seed)
{
RotateCube();
i++;
}
i=0;
printf("Decoded message reads:\n");
do
{
fscanf(messcode, "%d %d %d", &x, &y, &z);
fprintf(messdat, "%c", cube[x][y][z]);
printf("%c",cube[x][y][z]);
RotateCube();
i++;
}while(!feof(messcode));
printf("\n\nMessage decoded. Refer to 'message.txt' for message.\n");
i=0;
fclose(messcode);
fclose(messdat);
}
/*----------------------------------------------------------*/
void RotateCube()
{
char outcube [4][4][4], incube[4][4][4];
int x,y,z;
for(z=0;z<3;z++)
{
for(y=0;y<3;y++)
{
for(x=0;x<3;x++)
{
incube[x][y][z]=cube[x][y][z];
outcube[x][y][z]=incube[x][y][z];
}
}
}
dir = dir % 12;
switch (dir)
{
case 0:
{
// Rotate whole cube on x axis
outcube[2][0][0] = incube[0][0][0];
outcube[2][0][1] = incube[1][0][0];
outcube[2][0][2] = incube[2][0][0];
outcube[1][0][0] = incube[0][0][1];
outcube[1][0][1] = incube[1][0][1];
outcube[1][0][2] = incube[2][0][1];
outcube[0][0][0] = incube[0][0][2];
outcube[0][0][1] = incube[1][0][2];
outcube[0][0][2] = incube[2][0][2];
outcube[2][1][0] = incube[0][1][0];
outcube[2][1][1] = incube[1][1][0];
outcube[2][1][2] = incube[2][1][0];
outcube[1][1][0] = incube[0][1][1];
outcube[1][1][1] = incube[1][1][1];
outcube[1][1][2] = incube[2][1][1];
outcube[0][1][0] = incube[0][1][2];
outcube[0][1][1] = incube[1][1][2];
outcube[0][1][2] = incube[2][1][2];
outcube[2][2][0] = incube[0][2][0];
outcube[2][2][1] = incube[1][2][0];
outcube[2][2][2] = incube[2][2][0];
outcube[1][2][0] = incube[0][2][1];
outcube[1][2][1] = incube[1][2][1];
outcube[1][2][2] = incube[2][2][1];
outcube[0][2][0] = incube[0][2][2];
outcube[0][2][1] = incube[1][2][2];
outcube[0][2][2] = incube[2][2][2];
break;
}
case 1:
{
// Rotate whole cube on y axis
outcube[0][2][0] = incube[0][0][0];
outcube[0][2][1] = incube[0][1][0];
outcube[0][2][2] = incube[0][2][0];
outcube[0][1][0] = incube[0][0][1];
outcube[0][1][1] = incube[0][1][1];
outcube[0][1][2] = incube[0][2][1];
outcube[0][0][0] = incube[0][0][2];
outcube[0][0][1] = incube[0][1][2];
outcube[0][0][2] = incube[0][2][2];
outcube[1][2][0] = incube[1][0][0];
outcube[1][2][1] = incube[1][1][0];
outcube[1][2][2] = incube[1][2][0];
outcube[1][1][0] = incube[1][0][1];
outcube[1][1][1] = incube[1][1][1];
outcube[1][1][2] = incube[1][2][1];
outcube[1][0][0] = incube[1][0][2];
outcube[1][0][1] = incube[1][1][2];
outcube[1][0][2] = incube[1][2][2];
outcube[2][2][0] = incube[2][0][0];
outcube[2][2][1] = incube[2][1][0];
outcube[2][2][2] = incube[2][2][0];
outcube[2][1][0] = incube[2][0][1];
outcube[2][1][1] = incube[2][1][1];
outcube[2][1][2] = incube[2][2][1];
outcube[2][0][0] = incube[2][0][2];
outcube[2][0][1] = incube[2][1][2];
outcube[2][0][2] = incube[2][2][2];
break;
}
case 2:
{
// Rotate whole cube on z axis
outcube[0][2][0] = incube[0][0][0];
outcube[1][2][0] = incube[0][1][0];
outcube[2][2][0] = incube[0][2][0];
outcube[0][1][0] = incube[1][0][0];
outcube[1][1][0] = incube[1][1][0];
outcube[2][1][0] = incube[1][2][0];
outcube[0][0][0] = incube[2][0][0];
outcube[1][0][0] = incube[2][1][0];
outcube[2][0][0] = incube[2][2][0];
outcube[0][2][1] = incube[0][0][1];
outcube[1][2][1] = incube[0][1][1];
outcube[2][2][1] = incube[0][2][1];
outcube[0][1][1] = incube[1][0][1];
outcube[1][1][1] = incube[1][1][1];
outcube[2][1][1] = incube[1][2][1];
outcube[0][0][1] = incube[2][0][1];
outcube[1][0][1] = incube[2][1][1];
outcube[2][0][1] = incube[2][2][1];
outcube[0][2][2] = incube[0][0][2];
outcube[1][2][2] = incube[0][1][2];
outcube[2][2][2] = incube[0][2][2];
outcube[0][1][2] = incube[1][0][2];
outcube[1][1][2] = incube[1][1][2];
outcube[2][1][2] = incube[1][2][2];
outcube[0][0][2] = incube[2][0][2];
outcube[1][0][2] = incube[2][1][2];
outcube[2][0][2] = incube[2][2][2];
break;
}
case 3:
{
//Twist Layer 1 on x axis
outcube[2][0][0] = incube[0][0][0];
outcube[2][0][1] = incube[1][0][0];
outcube[2][0][2] = incube[2][0][0];
outcube[1][0][0] = incube[0][0][1];
outcube[1][0][1] = incube[1][0][1];
outcube[1][0][2] = incube[2][0][1];
outcube[0][0][0] = incube[0][0][2];
outcube[0][0][1] = incube[1][0][2];
outcube[0][0][2] = incube[2][0][2];
break;
}
case 4:
{
//Twist Layer 1 on y axis
outcube[0][2][0] = incube[0][0][0];
outcube[0][2][1] = incube[0][1][0];
outcube[0][2][2] = incube[0][2][0];
outcube[0][1][0] = incube[0][0][1];
outcube[0][1][1] = incube[0][1][1];
outcube[0][1][2] = incube[0][2][1];
outcube[0][0][0] = incube[0][0][2];
outcube[0][0][1] = incube[0][1][2];
outcube[0][0][2] = incube[0][2][2];
break;
}
case 5:
{
//Twist Layer 1 on z axis
outcube[0][2][0] = incube[0][0][0];
outcube[1][2][0] = incube[0][1][0];
outcube[2][2][0] = incube[0][2][0];
outcube[0][1][0] = incube[1][0][0];
outcube[1][1][0] = incube[1][1][0];
outcube[2][1][0] = incube[1][2][0];
outcube[0][0][0] = incube[2][0][0];
outcube[1][0][0] = incube[2][1][0];
outcube[2][0][0] = incube[2][2][0];
break;
}
case 6:
{
//Twist Layer 2 on x axis
outcube[2][1][0] = incube[0][1][0];
outcube[2][1][1] = incube[1][1][0];
outcube[2][1][2] = incube[2][1][0];
outcube[1][1][0] = incube[0][1][1];
outcube[1][1][1] = incube[1][1][1];
outcube[1][1][2] = incube[2][1][1];
outcube[0][1][0] = incube[0][1][2];
outcube[0][1][1] = incube[1][1][2];
outcube[0][1][2] = incube[2][1][2];
break;
}
case 7:
{
//Twist Layer 2 on y axis
outcube[1][2][0] = incube[1][0][0];
outcube[1][2][1] = incube[1][1][0];
outcube[1][2][2] = incube[1][2][0];
outcube[1][1][0] = incube[1][0][1];
outcube[1][1][1] = incube[1][1][1];
outcube[1][1][2] = incube[1][2][1];
outcube[1][0][0] = incube[1][0][2];
outcube[1][0][1] = incube[1][1][2];
outcube[1][0][2] = incube[1][2][2];
break;
}
case 8:
{
//Twist Layer 2 on z axis
outcube[0][2][1] = incube[0][0][1];
outcube[1][2][1] = incube[0][1][1];
outcube[2][2][1] = incube[0][2][1];
outcube[0][1][1] = incube[1][0][1];
outcube[1][1][1] = incube[1][1][1];
outcube[2][1][1] = incube[1][2][1];
outcube[0][0][1] = incube[2][0][1];
outcube[1][0][1] = incube[2][1][1];
outcube[2][0][1] = incube[2][2][1];
break;
}
case 9:
{
//Twist Layer 3 on x axis
outcube[2][2][0] = incube[0][2][0];
outcube[2][2][1] = incube[1][2][0];
outcube[2][2][2] = incube[2][2][0];
outcube[1][2][0] = incube[0][2][1];
outcube[1][2][1] = incube[1][2][1];
outcube[1][2][2] = incube[2][2][1];
outcube[0][2][0] = incube[0][2][2];
outcube[0][2][1] = incube[1][2][2];
outcube[0][2][2] = incube[2][2][2];
break;
}
case 10:
{
//Twist Layer 3 on y axis
outcube[2][2][0] = incube[2][0][0];
outcube[2][2][1] = incube[2][1][0];
outcube[2][2][2] = incube[2][2][0];
outcube[2][1][0] = incube[2][0][1];
outcube[2][1][1] = incube[2][1][1];
outcube[2][1][2] = incube[2][2][1];
outcube[2][0][0] = incube[2][0][2];
outcube[2][0][1] = incube[2][1][2];
outcube[2][0][2] = incube[2][2][2];
break;
}
case 11:
{
//Twist Layer 3 on z axis
outcube[0][2][2] = incube[0][0][2];
outcube[1][2][2] = incube[0][1][2];
outcube[2][2][2] = incube[0][2][2];
outcube[0][1][2] = incube[1][0][2];
outcube[1][1][2] = incube[1][1][2];
outcube[2][1][2] = incube[1][2][2];
outcube[0][0][2] = incube[2][0][2];
outcube[1][0][2] = incube[2][1][2];
outcube[2][0][2] = incube[2][2][2];
break;
}
default:
printf("Incorrect syntax sent to cube twisting function. Aborting.\n\n");
exit(EXIT_FAILURE);
break;
}
for(z=0;z<3;z++)
{
for(y=0;y<3;y++)
{
for(x=0;x<3;x++)
{
cube[x][y][z]=outcube[x][y][z];
}
}
}
dir++;
}