# Scope calculation and affine cipher

2, Name of experiment project:
Scope calculation and affine cipher

4, Experimental principle:

Set the scope p, add or multiply the two numbers to get Z1, and then calculate the p of Z1 (z2 = Z1% p) to get Z2.
If Z1 is a negative number, it needs to be calculated first (z1 = Z1% P, Z1 += p) to ensure that Z1 is in the scope.

a) Algorithm principle
Affine encryption algorithm: C=Ek(m)=(k1m+k2)modn

Affine decryption algorithm: M=Dk © = k3 (c-k2) MODN (where k3 × k1mod 26=1).

i. The condition for the reversibility of affine ciphers is gcd(k, n)=1. When k1=1, the affine password becomes the addition password, and when k2=0, the affine password becomes the multiplication password.
ii. The size of the key space in the affine password is n φ (n), when n is 26 letters, φ (n)=12, so the key space of the affine password is 12 × 26 = 312.

b) Algorithm parameters
The affine cipher algorithm has four parameters: c, m, k1 and k2. c is ciphertext, M is plaintext, k1 and k2 are key.

c) Algorithm flow
The algorithm flow is as follows.

5, Objective:

1. Learn the principles of scope addition and multiplication.
2. Learning scope addition and multiplication.
3. Learn the principle of affine cryptography.
4. Learning the algorithm implementation of affine cryptography.

6, Experiment content:

1. Add and multiply with C + + scope.
2. C + + is used to realize the encryption / decryption algorithm of affine transformation.

7, Experimental equipment (name of equipment and virtual machine):
Spc_mmx_w7

8, Experimental steps:
First understand the two calculation principles, and then use C + + to program, including some special cases of processing (including the positive and negative value of the value, the case of the input characters, etc.)

9, Experimental results and analysis:

1. MOD P addition and multiplication
```#include<iostream>

using namespace std;

unsigned long long addmodp(long long x,long long y,unsigned long long p){
//Module if the input is negative
if(x<0) x = x%p + p;
if(y<0) y = y%p + p;
return (x+y)%p;
}

unsigned long long mulmodp(long long x,long long y,unsigned long long p){
if(x<0) x = x%p + p;
if(y<0) y = y%p + p;
return (x*y)%p;
}

int main(){
//Input scope P
unsigned long long p;
cout<<"Please enter scope p : ";
cin>>p;
//Enter two arbitrary numbers X Y
cout<<"Please enter two arbitrary numbers X Y: ";
long long x,y;
cin>>x>>y;
cout<<"X Y Progressive module P Results of addition:";
//Modulo P addition of X Y
cout<<"Please enter two arbitrary numbers X Y: ";
cin>>x>>y;
cout<<"X Y Progressive module P Result of multiplication:";
//Modulo P multiplication of X Y
cout<<mulmodp(x,y,p);
}

```

Code run result:

verification:
11 + 18 = 29 29 mod 23 = 23 * 1 + 3
77 * 62 = 4774 4774 mod 23 = 23*207 + 13

1. Affine cipher (including extended Euclidean algorithm and inverse element):
```#include<iostream>
#include<cstring>

using namespace std;

//extended euclidean algorithm
int exgcd(int a,int b,int &x,int &y){
if(b == 0){
x = 1;
y = 0;
return a;
}
int r = exgcd(b,a%b,x,y);
int t = x;
x = y;
y = t - a/b*y;
return r;
}

//Using extended Euclidean algorithm to calculate inverse elements
int getInverse(int a,int p){
int x,y;
if(a<0) a = a%p + p;
int ret = exgcd(a,p,x,y);
if(ret != 1){
cout<<"No inverse element"<<endl;
return 0;
}
if(x<0) x=p+x;
else return x%p;
}

//Calculate the maximum common divisor
int gcd(int k1,int k2){
return k2 == 0?k1:gcd(k2,k1%k2);
}

//Affine encryption
//The input parameters are: clear text; key k1; key k2; scope (default is 26)
int Affine_encryption(char*_ptext,int k1,int k2,int p){
int*ptext = new int[strlen(_ptext)+1];
int*ctextnum = new int[strlen(_ptext)+1];
char*ctext = new char[strlen(_ptext)+1];
//Used to determine the case of the ciphertext input, sig=0 is lower case, sig=1 is upper case
bool sig=0;
for(int i=0;(*(_ptext+i)) != '\0';i++){
//Convert characters to corresponding numbers
//ptext records the value corresponding to plaintext
if(*(_ptext+i) >= 'A'&&*(_ptext+i) <= 'Z'){
*(ptext+i) = *(_ptext+i)-'A';
sig = 1;
}
else{
*(ptext+i) = *(_ptext+i)-'a';
sig = 0;
}
//Encrypted function ciphertext = (k1 * number corresponding to plaintext + k2) mod p (P = 26)
//ctextnum records the corresponding value of ciphertext, ctext is the final ciphertext
*(ctextnum+i) = (k1 * (*(ptext+i)) + k2)%p;
//Case conversion according to the value of sig
if(sig) *(ctext+i) =  *(ctextnum+i) + 'A';
else *(ctext+i) =  *(ctextnum+i) + 'a';
cout<<*(ctext+i);
}
}

//Affine decryption
//The input parameters are: ciphertext; key k1; key k2; scope (default is 26)
int Affine_decrypt(char*_ctext,int k1,int k2,int p){
int*ctext = new int[strlen(_ctext)+1];
int*ptextnum = new int[strlen(_ctext)+1];
char*ptext = new char[strlen(_ctext)+1];
//Used to determine the case of the ciphertext input, sig=0 is lower case, sig=1 is upper case
bool sig=0;
//Computing inverse element
int inverse = getInverse(k1,p);
for(int i=0;(*(_ctext+i)) != '\0';i++){
//Convert characters to corresponding numbers
if(*(_ctext+i) >= 'A'&&*(_ctext+i) <= 'Z'){
*(ctext+i) = *(_ctext+i)-'A';
sig = 1;
}
else{
*(ctext+i) = *(_ctext+i)-'a';
sig = 0;
}
//Decryption function: clear text = (inverse of k1 * number corresponding to ciphertext - k2) mod p (P = 26)
*(ptextnum+i) = (inverse*((*(ctext+i))-k2))%p;
//Since the result may be negative when k2 is subtracted, and% p is only the remainder, it is necessary to add 26 first to ensure that% p is in [0,25]
if(*(ptextnum+i)<0) *(ptextnum+i) += 26;
//Case conversion according to the value of sig
if(sig) *(ptext+i) =  *(ptextnum+i) + 'A';
else *(ptext+i) =  *(ptextnum+i) + 'a';
cout<<*(ptext+i);
}
}

int main(){
char ptext;
int k1,k2,p;
p=26;//General p=26
cout<<"Please enter the required encrypted clear text:";
cin>>ptext;
//Input two keys, and judge whether k1 and p(p=26) are mutually prime, that is, whether k1 is reversible
//Encryption if the key is legal
cout<<"Please enter the key k1 and k2: ";
cin>>k1>>k2;
if(gcd(k1,26) == 1){
cout<<"Encryption result:" ;
Affine_encryption(ptext,k1,k2,p);
cout<<endl;
}
else{
cout<<"Entered k1 Irreversible."<<endl;
}
char ctext;
p=26;//General p=26
cout<<"Please enter the ciphertext to be decrypted:";
cin>>ctext;
//Input two keys, and judge whether k1 and p(p=26) are mutually prime, that is, whether k1 is reversible
//Decrypt if the key is legal
cout<<"Please enter the key k1 and k2: ";
cin>>k1>>k2;
if(gcd(k1,26) == 1){
cout<<"Decryption result:" ;
Affine_decrypt(ctext,k1,k2,p);
}
else{
cout<<"Entered k1 Irreversible.";
}
}

```

Code run result: verification:

(the tool is provided by the experimental platform)

10, Conclusion:
Familiar with affine cipher algorithm and realize the encryption and decryption process of affine cipher with C + +, understand the concepts of plaintext, ciphertext, encryption key and decryption key and their logical relationship, and have a different understanding of the encryption algorithm and decryption algorithm of affine cipher than before. A practical affine encryption and decryption program is completed.

11, Summary and experience:
This experiment made me familiar with the principle of affine cipher algorithm, analyze the algorithm a little, and clear the logic step by step. By using C + + to realize encryption algorithm and decryption algorithm step by step, to think about every formula and every loop nesting, we have a deeper understanding of the algorithm.

Posted on Sat, 13 Jun 2020 03:03:38 -0400 by cjosephson