Sie sind auf Seite 1von 172

Q.

1 Write a program to find the modulo multiplicative inverse for the given number ‘n’ with
respect to modulus value.
Input Data:
Number n: 169
Modulus Value: 569
Code:
#include<bits/stdc++.h>
using namespace std;
int gcd(int a,int b){
if(a%b==0)
return b;
else
return gcd(b,a%b);
}
int mod_inv(int n,int mod){
if(gcd(n,mod)!=1){
return -1;
}
int inv=1;
while((n*inv)%mod!=1){
inv++;
}
return inv;
}
int main(){
int n,mod;
cin>>n>>mod;
cout<<mod_inv(n,mod)<<endl;
}
Q.2 Write a program to encrypt the message “this is an exercise” using the following
ciphers. Ignore the space between words. Also, decrypt the message to get the original plain
text.
a) Additive cipher with key = 3
b) Multiplicative cipher with key = 15
c) Affine cipher with key = (15,20)

Code:
#include<bits/stdc++.h>
using namespace std;
int gcd(int a,int b){
if(a%b==0)
return b;
else
return gcd(b,a%b);
}
int mod_inv(int n,int mod){
if(gcd(n,mod)!=1){
return -1;
}
int inv=1;
while((n*inv)%mod!=1){
inv++;
}
cout<<"INV("<<inv<<")";
return inv;
}
string multi_cipher(string s,int key){
cout<<"KEY("<<key<<")";
char encchar;
for(int i=0;i<s.size();i++){
if(s[i]==' '){
s[i]=char('z'+1);
}
if(s[i]>='a' && s[i]<='z'+1){
int offset = s[i]-'a';
int enc = (offset*key)%27;
if(enc<0) enc+=27;
encchar = char(enc+'a');
}
else{
return "Invalid String";
}

if(encchar=='z'+1){
encchar = ' ';
}
s[i]=encchar;
}
return s;
}
string multi_decipher(string s,int key){
return multi_cipher(s,mod_inv(key,27));
}
string additive_cipher(string s,int key){
char encchar;
for(int i=0;i<s.size();i++){
if(s[i]==' '){
s[i]=char('z'+1);
}
if(s[i]>='a' && s[i]<='z'+1){
int offset = s[i]-'a';
int enc = (offset+key)%27;
if(enc<0) enc+=27;
encchar = char(enc+'a');
}
else{
return "Invalid String";
}

if(encchar=='z'+1){
encchar = ' ';
}
s[i]=encchar;
}
return s;
}
string additive_decipher(string s,int key){
return additive_cipher(s,-key);
}
string encryptMessage(string msg,int a,int b){
string cipher = "";
for (int i = 0; i < msg.length(); i++){
if(msg[i]!=' ')
cipher = cipher +(char) ((((a * (msg[i]-'a') ) + b) % 26) + 'a');
else
cipher += msg[i];
}
return cipher;
}
string decryptCipher(string cipher,int a,int b)
{
string msg = "";
int a_inv = 0;
int flag = 0;
for (int i = 0; i < 26; i++){
flag = (a * i) % 26;
if (flag == 1){
a_inv = i;
}
}
for (int i = 0; i < cipher.length(); i++){
if(cipher[i]!=' ')
msg = msg +(char) (((a_inv * ((cipher[i]+'a' - b)) % 26)) + 'a');
else
msg += cipher[i];
}
return msg;
}
int main(){
string plain = "this is an example";
string enc,dec;
ascii(plain);
enc = additive_cipher(plain,3);
cout<<enc<<endl;
dec = additive_decipher(enc,3);
cout<<dec<<endl;
enc = multi_cipher(plain,5);
cout<<enc<<endl;
dec = multi_decipher(enc,5);
cout<<dec<<endl;
enc = encryptMessage(plain,5,7);
cout<<enc<<endl;
dec = decryptCipher(enc,5,7);
cout<<dec<<endl;
}
Q.3 Write a program using a brute force attack to decipher the following message
enciphered by Alice using an additive cipher. Suppose that Alice always uses a key that is
close to her birthday, which is on 13th of the month.
Text : NCJAEZRCLASJLYODEPRLYZRCLASJLCPEHZDTOPDZQLNZTY

Code:
#include<stdio.h>
int main()
{
char ch;
int i, key;
char message[100];
printf("Enter a message to decrypt: ");
gets(message);
int d = 1;
while(d<=30){
key = d;
for(i = 0; message[i] != '\0'; ++i){
ch = message[i];
if(ch >= 'a' && ch <= 'z'){
ch = ch - key;
if(ch < 'a'){
ch = ch + 'z' - 'a' + 1;
}
dec[i] = ch;
}
else if(ch >= 'A' && ch <= 'Z'){
ch = ch - key;
if(ch < 'A'){
ch = ch + 'Z' - 'A' + 1;
}
dec[i] = ch;
}
}
d++;
printf("Decrypted message: %s key used: %d\n", dec, key);
}
printf("\n*************************************************\n");
printf("\nBased on observation the key used was 11.\n");
key = 13;
for(i = 0; message[i] != '\0'; ++i){
ch = message[i];
if(ch >= 'a' && ch <= 'z'){
ch = ch - key;
if(ch < 'a'){
ch = ch + 'z' - 'a' + 1;
}
dec[i] = ch;
}
else if(ch >= 'A' && ch <= 'Z'){
ch = ch - key;

if(ch < 'A'){


ch = ch + 'Z' - 'A' + 1;
}
dec[i] = ch;
}
}
d++;
printf("Decrypted message: %s key used: %d\n", dec, key);
return 0;
}

Q.4 Write a program to implement Playfair cipher.


Input data:
Key : GUIDANCE
Plain Text: Cryptography

Code:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MX 5
void playfair(char ch1, char ch2, char key[MX][MX]) {
int i, j, w, x, y, z;
for (i = 0; i < MX; i++) {
for (j = 0; j < MX; j++) {
if (ch1 == key[i][j]) {
w = i;
x = j;
} else if (ch2 == key[i][j]) {
y = i;
z = j;
}
}
}
if (w == y) {
x = (x + 1) % 5;
z = (z + 1) % 5;
printf("%c%c", key[w][x], key[y][z]);
printf("%c%c", key[w][x], key[y][z]);
} else if (x == z) {
w = (w + 1) % 5;
y = (y + 1) % 5;
printf("%c%c", key[w][x], key[y][z]);
printf("%c%c", key[w][x], key[y][z]);
} else {
printf("%c%c", key[w][z], key[y][x]);
printf("%c%c", key[w][z], key[y][x]);
}
}
void main() {
int i, j, k = 0, l, m = 0, n;
char key[MX][MX], keyminus[25], keystr[10], str[25] = {
0
};
char alpa[26] = {'A', 'B','C','D',
'E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y ','Z'};
printf("\nEnter key:");
gets(keystr);
printf("\nEnter the plain text:\n");
gets(str);
n = strlen(keystr);
for (i = 0; i < n; i++) {
if (keystr[i] == 'j') keystr[i] = 'i';
else if (keystr[i] == 'J') keystr[i] = 'I';
keystr[i] = toupper(keystr[i]);
}
for (i = 0; i < strlen(str); i++) {
if (str[i] == 'j') str[i] = 'i';
else if (str[i] == 'J') str[i] = 'I';
str[i] = toupper(str[i]);
}
j = 0;
for (i = 0; i < 26; i++) {
for (k = 0; k < n; k++) {
if (keystr[k] == alpa[i]) break;
else if (alpa[i] == 'J') break;
}
if (k == n) {
keyminus[j] = alpa[i];
j++;
}
}
k = 0;
for (i = 0; i < MX; i++) {
for (j = 0; j < MX; j++) {
if (k < n) {
key[i][j] = keystr[k];
k++;
} else {
key[i][j] = keyminus[m];
m++;
}
printf("%c ", key[i][j]);
}
printf("\n");
}
printf("\n\nEntered text :%s\nCipher Text :", str);
for (i = 0; i < strlen(str); i++) {
if (str[i] == 'J') str[i] = 'I';
if (str[i + 1] == '\0') playfair(str[i], 'X', key);
else {
if (str[i + 1] == 'J') str[i + 1] = 'I';
if (str[i] == str[i + 1]) playfair(str[i], 'X', key);
else {
playfair(str[i], str[i + 1], key);
i++;
}
}
}
}
Q 5: VIGENERE Cipher.
Code:
#include<bits/stdc++.h>
using namespace std;
void vigenere_cipher(string plain,string key){
vector<int> numkey;
int tmp;
for(int i=0;i<key.length();i++){
tmp=(int)key[i]-'A';
numkey.push_back(tmp%26);
}
int n=key.length();
int ci=0;
int cur_key;
string enc_text="";
for(int i=0;i<plain.length();i++){
cur_key=numkey[ci];
if(plain[i]>='A' && plain[i]<='Z'){
enc_text+='A'+((int)(plain[i]-'A')+cur_key)%27;
}
else if(plain[i]>='a' && plain[i]<='z'){
enc_text+='a'+((int)(plain[i]-'a')+cur_key)%27;
}
else{
enc_text+=' ';
}
ci=(ci+1)%n;
}
cout<<"Encrypted text : "<<enc_text<<endl;
}
int main(){
string plain,key;
getline(cin,plain);
getline(cin,key);
vigenere_cipher(plain,key);
return 0;
}
Q 6. Decryption Key of TRANSPOSITION Cipher.
Code:

#include<bits/stdc++.h>
using namespace std;
int main(){

int l;
cout<<"\n Enter length: ";
cin>>l;
int a[l+1];
cout<<"\nEnter the elements: ";
for (int i=1;i<=l;i++)
cin>>a[i];
int b[l+1];
for (int i=1;i<=l;i++) b[a[i]]=i;
cout<<"\nDecryption key : ";
for(int i=1;i<=l;i++)
cout<<b[i]<<" ";
cout<<endl;
}
Q 7. One-Pad version of VIGENERE Cipher.
Code:

#include<bits/stdc++.h>
#include<string>
using namespace std;
void onetimepad_cipher(string plain,string key,string dec){
if(key.length()<plain.length()){
cout<<"Invalid String";
return ;
}
vector<int> numkey;
int tmp=0;
for(int i=0;i<key.length();i++){
if(key[i]!=' '){
tmp=tmp*10+(int)(key[i]-'0');
}
else{
numkey.push_back(tmp);
tmp=0;
}
}
int n=key.length();
int ci=0;
int cur_key;
string enc_text="";
vector<int > asci;
for(int i=0;i<plain.length();i++){
cur_key=numkey[ci];
if(plain[i]==' '){
enc_text+=' ';
}
else{
enc_text+=(((int)plain[i]+cur_key)%256);
asci.push_back((int)(plain[i]+cur_key)%256);
}
ci=(ci+1)%n;
}
cout<<endl<<"Ascii values : ";
for(int i=0;i<plain.length();i++)
cout<<asci[i]<<" ";
cout<<endl;
cout<<"Encrypted text : "<<enc_text<<endl;
for(int i=0;i<dec.length();i++)
cout<<((int)dec[i]-asci[i]+256)%256<<" ";
cout<<endl;
}
int main(){
string plain;
getline(cin,plain);
string key;
getline(cin,key);
string dec;
getline(cin,dec);
onetimepad_cipher(plain,key,dec);
return 0;
}

Q 8. AUTO-KEY Cipher
Code:

#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
getline(cin,s);
char ans[s.length()];
int k;
cin>>k;
for(int i=0;i<s.length();i++){
if(i){
if(s[i]!=' '){
if(s[i]-'a'>=0&&s[i]-'a'<=26)
{
ans[i]=(s[i]-'a'+k)%26+'a';
k=(s[i]-'a'+k)%26;
}
else{
ans[i]=(s[i]-'A'+k)%26+'A';
k=(s[i]-'A'+k)%26;
}
}
else{
ans[i]=s[i];
}
}
else{
ans[i]=(s[i]-'A'+k)%26+'A';
k=(s[i]-'A'+k)%26;
}
cout<<ans[i];
}
cout<<endl;
}

Q 9: Write a program to encrypt & decrypt given test data using S-DES.
Key : 0111111101
Plain text: 10100010
Code:
#include<bits/stdc++.h>
using namespace std;
void p(vector<int> v){
for(int i=0;i<v.size();i++)
cout<<v[i]<<" ";
cout<<endl;
}
vector<int> permute(vector<int> v,int p[],int l){
vector<int> ans(l);
for(int i=0;i<l;i++)
ans[i] = v[p[i]-1];
return ans;
}
vector<int> cycle_shift(vector<int> v,int n){
int l = v.size();
vector<int> v1(v.begin(),v.begin()+l/2);
vector<int> v2(v.begin()+l/2,v.end());
rotate(v1.begin(),v1.begin()+n,v1.end());
rotate(v2.begin(),v2.begin()+n,v2.end());
v1.insert(v1.end(),v2.begin(),v2.end());
return v1;
}
void generate_keys(vector<int> key,vector<int> &k1,vector<int> &k2){
int a10[] = {3,5,2,7,4,10,1,9,8,6};
int a8[] = {6,3,7,4,8,5,10,9};
key = permute(key,a10,10);
k1 = cycle_shift(key,1);
k2 = cycle_shift(k1,2);
k1 = permute(k1,a8,8);
k2 = permute(k2,a8,8);
}
void fk(vector<int> &ptext, vector<int> k){
int s1[4][4] = {{1,0,3,2},{3,2,1,0},{0,2,1,3},{3,1,3,2}};
int s2[4][4] = {{0,1,2,3},{2,0,1,3},{3,0,1,0},{2,1,0,3}};
int ep[] = {4,1,2,3,2,3,4,1};
int p4[] = {2,4,3,1};
vector<int> L(ptext.begin(),ptext.begin()+4);
vector<int> R(ptext.begin()+4,ptext.end());
vector<int> v = permute(R,ep,8);
for(int i=0;i<8;i++)
v[i] = v[i] ^ k[i];
vector<int> v1(v.begin(),v.begin()+4);

vector<int> v2(v.begin()+4,v.end());
int r1 = v1[0]*2+v1[3], c1 = v1[1]*2+v1[2];
int r2 = v2[0]*2+v2[3], c2 = v2[1]*2+v2[2];
ptext.clear();
ptext.push_back(s1[r1][c1]/2);
ptext.push_back(s1[r1][c1]%2);
ptext.push_back(s2[r2][c2]/2);
ptext.push_back(s2[r2][c2]%2);
ptext = permute(ptext,p4,4);
for(int i=0;i<4;i++)
ptext[i] = ptext[i] ^ L[i];
ptext.insert(ptext.end(),R.begin(),R.end());
}
int main(){
vector<int> ptext(8),key(10),k1(8),k2(8);
int ip[] = {2,6,3,1,4,8,5,7};
int ipi[] = {4,1,3,5,7,2,8,6};
cout<<"Enter the plain text : ";
for(int i=0;i<8;i++)
cin>>ptext[i];
cout<<"Enter the key : ";
for(int i=0;i<10;i++)
cin>>key[i];
generate_keys(key,k1,k2);
cout<<"Key 1 : ";
p(k1);
cout<<"Key 2 : ";
p(k2);
ptext = permute(ptext,ip,8);
fk(ptext,k1);
rotate(ptext.begin(),ptext.begin()+4,ptext.end());
fk(ptext,k2);
ptext = permute(ptext,ipi,8);
cout<<"Cipher text : ";
p(ptext);
ptext = permute(ptext,ip,8);
fk(ptext,k2);
rotate(ptext.begin(),ptext.begin()+4,ptext.end());
fk(ptext,k1);
ptext = permute(ptext,ipi,8);
cout<<"Decrypted text : ";
p(ptext);
return 0;
}

Q 10: Implement addition, multiplication and inverse operation on GF(2 power 4) with
Irreducible polynomial 10011.
Code:
#include<bits/stdc++.h>
#define N 2
using namespace std;
string MOD;
string dp[N][N],idp[N][N],C[N][N];

string stuffZero(string s,int n)


{ while(s.length()<n)
s='0'+s;
return s;
}
int binaryToInt(string s)
{ int ans=0;
reverse(s.begin(),s.end());
for(int i=0;i<s.length();i++)
ans+=(1<<i)*(s[i]-'0');
return ans;
}
string intToBinary(int num)
{ string ans="";
while(num)
{ char c=num%2;
ans+=(c+'0');
num/=2;
}
reverse(ans.begin(),ans.end());
return ans;
}

int len(int n){


int m=0;
while(n){
n=n/2;
m++;
}
return m;
}

string divide(string m,string MOD) {


int mod=binaryToInt(MOD),n=binaryToInt(m);
while(len(n)>=len(mod)){
n=n^(mod<<(len(n)-len(mod)));
}
return intToBinary(n);
}

string add( string s, string p ) {


int n=binaryToInt(s),m=binaryToInt(p);
return divide(intToBinary(n^m), MOD);
}

string mul( string s, string p){


int n = binaryToInt(s),m = binaryToInt(p),ans=0;
for(int i=0;(1<<i)<=n;i++){
if(n&(1<<i))
ans=ans^(m<<i);
}
return divide(intToBinary(ans), MOD);
}

void matrixMul(string A[N][N],string B[N][N]){


for(int i=0;i<N;i++)
for(int j=0;j<N;j++){
C[i][j]="0";
for(int k=0;k<N;k++)
C[i][j]=add(C[i][j],mul(A[i][k],B[k][j]));
}
}

int main()
{
int c;
char t='y';
string s,p;
cout<<"Enter Irreducible polynomial : ";
cin>>MOD;

while(t == 'y'){
cout<<"\nEnter 1:Addition 2:Multiplication 3:Inverse Operation : ";
cin>>c;

switch(c){

case 1:{
cout<<"\nADDITION\nEnter the two polynomials : ";
cin>>s>>p;
cout<<"Resultant polynomial : "<<stuffZero(add(s,p),2*N)<<endl;
break;
}
case 2:{
cout<<"\nMULTIPLICATION\nEnter the two polynomials : ";
cin>>s>>p;
cout<<"Resultant polynomial : "<<stuffZero(mul(s,p),2*N);
break;
}

case 3:{
cout<<"\nINVERSE OF A MATRIX\nEnter the matrix :\n";
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
cin>>dp[i][j];

string det=add(mul(dp[0][0],dp[1][1]),mul(dp[0][1],dp[1][0]));
cout<<"Result of inverse operation : \n";
idp[0][0]=divide(dp[1][1],det);
idp[0][1]=divide(dp[1][0],det);
idp[1][0]=divide(dp[0][1],det);
idp[1][1]=divide(dp[0][0],det);
for(int i=0;i<N;i++){
for(int j=0;j<N;j++)
cout<<stuffZero(idp[i][j],2*N)<<" ";
cout<<endl;
}
}
}

cout<<"\nWant to perform more operations ? (y/n) : ";


cin>>t;
}
return 0;
}
Q 11: Implement Mix Column and Inverse Mix Column operations in S – AES with previous
Matrix as key.
Code:
#include<bits/stdc++.h>
#define N 2
using namespace std;
string MOD;
string dp[N][N],idp[N][N],C[N][N];
string stuffZero(string s,int n)
{ while(s.length()<n)
s='0'+s;
return s;
}
int binaryToInt(string s)
{ int ans=0;
reverse(s.begin(),s.end());
for(int i=0;i<s.length();i++)
ans+=(1<<i)*(s[i]-'0');
return ans;
}
string intToBinary(int num)
{ string ans="";
while(num)
{ char c=num%2;
ans+=(c+'0');
num/=2;
}
reverse(ans.begin(),ans.end());
return ans;
}
int len(int n){
int m=0;
while(n){
n=n/2;
m++;
}
return m;
}
string divide(string m,string MOD)
{ int mod=binaryToInt(MOD),n=binaryToInt(m);
while(len(n)>=len(mod)){
n=n^(mod<<(len(n)-len(mod)));
}
return intToBinary(n);
}
string add( string s, string p )
{ int n=binaryToInt(s),m=binaryToInt(p);
return divide(intToBinary(n^m), MOD);
}
string mul( string s, string p)
{ int n = binaryToInt(s),m = binaryToInt(p),ans=0;
for(int i=0;(1<<i)<=n;i++){
if(n&(1<<i))
ans=ans^(m<<i);
}
return divide(intToBinary(ans), MOD);
}
void matrixMul(string A[N][N],string B[N][N]){
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
C[i][j]="0";
for(int k=0;k<N;k++)
C[i][j]=add(C[i][j],mul(A[i][k],B[k][j]));
}
}
}
int main()
{
int t,c;
string s,p;
MOD="10011";
cout<<"\n** S-AES Encryption **\nEnter the matrix\n";
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
cin>>dp[i][j];
string det=add(mul(dp[0][0],dp[1][1]),mul(dp[0][1],dp[1][0]));
idp[0][0]=divide(dp[1][1],det);
idp[0][1]=divide(dp[1][0],det);
idp[1][0]=divide(dp[0][1],det);
idp[1][1]=divide(dp[0][0],det);
string A[N][N]={{"0110","1111"},{"0110","1011"}};
matrixMul(A,dp);
cout<<"\nMIX COLUMN: \n";
for(int i=0;i<N;i++){
for(int j=0;j<N;j++)
cout<<stuffZero(C[i][j],2*N)<<" ";
cout<<endl;
}
cout<<endl;
matrixMul(A,idp);
cout<<"\nINVERSE MIX COLUMN: \n";
for(int i=0;i<N;i++){
for(int j=0;j<N;j++)
cout<<stuffZero(C[i][j],2*N)<<" ";
cout<<endl;
}
cout<<endl;
return 0;
}

//rc4

12. IMPLEMENTATION OF RC5 ALGORITHM


#include <stdio.h>
#include <time.h>
#define KEYSIZE 16
typedef unsigned int WORD;
typedef enum { ShiftLeft, ShiftRight } ShiftDir;
typedef enum { KeyWords = KEYSIZE / 4, NumRounds = 15, TableSize = 32 } bogus;
WORD Table[ TableSize ];
WORD L[KeyWords];
WORD ROT(const WORD x, const WORD y, const ShiftDir dir)
{
const unsigned int ShiftAmt = (y & (unsigned int)0x1f);
const unsigned int ShiftBack = 0x20 - ShiftAmt;
unsigned int result;
if (dir == ShiftLeft)
result = (x << ShiftAmt) | (x >> ShiftBack);
else
result = (x >> ShiftAmt) | (x << ShiftBack);
return result;
}
void SetKey( unsigned char KeyChar )
{
static unsigned int KeyCntr;
static unsigned int Shift;
int ix = KeyCntr >> 2;
L[ ix ] = (L[ ix ] & (~(0xff << Shift))) | (KeyChar << Shift);
Shift = (Shift + 8) & 0x1f;
KeyCntr = (KeyCntr + 1) & (KEYSIZE - 1);
}
void encrypt(WORD *PlainText, WORD *CryptoText)
{
WORD i, temp; WORD A; WORD B;
A = PlainText[0] + Table[0];
B = PlainText[1] + Table[1];
for (i = 1; i <= NumRounds; i++) {
temp = i << 1;
A = ROT(A^B, B, ShiftLeft) + Table[temp];
B = ROT(A^B, A, ShiftLeft) + Table[temp+1];
}
CryptoText[0] = A; CryptoText[1] = B;
}
void decrypt(WORD *CryptoText, WORD *PlainText)
{
WORD i, temp;
WORD B;
WORD A;
B = CryptoText[1];
A = CryptoText[0];
for (i=NumRounds; i > 0; i--) {
temp = i << 1;
B = ROT(B - Table[temp+1],A, ShiftRight)^A;
A = ROT(A - Table[temp], B, ShiftRight)^B;
}
PlainText[1] = B-Table[1];
PlainText[0] = A-Table[0];
}
void setup()
{

static const WORD ROM[ TableSize ] = { 0xb7e15163, 0x5618cb1c, 0xf45044d5,


0x9287be8e, 0x30bf3847, 0xcef6b200,
0x6d2e2bb9, 0x0b65a572, 0xa99d1f2b,
0x47d498e4, 0xe60c129d, 0x84438c56,
0x227b060f, 0xc0b27fc8, 0x5ee9f981,
0xfd21733a, 0x9b58ecf3, 0x399066ac,
0xd7c7e065, 0x75ff5a1e, 0x1436d3d7,
0xb26e4d90, 0x50a5c749, 0xeedd4102,
0x8d14babb, 0x2b4c3474, 0xc983ae2d,
0x67bb27e6, 0x05f2a19f, 0xa42a1b58,
0x42619511, 0xe0990eca };
WORD i; WORD A; WORD B; WORD j;
WORD k;
for (i=0; i < TableSize; i++)
Table[i] = ROM[i];
A = 0;
B = 0;
i = 0;
j = 0;
for (k=0; k < 3*TableSize; k++) {
Table[i] = ROT(Table[i]+(A+B),3, ShiftLeft);
A = Table[i];
L[j] = ROT(L[j]+(A+B),(A+B), ShiftLeft);
B = L[j];
i= (i+1) & (TableSize-1);
j= (j+1) & (KeyWords-1);
}
}
int main()
{
WORD i, j;
WORD PlainText1[2], PlainText2[2];
WORD CryptoText[2] = {0,0};
time_t t0, t1;
char *keystr = "TheQuickBrownFox";

if (sizeof(WORD)!=4)
printf("RC5 error: WORD has %d bytes.\n",sizeof(WORD));

printf("RC5-32/12/16 encryption:\n");
for (i = 1; i<6; i++)
{
PlainText1[0] = CryptoText[0];
PlainText1[1] = CryptoText[1];
for (j=0; j < KEYSIZE; j++)
SetKey((unsigned char)keystr[j]);
setup();
encrypt(PlainText1,CryptoText);
decrypt(CryptoText,PlainText2);

printf("\n plaintext %.8lX %.8lX ---> ciphertext %.8lX %.8lX \n",


PlainText1[0], PlainText1[1], CryptoText[0], CryptoText[1]);
if (PlainText1[0]!=PlainText2[0] || PlainText1[1]!=PlainText2[1])
printf("Decryption Error!");
}
}

14. FAST EXPONENTIATION


#include <stdio.h>
int power(int a, unsigned int b, int n)
{
int res = 1;
a = a % n;
while (b > 0)
{
if (b & 1)
res = (res*a) % n;
b= b>>1; // b = b/2
a = (a*a) % n;
}
return res;
}
int main()
{
int a,b,n;
printf("Enter the base, power and modulus:");
scanf("%d%d%d",&a,&b,&n);
printf("%d^%dmod%d is %u\n",a,b,n, power(a, b, n));
return 0;
}

15. EULER TIOTIENT FUNCTION


#include <stdio.h>
int gcd(int a, int b)
{
if (a == 0)
return b;
return gcd(b % a, a);
}
int phi(unsigned int n)
{
unsigned int result = 1;
for (int i = 2; i < n; i++)
if (gcd(i, n) == 1)
result++;
return result;
}
int main()
{
int n;
printf("Enter the number:");
scanf("%d",&n);
printf("phi(%d) = %d\n", n, phi(n));
return 0;
}

16. EXTENDED EUCLIDEAN ALGORITHM


#include<iostream>
using namespace std;
int gcdExtended(int a, int b, int *x, int *y);
void modInverse(int a, int m)
{
int x, y;
int g = gcdExtended(a, m, &x, &y);
if (g != 1)
cout << "Inverse doesn't exist";
else
{
int res = (x%m + m) % m;
cout << "Modular multiplicative inverse is " << res;
}
}

int gcdExtended(int a, int b, int *x, int *y)


{
if (a == 0)
{
*x = 0, *y = 1;
return b;
}

int x1, y1;


int gcd = gcdExtended(b%a, a, &x1, &y1);
*x = y1 - (b/a) * x1;
*y = x1;

return gcd;
}

int main()
{
int a,m;
printf("\n Enter a and m:");
scanf("%d%d",&a,&m);
modInverse(a, m);
return 0;
}

17. RSA ALGORITHM


#include<stdio.h>
#include<conio.h>
#include<math.h>
int encrypt(int);int decrypt(int);
int prime(int);int expo(int,int,int);
int n,phi,p,q,e,d;
int main()
{
int i,s,m,c;
printf("***RSA IMPLEMENTATION***");
printf("\n Enter two prime numbers:");
scanf("%d%d",&p,&q);
n=p*q;
phi=(p-1)*(q-1);
printf("\n phi value is:%d",phi);
printf("\n Enter the value of e which is less than phi:");
scanf("%d",&e);
if(prime(p)&&prime(q)&&prime(e))
{
d=1;
do
{
s=(d*e)%phi;
d++;
}
while(s!=1);
d=d-1;
printf("\n Public Key:(%d,%d)",e,n);
printf("\n Private Key:(%d)",d);
printf("\n **ENCRYPTION**");
printf("\n Plain Text:");
scanf("%d",&m);
encrypt(m);
printf("\n **DECRYPTION**");
printf("\n Cipher text:");
scanf("%d",&c);
decrypt(c);
printf("\n");
}
else
return 0;
}

int encrypt(int m)
{
int c;
c=expo(m,e,n);
printf("\n Encrypted Text:%d",c);
}

int decrypt(int c)
{
int m;
m=expo(c,d,n);
printf("\n Decrypted Text:%d",m);
}

int expo(int a,int b,int n)


{
int d=1,i=0,q=b;
int bits[100];
while(q!=0)
{
bits[i]=q%2;
i++;
q=q/2;
}
while(i>=0)
{
d=(d*d)%n;
if(bits[i]==1)
{
d=(a*d)%n;
}
i--;
}
return d;
}
int prime(int pr)
{
int i,j;
j=pr/2;
for(i=2;i<=j;i++)
{
if(pr%i==0)
return 0;
}
return 1;
}

Q 18: Write a program to Generate primitive roots of Multiplicative Group Z29*.


Code:
#include<bits/stdc++.h>
using namespace std;
int main(){
int z=29;
cin>>z;
int ar[z];
int full=(z*(z-1))/2,a=1,s;
for(int i=1;i<z;i++){
a=1;
s=0;
for(int j=0;j<z;j++) ar[j]=0;
for(int k=1;k<z;k++){
a=(a*i)%z;
ar[a]=1;
}
if(ar[0]==0){
for(int j=1;j<z;j++) s+=ar[j];
if(s==z-1) cout<<i<<endl;
}
}
return 0;
}

18. PRIMITIVE ROOTS OF A MULTIPLICATIVE GROUP


#include<bits/stdc++.h>
#include<time.h>
using namespace std;
int gcd(int a,int b){
if(!b)
return a;
return gcd(b,a%b);
}
int fastexp(int x,int y, int mod){
int res=1;
while(y){
if(y&1)
res=(res*x)%mod;
x=(x*x)%mod;
y=y>>1;
}
return res;
}
vector<int> find_generator(int prime){
int i;
vector<int> elements, primitives;
for(i=0;i<prime;i++){
if(gcd(prime,i)==1)
elements.push_back(i);
}
int order=elements.size();
for(i=0;i<order;i++){
int j;
vector<bool> p(prime,0);
for(j=0;j<prime;j++){
int t=fastexp(elements[i],j,prime);
p[t]=1;
}
for(j=1;j<prime;j++)
if(p[j]==0)
break;
if(j==prime)
primitives.push_back(elements[i]);
}
return primitives;
}
int main(){
int prime;
cout<<"Enter the value of p"<<endl;
cin>>prime;
vector<int> generators=find_generator(prime);
cout<<"The generators of prime "<<prime<<" are: "<<endl;
for(auto generator:generators)
cout<<generator<<" ";
return 0;
}
Q 19. In Multiplicative group < Z421*,x >
a. Encrypt the Input: “Learning is Studying” (Consider ASCII Values) with Elgamal
Cryptosystem.
b. Decrypt the above generated Cipher.
Code:
#include<bits/stdc++.h>
using namespace std;

int power(int a,int b,int prime)


{
int res=1;
for(int i=0;i<b;i++)
res=(res%prime*a%prime)%prime;
return res;
}
int gcdextended(int a,int b,int *x,int *y)
{
if(a==0)
{
*x=0;
*y=1;
return b;
}
int x1,y1;
int g=gcdextended(b%a,a,&x1,&y1);
*x=y1-(b/a)*x1;
*y=x1;
return g;
}
int mod_inv(int n,int mod)
{
int x,y;
int g=gcdextended(n,mod,&x,&y);
if(g!=1)
cout<<"Inverse doesn't exist"<<endl;
else
{
int res=(x%mod+mod)%mod;
return res;
}
}
void getprimitiveroots(int prime,vector<int> &a)
{
for(int r=1;r<prime;r++)
{
bool isprimitive=true;
map<int,bool> m;
for(int x=0;x<prime-1;x++)
{
int t=power(r,x,prime);
if(m.find(t)!=m.end())
{
isprimitive=false;
break;
}
m[t]=true;
}
if(isprimitive)
a.push_back(r);
m.clear();
}
}
vector<int> encryption(string text,int e1,int d,int prime,int &c1)
{
int r=rand()%prime;
int e2=power(e1,d,prime);
c1=power(e1,r,prime);

vector<int> c2;

for(int i=0;i<text.length();i++)
{
int temp=(power(e2,r,prime)*text[i])%prime;
c2.push_back(temp);
}
return c2;
}
string decryption(vector<int> ans,int d,int c1,int prime)
{
string temp="";
for(int i=0;i<ans.size();i++)
{
int t=(ans[i]*mod_inv(power(c1,d,prime),prime))%prime;
temp.push_back(char(t));
}
return temp;
}
int main()
{
cout<<"Input"<<endl;
int prime;
cin>>prime;
string text;
cin>>text;
vector<int> rootset;
getprimitiveroots(prime,rootset);
int n=rootset.size();
srand (time(NULL));
int e1=rootset[rand()%n];
int d=rootset[rand()%n];
int c1;
vector<int> ans=encryption(text,e1,d,prime,c1);

cout<<"Encrypted Text"<<endl;
for(int i=0;i<ans.size();i++)
cout<<ans[i]<<" ";
cout<<endl;
string decrypted=decryption(ans,d,c1,prime);
cout<<"Decrypted Text"<<endl;
cout<<decrypted<<endl;
}

Q 20: Given the super increasing tuple b = [7, 11, 23, 43, 87, 173, 357], r = 41, and modulus
n = 1001, write a program to encrypt and decrypt the letter “a” using knapsack
cryptosystem. Use [7 6 5 1 2 3 4] as the permutation table.
Code:
#include<bits/stdc++.h>
using namespace std;

int tobin(int n, int tup[]){


int i = 6;
while(n>0){
int j = n%2;
tup[i--] = j;
n/=2;
}
}
int main(){
int m;
cout<<"No. of terms: ";
cin>>m;
cout<<"Enter items: ";
int b[m];
for(int i=0;i<m;i++)
cin>>b[i];
int r, n;
cout<<"Enter r and n";
cin>>r>>n;
int t[m];
for(int i=0;i<m;i++){
t[i] = (b[i]*r)%n;
}
int a[m];
int perm[m];
cout<<"Enter permutation matrix: ";
for(int i=0;i<m;i++) cin>>perm[i];
for(int i=0;i<m;i++){
a[i] = t[perm[i]-1];
}
char c;
cout<<"Enter the message to encrypt: ";
cin>>c;
int tup[7];
tobin((int)(c), tup);
for(int i=0;i<7;i++)
cout<<tup[i];
cout<<endl;
int sum = 0;
for(int i=0;i<m;i++)
sum+=(tup[i]*a[i]);
cout<<sum<<endl;
int rinv;
for(int i=1;i<n;i++){
if((r*i)%n == 1) rinv = i;
}
int sdash = (sum*rinv)%n;
cout<<sdash<<endl;

for(int i=6;i>=0;i--){
if(sdash>=b[i]){
tup[i] = 1;
sdash = sdash-b[i];
}
else tup[i] = 0;
}
for(int i=0;i<7;i++)
cout<<tup[i];
cout<<endl;
int a1[7];
for(int i=0;i<m;i++){
a1[i] = tup[perm[i]-1];
}
for(int i=0;i<7;i++)
cout<<a1[i];
cout<<endl;
int ascii = 0;
int j=0;
for(int i=6;i>=0;i--){
ascii += a1[i]*pow(2,j);
j++;
}
cout<<ascii<<endl;
cout<<(char)(ascii-97+'a')<<endl;
}

21/22. ELLIPTIC CURVE CRYPTOGRAPHY of E29(1,27) a) Generate points b) Perform addition


and multiplication.
#include <bits/stdc++.h>
using namespace std;
int A,B,P;
struct point
{ int x,y; };
vector<int> findY(int a,int mod)
{ int y=0;
vector<int> vec;
for(;y<mod;y++)
{
if((y*y)%mod==a%mod)
vec.push_back(y);
}
return vec;
}
int gcdExtended(int a, int b, int *x, int *y)
{
if (a == 0)
{
*x = 0, *y = 1;
return b;
}
int x1, y1; // To store results of recursive call
int gcd = gcdExtended(b%a, a, &x1, &y1);
*x = y1 - (b/a) * x1;
*y = x1;
return gcd;
}
int inv_mod(int a,int p)
{
int x, y;
int g = gcdExtended(a, p, &x, &y);
if (g != 1)
return -1;
else
{
int res = (x%p + p) % p;
return res;
}
}
point add(point a, point b)
{
int lambda;
if(a.x==b.x and a.y==b.y)
{
lambda = (P+(3*a.x*a.x+A+P)%P)%P;
int temp = (P+inv_mod((P+2*a.y)%P,P))%P;
lambda = (lambda*temp)%P;
}
else if(a.x==b.x)
{
return {0,0};
}
else
{ lambda = (P+(b.y-a.y)%P)%P;
int temp = (P+inv_mod((P+b.x-a.x)%P,P))%P;
lambda = (lambda*temp)%P;
}
point c;
//cout<<lambda<<endl;
c.x = (P + ((lambda*lambda)%P - a.x%P - b.x%P)%P)%P;
int t = (a.x-c.x)%P;
//cout<<t<<endl;
c.y = (100*P+((lambda*t)%P - a.y)%P)%P;
return c;
}
int main() {
cout<<"** Elliptic Curve Cryptography **";
cout<<"\n\nEnter a, b, p: ";
cin>>A>>B>>P;
point a,b;
vector<pair<int,int> > v;
int mod = P;
for(int x=0;x<mod;x++){
int h=x*x*x+A*x+B;
vector<int> vec=findY(h,mod);
for(int j=0;j<vec.size();j++){
v.push_back(make_pair(x,vec[j]));
}
}
cout<<"\nTotal Points are "<<v.size()<<endl;
cout<<"The Points are: "<<endl;
for(int i=0;i<v.size();i++){
cout<<"("<<v[i].first<<" "<<v[i].second<<") ";
}
int k;
// points input
cout<<"\n\n Enter Two points: ";
cin>>a.x>>a.y>>b.x>>b.y;
point c = add(a,b);
cout<<"\nFinal Sum: ";
if(c.x==0 and c.y==0)
cout<<"POINT AT INFINITY\n";
cout<<c.x<<" "<<c.y<<endl;

cout<<"\nEnter the points and the number: ";


cin>>a.x>>a.y;
cin>>k;
c=a;
for(int i=1;i<=k-1;i++)
{
//cout<<c.x<<" "<<c.y<<" adds to "<<a.x<<" "<<a.y<<endl;
if(c.x==0 and c.y==0)
{ c=a;cout<<"<INFINITY CASE at iter "<<i<<">\n";continue; }
c=add(c,a);
}
if(c.x==0 and c.y==0)
cout<<"POINT AT INFINITY\n";
cout<<"Final Product: ";
cout<<c.x<<" "<<c.y<<endl;
return 0;
}

23. Implement Elgamal Digital Signature


#include<bits/stdc++.h>
using namespace std;
int modInverse(int a, int m){
a = a%m;
for (int x=1; x<m; x++)
if ((a*x) % m == 1)
return x;
}
int exp(int b,int e,int m){
int r=1;
while(e>0){
if(e&1)
r=(r*b)%m;
e/=2;
b=(b*b)%m;
}
return r;
}
int main(){
int m,p,e1,d,r;
cout<<"** Elgamal Digital Signature **\nEnter m, p, e1, d ,r: ";
cin>>m>>p>>e1>>d>>r;
int e2=exp(e1,d,p);
int s1=exp(e1,r,p);
int rr=modInverse(r,p-1);
int s2=((m-d*s1)*rr)%(p-1);
while(s2<0)
s2+=p-1;
s2=s2%(p-1);
int v2=(exp(e2,s1,p)*exp(s1,s2,p))%p;
int v1=exp(e1,m,p);
cout<<"\nv1 = "<<v1<<endl<<"v2 = "<<v2<<endl;
if(v1==v2)
cout<<"Accept"<<endl;
else
cout<<"Reject"<<endl;
return 0;
}

24. ELGAMAL SIMULATED BY ELLIPTIC CURVE CRYPTOGRAPHY


#include<bits/stdc++.h>
using namespace std;
struct coord
{ int x; int y; };
int inverse(int a, int p)
{
for(int i = 1; i < p; i += 1)
if((a * i) % p == 1)
return i;
}
coord generate(int a, int b, int p)
{
vector<int> y_2;
vector<int> x;
for(int i = 0; i < p; i += 1)
{
y_2.push_back((i * i * i + a * i + b) % p);
x.push_back(i);
}
for(int i = 0; i < p; i += 1)
{
for(int j = 0; j < x.size(); j += 1)
{
if(y_2[j] == ((i * i) % p))
{
coord res;
res.x = x[j];
res.y = i;
return res;
} } } }
int find_lambda(struct coord a, struct coord b, int p)
{
int lambda;
if((a.x == b.x) && (a.y == b.y))
{
int nr = (p + 3 * a.x * a.x + 1);int dr = (p + 2 * a.y);
lambda = (p + nr * inverse(dr, p)) % p;
}
else
{
int nr = (b.y - a.y); int dr = (b.x - a.x);
lambda = (p + nr * inverse(dr, p)) % p;
}
return lambda;
}
struct coord addn(struct coord a, struct coord b, int p)
{
struct coord res; int lambda = find_lambda(a, b, p);
res.x = (p + lambda * lambda - a.x - b.x) % p;
res.y = (p + lambda * (a.x - res.x) - a.y) % p;
return res;
}

struct coord mult(int d, struct coord e1, int p)


{
coord e2; int v = d;
struct coord temp;
temp.x = e1.x; temp.y = e1.y;
for(int i = 0; i < v; i += 1)
{
if(temp.x < 0)
temp.x += p;
if(temp.y < 0)
temp.y += p;
if(temp.x == e1.x && (temp.y != e1.y))
{
temp = e1;
i += 2;
}
else temp = addn(temp, e1, p);
}
e2.x = ((temp.x >= 0) ? (temp.x) : (p + temp.x));
e2.y = ((temp.y >= 0) ? (temp.y) : (p + temp.y));
return e2;
}

int main()
{
int p, a, b, d; cout<<"** ELLPTIC CURVE SIMULATING ELGAMAL **\nEnter p, a, b, d:
";
cin >> p >> a >> b >> d;
struct coord plain;
struct coord e1 = generate(a, b, p); struct coord e2 = mult(d, e1, p);
cout << "E1 " << e1.x << " " << e1.y << endl;
cout << "E2 " << e2.x << " " << e2.y << endl;
int r = 27;
struct coord c1 = mult(r, e1, p);
cout << "C1 " << c1.x << " " << c1.y << endl;
cout<<"\n Enter the number of test case: "; int t; cin>>t;
for(int i=0;i<t;i++){
cout<<"\nENter Coordinates: ";
cin >> plain.x >> plain.y;
struct coord c2 = addn(plain, mult(r, e2, p), p);
cout << "C2 " << c2.x << " " << c2.y << endl;
struct coord decr = addn(c2, mult(-1, mult(d, c1, p), p), p);
cout << "Decrypted " << ((decr.x >= 0) ? (decr.x) : (p + decr.x)) << " " << ((decr.y >= 0)
? (decr.y) : (p + decr.y)) << endl;
}
return 0;
}

//md5

27. RSA DIGITAL SIGNATURE


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll modexp(ll a,ll p,ll m)
{
ll r=1;
while(p!=0)
{
if(p&1)
r=(r*a)%m; a=(a*a)%m;
p=p/2;
}
return r;
}
ll extended(ll a,ll b,ll &x,ll &y)
{
if(a==0)
{ x=0; y=1; return b;
}
ll x1,y1;
ll gcd = extended(b%a,a,x1,y1);
x = y1-(b/a)*x1; y = x1;
}
ll mulInverse(ll a,ll m)
{
if(__gcd(a,m)!=1)
return -1;
ll x,y; ll g = extended(a,m,x,y);
return (x+m)%m;
}
int main()
{
cout << "** RSA ALgorithm **\nEnter p and q:";
ll p ,q; cin >> p >> q;
ll n = p*q; ll phi = (p-1)*(q-1);
ll e = 3; cout << "phi ( " << n <<") = "<< phi << "\n";
ll d;
for(ll i=2;;i++)
{
d = mulInverse(i,phi);
if(d!=-1) {e=i; break;}
}
cout << "\nEnter m :"; ll m; cin >> m;
cout << "\nSIGNED MESSAGE \n";
ll sign; cout << (sign=modexp(m,d,n)) << "\n";
cout << "Verification : \n"; cout << modexp(sign,e,n) << "\n";
return 0;
}

28. Append Bits to the given input according to SHA-1 and print results in Hexadecimal
representation.
#include<bits/stdc++.h?
using namespace std;

vector<int>int_bnry(int a){
vector<int> r;
if(a==0){
r.push_back(0);
return r;
}
while(a>0){
int temp = a%2;
a=a/2;
r.push_back(temp);
}
if(r.size()<8)
{
inti=r.size();
while(i<8){
r.push_back(0);
i++;
}
}
reverse(r.begin(),r.end());
return r;
}

vector<int> pad(vector<int> v){


int n=v.size();
v.push_back(1);
int m = n+1;
while(m%512<448){
v.push_back(0);
m++;
}
vector<int> x=int_bnry(n);
n=64-x.size();//1794
for(inti=1;i<=n;i++) v.push_back(0);
for(inti=0;i<x.size();i++) v.push_back(x[i]);
return v;
}

vector<int>b_hex(vector<int> v){
if(v.size()%512==0){//1794
vector<int> X;
inti,j=v.size()/4;
for(i=0;i<j;i++){
int x = (v[4*i]?pow(2,3):0) + (v[4*i+1]?pow(2,2):0) +
(v[4*i+2]?pow(2,1):0) + (v[4*i+3]?pow(2,0):0);
X.push_back(x);
}return X;
}else{
cout<<"\nNot allowed\n";
return v;
}
}

vector<int> padding(){
string p;
cout<<"\nEnter the text: ";
cin>>p;
int n=p.length(),k=0;
vector<int> r;//1794
for(inti=0;i<n;i++){
vector<int> v= int_bnry(int(p[i]));
for(int j=0;j<v.size();j++){
r.push_back(v[j]);
k++;
}
}
vector<int>r_pad=pad(r);
returnr_pad;
}

int main(){
vector<int>r_pad=padding();
vector<int>r_hex = b_hex(r_pad);
cout<<"\nHex representation of padded message is: "<<endl;
for(inti=0;i<r_hex.size();i++){//1794
if(r_hex[i]>9) cout<<char(r_hex[i]+55);
else cout<<r_hex[i];
cout<<endl;
return 0;
}

29. Implement 4 major operations/processes with given below input and print result in
hexadecimal representation.
A=01234567
B=89ABCDEF
C=FEDCBA98
D=76543210

Process 1: (B AND C) OR ((NOT B) AND D)


Process 2: (B XOR C XOR D)
Process 3: (B AND C) OR (B AND D) OR (C AND D)
Process 4: (B XOR C XOR D)

#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<math.h>
#include<stdlib.h>
#define rotateleft(x,n) ((x<<n) | (x>>(32-n)))
#define rotateright(x,n) ((x>>n) | (x<<(32-n)))
void SHA1(unsigned char * str1)
{
int i,j;
unsigned long int h0,h1,h2,h3,h4,a,b,c,d,e,f,k,temp;
h0 = 0x67452301;
h1 = 0xEFCDAB89;
h2 = 0x98BADCFE;
h3 = 0x10325476;
h4 = 0xC3D2E1F0;
unsigned char * str;
str = (unsigned char *)malloc(strlen((const char *)str1)+100);
strcpy((char *)str,(const char *)str1);
int current_length = strlen((const char *)str);
int original_length = current_length;
str[current_length] = 0x80;
str[current_length + 1] = '\0';
char ic = str[current_length];
current_length++;
int ib = current_length % 64;
if(ib<56)
ib = 56-ib;
else
ib = 120 - ib;
for(int i=0;i < ib;i++)
{
str[current_length]=0x00;
current_length++;
}
str[current_length + 1]='\0';
for(i=0;i<6;i++)
{
str[current_length]=0x0;
current_length++;
}
str[current_length] = (original_length * 8) / 0x100 ;
current_length++;
str[current_length] = (original_length * 8) % 0x100;
current_length++;
str[current_length+i]='\0';
int number_of_chunks = current_length/64;
unsigned long int word[80];
for(i=0;i<number_of_chunks;i++)
{
for(int j=0;j<16;j++)
{
word[j] = str[i*64 + j*4 + 0] * 0x1000000 + str[i*64 + j*4 + 1] *
0x10000 + str[i*64 + j*4 + 2] * 0x100 + str[i*64 + j*4 + 3];
}
for(j=16;j<80;j++)
{
word[j] = rotateleft((word[j-3] ^ word[j-8] ^ word[j-14] ^ word[j-16]),1);
}
a = h0;
b = h1;
c = h2;
d = h3;
e = h4;
for(int m=0;m<80;m++)
{
if(m<=19)
{
f = (b & c) | ((~b) & d);
k = 0x5A827999;
}
else if(m<=39)
{
f = b ^ c ^ d;
k = 0x6ED9EBA1;
}
else if(m<=59)
{
f = (b & c) | (b & d) | (c & d);
k = 0x8F1BBCDC;
}
else
{
f = b ^ c ^ d;
k = 0xCA62C1D6;
}
temp = (rotateleft(a,5) + f + e + k + word[m]) & 0xFFFFFFFF;
e = d;
d = c;
c = rotateleft(b,30);
b = a;
a = temp;
}
h0 = h0 + a;
h1 = h1 + b;
h2 = h2 + c;
h3 = h3 + d;
h4 = h4 + e;
}
printf("\n\n");
printf("Hash: %x %x %x %x %x",h0, h1, h2, h3, h4);
printf("\n\n");
}
void SHA1_part3(unsigned char * str1)
{
int i,j;
unsigned long int h0,h1,h2,h3,h4,a,b,c,d,e,f,k,temp;
h0 = 0x01234567;
h1 = 0x89ABCDEF;
h2 = 0xFEDCBA98;
h3 = 0x76543210;
h4 = 0xC3D2E1F0;
unsigned char * str;
str = (unsigned char *)malloc(strlen((const char *)str1)+100);
strcpy((char *)str,(const char *)str1);
int current_length = strlen((const char *)str);
int original_length = current_length;
str[current_length] = 0x80;
str[current_length + 1] = '\0';
char ic = str[current_length];
current_length++;
int ib = current_length % 64;
if(ib<56)
ib = 56-ib;
else
ib = 120 - ib;
for(int i=0;i < ib;i++)
{
str[current_length]=0x00;
current_length++;
}
str[current_length + 1]='\0';
for(i=0;i<6;i++)
{
str[current_length]=0x0;
current_length++;
}
str[current_length] = (original_length * 8) / 0x100 ;
current_length++;
str[current_length] = (original_length * 8) % 0x100;
current_length++;
str[current_length+i]='\0';
int number_of_chunks = current_length/64;
unsigned long int word[80];
for(i=0;i<number_of_chunks;i++)
{
for(int j=0;j<16;j++)
{
word[j] = str[i*64 + j*4 + 0] * 0x100 + str[i*64 + j*4 + 1] ;
}
for(j=16;j<80;j++)
{
word[j] = rotateleft((word[j-3] ^ word[j-8] ^ word[j-14] ^ word[j-16]),1);
}
a = h0;
b = h1;
c = h2;
d = h3;
e = h4;
for(int m=0;m<80;m++)
{
f = (b & c) | ((~b) & d);
k = 0xFEDCBA98;

temp = (rotateleft(a,5) + f + e + k + word[m]) & 0xFFFFFFFF;


e = d;
d = c;
c = rotateleft(b,30);
b = a;
a = temp;}
// second 32 bit
for(int j=0;j<16;j++)
{
word[j] = str[i*64 + j*4 + 2] * 0x100 + str[i*64 + j*4 + 3];
}
for(j=16;j<80;j++)
{
word[j] = rotateleft((word[j-3] ^ word[j-8] ^ word[j-14] ^ word[j-16]),1);
}
for(int m=0;m<80;m++)
{
f = b ^ c ^ d;
k = 0x76543210;

temp = (rotateleft(a,5) + f + e + k + word[m]) & 0xFFFFFFFF;


e = d;
d = c;
c = rotateleft(b,30);
b = a;
a = temp;}

h0 = h0 + a;
h1 = h1 + b;
h2 = h2 + c;
h3 = h3 + d;
h4 = h4 + e;
}
printf("\n\n");
printf("Hash: %x %x %x %x %x",h0, h1, h2, h3, h4);
printf("\n\n");
}
void SHA1_part2()
{
int i,j;
unsigned long int h0,h1,h2,h3,h4,a,b,c,d,e,f,k,temp;
h0 = 0x01234567;
h1 = 0x89ABCDEF;
h2 = 0xFEDCBA98;
h3 = 0x76543210;
h4 = 0xC3D2E1F0;
a = h0;
b = h1;
c = h2;
d = h3;
e = h4;
f = (b & c) | ((~b) & d);
printf("Op 1: %x \n",f);
f = b ^ c ^ d;
printf("Op 2: %x \n",f);
f = (b & c) | (b & d) | (c & d);
printf("Op 3: %x \n",f);
f = b ^ c ^ d;
printf("Op 4: %x \n",f);
}
int main()
{SHA1((unsigned char *)"hello");
SHA1_part2();
SHA1_part3((unsigned char *)"hello");
return 0;
}

30. Implement 2 round of sha-1 with given 2 inputs.

#include<bits/stdc++.h>
#include"padding.cpp"
#include"SHa_opp.cpp"
vector<int> w;
using namespace std;
stringlc_shift(string v,int round){
int n=v.length();
for(inti=0;i<round;i++){
char temp=v[0];//1794
for(int j=0;j<n-1;j++) v[j]=v[j+1];
v[n-1]=temp;
}
return v;
}
int SHA_1(string &a,string&b,string&c,string&d,string&e,int round){
string r1=sha_opp(a,b,c,d,e,round);
string w0="",k0="FEDCBA98",k1="76543210";
for(inti=0;i<32;i++) w0+=char(w[i+((round-1)*32)]+'0');
if(round==2) k0=k1;
string a_l5=lc_shift(me(a,ma),5),b_l30=lc_shift(me(b,ma),30);
b=a;d=c;c=me2(b_l30,m2);//1794
a=me2(ro(ro(ro(ro(r1,e),a_l5),w0),k0),m2);e=d;
cout<<"\nAnswer after round "<<round<<" is: \n";
cout<<a<<"\t"<<b<<"\t"<<c<<"\t"<<d<<"\t"<<e<<endl;
return 0;
}
int main(){
w=padding();
stringa,b,c,d,e;
cout<<"\nEnter five strings a, b, c, d, e : \n";
cin>>a>>b>>c>>d>>e;
SHA_1(a,b,c,d,e,1);
SHA_1(a,b,c,d,e,2);
return 0;
}

//Brute force decipher the text using additive cipher:


NCJAEZRCLASJLYODEPRLYZRCLASJLCPEHZDTOPDZQLNZTY
#include <stdio.h>
using namespace std;

int main() {
char ch;
int i, key;
char message[100];
printf("Enter a message to decrypt: ");
gets(message);
int d = 1;
while(d<=30){
key = d;
for(i = 0; message[i] != '\0'; ++i){
ch = message[i];
if(ch>='a' && ch<='z'){
ch = ch - key;
if(ch < 'a'){
ch = ch + 'z' - 'a' + 1;
}
dec[i] = ch;
}
else if(ch >= 'A' && ch <= 'Z'){
ch = ch - key;
if(ch < 'A'){
ch = ch + 'Z' - 'A' + 1;
}
dec[i] = ch;
}
}
d++;
printf("Decrypted message: %s key used: %d\n", dec, key);
}
printf("\n**********************\n");
printf("\nBased on observation the key used was 11\n");
key = 13;
for(i = 0; message[i]!= '\0'; ++i){
ch = message[i];
if(ch >= 'a' && ch <= 'z'){
ch = ch - key;
if(ch < 'a'){
ch = ch + 'z' - 'a' + 1;
}
dec[i] = ch;
}
else if(ch >= 'A' && ch <= 'Z'){
ch = ch - key;
if(ch < 'a'){
ch = ch + 'z' - 'a' + 1;
}
dec[i] = ch;
}
}
d++;
printf("Decrypted message: %s key used: %d\n", dec, key);
return 0;
}
/*

Q. Write a program to implement Playfair cipher.


Input data
:
Key
:GUIDANCE
Plain Text
: Cryptography
*/
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#define MX 5
void playfair(char ch1, char ch2, char key[MX][MX]){
int i, j, w, x, y, z;
for(i = 0; i<MX; i++){
for(j = 0; j<MX; j++){
if(ch1 == key[i][j]){
w = i;
x = j;
}
else if(ch2 == key[i][j]){
y = i;
z = j;
}
}
}
if(w == y){
x = (x + 1) % 5;
z = (z + 1) % 5;
printf("%c %c", key[w][x], key[y][z]);
printf("%c %c", key[w][x], key[y][z]);
}
else if(x == z){
w = (w + 1) % 5;
y = (y + 1) % 5;
printf("%c %c", key[w][x], key[y][z]);
printf("%c %c", key[w][x], key[y][z]);
}
else{
printf("%c %c", key[w][z], key[y][x]);
printf("%c %c", key[w][z], key[y][x]);
}
}
void main(){
int i, j, k = 0, l, m = 0, n;
char key[MX][MX], keyminus[25], keystr[10], str[25] = {0};
char alpa[26] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z'};
printf("\nEnter key: ");
gets(keystr);
printf("\nEnter the plain text:\n");
gets(str);
n = strlen(keystr);
for(i = 0; i<n; i++){
if(keystr[i] == 'j'){
keystr[i] = 'i';
}
else if(keystr[i] == 'J'){
keystr[i] = 'I';
}
keystr[i] = toupper(keystr[i]);
}
for(i = 0; i<strlen(str); i++){
if(str[i] == 'j'){
str[i] = 'i';
}
else if(str[i] == 'J'){
str[i] = 'I';
}
str[i] = toupper(str[i]);
}
j = 0;
for(i = 0; i<26; i++){
for(k = 0; k<n; k++){
if(keystr[k] == alpa[i]){
break;
}
else if(alpa[i] == 'J'){
break;
}
}
if(k == n){
keyminus[j] = alpa[i];
j++;
}
}
k = 0;
for(i = 0; i<MX; i++){
for(j = 0; j<MX; j++){
if(k<n){
key[i][j] = keystr[k];
k++;
}
else{
key[i][j] = keyminus[m];
m++;
}
printf("%c", key[i][j]);
}
printf("\n");
}
printf("\n\nEntered text: %s\nCipher Text: ", str);
for(i = 0; i<strlen(str); i++){
if(str[i] == 'J'){
str[i] = 'I'; //the capital I might be l
}
if(str[i+1] == '\0'){
playfair(str[i], 'X', key);
}
else{
if(str[i+1] == 'J'){
str[i+1] = 'I';
}
if(str[i] == str[i+1]){
playfair(str[i], 'X', key);
}
else{
playfair(str[i], str[i+1], key);
i++;
}
}
}
}

/*
Q. Write a program to encrypt the message "this is an exercise" using the following cipher
following cipher ignore the
space between words. Also, decrypt the message to get the original plain text,
a) Additive cipher with key = 3
b) Multiplicative cipher with key = 15
c) Affine cipher with key = (15,20)
*/

#include<bits/stdc++.h>
using namespace std;
int gcd(int a, int b){
if(a % b == 0){
return b;
}
else{
return gcd(b, a % b);
}
}
int mod_inv(int n, int mod){
if(gcd(n, mod)!=1){
return -1;
}
int inv = 1;
while((n*inv) % mod != 1){
inv++;
}
cout<<"INV("<<inv<<")";
return inv;
}
string additive_cipher(string s, int key){
char encchar;
for(int i = 0; i<s.size(); i++){
if(s[i] == ''){
s[i] = char('z' + 1);
}
if(s[i] >= 'a' && s[i]<='z'+1){
int offset = s[i] - 'a';
int enc = (offset + key) %27;
if(enc<0){
enc += 27;
}
encchar = char(enc + 'a');
}
else{
return "Invalid String";
}
if(encchar == 'z'+1){
encchar = '';
}
s[i] = encchar;
}
return s;
}
string additive_decipher(string s, int key){
return additive_cipher(s, -key);
}
string multi_cipher(string s, int key){
cout<<"KEY("<<key<<")";
char encchar;
for(int i = 0; i<s.size(); i++){
if(s[i] == '('){
s[i] = char('z' + 1);
}
if(s[i] >= 'a' && s[i]<='z' + 1){
int offset = s[i] - 'a';
int enc = (offset * key) % 27;
if(enc < 0){
enc += 27;
}
encchar = char(enc + 'a');
}
else{
return "Invalid String";
}
if(encchar == 'z' + 1){
encchar = '';
}
s[i] = encchar;
}
return s;
}
string multi_decipher(string s, int key){
return multi_cipher(s, mod_inv(key, 27));
}
string encryptMessage(string msg, int a, int b){
string cipher = "";
for(int i = 0; i<msg.length(); i++){
if(msg[i] != ''){
cipher = cipher + (char)((((a * (msg[i] - 'a')) + b) % 26) + 'a');
}
else{
cipher += msg[i];
}
}
return cipher;
}
string decryptCipher(string cipher, int a, int b){
string msg = "";
int a_inv = 0;
int flag = 0;;
for(int i = 0; i<26; i++){
flag = (a * i) % 26;
if(flag == 1){
a_inv = i;
}
}
for(int i = 0; i<cipher.length(); i++){
if(cipher[i]!= ''){
msg = msg + (char)(((a_inv * ((cipher[i] + 'a' - b)) % 26)) + 'a');
}
else{
msg += cipher[i];
}
}
return msg;
}
int main(){
string plain = "this is an example";
string enc, dec;
ascii(plain);
enc = additive_cipher(plain, 3);
cout<<enc<<endl;
dec = additive_decipher(enc, 3);
cout<<dec<<endl;
enc = multi_cipher(plain, 5);
cout<<enc<<endl;
dec = multi_decipher(enc, 5);
cout<<dec<<endl;
enc = encryptMessage(plain, 5, 7);
cout<<enc<<endl;
dec = decryptCipher(enc, 5, 7);
cout<<dec<<endl;
}

/*
Q. Write a program to find the modulo multiplicative inverse for the given number V with
respect to
modulus value.
Input Data:
Number n: 169
Modulus Value: 569
*/

#include<bits/stdc++.h>
using namespace std;
int gcd(int a, int b){
if(a % b == 0){
return b;
}
else{
return gcd(b, a % b);
}
}
int mod_inv(int n, int mod){
if(gcd(n, mod) != 1){
return -1;
}
int inv = 1;
while((n*inv) % mod!= 1){
inv++;
}
return inv;
}
int main(){
int n, mod;
cin>>n>>mod;
cout<<mod_inv(n, mod)<<endl;
}

/*
Write a program using Vigenere cipher with keyword "HEALTH" to encipher
the message "Life is full of surprises"
*/
#include<bits/stdc++.h>
using namespace std;
int main(){
string p, key, c = "", r = "";
cout<<"\nInsert the text:\n";
getline(cin, p);
int m = p.length();
cout<<"\nInsert keyword:\n";
cin>>key;
int n = key.length();
int N = 26, j = 0;
for(int i = 0;i<m; i++){
if(p[i] == ''){
continue;
}
if(j>=n){
j = 0;
}
c += (p[i] - 97 + key[j] - 97) % N + 97;
j++;
}
cout<<"\nCrypted text is:"<<c<<endl;
return 0;
}
/*
Write a program to find the decryption key in a transposition cipher using the encryption
key (3,2,6,1,5,4)
*/
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cout<<"\nEnter the length of encryption key:";
cin>>n;
int key[n], key2[n];
cout<<"\nEnter the key order:\n";
for(int i = 0; i<n; i++){
cin>>key[i];
if(key[i] == 0){
key2[0] = i+1;
}
else{
key2[key[i] - 1] = i+1;// outofbound if key[i]<1
}
}
cout<<"\nDecryption key is: \n";
for(int i = 0; i<n; i++){
cout<<key2[i]<<" ";
}
cout<<endl;
return 0;
}

/*
Write a program for below defined problem. This problem explores the use of a one-time
pad version of the Vigenere cipher. In this scheme, the key is a stream of random numbers
between 0 and 26. For example, if the key is 3 19 5..., then the first
letter of plaintext is encrypted with a shift of 3 letters, the second with a shift of 19 letters,
the third with a shift of 5 letters, and so on.
a. Encrypt the plaintext "sendmoremoney" with the key stream 9 0 1 7 23 15 21 14 11 11 2 8
9
b. Using the ciphertext produced in part a, find a key so that the cipher text decrypts to the
plaintext "cashnotneeded"
*/
#include<bits/stdc++.h>
using namespace std;
int main(){
string p, c = "", r = "";
cout<<"\nInsert the text:\n";
getline(cin, p);
int m = p.length();
int key[m], p1[m], N = 26;
cout<<"\nInsert keyword: \n";
for(int i = 0; i<m; i++){
cin>>key[i];
p1[i] = p[i] - 97;
c += (p1[i] + key[i]) % N + 97;
}
cout<<"\nEncrypted text is: "<<c<<endl;
cout<<"\nInsert the new plain text:\n";
cin>>p;
int m1 = p.length();
int key1[m];
if(m!=m1){
cout<<"\nNot possible as text size don't match \n";
}
else{
cout<<"\n Decryption key to new text is: \n";
for(int i = 0; i<m1; i++){
int x = c[i] - p[i];
if(x > 0){
key1[i] = x % N;
}
else{
key1[i] = (N + x) % N;
}
cout<<key1[i]<<" ";
}
}
cout<<endl;
return 0;
}

/*
Write a program to encrypt the message "The house is being sold to night" using Autokey
cipher with key = 7. Ignore the space between the words.
Decrypt the message to get the plain text.
*/

#include<bits/stdc++.h>
using namespace std;
int main(){
string p, c = "", r = "";
cout<<"\nInsert the text:\n";
getline(cin, p);
int m = p.length(), key, N = 26;
cout<<"\nEnter the key: ";
cin>>key;
vector<char> p1, c1;
int x = 0;
for(int i = 0; i<m; i++){
if(p[i] == ''){
continue;
}
p1.push_back(p[i] - 97);
if(i == 0){
c+= (p1[x] + key) % N + 97;
}
else{
c += (p1[x] + p1[x-1]) % N + 97;
}
x++;
}
cout<<"\nEncrypted text is:"<<c<<endl;
for(int i = 0;i<c.length(); i++){
c1.push_back(c[i] - 97);
if(i == 0){
int temp = c1[i] - key;
if(temp < 0){
temp += N;
}
r += (temp) % N + 97;
}
else{
int temp = c1[i] - r[i-1] + 97;
if(temp < 0){
temp+= N;
}
r+= (temp) % N + 97;
}
}
cout<<"\nDencrypted text is: "<<r<<endl;
return 0;
}

/*
Q 9. Write a program to encrypt a message using S-DES encryption and also decrypt it.
*/
#include<bits/stdc++.h>
using namespace std;
vector<int> permute(vector<int> & key, vector<int> & permutation_key){
vector<int> ret(permutation_key.size());
for(int i = 0; i<permutation_key.size(): ++i){
ret[i] = key[permutation_key[i] - 1];
}
return ret;
}
vector<int> circular_shift(vector<int> & permutation_key, int shift){
int n = permutation_key.size();
int lim = n/2;
vector<int> ret(n);
for(int i = 0; i<lim; ++i){
ret[(i-shift+lim) % lim] = permutation_key[i];
}
for(int i = 0; i<lim; ++i){
ret[lim + (i-shift+lim) % lim] = permutation_key[lim+i];
}
return ret;
}
vector<int> expand(vector<int> & plain_text){
vector<int> expansion_key = {4,1,2,3,2,3,4,1};
vector<int> ret(expansion_key.size());
int lim = plain_text.size()/2;
for(int i = 0; i<expansion_key.size(); ++i){
ret[i] = plain_text[lim + expansion_key[i] - 1];
}
return ret;
}
vector<int> apply_xor(vector<int> & lhs, vector<int> & rhs, int lim){
vector<int> ret(lhs);
for(int i = 0; i<lim; ++i){
ret[i] = lhs[i] ^ rhs[i];
}
return ret;
}
void apply_swap(vector<int> & text){
int n = text.size():
int lim = n/2;
for(int i =0; i<lim; ++i){
swap(text[i], text[lim+i]);
}
}
int value(int bit1, int bit2){
int ret = 0;
if(bit2){
ret |= 1;
}
if(bit1){
ret |= 2;
}
return ret;
}
vector<int> f_output(vector<int> & key, vector<vector<int>> & s0, vector<int> & s1){
vector<int> ret;
int r = value(key[0], key[3]);
int c = value(key[1], key[2]);
int val = s0[r][c];
ret.push_back((int)val>>1 & 1);
ret.push_back((int)val & 1);
r = value(key[4], key[7]);
c = value(key[5], key[6]);
val = s1[r][c];
ret.push_back((int)(val>>1 & 1));
ret.push_back((int)(val & 1));
return ret;
}
void fkey(vector<int> & plain_text, vector<int> & key){
vector<vector<int>> s0 = {{1,0,3,2}, {3,2,1, 0}, {0,2,1,3}, {3,1,3,2}};
vector<vector<int>> s1 = {{0,1,2,3}, {2,0,1,3}, {3,0,1,0},{2,1,0,3}};
vector<int> p4 = {2,4,3,1};
int n = plain_text.size();
vector<int> temp = expand(plain_text);
vector<int> fkey = apply_xor(temp, key, n);
vector<int> fkey = apply_xor(temp , key, n);
vector<int> f = f_output(fkey, s0, s1);
f = permute(f, p4);
plain_text = apply_xor(plain_text, f, n/2);
}
int main(){
int n = 8, k = 10;
vector<int> plain_text(n);
vector<int> cipher_text;
vector<int> decipher_text;
vector<int> cipher_key(k);
for(int i = 0; i<n; ++i){
cin>>plain_text[i];
}
for(int i = 0; i<k; i++){
cin>>cipher_key[i];
}
vector<int> ip = {2, 6, 3, 1, 4, 8, 5, 7};
plain_text = permute(plain_text, ip);
vector<int> p10 = {3, 5, 2, 7, 4, 10, 1, 9, 8, 6};
vector<int> p8 = {6, 3, 7, 4, 8, 5, 10, 9};
vector<int> key_1, key_2;
key_1 = permute(cipher_key, p10);
key_1 = circular_shift(key_1, 1);
key_2 = circular_shift(key_1, 2);
key_1 = permute(key_1, p8);
key_2 = permute(key_2, p8);
fkey(plain_text, key_1);
apply_swap(plain_text);
fkey(plain_text, key_2);
vector<int> fip = {4, 1, 3, 7, 2, 8, 6};
plain_text = permute(plain_text,fip);
for(int i = 0; i<plain_text.size(); ++i){
cout<<plain_text[i]<<" ";
}
cout<<endl;
plain_text = permute(plain_text, ip);
fkey(plain_text, key_2);
apply_swap(plain_text);
fkey(plain_text, key_1);
plain_text = permute(plain_text, fip);
for(int i = 0; i<plain_text.size(); ++i){
cout<<plain_text[i]<<" "
}
cout<<endl;
return 0;
}

/*
10. Implement addition, multiplication and inverse operation on GF(2 power 4) with
Irreducible polynomial 10011.

*/
#include<bits/stdc++.h>
#define N 2
using namespace std;
string MOD;
string dp[N][N], idp[N][N], C[N][N];

string stuffZero(string s, int n){


while(s.length()<n){
s = '0' + s;
}
return s;
}

int binaryToInt(string s){


int ans = 0;
reverse(s.begin(), s.end());
for(int i = 0; i<s.length(); i++){
ans += (1<<i) * (s[i] - '0');
}
return ans;
}

string intToBinary(int num){


string ans = "";
while(num){
char c = num % 2;
ans += (c + '0');
num /= 2;
}
reverse(ans.begin(), ans.end());
return ans;
}
int len(int n){
int m = 0;
while(n){
n = n/2;
m++;
}
return m;
}

string divide(string m, string MOD){


int mod = binaryToInt(MOD), n = binaryToInt(m);
while(len(n)>=len(mod)){
n = n^(mod<<(len(n) - len(mod)));
}
return intToBinary(n);
}

string add(string s, string p){


int n = binaryToInt(s), m = binaryToInt(p);
return divide(intToBinary(n^m), MOD);
}
string mul(string s, string p){
int n = binaryToInt(s), m = binaryToInt(p), ans = 0;
for(int i = 0; (1<<i)<=n; i++){
if(n & (1<<i)){
ans = ans ^ (m<<i)'
}
}
return divide(intToBinary(ans), MOD);
}

void matrixMul(string A[N][N], string B[N][N]){


for(int i = 0; i<N; i++){
for(int j = 0; j<N; j++){
C[i][j] = "0";
for(int k = 0; k<N; k++){
C[i][j] = add(C[i][j], mul(A[i][k], B[k][j]));
}
}
}
}
int main(){
int c;
char t = 'y';
string s, p;
cout<<"Enter Irreducible polynomial: ";
cin>>MOD;
while(t == 'y'){
cout<<"\nEnter 1: Addition 2: Multiplication 3: Inverse Operation : ";
cin>>c;
switch(c){
case 1:{
cout<<"\nADDITION\nEnter the two polynomials : ";
cin>>s>>p;
cout<<"Resultant polynomial: "<<stuffZero(add(s, p),
2*N)<<endl;
break;
}
case 2:{
cout<<"\nMULTIPLICATION\nEnter the two polynomials : ";
cin>>s>>p;
cout<<"Resultant polynomial: "<<stuffZero(mul(s, p), 2*N);
break;
}
case 3:{
cout<<"\nINVERSE OF A MATRIX\nEnter the matrix :\n";
for(int i = 0; i<N; i++){
for(int j = 0; j<N; j++){
cin>>dp[i][j];
}
}
string det = add(mul(dp[0][0], dp[1][1]), mul(dp[0][1],
dp[1][0]));
cout<<"Result of inverse operation: \n";
idp[0][0] = divide(dp[1][1], det);
idp[0][1] = divide(dp[1][0], det);
idp[1][0] = divide(dp[0][1], det);
idp[1][1] = divide(dp[0][0], det);
for(int i = 0; i<N; i++){
for(int j = 0; j<N; j++){
cout<<stuffZero(idp[i][j], 2*N)<<" ";
}
cout<<endl;
}
}
}
cout<<"\nWant to perform more operations ? (y/n) : ";
cin>>t;
}
return 0;
}

/*
11. Implement Mix Column and Inverse Mix Column operations in S-AES With previous
Matrix as key.
*/
#include<bits/stdc++.h>
#define N 2
using namespace std;
string MOD;
string dp[N][N], idp[N][N], C[N][N];
string stuffZero(string s, int n){
while(s.length()<n){
s = '0' + s;
}
return s;
}
int binaryToInt(string s){
int ans = 0;
reverse(s.begin(), s.end());
for(int i = 0; i<s.length(); i++){
ans += (1<<i) * (s[i] - '0');
}
return ans;
}
string intToBinary(int num){
string ans = "";
while(num){
char c = num % 2;
ans += (c + '0');
num/=2;
}
reverse(ans.begin(), ans.end());
return ans;
}
int len(int n){
int m = 0;
while(n){
n = n/2;
m++;
}
return m;
}
string divide(string m, string MOD){
int mod = binaryToInt(MOD), n = binaryToInt(m);
while(len(n) >= len(mod)){
n = n^(mod<<(len(n) - len(mod)));
}
return intToBinary(n);
}
string add(string s, string p){
int n = binaryToInt(s), m = binaryToInt(p);
return divide(intToBinary(n^m), MOD);
}
string mul(string s, string p){
int n = binaryToInt(s), m = binaryToInt(p), ans = 0;
for(int i = 0; (1<<i)<=n; i++){
if(n & (1<<i)){
ans = ans ^ (m<<i);
}
}
return divide(intToBinary(ans), MOD);
}
void matrixMul(string A[N][N], string B[N][N]){
for(int i = 0; i<N; i++){
for(int j = 0; j<N; j++){
C[i][j] = "0";
for(int k = 0; k<N; k++){
C[i][j] = add(C[i][j], mul(A[i][k], B[k][j]));
}
}
}
}
int main(){
int t, c;
string s, p;
MOD = "10011";
cout<<"\n** S-AES Encryption **\nEnter the matrix\n";
for(int i = 0; i<N; i++){
for(int j = 0; j<N; j++){
cin>>dp[i][j];
}
}
string det = add(mul(dp[0][0], dp[1][1]), mul(dp[0][1]), dp[1][0]);
idp[0][0] = divide(dp[1][1], det);
idp[0][1] = divide(dp[1][0], det);
idp[1][0] = divide(dp[0][1], det);
idp[1][1] = divide(dp[0][0], det);
string A[N][N] = {{"0110", "1111"}, {"0110", "1011"}};
matrixMul(A, dp);
cout<<"\nMIX COLUMN: \n";
for(int i = 0; i<N; i++){
for(int j = 0; j<N; j++){
cout<<stuffZero(C[i][j], 2*N)<<" ";
}
cout<<endl;
}
cout<<endl;
matrixMul(A, idp);
cout<<"\nInverse MIX COLUMN: \n";
for(int i = 0; i<N; i++){
for(int j = 0; j<N; j++){
cout<<stuffZero(C[i][j], 2*N)<<" ";
}
cout<<endl;
}
cout<<endl;
return 0;
}

/*
Q 12. WAP to implement RC4 Algorithm.
*/
#include<bits/stdc++.h>
using namespace std;
#define vi vector<int>

void print(vi A){


for(int i = 0; i<A.size(); i++){
cout<<A[i]<<" ";
}
cout<<endl;
}
vi KSA(vi key){
vi S(256);
for(int i = 0; i<S.size(); i++){
S[i] = i;
}
int j = 0;
for(int i = 0; i<S.size(); i++){
j = (j + S[i] + key[i%key.size()] % S.size());
swap(S[i], S[j]);
}
return S;
}
vigen_xor_key(vi S){
vi xor_key;
int i = 0, j = 0;
for(int ind = 0; ind<S.size(); ind++){
i = (i+1) % 256;
j = (j + S[i]) % 256;
swap(S[i], S[j]);
int k = S[(S[i] + S[j]) % 256];
xor_key.push_back(k);
}
return xor_key;
}

vi encrypt(vi inp, vi key){


vi output;
for(int i = 0; i<inp.size(); i++){
int out = inp[i] ^ key[i % key.size()];
output.push_back(out);
}
return output;
}

vi decrypt(vi inp, vi key){


vi output;
for(int i = 0; i<inp.size(); i++){
int out = inp[i]^key[i % key.size()];
output.push_back(out);
}
return output;
}

int main(){
vi key(5);
while(1){
int x;
cin>>x;
if(x == -1){
break;
}
key.push_back(x);
}
vi plain;
while(1){
int x;
cin>>x;
if(x == -1){
break;
}
plain.push_back(x);
}
vi main_key = KSA(key);
vi enc = encrypt(plain, main_key);
vi dec = decrypt(enc, main_key);
print(enc);
print(dec);
}

/*
Q 13. WAP to show RC5 encryption & decryption

*/
#include<stdio.h>
#include<time.h>
#define KEYSIZE 16
typedef unsigned int WORD;
typedef enum {ShiftLeft, ShiftRight} ShiftDir;
typedef enum {KeyWords = KEYSIZE /4, NumRounds = 15, TableSize = 32} bogus;
WORD Table[TableSize];
WORD L[KeyWords];
WORD ROT(const WORD x, const WORD y, constShiftDirdir){
const unsigned intShiftAmt = (y & (unsigned int)0x1f);
const unsigned intShiftBack = 0x20 - ShiftAmt;
unsigned int result;
if(dir == ShiftLeft){
result = (x << ShiftAmt) | (x >> ShiftBack);
}
else{
result = (x >> ShiftAmt) | (x << ShiftBack);
}
return result;
}
void SetKey(unsigned char KeyChar){
static unsigned intKeyCntr;
static unsigned int Shift;
int ix = KeyCntr>>2;
L[ix] = (L[ix] & (~(0xff << Shift))) | (KeyChar << Shift);
Shift = (Shift + 8) & 0x1f;
KeyCntr = (KeyCntr + 1) & (KEYSIZE - 1);
}

void encrypt(WORD * PlainText, WORD * CryptoText){


WORD i, temp;
WORD A;
WORD B;
A = PlainText[0] + Table[0];
B = PlainText[1] + Table[1];
for(i = 1; i<=NumRounds; i++){
temp = i<<1;
A = ROT(A^B, B, ShiftLeft) + Table[temp];
B = ROT(A^B, A, ShiftLeft) + Table[temp+1];
}
CryptoText[0] = A;
CryptoText[1] = B;
}
void decrypt(WORD * CryptoText, WORD * PlainText){
WORD i, temp;
WORD B;
WORD A;
B = CryptoText[1];
A = CryptoText[0];
for(i = NumRounds; i>0; i--){
temp = (i<<1);
B = ROT(B - Table[temp + 1], A, ShiftRight) ^ A;
A = ROT(A - Table[temp], B, ShiftRight ^ B);
}
PlainText[1] = B - Table[1];
PlainText[0] = A-Table[0];
}
void setup(){
static const WORD ROM[TableSize] = {0xb7e15163, 0x5618cb1c, 0xf45044d5,
0x9287be8e, 0x30bf3847, 0xcef6b200, 0x6d2e2bb9, 0x0b65a572, 0xa99d1f2b, 0x47d498e4,
0xe60c129d, 0x84438c56, 0x227b060f, 0xc0b27fc8, 0x5ee9f981, 0xfd21733a, 0x9b58ecf3,
0x399066ac, 0xd7c7e065, 0x75ff5a1e, 0x1436d3d7, 0xb26e4d90, 0x50a5c749, 0xeedd4102,
0x8d14babb, 0x2b4c3474, 0xc983ae2d, 0x67bb27e6, 0x05f2a19f, 0xa42a1b58, 0x42619511,
0xe0990eca};
WORD i;
WORD A;
WORD B;
WORD j;
WORD k;
for(i = 0; i<TableSize; i++){
Table[i] = ROM[i];
}
A = 0;
B= 0;
i = 0;
j = 0;
for(k = 0; k<3*TableSize; k++){
Table[i] = ROT(Table[i] + (A + B), (A+B), ShiftLeft);
A = Table[i];
L[j] = ROT(L[j] + (A + B), (A + B), ShiftLeft);
B = L[j];
i = (i+1) & (TableSize - 1);
j = (j + 1) & (KeyWords - 1);
}
}
int main(){
WORD i, j;
WORD PlainText1[2], PlainText2[2];
WORD CryptoText[2] = {0, 0};
time_t t0, t1;
char * keystr = "TheQuickBrownFox";
if(sizeof(WORD) != 4){
printf("RC5 error: WORD has %d bytes.\n", sizeof(6; WORD));
}
printf("RC5-32/12/16 encryption: \n");
for(i = 1; i<6; i++){
PlainText1[0] = CryptoText[0];
PlainText1[1] = CryptoText[1];
for(j = 0; j<KEYSIZE; j++){
SetKey((unsigned char) keystr[j]);
}
setup();
encrypt(PlainText1, CryptoText);
decrypt(CryptoText, PlainText2);
printf("\n plainText %.8lX %.8lX --->ciphertext %.9lX %.8lX \n", PlainText1[0],
PlainText1[1], CryptoText[0], CryptoText[1]);
if(PlainText1[0]!=PlainText2[0] || PlainText1[1] != PlainText2[1]){
printf("Decryption Error!");
}
}
}

/*
Q 13. Write a progrum to implement Fast Exponent Method.
*/
#include<bits/stdc++.h>
using namespace std;
#define loop(i, a, b) for(i = a; i<b; i++)
int solve_fast_exponent(int x, int y, int n){
int res = 1;
x = x%n;
while(y > 0){
if(y & 1){
res = (res * x) % n;
}
y >>=1;
x = (x*x) % n;
}
return res;
}
int main(){
int x, y, n;
cout<<"Enter x, y, n:";
cin>>x>>y>>n;
cout<<"Fast Exponent Method: "<<solve_fast_exponent(x, y, n)<<endl;
return 0;
}

/*
Q 14. Implement Euler Totient Function(phi) .
*/
#include<bits/stdc++.h>
using namespace std;
#define loop(i, a, b) for(i = a; i<b; i++)

int gcd(int x, int y){


if(x == 0){
return y;
}
return gcd(y % x, x);
}

int solve_euler_to(int n){


int res = 0;
int i;
loop(i, 1, n){
if(gcd(i, n) == 1){
res++;
}
}
return res;
}
int main(){
int m;
cout<<"Enter M: ";
cin>>m;
cout<<"Euler Totient: "<<solve_euler_to(m)<<endl;
return 0;
}

/*
Q 15. Find Modular Multiplicative Inverse using Extended Euclidean Method?
*/
#include<bits/stdc++.h>
using namespace std;
#define loop(i, a, b) for(i = a; i<b; i++)

int ext_gcd(int a, int b, int & x, int & y){


if(a == 0){
x = 0;
y = 1;
return b;
}
int x1, y1;
int g= ext_gcd(b%a, a, x1, y1);
x = y1 - (b/a)*x1;
y = x1;
return g;
}

int solve_multi_inverse(int a, int m){


int x, y;
int g = ext_gcd(a, m, x, y);
if(g!=1){
cout<<"Inverse doesn't exist";
}
else{
int res = (x%m + m) % m;
cout<<res;
}
}
int main(){
int p, q;
cout<<"Enter p, q: ";
cin>>p>>q;
cout<<"Modulo Multiplicative Inverse: ";
solve_multi_inverse(p, q);
return 0;
}

/*
QI6 Implement RSA Encryption and Decryption Algorithm?
*/
#include<bits/stdc++.h>
using namespace std;
#define loop(i, a, b) for(i = a; i<b; i++)
int ext_gcd(int a, int b, int & x, int & y){
if(a == 0){
x = 0;
y= 1;
return b;
}
int x1, y1;
int g = ext_gcd(b%a, a, x1, y1);
x = y1 - (b/a) * x1;
y = x1;
return g;
}

int solve_multi_inverse(int a, int m){


int x, y;
int g = ext_gcd(a, m, x, y);
if(g != 1){
cout<<"Inverse doesn't exist";
return -1;
}
else{
int res = (x%m + m) % m;
return res;
}
}
int solve_fast_exponent(int x, int y, int n){
int res = 1;
x = x % n;
while(y > 0){
if(y & 1){
res = (res * x) 5 n;
}
y >>= 1;
x = (x * x) % n;
}
return res;
}

int main(){
int p,q,e,i;
cout<<"Enter prime1(p), prime2(q), public key(e):";
cin>>p>>q>>e;
string plain_text;
cout<<"Enter Plain_text:";
cin>>plain_text;
int phi_n = (p-1) * (q-1);
int d = solve_multi_inverse(e, phi_n);
cout<<"Private Key: "<<d<<endl;
vector<int> cipher_code(plain_text.length());
cout<<"Cipher codes:";
loop(i, 0, plain_text.length()){
cipher_code[i] = solve_fast_exponent(plain_text[i], e, p*q);
cout<<cipher_code[i]<<" ";
}
cout<<"\nplain_text codes:";
loop(i, 0, plain_text.length()){
cout<<solve_fast_exponent(cipher_code[i], d, p*q)<<" ";
}
return 0;
}

/*
1 Write a program to Generate primitive roots of Multiplicative Group Z29*.

*/
#include<bits/stdc++.h>
using namespace std;
int main(){
int z = 29;
cin>>z;
int ar[z];
int full = (z*(z-1))/2, a= 1, s;
for(int i = 1; i<z; i++){
a = 1;
s = 0;
for(int j = 0; j<z; j++){
ar[j] = 0;
}
for(int k = 1; k<z; k++){
a = (a*i) % z;
ar[a] = 1;
}
if(ar[0] == 0){
for(int j = 1; j<z; j++){
s += ar[j];
}
if(s == z-1){
cout<<i<<endl;
}
}
}
return 0;
}
/*
2. Irv Multiplicative group < Z421*,x>
a. Encrypt the Input:“ Learning is Studying"(Consider ASCII Values) with Elgamal
CryptoSystem.
b. Decrypt the above generated Cipher.
*/
#include<bits/stdc++.h>
using namespace std;
int power(int a, int b, int prime){
int res = 1;
for(int i = 0; i<b; i++){
res = (res % prime * a % prime) % prime;
}
return res;
}
int gcdextended(int a, int b, int *x, int * y){
if(a == 0){
*x = 0;
*y = 1;
return b;
}
int x1, y1;
int g = gcdextended(b%a, a, &x1, &y1);
*x = y1 - (b/a) * x1;
*y1 = x1;
return g;
}

int mod_inv(int n, int mod){


int x, y;
int g = gcdextended(n, mod, &x, &y);
if(g != 1){
cout<<"Inverse doesn't exist"<<endl;
}
else{
int res = (x % mod + mod) % mod;
return res;
}
}

void getprimitiveroots(int prime, vector<int> & a){


for(int r = 1; r<prime; r++){
bool isprimitive = true;
map<int, bool> m;
for(int x = 0; x<prime-1; x++){
int t = power(r, x, prime);
if(m.find(t) != m.end()){
isprimitive = false;
break;
}
m[t] = true;
}
if(isprimitive){
a.push_back(r);
}
m.clear();
}
}

vector<int> encryption(string text, int e1, int d, int prime, int & c1){
int r = rand() % prime;
int e2 = power(e1, d, prime);
c1 = power(e1, r, prime);
vector<int> c2;
for(int i = 0; i<text.length(); i++){
int temp = (power(e2, r, prime) * text[i]) % prime;
c2.push_back(temp);
}
return c2;
}

string decryption(vector<int> ans, int d, int c1, int prime){


string temp = "";
for(int i = 0; i<ans.size(); i++){
int t = (ans[i] * mod_inv(power(c1, d, prime), prime)) % prime;
temp.push_back(char(t));
}
return temp;
}
int main(){
cout<<"Input"<<endl;
int prime;
cin>>prime;
string text;
cin>>text;
vector<int> rootset;
getprimitiveroots(prime, rootset);
int n = rootset.size();
srand(time(NULL));
int e1 = rootset[rand() % n];
int d = rootset[rand() % n];
int c1;
vector<int> ans = encryption(text, e1, d, prime, c1);
cout<<"Encrypted Text"<<endl;
for(int i = 0; i<ans.size(); i++){
cout<<ans[i]<<" "
}
coout<<endl;
string decrypted = decryption(ans, d, c1, prime);
cout<<"Decrypted Text"<<endl;
cout<<decrypted<<endl;
}

/*
Given the super increasing tuple b =[7, 11, 23,43,87, 173, 357). r = 41, amt modulus n = 1001
.write a program to encrypt and decrypt the letter "a" using knapsack cryptosystem, Use [7
65
1 2 3 4) as the permutation table.
*/
#include<bits/stdc++.h>
using namespace std;
void tobin(int a, int tup[]){
int i = 6;
while(n > 0){
int j = n % 2;
tup[i--] = j;
n /= 2;
}
}
int main(){
int m;
cout<<"No of terms: ";
cin>>m;
cout<<"Enter items: ";
int b[m];
for(int i = 0; i<m; i++){
cin>>b[i];
}
int r, n;
cout<<"Enter r and n";
cin>>r>>n;
int t[m];
for(int i = 0; i<m; i++){
t[i] = (b[i] * r) % n;
}
int a[m];
int perm[m];
cout<<"Enter permutation matrix: ";
for(int i = 0; i<m; i++){
cin>>perm[i];
}
for(int i = 0; i<m; i++){
a[i] = t[perm[i] - 1];
}
char c;
cout<<"Enter the message to encrypt: ";
cin>>c;
int tup[7];
tobin((int)c, tup);
for(int i = 0; i<7; i++){
cout<<tup[i];
}
cout<<endl;
int sum = 0;
for(int i = 0; i<m; i++){
sum += (tup[i] * a[i]);
}
cout<<sum<<endl;
int rinv;
for(int i = 1; i<n; i++){
if((r*i) % n == 1){
rinv = i;
}
}
int sdash = (sum * rinv) % n;
cout<<sdash<<endl;
for(int i = 6; i>=0; i--){
if(sdash >= b[i]){
tup[i] = 1;
sdash = sdash - b[i];
}
else{
tup[i] = 0;
}
}
for(int i = 0; i<7; i++){
cout<<tup[i];
}
cout<<endl;
int a1[7];
for(int i = 0; i<m; i++){
a1[i] = tup[perm[i] - 1];
}
for(int i = 0; i<7; i++){
cout<<a1[i];
}
cout<<endl;
int ascii = 0;
int j = 0;
for(int i = 6; i>=0; i--){
ascii += a1[i] * pow(2, j);
j++;
}
cout<<ascii<<endl;
cout<<(char)(ascii - 97 + 'a')<<endl;
}
/*
Q 21. Output points on elliptic curve E29(1, 27).
*/
#include<bits/stdc++.h>
using namespace std;
int main(){
int a, b, p;
cout<<"Enter a, b and p"<<endl;
cin>>a>>b>>p;
set<pair<int, int>> v;
for(int i = 0; i<p; i++){
int y = ((int)pow(i, 3) + a * i + b) % p;
for(int j = 0; j<=p-1; j++){
if(((j*j) % p) == y){
v.insert(make_pair(i, j));
}
}
}
cout<<"Generated point for E"<<p<<"("<<a<<","<<b<<")"<<endl;
for(set<pair<int, int> >::iterator itr = v.begin(); itr!=v.end(); itr++){
cout<<(*itr).first<<" "<<(*itr).second<<endl;
}
}

/*
Q 22. Apply below operations on Elliptic Curve
E29(1, 27).
a) Add (14. 28) and (15, 16) b) Multiply 10 * (24, 10)
*/

#include<bits/stdc++.h>
using namespace std;
int K = 4;
pair<int, int> addEllip(pair<int, int> x1, pair<int, int> x2, int p, int a, int b){
int k,f,g,i;
if(x1.first == x2.first && x1.seconnd == x2.second){
f = 2*x1.second;
g = (3 * x1.first * x1.first) + a;
}
else{
f = x1.first - x2.first;
g = x1.second - x2.second;
}
i = 0;
if(f<0){
f += p;
}
while(i<p){
if(((i*i) % p) == 1) {
break;
}
i++;
}
k = ((g*i)%p + p) % p;
int x3 = ((k*(x2.first - x3) - x2.second) % p + p) % p;
return make_pair(x3, y3);
}

pair<int, int> mulEllip(pair<int, int> x1, int k, int p, int a, int b){
pair<int, int> ans;
if(k >= 2){
ans = addEllip(x1, x1, p, a, b);
}
int i = 2;
while(i<k-1){
if(x1.first == ans.first && x1.second != ans.second){
ans = x1;
}
else{
ans = addEllip(x1, ans, p, a, b);
}
i++;
}
return ans;
}

int main(){
int a, b, p, x1, y1, x2, y2;
cout<<"Enter a, b and p"<<endl;
cin>>a>>b>>p;
cout<<"Enter first pair of co-ordinates"<<endl;
cin>>x1>>y1;
cout<<"Enter second pair of co-ordinates"<<endl;
cin>>x2>>y2;
int k2;
pair<int, int> k = addEllip(make_pair(x1, y1), make_pair(x2, y2),p, a, b);
cout<<"Sum of points is"<<endl;
cout<<k.first<<" "<<k.second<<endl;
cout<<"Enter pair of co-ordinates"<<endl;
cin>>x1>>y1;
cout<<"Enter multiplication factor"<<endl;
cin>>k2;
pair<int, int> k1 = mulEllip(make_pair(x1, x2), k2, p, a, b);
cout<<k1.first<<" "<<k1.second<<endl;
}

/*
Q. Elagamal Digital Signature scheme
*/

#include<bits/stdc++.h>
#include "elagamal.cpp"
using namespace std;
int main(){
cout<<"\nEnter the prime: ";
cin>>p;
vector<int> v, R;
v = ppr(p);
int n = v.size();
cout<<"\n primitive roots are:";
for(j = 0; j<n; j++){
cout<<<v[j]<<" ";
}
cout<<endl;
int p, f, e1, d,r,M;
string t;
cout<<"\nEnter p, e1, d and r";
cinn>>p>>e1>>d>>r;
cout<<"\nEnter M: "<<endl;
cin>>M;
int s2, s1 = fte(e1, r, p), r_inv, x, y, e2 = fte(e1, d, p);
if(e_gcd(r, p-1, &x, &y) == 1){
r_inv = x;
if(r_inv<0){
r_inv += p-1;
}
}
s2 = ((M-d*s1)*r_inv) % (p-1);
if(s2<0){
s2 += p-1;
}
int v1 = fte(e1, M, p), v2 = (fte(e2, s1, p) * fte(s1, s2, p)) % p;
if(v1 == v2){
printf("\nSignature verified:\n");
}
else{
printf("\n Not verified\n");
}
return 0;
}

/*
Q
. Elliptic curve implementation of Elgamal crypto system
*/
#include<bits/stdc++.h>
#include "elliptic1.cpp"

using namespace std;


int main(){
int p, x1[2], y1[2], a, b, m = 4, *e1;
cout<<"\nEnter the value of prime, a and b:";
cin>>p>>a>>b;
set<int> zp;
set<int>::iterator it_st;
map<int, int> ps;
for(int i = 0; i<p; i++){
zp.insert(i);
int x = int(pow(i,2)) % p;
ps[i]= x;
}
e1 = generate(ps,p , a, b);
int d = 751, r = 4;
int *e2 = mul(e1[0], e1[1], d, p, a, b);
int *c1 = mul(e1[0], e1[1], r, p, a, b);
int *c2_r = mul(e2[0], e2[1], r, p, a, b);
while(m--){
cout<<"\nEnter the plain text:";
cin>>x1[0]>>y1[0];
x1[1] = c2_r[0];
y1[1] = c2_r[1];
int *c2 = add(x1, y1, p, a, b);
cout<<"Encrypted message is: "<<"("<<c2[0]<<","<<c2[1]<<")";
int *c1_d = mul(c1[0], c1[1], d, p, a, b);
cout<<"\nDecrypted message is: "<<"("<<x1[0]<<","<<y1[0]<<")"<<endl;
}
return 0;
}

Generate keys and Implement 4 basic operations of MD5


#include<bits/stdc++.h>
using namespace std;
map<char,string> m;
map<string,char> m1;
string no(string x)
{
for(int i=0;i<x.length();i++)
{
if(x[i]=='1')
x[i]='0';
else
x[i]='1';
}
return x;
}
string xo(string a,string b)
{
string r="";
for(int i=0;i<a.length();i++)
{if(a[i]==b[i])
r='0'+r;
else
r='1'+r;
}
return r;
}
string oR(string a,string b)
{
string r="";
for(int i=0;i<a.length();i++)
{if((a[i]=='1')||(b[i]=='1'))
r='1'+r;
else
r='0'+r;
}
return r;
}
string an(string a,string b)
{
string r="";
for(int i=0;i<a.length();i++)
{if(a[i]==b[i])
r=a[i]+r;
else
r='0'+r;
}
return r;
}
string hex(string a)
{
string hex="",temp;
for(int i=0;i<a.length();)
{
temp="";
for(int k=0;k<4;k++,i++)
{
temp+=a[i];
}
hex+=m1[temp];
}
return hex;
}
int main()
{
m['0']="0000";m['1']="0001";m['2']="0010";m['3']="0011";m['4']="0100";m['5']="0101";m['6
']="0110"
;m['7']="0111";m['8']="1000";m['9']="1001";m['A']="1010";m['B']="1011";m['C']="1100";m['
D']="110
1";m['E']="1110";m['F']="1111";
m1["0000"]='0';m1["0001"]='1';m1["0010"]='2';m1["0011"]='3';m1["0100"]='4';m1["0101"]=
'5';m1["
0110"]='6;m1["0111"]='7';m1["1000"]='8';m1["1001"]='9';m1["1010"]='A';m1["1011"]='B';m
1["1100
"]='C';m1["1101"]='D';m1["1110"]='E';m1["1111"]='F';
long long k[65];
cout<<"Keys:\n";
for(int i=1;i<=64;i++)
{
k[i]=abs(sin(i+1))*pow(2,32);
cout<<k[i]<<" ";
}
string a="",b="",c="",d="";
string s1="67452301",s2="EFCDAB89",s3="98BADCFE",s4="10325476";
for(int i=0;i<s1.length();i++)
{
a=m[s1[i]]+a;
b=m[s2[i]]+b;
c=m[s3[i]]+c;
d=m[s4[i]]+d;
}
//Operation A
string ans=oR(an(b,c),an(no(b),d));
cout<<endl<<"Op A: "<<hex(ans)<<endl;
//B
ans=oR(an(d,b),an(no(d),c));
cout<<"Op B: "<<hex(ans)<<endl;
//C
ans=xo(b,xo(c,d));
cout<<"Op C: "<<hex(ans)<<endl;
//D
ans=xo(c,oR(b,no(d)));
cout<<"Op D: "<<hex(ans)<<endl;
}

MD5 hash function


#include<bits/stdc++.h>
using namespace std;
map<string,char> m;
int main()
{
m["0000"]='0';m["0001"]='1';m["0010"]='2';m["0011"]='3';m["0100"]='4';m["0101"]='5';m["
0110"]='6
;m["0111"]='7';m["1000"]='8';m["1001"]='9';m["1010"]='A';m["1011"]='B';m["1100"]='C';m[
"1101"]='
D';m["1110"]='E';m["1111"]='F';
string input="hello";
string pad="",temp="";
int i;
for(i=0;i<input.size();i++)
{
int x=(int)(input[i]);
temp="";
for(int j=0;j<8;j++)
{
temp=(char)(x%2+'0')+temp;
x=x/2;
}
pad=pad+temp;
}
i=pad.length();
if(i<=447)
{
pad+='1';
i++;
}
while(i<448)
{
pad+='0';
i++;
}
int tmp=input.length()*8;
temp="";
for(i=0;i<64;i++)
{
temp=(char)(tmp%2+'0')+temp;
tmp=tmp/2;
}
pad=pad+temp;
string hex="";
temp="";
for(i=0;i<pad.length();)
{
temp="";
for(int k=0;k<4;k++,i++)
{
temp+=pad[i];
}
hex+=m[temp];
}
cout<<hex<<endl;
}

RSA Digital Signature


#include <bits/stdc++.h>
using namespace std;
int ext_eucl(int p, int m, int *x, int *y)
{
if(p == 0)
{
*x = 0;
*y = 1;
return m;
}
int x1, y1;
int gcd = ext_eucl(m % p, p, &x1, &y1);
*x = y1 ­ (m / p) * x1;
*y = x1;
return gcd;
}
int gcd(int a, int b)
{
if(a == 0)
return b;
return gcd(b % a, a);
}
long long int mod_exp(long long int a, unsigned int p, int n)
{
long long int res = 1;
while(p > 0)
{
if(p & 1)
res = (res * a) % n;
p = p >> 1;
a = (a * a) % n;
}
return res;
}
int coprime(int val)
{
for(int i = val / 2; i < val; i += 1)
if(gcd(i, val) == 1)
return i;
}
int main()
{
int p=55243, q=7669, n;
long long int m=10;
n = p * q;
int totient = (p ­ 1) * (q ­ 1);
int e = coprime(totient);
cout << "E " << e << endl;
int d = 0, y = 0;
ext_eucl(e, totient, &d, &y);
long long int encr = mod_exp(m, e, n);
long long int decr = mod_exp(encr, d, n);
cout << "Cipher: " << decr << endl;
cout << "Decrypt: " << encr << endl;
}

Elliptical Curve Cryptosystem


#include<bits/stdc++.h>
using namespace std;
struct coord
{
int x;
int y;

int inverse(int a, int p)
{
for(int i = 1; i < p; i += 1)
if((a * i) % p == 1)
return i;
}
coord generate(int a, int b, int p)
{
vector<int> y_2;
vector<int> x;
for(int i = 0; i < p; i += 1)
{
y_2.push_back((i * i * i + a * i + b) % p);
x.push_back(i);
}
for(int i = 0; i < p; i += 1)
{
for(int j = 0; j < x.size(); j += 1)
{
if(y_2[j] == ((i * i) % p))
{
coord res;
res.x = x[j];
res.y = i;
return res;
}
}
}
}
int find_lambda(struct coord a, struct coord b, int p)
{
int lambda;
if((a.x == b.x) && (a.y == b.y))
{
int nr = (p + 3 * a.x * a.x + 1);
int dr = (p + 2 * a.y);
lambda = (p + nr * inverse(dr, p)) % p;
}
else
{
int nr = (b.y ­ a.y);
int dr = (b.x ­ a.x);
lambda = (p + nr * inverse(dr, p)) % p;
}
return lambda;
}
struct coord addn(struct coord a, struct coord b, int p)
{
struct coord res;
int lambda = find_lambda(a, b, p);
res.x = (p + lambda * lambda ­ a.x ­ b.x) % p;
res.y = (p + lambda * (a.x ­ res.x) ­ a.y) % p;
return res;
}
struct coord mult(int d, struct coord e1, int p)
{
coord e2;
int v = d;
struct coord temp;
temp.x = e1.x;
temp.y = e1.y;
for(int i = 0; i < v; i += 1)
{
if(temp.x < 0)
temp.x += p;
if(temp.y < 0)
temp.y += p;
if(temp.x == e1.x && (temp.y != e1.y))
{
temp = e1;
i += 2;
}
else
temp = addn(temp, e1, p);
}
e2.x = ((temp.x >= 0) ? (temp.x) : (p + temp.x));
e2.y = ((temp.y >= 0) ? (temp.y) : (p + temp.y));
return e2;
}
int main()
{
int p, a, b, d;
cin >> p >> a >> b >> d;
struct coord plain;
cin >> plain.x >> plain.y;
struct coord e1 = generate(a, b, p);
struct coord e2 = mult(d, e1, p);
cout << "E1 " << e1.x << " " << e1.y << endl;
cout << "E2 " << e2.x << " " << e2.y << endl;
int r = 27;
struct coord c1 = mult(r, e1, p);
cout << "C1 " << c1.x << " " << c1.y << endl;
struct coord c2 = addn(plain, mult(r, e2, p), p);
cout << "C2 " << c2.x << " " << c2.y << endl;
struct coord decr = addn(c2, mult(­1, mult(d, c1, p), p), p);
cout << "Decrypted " << ((decr.x >= 0) ? (decr.x) : (p + decr.x)) << " " << ((decr.y >= 0) ?
(decr.y) : (p + decr.y)) << endl;
}

Generate primitive roots of Z29*


#include<bits/stdc++.h>
using namespace std;
int power(int x, unsigned int y, int p)
{
int res = 1;
x = x % p;
while (y > 0)
{
if (y & 1)
res = (res*x) % p;
y = y>>1; // y = y/2
x = (x*x) % p;
}
return res;
}
bool isGenerator(int x,int n){
set<int>s;
for(int j=1;j<n;j++){
s.insert(power(x,j,n));
}
if(s.size()==n-1)
return true;
return false;
}
bool isPrime(int n){
for(int i=2;i*i<=n;i++){
if(n%i==0) return false;
}
return true;
}
bool isPrimitive(int n){
if(n==2||n==4) return true;
if(n%2==0) n=n/2;
if(n==1) return true;
int x=0;
for(int i=3;i<=n;i++){
if(isPrime(i)&&n%i==0) {x=i;break;}
}
if(x==0&&n!=1) return false;
while(n%x==0) n=n/x;
if(n==1) return true;
return false;
}
int main(){
int p;
cin>>p;
for(int i=2;i<p;i++){
if(isGenerator(i,p)&&isPrimitive(i))
cout<<i<<endl;
}
return 0;
}

Implement Elgamal digital signature scheme


#include<bits/stdc++.h>
using namespace std;
int modInverse(int n, int m)
{
for(int i=1;i<m;i++){
if((n*i)%m==1){
return i;
}
}
}
int power(int x, unsigned int y, int p)
{
int res = 1;
x = x % p;
while (y > 0)
{if (y & 1)
res = (res*x) % p;
y = y>>1; // y = y/2
x = (x*x) % p; }
return res;
}
int main(){
int M=320,p=3119,e1=2,d=127,r=307;
int e2=power(e1,d,p);
cout<<"e2="<<e2<<endl;
int s1=power(e1,r,p);
cout<<"S1="<<s1<<endl;
int s2=modInverse(r,p­1);
// cout<<s2<<" "<<(M­d*s1)<<endl;
s2=(((M­d*s1)*s2)%(p­1)+(p­1))%(p­1);
cout<<"S2="<<s2<<endl;
int v1=power(e1,M,p);
cout<<"V1="<<v1<<endl;
int v2=(power(e2,s1,p)*power(s1,s2,p))%p;
cout<<"V2="<<v2<<endl;
return 0;
}

Q. Padding operation in SHA-1

#include<bits/stdc++.h?
using namespace std;

vector<int>int_bnry(int a){
vector<int> r;
if(a==0){
r.push_back(0);
return r;
}
while(a>0){
int temp = a%2;
a=a/2;
r.push_back(temp);
}
if(r.size()<8)
{
inti=r.size();
while(i<8){
r.push_back(0);
i++;
}
}
reverse(r.begin(),r.end());
return r;
}

vector<int> pad(vector<int> v){


int n=v.size();
v.push_back(1);
int m = n+1;
while(m%512<448){
v.push_back(0);
m++;
}
vector<int> x=int_bnry(n);
n=64-x.size();//1794
for(inti=1;i<=n;i++) v.push_back(0);
for(inti=0;i<x.size();i++) v.push_back(x[i]);
return v;
}

vector<int>b_hex(vector<int> v){
if(v.size()%512==0){//1794
vector<int> X;
inti,j=v.size()/4;
for(i=0;i<j;i++){
int x = (v[4*i]?pow(2,3):0) + (v[4*i+1]?pow(2,2):0) +
(v[4*i+2]?pow(2,1):0) + (v[4*i+3]?pow(2,0):0);
X.push_back(x);
}return X;
}else{
cout<<"\nNot allowed\n";
return v;
}
}

vector<int> padding(){
string p;
cout<<"\nEnter the text: ";
cin>>p;
int n=p.length(),k=0;
vector<int> r;//1794
for(inti=0;i<n;i++){
vector<int> v= int_bnry(int(p[i]));
for(int j=0;j<v.size();j++){
r.push_back(v[j]);
k++;
}
}
vector<int>r_pad=pad(r);
returnr_pad;
}

int main(){
vector<int>r_pad=padding();
vector<int>r_hex = b_hex(r_pad);
cout<<"\nHex representation of padded message is: "<<endl;
for(inti=0;i<r_hex.size();i++){//1794
if(r_hex[i]>9) cout<<char(r_hex[i]+55);
else cout<<r_hex[i];
cout<<endl;
return 0;
}

Q. SHA-1 basic operations

#include<bits/stdc++.h>
using namespace std;
#define ll long longint
#define mm map<char, string>
#define m1 map<string, char>
mm ma;
m1 m2;
string me(string a, mm ma){
string a1 = "";
for(inti = a.length()-1; i>=0; i--) a1 = ma[a[i]] + a1;
return a1;
}
stringxr(string a, string b){
string re = "";//1794
for(inti = 0; i<a.length(); i++) re = re + (a[i] == b[i] ? string(1, '0') : string(1,
'1'));
return re;
}
string ad(string a, string b){
string re = "";
for(inti = 0; i<a.length(); i++) re = re + (((a[i] == '0') || (b[i] == '0')) ? string(1,
'0') : string(1, '1'));
return re;
}
stringnt(string a){
string re = "";
for(inti = 0; i<a.length(); i++) re = re + (a[i] == '0' ? string(1, '1') : string(1, '0'));
return re;
}
stringro(string a, string b){
string re = "";//1794
for(inti = 0; i<a.length(); i++) re = re + (((a[i] == '1') || (b[i] == '1')) ? string(1,
'1') : string(1, '0'));
return re;
}
string me2(string a, m1 m2){
string te = "", re = "";
for(inti = 0; i<a.length(); i++){
if(i!=0 &&i% 4 == 0){
re += m2[te];
te = "";
}
te += string(1, a[i]);
}
re += m2[te];
te = "";
return re;
}
stringsha_opp(string a,stringb,stringc,stringd,string e, int choice){
ma['0'] = "0000", ma['1'] = "0001", ma['2'] = "0010", ma['3'] = "0011", ma['4'] = "0100",
ma['5'] = "0101", ma['6'] = "0110", ma['7'] = "0111", ma['8'] = "1000", ma['9'] = "1001",
ma['A'] = "1010", ma['B'] = "1011", ma['C'] = "1100", ma['D'] = "1101", ma['E'] = "1110",
ma['F'] = "1111";//1794
m2["0000"] = '0', m2["0001"] = '1', m2["0010"] = '2', m2["0011"] = '3', m2["0100"] = '4',
m2["0101"] = '5', m2["0110"] = '6', m2["0111"] = '7', m2["1000"] = '8', m2["1001"] = '9',
m2["1010"] = 'A', m2["1011"] = 'B', m2["1100"] = 'C', m2["1101"] = 'D', m2["1110"] = 'E',
m2["1111"] = 'F';
string a1 = "", b1 = "", c1 = "", d1 = "", e1 = "";
string re = "";
a1 = me(a, ma);
b1 = me(b, ma);
c1 = me(c, ma);
d1 = me(d, ma);
e1 = me(e, ma);
string o1 = "", o2 = "", o3 = "", o4 = "";
o1 = ro((ad(b1, c1)), ad(nt(b1),d1));
o2 = xr(xr(b1, c1), d1);//1794
o3 = ro(ro(ad(b1, c1), ad(b1, d1)) , ad(c1, d1));
o4 = xr(xr(b1, c1), d1);
switch (choice){
case 1: return o1; break;
case 2: return o2; break;
case 3: return o; break;
case 4: return o4; break;
default:
cout<<"Process 1: "<<me2(o1, m2)<<endl;
cout<<"Process 2: "<<me2(o2, m2)<<endl;
cout<<"Process 3: "<<me2(o3, m2)<<endl;
cout<<"Process 4: "<<me2(o4, m2)<<endl;
}
return "0";
}

int main()
{
stringa,b,c,d,e;
cout<<"\nEnter five strings a, b, c, d, e : \n";
cin>>a>>b>>c>>d>>e;
sha_opp(a,b,c,d,e,0);
return 0;
}

Q. SHA-1 implement

#include<bits/stdc++.h>
#include"padding.cpp"
#include"SHa_opp.cpp"
vector<int> w;
using namespace std;

stringlc_shift(string v,int round){


int n=v.length();
for(inti=0;i<round;i++){
char temp=v[0];//1794
for(int j=0;j<n-1;j++) v[j]=v[j+1];
v[n-1]=temp;
}
return v;
}

int SHA_1(string &a,string&b,string&c,string&d,string&e,int round){


string r1=sha_opp(a,b,c,d,e,round);
string w0="",k0="FEDCBA98",k1="76543210";
for(inti=0;i<32;i++) w0+=char(w[i+((round-1)*32)]+'0');
if(round==2) k0=k1;
string a_l5=lc_shift(me(a,ma),5),b_l30=lc_shift(me(b,ma),30);
b=a;d=c;c=me2(b_l30,m2);//1794
a=me2(ro(ro(ro(ro(r1,e),a_l5),w0),k0),m2);e=d;
cout<<"\nAnswer after round "<<round<<" is: \n";
cout<<a<<"\t"<<b<<"\t"<<c<<"\t"<<d<<"\t"<<e<<endl;
return 0;
}

int main(){
w=padding();
stringa,b,c,d,e;
cout<<"\nEnter five strings a, b, c, d, e : \n";
cin>>a>>b>>c>>d>>e;
SHA_1(a,b,c,d,e,1);
SHA_1(a,b,c,d,e,2);
return 0;
}
IDEA Algorithm
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define mm map<char, string>
#define m1 map<string, char>

string me(string a, mm ma){


string a1 = "";
for(int i = a.length()-1; i>=0; i--){
a1 = ma[a[i]] + a1;
}
return a1;
}

string xr(string a, string b){


string re = "";
for(int i = 0; i<a.length(); i++){
re = re + (a[i] == b[i] ? string(1, '0') : string(1, '1'));
}
return re;
}

string ad(string a, string b){


string re = "";
for(int i = 0; i<a.length(); i++){
re = re + (((a[i] == '0') || (b[i] == '0')) ? string(1, '0') : string(1, '1'));
}
return re;
}

string nt(string a){


string re = "";
for(int i = 0; i<a.length(); i++){
re = re + (a[i] == '0' ? string(1, '1') : string(1, '0'));
}
return re;
}

string ro(string a, string b){


string re = "";
for(int i = 0; i<a.length(); i++){
re = re + (((a[i] == '1') || (b[i] == '1')) ? string(1, '1') : string(1, '0'));
}
return re;
}

string me2(string a, m1 m2){


string te = "", re = "";
for(int i = 0; i<a.length(); i++){
if(i!=0 && i% 4 == 0){
re += m2[te];
te = "";
}
te += string(1, a[i]);
}
re += m2[te];
te = "";
return re;
}

string shift(string a){


string x="",y="";
for(int i=25;i<a.length();i++){
x+=a[i];
}
for(int i=0;i<25;i++)
y = y+a[i];
x = x+y;
return x;
}

int main(){
string key;
cout<<"Insert key in hexadecimal: "<<endl;
cin>>key;
mm ma;
m1 m2;
ma['0'] = "0000", ma['1'] = "0001", ma['2'] = "0010", ma['3'] = "0011", ma['4'] = "0100",
ma['5'] = "0101", ma['6'] = "0110", ma['7'] = "0111", ma['8'] = "1000", ma['9'] = "1001",
ma['A'] = "1010", ma['B'] = "1011", ma['C'] = "1100", ma['D'] = "1101", ma['E'] = "1110",
ma['F'] = "1111";
m2["0000"] = '0', m2["0001"] = '1', m2["0010"] = '2', m2["0011"] = '3', m2["0100"] = '4',
m2["0101"] = '5', m2["0110"] = '6', m2["0111"] = '7', m2["1000"] = '8', m2["1001"] = '9',
m2["1010"] = 'A', m2["1011"] = 'B', m2["1100"] = 'C', m2["1101"] = 'D', m2["1110"] = 'E',
m2["1111"] = 'F';
string a[52],a1[52];
string re = "",re1="";
re = me(key,ma);
int k=0;
for(int i=0;i<8;i++){
a[k++] = re.substr(16*i,16);
}
for(int i=0;i<5;i++){
re = shift(re);
for(int i=0;i<8;i++){
a[k++] = re.substr(16*i,16);
}
}
re=shift(re);
re1=re.substr(0,64);
for(int i=0;i<4;i++){
a[k++] = re.substr(16*i,16);
}
cout<<"\n52 subkeys generated are: "<<"\n";
for(int i=0;i<52;i++){
a1[i]=me2(a[i],m2);
cout<<a[i]<<"\t"<<a1[i]<<endl;
}
string p1[4],re2[4],re3[4],p,pb;//a,b,c,d,e,a1,b1,c1,d1,e1,a2,b2,c2,d2;
cout<<"\nEnter the plain text: "<<endl;
cin>>p;
pb=me(p,ma);
cout<<"\nEncrypted message is: "<<endl;
for(int i=0;i<4;i++){
p1[i] = pb.substr(16*i,16);
re2[i] = xr(p1[i],a[i]);
re3[i] = me2(re2[i],m2);
cout<<re3[i];
}
cout<<endl;

//hextoinary
/*a1 = me(a, ma);
b1 = me(b, ma);
c1 = me(c, ma);
d1 = me(d, ma);
e1 = me(e, ma);
string o1 = "", o2 = "", o3 = "", o4 = "";
o1 = ro((ad(b1, c1)), ad(nt(b1),d1));
o2 = xr(xr(b1, c1), d1);
o3 = ro(ro(ad(b1, c1), ad(b1, d1)) , ad(c1, d1));
o4 = xr(xr(b1, c1), d1);
//binary to hex
cout<<"Process 1: "<<me2(o1, m2)<<endl;
cout<<"Process 2: "<<me2(o2, m2)<<endl;
cout<<"Process 3: "<<me2(o3, m2)<<endl;
cout<<"Process 4: "<<me2(o4, m2)<<endl;
*/
return 0;
}

INPUT:
Key: 7834A4567834CA6B9C4E6B12593A7B91
Plain text: 5634721A7BABC85E

OUTPUT:
Insert key in hexadecimal:

52 subkeys generated are:


0111100000110100 7834
1010010001010110 A456
0111100000110100 7834
1100101001101011 CA6B
1001110001001110 9C4E
0110101100010010 6B12
0101100100111010 593A
0111101110010001 7B91
1010110011110000 ACF0
0110100110010100 6994
1101011100111000 D738
1001110011010110 9CD6
0010010010110010 24B2
0111010011110111 74F7
0010001011110000 22F0
0110100101001000 6948
0010100110101110 29AE
0111000100111001 7139
1010110001001001 AC49
0110010011101001 64E9
1110111001000101 EE45
1110000011010010 E0D2
1001000101011001 9159
1110000011010011 E0D3
0111001101011000 7358
1001001011001001 92C9
1101001111011100 D3DC
1000101111000001 8BC1
1010010100100010 A522
1011001111000001 B3C1
1010011001010011 A653
0101110011100010 5CE2
1001001110100111 93A7
1011100100010111 B917
1000001101001010 834A
0100010101100111 4567
1000001101001100 834C
1010011010111001 A6B9
1100010011100110 C4E6
1011000100100101 B125
0010111100000110 2F06
1001010010001010 948A
1100111100000110 CF06
1001100101001101 994D
0111001110001001 7389
1100110101100010 CD62
0100101100100111 4B27
0100111101110010 4F72
0001010110011110 159E
0000110100110010 0D32
1001101011100111 9AE7
0001001110011010 139A

Enter the plain text:

Encrypted message is:


2E00D64C039F0235

1.Implement Elgamal Digital Signature Scheme for the below given values and check and
verify the digital signature, also ensure that all the generated values are printed whenever it
is required.
Input: Message M=320.
P=3119, e1=2, d=127, r=307.

#include<bits/stdc++.h>
using namespace std;

int main(){
string s;
cin>>s;
string t;
for(int i=0;i<s.length();i++){
int k=s[i];string a;

for(int i=1;i<=8;i++){
int t=k%2;
if(t)a+="1";
else a+="0";
k/=2; }
reverse(a.begin(),a.end());
t+=a; }
t+="1";

while(t.length()!=496){
t+="0";
}

t+="0000000000101000";
string an;

for(int i=0;i<512;i++){
int k=0,x=0;

for(int j=i+3;j>=i;j--){
k+=(t[j]-'0')*(1<<x);
x++;
}
i+=3;
if(k>9){
k=k%10;
an+=('A'+k);
}
else an+=('0'+k);
}
cout<<an<<"\n";
return 0;
}

2.A message m=10 to be signed with sender Private key (n,d). Print the signed message.(
using RSA Digital signature algorithm and each symbols have their usual meaning as in RSA)
&
Design code for RSA digital signature verification, the signed message generated in above
problem (2), should be verified using (n, e) as senders public key. The output should state
verification status of signature.
Input for questions 2 and 3:
p=55243,
q=7669.

#include <bits/stdc++.h>
#define ll long long int
using namespace std;
long long int htd(string hexVal)
{
int len = hexVal.size();
long long int base = 1;

long long int dec_val = 0;

for (int i=len-1; i>=0; i--)


{
if (hexVal[i]>='0' && hexVal[i]<='9')
{
dec_val += (hexVal[i] - 48)*base;
base = base * 16;
}
else if (hexVal[i]>='A' && hexVal[i]<='F')
{
dec_val += (hexVal[i] - 55)*base;
base = base*16;
}
}
return dec_val;
}
string dth(long long int n)
{
string hexaDeciNum = "";
while(n!=0)
{
int temp = 0;
temp = n % 16;
if(temp < 10)
{
hexaDeciNum = char(temp + 48) + hexaDeciNum;
}
else
{
hexaDeciNum = char(temp + 55) + hexaDeciNum;
}
n = n/16;
}
return hexaDeciNum;
}
int main()
{
vector<string>k(64);
for(int i=0;i<64;i++){
double p=sin(i+1);
ll y=1;
p=(p*(1.0*(ll)(y<<32)));
ll t=(ll)p;
k[i]=dth((ll)abs(t));
cout<<k[i]<<" ";
}
cout<<"\n";
string h1 = "67452301";
string h2 = "EFCDAB89";
string h3 = "98BADCFE";
string h4 = "10325476";
long long int a = htd(h1);
long long int b = htd(h2);
long long int c = htd(h3);
long long int d = htd(h4);
long long int fa = (b&c)|(~b&d);
long long int fb = (d&b)|((~d)&c);
long long int fc = b^c^d;
long long int fd = c^(b&(~d));
cout<<fa<<" "<<dth(fa)<<endl;
cout<<fb<<" "<<dth(fb)<<endl;
cout<<fc<<" "<<dth(fc)<<endl;
cout<<fd<<" "<<dth(fd)<<endl;

4.Implement Elliptic Curve CryptoSystem Simulating Elgamal.


Input:
a. Elliptic Curve is E1229(25,64)
b. Take any Generator/Primitive root point of above curve as e1
c. Take private key d=751.
d. Encrypt and decrypt the Plain text: (80, 805)(109,1037)(172,359)(197,989)

#include<bits/stdc++.h>
using namespace std;
long fe(long x,long y,long m)
{
long r=1;
x=x%m;
while(y)
{
if(y&1) r=(r*x)%m;
y=y/2;
x=((x%m)*(x%m))%m;
}
return r;
}
long inv(long x,long p)
{
long i;
for(i=1;i<p;i++)
{
if(((x%p)*i)%p==1) return i;
}
}
int main()
{
long m=10,p=55243,q=7669,e=131;
long qn=(p-1)*(q-1);
long n=p*q;
long d=inv(e,qn);
long s=(fe(m,d,n)+n*n)%n;
cout<<"d: "<<d<<endl;
cout<<"Sent Message:"<<m<<endl;
cout<<"Signature:"<<s<<endl;
long mt=fe(s,e,n);
cout<<"Received Message:"<<m<<endl;
if(m!=mt) cout<<"Accepted"<<endl;
else cout<<"Rejected"<<endl;
cout<<endl;
}

//////////////RSA
#include<bits/stdc++.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
int N =256;

void swap(unsigned char *a, unsigned char *b) {


int tmp = *a;
*a = *b;
*b = tmp;
}

int KSA(char *key, unsigned char *S) {

int len = strlen(key);


int j = 0;

for(int i = 0;i<N;i++)
S[i] = i;

for(int i = 0;i<N;i++) {
j = (j + S[i] + key[i%len]) % N;
swap(&S[i], &S[j]);
}

return 0;
}

int PRGA(unsigned char *S, char *plaintext, unsigned char *ciphertext) {

int i = 0;
int j = 0;

for(int n = 0, len = strlen(plaintext); n < len; n++) {


i = (i + 1) % N;
j = (j + S[i]) % N;
swap(&S[i], &S[j]);
int k= S[(S[i] + S[j]) % N];
ciphertext[n] =(char) (k^plaintext[n]);
}

ciphertext[strlen(plaintext)]='\0';

return 0;
}

int RC4(char *key, char *plaintext, unsigned char *ciphertext) {


unsigned char S[N];
KSA(key, S);
PRGA(S, plaintext, ciphertext);
return 0;
}

int main() {

char key[100],plaintext[100];
unsigned char ciphertext[100];
cin>>key>>plaintext;

RC4(key,plaintext,ciphertext);

for(int i=0,len=strlen(plaintext);i<len;i++)
printf("%02hhX",ciphertext[i]);
cout<<endl;

return 0;
}
//------------------------------elliptic-------------------
#include<bits/stdc++.h>
using namespace std;

vector<int> findY(int a,int mod){


int y=0;
vector<int> vec;
for(;y<mod;y++){
if((y*y)%mod==a%mod)
vec.push_back(y);
}

return vec;
}

int main(){
int a=1,b=27,mod=29;

vector<pair<int,int> > v;

for(int x=0;x<mod;x++){
int h=x*x*x+a*x+b;
vector<int> vec=findY(h,mod);
for(int j=0;j<vec.size();j++){
v.push_back(make_pair(x,vec[j]));
}
}

cout<<v.size()<<endl;
for(int i=0;i<v.size();i++){
cout<<"("<<v[i].first<<" "<<v[i].second<<")"<<endl;
}

}
//------------elliptic add
#include<bits/stdc++.h>
using namespace std;

int modInverse(int a, int m)


{
a = a%m;
for (int x=1; x<m; x++)
if ((a*x) % m == 1)
return x;
}

void posit(int &a,int mod){


if(a<0)
a=a%mod+mod;
}

pair<int,int> Add(int x1,int y1,int x2,int y2,int a,int b,int mod){

pair<int,int> point;

if((x1==x2)&&(y1==y2)){
int modI=modInverse(2*y1,mod);
int lemda=((3*x1*x1+a)*modI)%mod;

int xR=(lemda*lemda-x1-x2)%mod;
int yR=(lemda*(x1-xR)-y1)%mod;

posit(xR,mod);
posit(yR,mod);

point.first=xR;
point.second=yR;
}

else{
int diffY=y2-y1;
int diffX=x2-x1;

posit(diffY,mod);
posit(diffX,mod);

diffX=modInverse(diffX,mod);
int lemda=(diffY*diffX)%mod;

int xR=(lemda*lemda-x1-x2)%mod;
int yR=(lemda*(x1-xR)-y1)%mod;

posit(xR,mod);
posit(yR,mod);

point.first=xR;
point.second=yR;
}

return point;
}

pair<int,int> multiplication(int times,int x1,int y1,int a,int b,int mod){

pair<int,int> point;
point.first=x1;
point.second=y1;

for(int i=1;i<=times;i++){
point=Add(point.first,point.second,x1,y1,a,b,mod);
}

return point;
}

int main(){
int a=1,b=27,mod=29;

int x1,y1,x2,y2,times;
cin>>x1>>y1>>x2>>y2;

pair<int,int> point1=Add(x1,y1,x2,y2,a,b,mod);
cout<<point1.first<<" "<<point1.second<<endl;

cin>>x1>>y1>>times;
point1=multiplication(10,x1,y1,a,b,mod);
cout<<point1.first<<" "<<point1.second<<endl;

}
for(int i=1;i<=k-1;i++)
{
//cout<<c.x<<" "<<c.y<<" adds to "<<a.x<<" "<<a.y<<endl;
if(c.x==0 and c.y==0)
{ c=a;cout<<"<INFINITY CASE at iter "<<i<<">\n";continue; }
c=add(c,a);
}

//--------------------digital signature elliptic curve------------------


#include<bits/stdc++.h>
using namespace std;

int modInverse(int a, int m){


a = a%m;
for (int x=1; x<m; x++)
if ((a*x) % m == 1)
return x;
}

int exp(int b,int e,int m){


int r=1;
while(e>0){
if(e&1)
r=(r*b)%m;
e/=2;
b=(b*b)%m;
}
return r;
}

int main(){
int m,p,e1,d,r;
cin>>m>>p>>e1>>d>>r;
int e2=exp(e1,d,p);
int s1=exp(e1,r,p);
int rr=modInverse(r,p-1);
int s2=((m-d*s1)*rr)%(p-1);
while(s2<0)
s2+=p-1;
s2=s2%(p-1);
int v2=(exp(e2,s1,p)*exp(s1,s2,p))%p;
int v1=exp(e1,m,p);
cout<<"v1 = "<<v1<<endl<<"v2 = "<<v2<<endl;
if(v1==v2)
cout<<"Accept"<<endl;
else
cout<<"Reject"<<endl;
return 0;
}
//--------------------------elliptic curve crypto system--------------------
#include<bits/stdc++.h>
using namespace std;

int modInverse(int a, int m){


a = a%m;
for (int x=1; x<m; x++)
if ((a*x) % m == 1)
return x;
}

int exp(int b,int e,int m){


int r=1;
while(e>0){
if(e&1)
r=(r*b)%m;
e/=2;
b=(b*b)%m;
}
return r;
}
int main(){
int m,p,e1,d,r;
cin>>m>>p>>e1>>d>>r;
int e2=exp(e1,d,p);
int s1=exp(e1,r,p);
int rr=modInverse(r,p-1);
int s2=((m-d*s1)*rr)%(p-1);
while(s2<0)
s2+=p-1;
s2=s2%(p-1);
int v2=(exp(e2,s1,p)*exp(s1,s2,p))%p;
int v1=exp(e1,m,p);
cout<<"v1 = "<<v1<<endl<<"v2 = "<<v2<<endl;
if(v1==v2)
cout<<"Accept"<<endl;
else
cout<<"Reject"<<endl;
return 0;
}
//

-----------------------------------------------RSA-----------------------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

ll modexp(ll a,ll p,ll m)


{
ll r=1;
while(p!=0)
{
if(p&1)
r=(r*a)%m;

a=(a*a)%m;

p=p/2;
}
return r;
}

ll extended(ll a,ll b,ll &x,ll &y)


{
if(a==0)
{
x=0; y=1;
return b;
}

ll x1,y1;
ll gcd = extended(b%a,a,x1,y1);

x = y1-(b/a)*x1;
y = x1;

ll mulInverse(ll a,ll m)
{
if(__gcd(a,m)!=1)
{
//cout << "Not possible";
return -1;
}

ll x,y;

ll g = extended(a,m,x,y);
// cout << "Inverse: " << x << "\n";
// cout << (x+m)%m << "\n";
return (x+m)%m;
}

int main()
{

cout << "Enter p and q \n";


ll p ,q; cin >> p >> q;
ll n = p*q;
ll phi = (p-1)*(q-1);

ll e = 3; // >1 && < phin


cout << phi << "\n";
ll d;

for(ll i=2;;i++)
{
d = mulInverse(i,phi);
if(d!=-1) {e=i; break;}
}
/cout << "Enter m :\n";
ll m;
cin >> m;
cout << "SIGNED MESSAGE \n";
ll sign;
cout << (sign=modexp(m,d,n)) << "\n";

cout << "Verification : \n";


cout << modexp(sign,e,n) << "\n";

return 0;}

////////////////SHA 1
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<math.h>
#include<stdlib.h>
#define rotateleft(x,n) ((x<<n) | (x>>(32-n)))
#define rotateright(x,n) ((x>>n) | (x<<(32-n)))
void SHA1(unsigned char * str1)
{
int i,j;
unsigned long int h0,h1,h2,h3,h4,a,b,c,d,e,f,k,temp;
h0 = 0x67452301;
h1 = 0xEFCDAB89;
h2 = 0x98BADCFE;
h3 = 0x10325476;
h4 = 0xC3D2E1F0;
unsigned char * str;
str = (unsigned char *)malloc(strlen((const char *)str1)+100);
strcpy((char *)str,(const char *)str1);
int current_length = strlen((const char *)str);
int original_length = current_length;
str[current_length] = 0x80;
str[current_length + 1] = '\0';
char ic = str[current_length];
current_length++;
int ib = current_length % 64;
if(ib<56)
ib = 56-ib;
else
ib = 120 - ib;
for(int i=0;i < ib;i++)
{
str[current_length]=0x00;
current_length++;
}
str[current_length + 1]='\0';
for(i=0;i<6;i++)
{
str[current_length]=0x0;
current_length++;
}
str[current_length] = (original_length * 8) / 0x100 ;
current_length++;
str[current_length] = (original_length * 8) % 0x100;
current_length++;
str[current_length+i]='\0';
int number_of_chunks = current_length/64;
unsigned long int word[80];
for(i=0;i<number_of_chunks;i++)
{
for(int j=0;j<16;j++)
{
word[j] = str[i*64 + j*4 + 0] * 0x1000000 + str[i*64 + j*4 + 1] *
0x10000 + str[i*64 + j*4 + 2] * 0x100 + str[i*64 + j*4 + 3];
}
for(j=16;j<80;j++)
{
word[j] = rotateleft((word[j-3] ^ word[j-8] ^ word[j-14] ^ word[j-16]),1);
}
a = h0;
b = h1;
c = h2;
d = h3;
e = h4;
for(int m=0;m<80;m++)
{
if(m<=19)
{
f = (b & c) | ((~b) & d);
k = 0x5A827999;
}
else if(m<=39)
{
f = b ^ c ^ d;
k = 0x6ED9EBA1;
}
else if(m<=59)
{
f = (b & c) | (b & d) | (c & d);
k = 0x8F1BBCDC;
}
else
{
f = b ^ c ^ d;
k = 0xCA62C1D6;
}
temp = (rotateleft(a,5) + f + e + k + word[m]) & 0xFFFFFFFF;
e = d;
d = c;
c = rotateleft(b,30);
b = a;
a = temp;
}
h0 = h0 + a;
h1 = h1 + b;
h2 = h2 + c;
h3 = h3 + d;
h4 = h4 + e;
}
printf("\n\n");
printf("Hash: %x %x %x %x %x",h0, h1, h2, h3, h4);
printf("\n\n");
}
void main()
{
SHA1((unsigned char *)"hello");
}

_______________________SHA 2nd part

#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<math.h>
#include<stdlib.h>
#define rotateleft(x,n) ((x<<n) | (x>>(32-n)))
#define rotateright(x,n) ((x>>n) | (x<<(32-n)))
void SHA1(unsigned char * str1)
{
int i,j;
unsigned long int h0,h1,h2,h3,h4,a,b,c,d,e,f,k,temp;
h0 = 0x67452301;
h1 = 0xEFCDAB89;
h2 = 0x98BADCFE;
h3 = 0x10325476;
h4 = 0xC3D2E1F0;
unsigned char * str;
str = (unsigned char *)malloc(strlen((const char *)str1)+100);
strcpy((char *)str,(const char *)str1);
int current_length = strlen((const char *)str);
int original_length = current_length;
str[current_length] = 0x80;
str[current_length + 1] = '\0';
char ic = str[current_length];
current_length++;
int ib = current_length % 64;
if(ib<56)
ib = 56-ib;
else
ib = 120 - ib;
for(int i=0;i < ib;i++)
{
str[current_length]=0x00;
current_length++;
}
str[current_length + 1]='\0';
for(i=0;i<6;i++)
{
str[current_length]=0x0;
current_length++;
}
str[current_length] = (original_length * 8) / 0x100 ;
current_length++;
str[current_length] = (original_length * 8) % 0x100;
current_length++;
str[current_length+i]='\0';
int number_of_chunks = current_length/64;
unsigned long int word[80];
for(i=0;i<number_of_chunks;i++)
{
for(int j=0;j<16;j++)
{
word[j] = str[i*64 + j*4 + 0] * 0x1000000 + str[i*64 + j*4 + 1] *
0x10000 + str[i*64 + j*4 + 2] * 0x100 + str[i*64 + j*4 + 3];
}
for(j=16;j<80;j++)
{
word[j] = rotateleft((word[j-3] ^ word[j-8] ^ word[j-14] ^ word[j-16]),1);
}
a = h0;
b = h1;
c = h2;
d = h3;
e = h4;
for(int m=0;m<80;m++)
{
if(m<=19)
{
f = (b & c) | ((~b) & d);
k = 0x5A827999;
}
else if(m<=39)
{
f = b ^ c ^ d;
k = 0x6ED9EBA1;
}
else if(m<=59)
{
f = (b & c) | (b & d) | (c & d);
k = 0x8F1BBCDC;
}
else
{
f = b ^ c ^ d;
k = 0xCA62C1D6;
}
temp = (rotateleft(a,5) + f + e + k + word[m]) & 0xFFFFFFFF;
e = d;
d = c;
c = rotateleft(b,30);
b = a;
a = temp;
}
h0 = h0 + a;
h1 = h1 + b;
h2 = h2 + c;
h3 = h3 + d;
h4 = h4 + e;
}
printf("\n\n");
printf("Hash: %x %x %x %x %x",h0, h1, h2, h3, h4);
printf("\n\n");
}
void SHA1_part3(unsigned char * str1)
{
int i,j;
unsigned long int h0,h1,h2,h3,h4,a,b,c,d,e,f,k,temp;
h0 = 0x01234567;
h1 = 0x89ABCDEF;
h2 = 0xFEDCBA98;
h3 = 0x76543210;
h4 = 0xC3D2E1F0;
unsigned char * str;
str = (unsigned char *)malloc(strlen((const char *)str1)+100);
strcpy((char *)str,(const char *)str1);
int current_length = strlen((const char *)str);
int original_length = current_length;
str[current_length] = 0x80;
str[current_length + 1] = '\0';
char ic = str[current_length];
current_length++;
int ib = current_length % 64;
if(ib<56)
ib = 56-ib;
else
ib = 120 - ib;
for(int i=0;i < ib;i++)
{
str[current_length]=0x00;
current_length++;
}
str[current_length + 1]='\0';
for(i=0;i<6;i++)
{
str[current_length]=0x0;
current_length++;
}
str[current_length] = (original_length * 8) / 0x100 ;
current_length++;
str[current_length] = (original_length * 8) % 0x100;
current_length++;
str[current_length+i]='\0';
int number_of_chunks = current_length/64;
unsigned long int word[80];
for(i=0;i<number_of_chunks;i++)
{
for(int j=0;j<16;j++)
{
word[j] = str[i*64 + j*4 + 0] * 0x1000000 + str[i*64 + j*4 + 1] *
0x10000 + str[i*64 + j*4 + 0] * 0x100 + str[i*64 + j*4 + 1];
}
for(j=16;j<80;j++)
{
word[j] = rotateleft((word[j-3] ^ word[j-8] ^ word[j-14] ^ word[j-16]),1);
}
a = h0;
b = h1;
c = h2;
d = h3;
e = h4;
for(int m=0;m<80;m++)
{
f = (b & c) | ((~b) & d);
k = 0xFEDCBA98;

temp = (rotateleft(a,5) + f + e + k + word[m]) & 0xFFFFFFFF;


e = d;
d = c;
c = rotateleft(b,30);
b = a;
a = temp;}
// second 32 bit
for(int j=0;j<16;j++)
{
word[j] = str[i*64 + j*4 + 2] * 0x100 + str[i*64 + j*4 + 3];
}
for(j=16;j<80;j++)
{
word[j] = rotateleft((word[j-3] ^ word[j-8] ^ word[j-14] ^ word[j-16]),1);
}
for(int m=0;m<80;m++)
{
f = b ^ c ^ d;
k = 0x76543210;

temp = (rotateleft(a,5) + f + e + k + word[m]) & 0xFFFFFFFF;


e = d;
d = c;
c = rotateleft(b,30);
b = a;
a = temp;}
h0 = h0 + a;
h1 = h1 + b;
h2 = h2 + c;
h3 = h3 + d;
h4 = h4 + e;
}
printf("\n\n");
printf("Hash: %x %x %x %x %x",h0, h1, h2, h3, h4);
printf("\n\n");
}
void SHA1_part2()
{
int i,j;
unsigned long int h0,h1,h2,h3,h4,a,b,c,d,e,f,k,temp;
h0 = 0x01234567;
h1 = 0x89ABCDEF;
h2 = 0xFEDCBA98;
h3 = 0x76543210;
h4 = 0xC3D2E1F0;

a = h0;
b = h1;
c = h2;
d = h3;
e = h4;

f = (b & c) | ((~b) & d);


printf("Op 1: %x \n",f);
f = b ^ c ^ d;
printf("Op 2: %x \n",f);

f = (b & c) | (b & d) | (c & d);


printf("Op 3: %x \n",f);

f = b ^ c ^ d;
printf("Op 4: %x \n",f);
}
void main()
{
SHA1((unsigned char *)"hello");
SHA1_part2();
SHA1_part3((unsigned char *)"hello");
}

---------------------IDEA------CPP
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define mm map<char, string>
#define m1 map<string, char>

string me(string a, mm ma){


string a1 = "";
for(int i = a.length()-1; i>=0; i--){
a1 = ma[a[i]] + a1;
}
return a1;
}

string xr(string a, string b){


string re = "";
for(int i = 0; i<a.length(); i++){
re = re + (a[i] == b[i] ? string(1, '0') : string(1, '1'));
}
return re;
}

string ad(string a, string b){


string re = "";
for(int i = 0; i<a.length(); i++){
re = re + (((a[i] == '0') || (b[i] == '0')) ? string(1, '0') : string(1, '1'));
}
return re;
}

string nt(string a){


string re = "";
for(int i = 0; i<a.length(); i++){
re = re + (a[i] == '0' ? string(1, '1') : string(1, '0'));
}
return re;
}

string ro(string a, string b){


string re = "";
for(int i = 0; i<a.length(); i++){
re = re + (((a[i] == '1') || (b[i] == '1')) ? string(1, '1') : string(1, '0'));
}
return re;
}

string me2(string a, m1 m2){


string te = "", re = "";
for(int i = 0; i<a.length(); i++){
if(i!=0 && i% 4 == 0){
re += m2[te];
te = "";
}
te += string(1, a[i]);
}
re += m2[te];
te = "";
return re;
}

string shift(string a){


string x="",y="";
for(int i=25;i<a.length();i++){
x+=a[i];
}
for(int i=0;i<25;i++)
y = y+a[i];
x = x+y;
return x;
}

int main(){
string key;
cout<<"Insert key in hexadecimal: "<<endl;
cin>>key;
mm ma;
m1 m2;
ma['0'] = "0000", ma['1'] = "0001", ma['2'] = "0010", ma['3'] = "0011", ma['4'] = "0100",
ma['5'] = "0101", ma['6'] = "0110", ma['7'] = "0111", ma['8'] = "1000", ma['9'] = "1001",
ma['A'] = "1010", ma['B'] = "1011", ma['C'] = "1100", ma['D'] = "1101", ma['E'] = "1110",
ma['F'] = "1111";
m2["0000"] = '0', m2["0001"] = '1', m2["0010"] = '2', m2["0011"] = '3', m2["0100"] = '4',
m2["0101"] = '5', m2["0110"] = '6', m2["0111"] = '7', m2["1000"] = '8', m2["1001"] = '9',
m2["1010"] = 'A', m2["1011"] = 'B', m2["1100"] = 'C', m2["1101"] = 'D', m2["1110"] = 'E',
m2["1111"] = 'F';
string a[52],a1[52];
string re = "",re1="";
re = me(key,ma);
int k=0;
for(int i=0;i<8;i++){
a[k++] = re.substr(16*i,16);
}
for(int i=0;i<5;i++){
re = shift(re);
for(int i=0;i<8;i++){
a[k++] = re.substr(16*i,16);
}
}
re=shift(re);
re1=re.substr(0,64);
for(int i=0;i<4;i++){
a[k++] = re.substr(16*i,16);
}
cout<<"\n52 subkeys generated are: "<<"\n";
for(int i=0;i<52;i++){
a1[i]=me2(a[i],m2);
cout<<a[i]<<"\t"<<a1[i]<<endl;
}
string p1[4],re2[4],re3[4],p,pb;//a,b,c,d,e,a1,b1,c1,d1,e1,a2,b2,c2,d2;
cout<<"\nEnter the plain text: "<<endl;
cin>>p;
pb=me(p,ma);
cout<<"\nEncrypted message is: "<<endl;
for(int i=0;i<4;i++){
p1[i] = pb.substr(16*i,16);
re2[i] = xr(p1[i],a[i]);
re3[i] = me2(re2[i],m2);
cout<<re3[i];
}
cout<<endl;

//hextoinary
/*a1 = me(a, ma);
b1 = me(b, ma);
c1 = me(c, ma);
d1 = me(d, ma);
e1 = me(e, ma);
string o1 = "", o2 = "", o3 = "", o4 = "";
o1 = ro((ad(b1, c1)), ad(nt(b1),d1));
o2 = xr(xr(b1, c1), d1);
o3 = ro(ro(ad(b1, c1), ad(b1, d1)) , ad(c1, d1));
o4 = xr(xr(b1, c1), d1);
//binary to hex
cout<<"Process 1: "<<me2(o1, m2)<<endl;
cout<<"Process 2: "<<me2(o2, m2)<<endl;
cout<<"Process 3: "<<me2(o3, m2)<<endl;
cout<<"Process 4: "<<me2(o4, m2)<<endl;
*/
return 0;
}

///////////////SAMPATH

#1. Aim: Encrypting and decrypting with a Ceaser Cipher


#include<bits/stdc++.h>
using namespace std;
int k = 3;
int base = 26;

string encrypt(string message){

string en_str = message;


for(int i=0; i<message.length(); i++){
int element = en_str[i];
int ascii = element - 'A';
int new_element = (ascii + k)%base + 'A';
en_str[i] = new_element;
}

return en_str;
}

string decrypt(string en_str){

string de_str = en_str;


for(int i=0; i<en_str.length(); i++){
int element = de_str[i];
int ascii = element - 'A';
int new_element = (ascii - k);
if (new_element < 0)
new_element = 26 + new_element;

new_element = new_element%base + 'A';


de_str[i] = new_element;
}
return de_str;
}

int main(){

string message = "CRYPTOGRAPHY";


string en_str = encrypt(message);
cout<<endl;
cout<<en_str<<endl;

string de_str = decrypt(en_str);


cout<<de_str<<endl;

return 0;

#2: Aim: decrypting a encrypted word to find its original word and key

#include<iostream>
#include<bits/stdc++.h>
using namespace std;

int base = 26;

string encrypt(string message, int k){

string en_str = message;


for(int i=0; i<message.length(); i++){
int element = en_str[i];
int ascii = element - 'A';
int new_element = (ascii + k)%base + 'A';
en_str[i] = new_element;
}

return en_str;
}

string decrypt(string en_str, int k){

string de_str = en_str;


for(int i=0; i<en_str.length(); i++){
int element = de_str[i];
int ascii = element - 'A';
int new_element = (ascii - k);
if (new_element < 0)
new_element = 26 + new_element;

new_element = new_element%base + 'A';


de_str[i] = new_element;
}

return de_str;
}

int main(){

string en_str = "FQOCUDEM";


//string en_str = encrypt(message);
//cout<<endl;
//cout<<en_str<<endl;

for(int i=0; i<base; i++){


string de_str = decrypt(en_str, i);
cout<<i<<". "<<de_str<<endl;
}
return 0;

#3: Aim: Encryption using Playfair cipher.

#include <bits/stdc++.h>
using namespace std;
map<char, pair<int,int> > reconvert;
map<pair<int,int>, char> convert;
void playfair_matrix(string key){
map<char, bool> temp;
int r=0, c=0;
for(int i=0; i<key.size(); ++i){
if(isalpha(key[i]) and key[i]!='J' and temp.find(key[i])==temp.end()){
temp[key[i]] = true;
reconvert[key[i]] = {r,c};
convert[{r,c}] = key[i];
++c;
if(c == 5)
++r, c=0;
}
}
for(char ch='A'; ch<='Z'; ++ch){
if(ch!='J' and temp.find(ch) == temp.end()){
temp[ch] = true;
reconvert[ch] = {r,c};
convert[{r,c}] = ch;
++c;
if(c == 5)
++r, c=0;
}
}
}
string cipher_text(string plain_text){
int n = 0;
for(int i=0; i<plain_text.size(); ++i){
if(isalpha(plain_text[i]))
plain_text[n++] = plain_text[i];
}
plain_text.erase(plain_text.begin()+n, plain_text.end());
int i = 0;
while(i<plain_text.size() and i+1<plain_text.size()){
if(plain_text[i] == plain_text[i+1])
plain_text.insert(plain_text.begin()+i+1, 'X');
else
i += 2;
}
if(plain_text.size()%2 == 1)
plain_text.push_back('X');
string ret(plain_text.size(), ' ');
pair<int,int> pos1, pos2;
for(int i=0,j=1; j<plain_text.size(); i+=2,j+=2){
pos1 = reconvert[plain_text[i]];
pos2 = reconvert[plain_text[j]];
if(pos1.first == pos2.first){
ret[i] = convert[{pos1.first,(pos1.second+1)%5}];
ret[j] = convert[{pos2.first,(pos2.second+1)%5}];
}
else if(pos1.second == pos2.second){
ret[i] = convert[{(pos1.first+1)%5,pos1.second}];
ret[j] = convert[{(pos2.first+1)%5,pos2.second}];
}
else{
ret[i] = convert[{pos1.first,pos2.second}];
ret[j] = convert[{pos2.first,pos1.second}];
}
}
return ret;
}
string decipher_text(string cipher_text){
string ret(cipher_text.size(), ' ');
pair<int,int> pos1, pos2;
for(int i=0,j=1; j<cipher_text.size(); i+=2,j+=2){
pos1 = reconvert[cipher_text[i]];
pos2 = reconvert[cipher_text[j]];
if(pos1.first == pos2.first){
ret[i] = convert[{pos1.first,(pos1.second+4)%5}];
ret[j] = convert[{pos2.first,(pos2.second+4)%5}];
}
else if(pos1.second == pos2.second){
ret[i] = convert[{(pos1.first+4)%5,pos1.second}];
ret[j] = convert[{(pos2.first+4)%5,pos2.second}];
}
else{
ret[i] = convert[{pos1.first,pos2.second}];
ret[j] = convert[{pos2.first,pos1.second}];
}
}
int n = 0;
for(int i=0; i<ret.size(); ++i){
if(ret[i] != 'X'){
ret[n++] = ret[i];
}
}
ret.erase(ret.begin()+n, ret.end());
return ret;
}
int main() {
string key, plain_text, cipher_text;
getline(cin,key);
getline(cin,plain_text);
transform(key.begin(), key.end(), key.begin(), towupper);
transform(plain_text.begin(), plain_text.end(), plain_text.begin(), towupper);
playfair_matrix(key);
for(int i=0; i<5; ++i){
for(int j=0; j<5; ++j){
cout<<convert[{i,j}]<<" ";
}
cout<<endl;
}
cout<<(cipher_text = cipher_text(plain_text))<<endl;
cout<<decipher_text(cipher_text)<<endl;
return 0;
}
#4: To implement Vignere cipher

#include<bits/stdc++.h>
using namespace std;

string string1 = "lifeisfullofsurprises";


string keyword = "health";

int main(){

int keylen = keyword.length();


int plainlen = string1.length();

int n = ceil(float(plainlen)/keylen);
string r = "";

for(int i=0; i<n; i++){


r += keyword;
}

//string s = r.substr(0, (r.length() - plainlen%keylen));


string encrypted = "";

for(int i=0; i<string1.length(); i++){


int j = (r[i] - 'a') + (string1[i] - 'a');
j = j%26;
char ch = j + 'a';
encrypted += ch;
}

cout<<encrypted<<endl;

return 0;
}

#5: To implement Transposition cipher:

#include<bits/stdc++.h>
using namespace std;

bool cmp(pair<int,int> a,pair<int,int> b){


if(a.first<b.first)
return true;
return false;
}

int main(){
int n=6;
int arr[6] = {3, 2, 6, 1, 5, 4};

vector<pair<int,int> > v;

for(int i=0;i<n;i++)
v.push_back(make_pair(arr[i],i));

sort(v.begin(),v.end(),cmp);

for(int i=0;i<n;i++)
cout<<v[i].second+1<<" ";

cout<<endl;
}

#6: To implement one-time pad version Vignere cipher:

#include<bits/stdc++.h>
using namespace std;

string string1 = "sendmoremoney";


string string2 = "cashnotneeded";

int arr[13] = {90, 1, 7, 23, 15, 21, 14, 11, 11, 2, 8, 9, 1};

int main(){

string ciphertext = "";


vector<int> v;

for(int i=0; i<string1.length(); i++){


int j = (string1[i] - 'a' + arr[i])%26;
char ch = j + 'a';
ciphertext += ch;
}

cout<<ciphertext<<endl;
for(int i=0; i<string1.length(); i++){
int j = (string2[i] - 'a' - ciphertext[i] - 'a')%26;
if(j < 0) j += 26;
v.push_back(j);
cout<<j<<" ";
}

cout<<endl;
return 0;

#7: To implement Autokey cipher:

#include<bits/stdc++.h>
using namespace std;

int main(){

int key = 7;

string plain = "thehouseisbeingsoldtonight", enc, dec;

enc=(plain[0]+key-'a')%26+'a';

for(int i=1;i<plain.length();i++){
enc+=(plain[i]+plain[i-1]-'a'-'a')%26+'a';
}

cout<<enc<<endl;

dec=(enc[0]-'a'-key+26)%26+'a';

for(int i=1;i<plain.length();i++){
dec+=(enc[i]-dec[i-1]+26)%26+'a';
}

cout<<dec;
cout<<endl;
return 0;
}

9. Implement addition, multiplication and inverse operation on GF(2 power 4) with


Irreducible polynomial 10011.
Code:

#include<bits/stdc++.h>
#define N 2
using namespace std;
string MOD;
string dp[N][N],idp[N][N],C[N][N];

string stuffZero(string s,int n)


{ while(s.length()<n)
s='0'+s;
return s;
}

int binaryToInt(string s)
{ int ans=0;
reverse(s.begin(),s.end());
for(int i=0;i<s.length();i++)
ans+=(1<<i)*(s[i]-'0');
return ans;
}

string intToBinary(int num)


{ string ans="";
while(num)
{ char c=num%2;
ans+=(c+'0');
num/=2;
}
reverse(ans.begin(),ans.end());
return ans;
}

int len(int n){


int m=0;
while(n){
n=n/2;
m++;
}
return m;
}

string divide(string m,string MOD) {


int mod=binaryToInt(MOD),n=binaryToInt(m);
while(len(n)>=len(mod)){
n=n^(mod<<(len(n)-len(mod)));
}
return intToBinary(n);
}

string add( string s, string p ) {


int n=binaryToInt(s),m=binaryToInt(p);
return divide(intToBinary(n^m), MOD);
}
string mul( string s, string p){
int n = binaryToInt(s),m = binaryToInt(p),ans=0;
for(int i=0;(1<<i)<=n;i++){
if(n&(1<<i))
ans=ans^(m<<i);
}
return divide(intToBinary(ans), MOD);
}

void matrixMul(string A[N][N],string B[N][N]){


for(int i=0;i<N;i++)
for(int j=0;j<N;j++){
C[i][j]="0";
for(int k=0;k<N;k++)
C[i][j]=add(C[i][j],mul(A[i][k],B[k][j]));
}
}

int main()
{
int c;
char t='y';
string s,p;
cout<<"Enter Irreducible polynomial : ";
cin>>MOD;

while(t == 'y'){
cout<<"\nEnter 1:Addition 2:Multiplication 3:Inverse Operation : ";
cin>>c;

switch(c){

case 1:{
cout<<"\nADDITION\nEnter the two polynomials : ";
cin>>s>>p;
cout<<"Resultant polynomial : "<<stuffZero(add(s,p),2*N)<<endl;
break;
}

case 2:{
cout<<"\nMULTIPLICATION\nEnter the two polynomials : ";
cin>>s>>p;
cout<<"Resultant polynomial : "<<stuffZero(mul(s,p),2*N);
break;
}

case 3:{
cout<<"\nINVERSE OF A MATRIX\nEnter the matrix :\n";
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
cin>>dp[i][j];

string det=add(mul(dp[0][0],dp[1][1]),mul(dp[0][1],dp[1][0]));
cout<<"Result of inverse operation : \n";
idp[0][0]=divide(dp[1][1],det);
idp[0][1]=divide(dp[1][0],det);
idp[1][0]=divide(dp[0][1],det);
idp[1][1]=divide(dp[0][0],det);
for(int i=0;i<N;i++){
for(int j=0;j<N;j++)
cout<<stuffZero(idp[i][j],2*N)<<" ";
cout<<endl;
}
}
}

cout<<"\nWant to perform more operations ? (y/n) : ";


cin>>t;
}
return 0;
}

Output:

10. Implement Mix Column and Inverse Mix Column operations in S – AES with previous
Matrix as key.

Code:
#include<bits/stdc++.h>
#define N 2
using namespace std;
string MOD;
string dp[N][N],idp[N][N],C[N][N];
string stuffZero(string s,int n)
{ while(s.length()<n)
s='0'+s;
return s;
}
int binaryToInt(string s)
{ int ans=0;
reverse(s.begin(),s.end());
for(int i=0;i<s.length();i++)
ans+=(1<<i)*(s[i]-'0');
return ans;
}
string intToBinary(int num)
{ string ans="";
while(num)
{ char c=num%2;
ans+=(c+'0');
num/=2;
}
reverse(ans.begin(),ans.end());
return ans;
}
int len(int n){
int m=0;
while(n){
n=n/2;
m++;
}
return m;
}
string divide(string m,string MOD)
{ int mod=binaryToInt(MOD),n=binaryToInt(m);
while(len(n)>=len(mod)){
n=n^(mod<<(len(n)-len(mod)));
}
return intToBinary(n);
}
string add( string s, string p )
{ int n=binaryToInt(s),m=binaryToInt(p);
return divide(intToBinary(n^m), MOD);
}
string mul( string s, string p)
{ int n = binaryToInt(s),m = binaryToInt(p),ans=0;
for(int i=0;(1<<i)<=n;i++){
if(n&(1<<i))
ans=ans^(m<<i);
}
return divide(intToBinary(ans), MOD);
}
void matrixMul(string A[N][N],string B[N][N]){
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
C[i][j]="0";
for(int k=0;k<N;k++)
C[i][j]=add(C[i][j],mul(A[i][k],B[k][j]));
}
}
}
int main()
{
int t,c;
string s,p;
MOD="10011";
cout<<"\n** S-AES Encryption **\nEnter the matrix\n";
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
cin>>dp[i][j];
string det=add(mul(dp[0][0],dp[1][1]),mul(dp[0][1],dp[1][0]));
idp[0][0]=divide(dp[1][1],det);
idp[0][1]=divide(dp[1][0],det);
idp[1][0]=divide(dp[0][1],det);
idp[1][1]=divide(dp[0][0],det);
string A[N][N]={{"0110","1111"},{"0110","1011"}};
matrixMul(A,dp);
cout<<"\nMIX COLUMN: \n";
for(int i=0;i<N;i++){
for(int j=0;j<N;j++)
cout<<stuffZero(C[i][j],2*N)<<" ";
cout<<endl;
}
cout<<endl;
matrixMul(A,idp);
cout<<"\nINVERSE MIX COLUMN: \n";
for(int i=0;i<N;i++){
for(int j=0;j<N;j++)
cout<<stuffZero(C[i][j],2*N)<<" ";
cout<<endl;
}
cout<<endl;
return 0;
}

OUTPUT:

11. Implement RC4 encryption algorithm

#include<bits/stdc++.h>
using namespace std;
int main()
{
string plain;
string key="01010000";
int keylength=key.length();
cin>>plain;

vector<int> S(256);
vector<int> T(256);

for(int i=0;i<=255;i++)
{
S[i]=i;
T[i]=key[i%keylength]-'0';
}

int j=0;

for(int i=0;i<=255;i++)
{
j=(j+S[i]+T[i])%256;
int temp=S[i];
S[i]=S[j];
S[j]=temp;

int i=0;
j=0;
int k;
while(true)
{
i=(i+1)%256;
j=(j+S[i])%256;
int temp=S[i];
S[i]=S[j];
S[j]=temp;
for(int x=0;x<=255;x++)
cout<<S[x]<<" ";
cout<<endl;
k=S[(S[i]+S[j])%256];
cout<<k<<endl;
vector<int> bin(8);
int index=7;
while(k)
{
int x1=k%2;
bin[index--]=x1;
k=k/2;
}
string cipher="";
for(int x=0;x<8;x++)
cipher.push_back(((plain[x]-'0') xor bin[x])+'0');
cout<<cipher;
cin>>plain;
}
}

RC4 alternate code


#include <bits/stdc++.h>
using namespace std;

int main() {
int n, k;
cin>>n;
vector<int> plain_text(n);
for(int i=0; i<n; ++i)
cin>>plain_text[i];
cin>>k;
vector<int> key(256);
for(int i=0; i<k; ++i)
cin>>key[i];
int s[256];
for(int i=0; i<256; ++i){
s[i] = i;
key[i] = key[i%k];
}
int i=0, j=0, t=0;
for(int i=0; i<256; ++i){
j = (j + s[i] + key[i])%256;
swap(s[i],s[j]);
}
i = j = 0;
vector<int> cipher(n), decipher(n);
for(int p=0; p<n; ++p){
i = (i + 1)%256;
j = (j + s[i])%256;
swap(s[i],s[j]);
t = s[(s[i]+s[j])%256];
cipher[p] = plain_text[p] ^ t;
decipher[p] = cipher[p] ^ t;
}
for(int i=0; i<n; ++i)
cout<<cipher[i]<<" ";
cout<<endl;
for(int i=0; i<n; ++i)
cout<<decipher[i]<<" ";
cout<<endl;
return 0;
}

//////RC5
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const double e = 2.718281828459;
const double f = 1.61803398875;
ll w, r, b, u, t, c, p, q, MOD;

ll odd(double val){
ll fl = val;
if(fl & 1)
return fl;
return fl+1;
}

ll left_circular_Shift(ll num, ll shift){


shift %= w;
return ((1ull<<w)-1) & ((num << shift) | (num >> (w-shift)));
}

ll right_circular_Shift(ll num, ll shift){


shift %= w;
return ((1ull<<w)-1) & ((num >> shift) | (num << (w-shift)));
}

int main() {
cin>>w>>r>>b;
MOD = 1ull << w;
t = 2*r+2;
u = w / 8;
c = ceil(b*1.0/u);
p = odd((e-2)*(1ll<<w));
q = odd((f-1)*(1ll<<w));
ll plain_text, cipher_text;
cin>>plain_text;
vector<ll> key(b), L(c), S(t);
for(int i=0; i<b; ++i)
cin>>key[i];
for(int i=b-1; i>=0; --i)
L[i/u] = (L[i/u] << 8ull) + key[i];
S[0] = p;
for(int i=1; i<t; ++i)
S[i] = (S[i-1] + q)%MOD;
ll i=0, j=0;
ll A=0, B=0;
for(int z=0; z<3*max(t,c); ++z){
A = S[i] = left_circular_Shift(((S[i] + A)%MOD + B)%MOD, 3);
B = L[j] = left_circular_Shift(((L[j] + A)%MOD + B)%MOD, (A + B));
i = (i + 1)%t;
j = (j + 1)%c;
}
A = plain_text >> w;
B = ((1ull<<w)-1) & plain_text;
A = (A + S[0])%MOD;
B = (B + S[1])%MOD;
for(int z=1; z<=r; ++z){
A = (left_circular_Shift((A ^ B), B) + S[2*z])%MOD;
B = (left_circular_Shift((A ^ B), A) + S[2*z+1])%MOD;
}
cipher_text = (A << w) | B;
cout<<cipher_text<<endl;
for(int z=r; z>0; --z){
B = right_circular_Shift(B - S[2*z+1], A) ^ A;
A = right_circular_Shift(A - S[2*z], B) ^ B;
}
B = B - S[1];
A = A - S[0];
plain_text = (A << w) | B;
cout<<plain_text<<endl;
return 0;
}

12. Implement Fast Exponent Method:

#include<bits/stdc++.h>
using namespace std;

int fast_expo(int base,int power,int mod)


{
int res=1;
while(power>0)
{
if(power & 1)
res=(res%mod * base%mod)%mod;
power=power>>1;
base=(base%mod * base%mod)%mod;
}
return res;
}

int main()
{
int a,b,c;
cin>>a>>b>>c;
cout<<fast_expo(a,b,c)<<endl;
}

13. Implement Euler Totient Function:

#include<bits/stdc++.h>
using namespace std;

int euler_totient(int n)
{
float ans=n;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
ans*=(1.0-(1.0/(float)i));
while(n%i==0)
n=n/i;
}
if(n>1)
ans*=(1.0-(1.0/(float)n));
return ans;
}

int main()
{
int n;
cin>>n;
cout<<euler_totient(n)<<endl;
}

#Affine cipher

#include <bits/stdc++.h>
using namespace std;

int extended_euclid(int a, int b, int& x, int& y){


if(b == 0){
x = 1;
y = 0;
return a;
}
int g = extended_euclid(b, a%b, x, y);
int temp = y;
y = x - (a/b)*y;
x = temp;
return g;
}

int modular_inverse(int a, int mod){


int x, y;
int g = extended_euclid(a, mod, x, y);
if(g != 1)
return 0;
return (x + mod)%mod;
}

string affine_cipher(string p, int a, int b, int mod){


string ret(p.size(), ' ');
for(int i=0; i<p.size(); ++i){
if(p[i] == ' ')
ret[i] = p[i];
else
ret[i] = 'a' + (((p[i]-'a')*a + b)%mod + mod)%mod;
}
return ret;
}

string affine_decipher(string c, int a, int b, int mod){


string ret(c.size(), ' ');
int a_inv = modular_inverse(a,mod);
for(int i=0; i<c.size(); ++i){
if(c[i] == ' ')
ret[i] = c[i];
else
ret[i] = 'a' + ((((c[i]-'a') - b)*a_inv)%mod + mod)%mod;
}
return ret;
}

int main() {
string p, c;
int a, b, mod;
getline(cin,p);
cin>>a>>b>>mod;
cout<<(c = affine_cipher(p,a,b,mod))<<endl;
cout<<affine_decipher(c,a,b,mod)<<endl;
return 0;
}

multiplicative cipher

#include <bits/stdc++.h>
using namespace std;

int extended_euclid(int a, int b, int& x, int& y){


if(b == 0){
x = 1;
y = 0;
return a;
}
int g = extended_euclid(b, a%b, x, y);
int temp = y;
y = x - (a/b)*y;
x = temp;
return g;
}

int modular_inverse(int a, int mod){


int x, y;
int g = extended_euclid(a, mod, x, y);
if(g != 1)
return 0;
return (x + mod)%mod;
}

string multiplicative_cipher(string p, int mul){


string ret(p.size(), ' ');
for(int i=0; i<p.size(); ++i){
if(p[i] == ' ')
ret[i] = p[i];
else
ret[i] = 'a' + (((p[i]-'a')*mul)%26 + 26)%26;
}
return ret;
}

string multiplicative_decipher(string c, int mul){


string ret(c.size(), ' ');
int a_inv = modular_inverse(mul,26);
for(int i=0; i<c.size(); ++i){
if(c[i] == ' ')
ret[i] = c[i];
else
ret[i] = 'a' + (((c[i]-'a')*a_inv)%26 + 26)%26;
}
return ret;
}

int main() {
string p, c;
int mul;
getline(cin,p);
cin>>mul;
cout<<(c = multiplicative_cipher(p,mul))<<endl;
cout<<multiplicative_decipher(c,mul)<<endl;
return 0;
}
14. Implement Modular Multiplicative Inverse using Extended Eucledian method.

#include<bits/stdc++.h>
using namespace std;

int gcdextended(int a,int b,int *x,int *y)


{
if(a==0)
{
*x=0;
*y=1;
return b;
}
int x1,y1;
int g=gcdextended(b%a,a,&x1,&y1);
*x=y1-(b/a)*x1;
*y=x1;
return g;
}

int mod_inv(int n,int mod)


{
int x,y;
int g=gcdextended(n,mod,&x,&y);
if(g!=1)
cout<<"Inverse doesn't exist"<<endl;
else
{
int res=(x%mod+mod)%mod;
return res;
}
}

int main()
{
int n;
int mod;
cin>>n>>mod;
cout<<mod_inv(n,mod)<<endl;
}

15. Find the private key for RSA:

#include <bits/stdc++.h>
using namespace std;

int fast_exponentiation(int a, int b, int MOD){


int ret = 1;
a = a % MOD;
while(b != 0){
if(b & 1)
ret = (ret * 1ll * a)%MOD;
a = (a * 1ll * a)%MOD;
b >>= 1;
}
return ret;
}

int extended_euclidean(int a, int b, int& x, int& y){


if(a == 0){
x = 0;
y = 1;
return b;
}
int xx, yy;
int g = extended_euclidean(b%a, a, xx, yy);
y = xx;
x = yy - (b*1ll/a) * xx;
return g;
}

int modular_inverse(int a, int MOD){


int x, y;
if(extended_euclidean(a,MOD,x,y) != 1)
return 0;
return (x + MOD)%MOD;
}

int phi(int n){


int ret = n;
if(n%2 == 0){
ret -= ret / 2ll;
while(n%2 == 0)
n /= 2;
}
int factor = 3;
int max_factor = sqrt(n);
while(n!=1 and factor<=max_factor){
if(n%factor == 0){
ret -= ret / factor;
while(n%factor == 0)
n /= factor;
max_factor = sqrt(n);
}
factor += 2;
}
if(n != 1)
ret -= ret / n;
return ret;
}

int findPrivateKey(int e, int p, int q){


int n = p * q;
int phi_n = (p-1) * (q-1);
int d = modular_inverse(e,phi_n);
return d;
}

vector<int> RSAEncrypt(vector<int> plain_text, int e, int p, int q){


int n = p * q;
vector<int> cipher_text(plain_text.size());
for(int i=0; i<plain_text.size(); ++i)
cipher_text[i] = fast_exponentiation(plain_text[i],e,n);
return cipher_text;
}

vector<int> RSADecrypt(vector<int> cipher_text, int d, int p, int q){


int n = p * q;
vector<int> plain_text(cipher_text.size());
for(int i=0; i<cipher_text.size(); ++i)
plain_text[i] = fast_exponentiation(cipher_text[i],d,n);
return plain_text;
}

int main() {
int p, q, e, d;
//cout<<"Enter values of p, q, e: ";
cin>>p>>q>>e;
d = findPrivateKey(e,p,q);
cout<<"Private Key = "<<d<<endl;
string str;
cin>>str;
vector<int> plain_text;
for(int i=0; i<str.size(); ++i)
plain_text.push_back((int)str[i]);
vector<int> cipher_text = RSAEncrypt(plain_text,e,p,q);
for(int i=0; i<cipher_text.size(); ++i)
cout<<cipher_text[i]<<" ";
cout<<endl;
plain_text = RSADecrypt(cipher_text,d,p,q);
for(int i=0; i<plain_text.size(); ++i)
cout<<plain_text[i]<<" ";
cout<<endl;
return 0;
}

elliptic curve

#include <bits/stdc++.h>
using namespace std;

int power(int a, int b, int MOD){


int ret = 1;
a %= MOD;
while(b != 0){
if(b & 1)
ret = (ret * 1ll * a)%MOD;
a = (a * 1ll * a)%MOD;
b >>= 1;
}
return ret;
}

int extended_euclidean(int a, int b, int& x, int& y){


if(a == 0){
x = 0;
y = 1;
return b;
}
int x1, y1;
int g = extended_euclidean(b%a,a,x1,y1);
x = y1 - (b/a) * x1;
y = x1;
return g;
}

int modular_inverse(int a, int n){


int x, y;
if(extended_euclidean(a,n,x,y) != 1)
return 0;
return (x + n)%n;
}
bool isPrimitive(int x, int p){
set<int> hash;
for(int e=1; e<p; ++e)
hash.insert(power(x,e,p));
return hash.size() == p-1;
}

void generateKey(int p, int& e1, int& e2, int& d){


d = 2 + (rand() % (p-3));
vector<int> primitive;
for(int i=1; i<p; ++i){
if(isPrimitive(i,p))
primitive.push_back(i);
}
int idx = rand() % primitive.size();
e1 = primitive[idx];
e2 = power(e1,d,p);
}

vector< pair<int,int> > elgamalEncrypt(string plain_text, int k, int e1, int e2, int p){
vector< pair<int,int> > cipher_text(plain_text.size());
for(int i=0; i<plain_text.size(); ++i){
int c1 = power(e1,k,p);
int c2 = power(e2,k,p);
int P = (int)plain_text[i];
cout<<P<<" ";
c2 = (c2 * 1ll * P)%p;
cipher_text[i] = {c1,c2};
}
cout<<endl;
return cipher_text;
}

vector<int> elgamalDecrypt(vector< pair<int,int> >& cipher_text, int d, int p){


vector<int> plain_text(cipher_text.size());
for(int i=0; i<cipher_text.size(); ++i){
int c1 = cipher_text[i].first;
int c2 = cipher_text[i].second;
c1 = power(c1,d,p);
c1 = modular_inverse(c1,p);
plain_text[i] = (c1 * 1ll * c2)%p;
}
return plain_text;
}

int main() {
int p, e1, e2, d, k;
string plain_text;
getline(cin,plain_text);
cin>>p;
generateKey(p,e1,e2,d);
k = 1 + rand() % (p-1);
cout<<"e1 = "<<e1<<" e2 = "<<e2<<" d = "<<d<<" k = "<<k<<endl;
vector< pair<int,int> > cipher_text = elgamalEncrypt(plain_text,k,e1,e2,p);
cout<<"Encrypted text: ";
for(int i=0; i<cipher_text.size(); ++i)
cout<<cipher_text[i].first<<" "<<cipher_text[i].second;
cout<<endl;
vector<int> ptext = elgamalDecrypt(cipher_text,d,p);
cout<<"Decrypted text: ";
for(int i=0; i<ptext.size(); ++i)
cout<<ptext[i]<<" ";
cout<<endl;
return 0;
}

Elgamal

#include <bits/stdc++.h>
using namespace std;

int power(int a, int b, int MOD){


int ret = 1;
a %= MOD;
while(b != 0){
if(b & 1)
ret = (ret * 1ll * a)%MOD;
a = (a * 1ll * a)%MOD;
b >>= 1;
}
return ret;
}

int extended_euclidean(int a, int b, int& x, int& y){


if(a == 0){
x = 0;
y = 1;
return b;
}
int x1, y1;
int g = extended_euclidean(b%a,a,x1,y1);
x = y1 - (b/a) * x1;
y = x1;
return g;
}

int modular_inverse(int a, int n){


int x, y;
if(extended_euclidean(a,n,x,y) != 1)
return 0;
return (x + n)%n;
}

bool isPrimitive(int x, int p){


set<int> hash;
for(int e=1; e<p; ++e)
hash.insert(power(x,e,p));
return hash.size() == p-1;
}

void generateKey(int p, int& e1, int& e2, int& d){


d = 2 + (rand() % (p-3));
vector<int> primitive;
for(int i=1; i<p; ++i){
if(isPrimitive(i,p))
primitive.push_back(i);
}
int idx = rand() % primitive.size();
e1 = primitive[idx];
e2 = power(e1,d,p);
}

vector< pair<int,int> > elgamalEncrypt(string plain_text, int k, int e1, int e2, int p){
vector< pair<int,int> > cipher_text(plain_text.size());
for(int i=0; i<plain_text.size(); ++i){
int c1 = power(e1,k,p);
int c2 = power(e2,k,p);
int P = (int)plain_text[i];
cout<<P<<" ";
c2 = (c2 * 1ll * P)%p;
cipher_text[i] = {c1,c2};
}
cout<<endl;
return cipher_text;
}

vector<int> elgamalDecrypt(vector< pair<int,int> >& cipher_text, int d, int p){


vector<int> plain_text(cipher_text.size());
for(int i=0; i<cipher_text.size(); ++i){
int c1 = cipher_text[i].first;
int c2 = cipher_text[i].second;
c1 = power(c1,d,p);
c1 = modular_inverse(c1,p);
plain_text[i] = (c1 * 1ll * c2)%p;
}
return plain_text;
}

int main() {
int p, e1, e2, d, k;
string plain_text;
getline(cin,plain_text);
cin>>p;
generateKey(p,e1,e2,d);
k = 1 + rand() % (p-1);
cout<<"e1 = "<<e1<<" e2 = "<<e2<<" d = "<<d<<" k = "<<k<<endl;
vector< pair<int,int> > cipher_text = elgamalEncrypt(plain_text,k,e1,e2,p);
cout<<"Encrypted text: ";
for(int i=0; i<cipher_text.size(); ++i)
cout<<cipher_text[i].second<<" ";
cout<<endl;
vector<int> ptext = elgamalDecrypt(cipher_text,d,p);
cout<<"Decrypted text: ";
for(int i=0; i<ptext.size(); ++i)
cout<<ptext[i]<<" ";
cout<<endl;
return 0;
}

. Implement Elgamal Digital Signature

#include<bits/stdc++.h>
using namespace std;
int modInverse(int a, int m){
a = a%m;
for (int x=1; x<m; x++)
if ((a*x) % m == 1)
return x;
}
int exp(int b,int e,int m){
int r=1;
while(e>0){
if(e&1)
r=(r*b)%m;
e/=2;
b=(b*b)%m;
}
return r;
}
int main(){
int m,p,e1,d,r;
cout<<"** Elgamal Digital Signature **\nEnter m, p, e1, d ,r: ";
cin>>m>>p>>e1>>d>>r;
int e2=exp(e1,d,p);
int s1=exp(e1,r,p);
int rr=modInverse(r,p-1);
int s2=((m-d*s1)*rr)%(p-1);
while(s2<0)
s2+=p-1;
s2=s2%(p-1);
int v2=(exp(e2,s1,p)*exp(s1,s2,p))%p;
int v1=exp(e1,m,p);
cout<<"\nv1 = "<<v1<<endl<<"v2 = "<<v2<<endl;
if(v1==v2)
cout<<"Accept"<<endl;
else
cout<<"Reject"<<endl;
return 0;
}
OUTPUT:

. RSA Digital Signature

#include <bits/stdc++.h>
using namespace std;
int ext_eucl(int p, int m, int *x, int *y) {
if(p == 0) {
*x = 0; *y = 1;
return m;
}
int x1, y1;
int gcd = ext_eucl(m % p, p, &x1, &y1);
*x = y1 ­ (m / p) * x1;
*y = x1;
return gcd;
}

int gcd(int a, int b) {


if(a == 0) return b;
return gcd(b % a, a);
}

long long int mod_exp(long long int a, unsigned int p, int n) {


long long int res = 1;

while(p > 0) {
if(p & 1) res = (res * a) % n;
p = p >> 1;
a = (a * a) % n;
}
return res;
}

int coprime(int val) {


for(int i = val / 2; i < val; i += 1)
if(gcd(i, val) == 1) return i;
}

int main() {
int p=55243, q=7669, n;
long long int m=10;
n = p * q;
int totient = (p ­ 1) * (q ­ 1); int e = coprime(totient);
cout << "E " << e << endl;
int d = 0, y = 0;
ext_eucl(e, totient, &d, &y);
long long int encr = mod_exp(m, e, n);
long long int decr = mod_exp(encr, d, n);
cout << "Cipher: " << decr << endl;
cout << "Decrypt: " << encr << endl;
}

Output:
E 211797829
Cipher: 140699680
Decrypt: 10

. ELGAMAL SIMULATED BY ELLIPTIC CURVE CRYPTOGRAPHY


#include<bits/stdc++.h>
using namespace std;
struct coord
{ int x; int y; };
int inverse(int a, int p)
{
for(int i = 1; i < p; i += 1)
if((a * i) % p == 1)
return i;
}
coord generate(int a, int b, int p)
{
vector<int> y_2;
vector<int> x;
for(int i = 0; i < p; i += 1)
{
y_2.push_back((i * i * i + a * i + b) % p);
x.push_back(i);
}
for(int i = 0; i < p; i += 1)
{
for(int j = 0; j < x.size(); j += 1)
{
if(y_2[j] == ((i * i) % p))
{
coord res;
res.x = x[j];
res.y = i;
return res;
} } } }
int find_lambda(struct coord a, struct coord b, int p)
{
int lambda;
if((a.x == b.x) && (a.y == b.y))
{
int nr = (p + 3 * a.x * a.x + 1);int dr = (p + 2 * a.y);
lambda = (p + nr * inverse(dr, p)) % p;
}
else
{
int nr = (b.y - a.y); int dr = (b.x - a.x);
lambda = (p + nr * inverse(dr, p)) % p;
}
return lambda;
}
struct coord addn(struct coord a, struct coord b, int p)
{
struct coord res; int lambda = find_lambda(a, b, p);
res.x = (p + lambda * lambda - a.x - b.x) % p;
res.y = (p + lambda * (a.x - res.x) - a.y) % p;
return res;
}

struct coord mult(int d, struct coord e1, int p){


coord e2; int v = d;
struct coord temp;
temp.x = e1.x; temp.y = e1.y;
for(int i = 0; i < v; i += 1){
if(temp.x < 0) temp.x += p;
if(temp.y < 0) temp.y += p;
if(temp.x == e1.x && (temp.y != e1.y)){
temp = e1;
i += 2;
}
else temp = addn(temp, e1, p);
}
e2.x = ((temp.x >= 0) ? (temp.x) : (p + temp.x));
e2.y = ((temp.y >= 0) ? (temp.y) : (p + temp.y));
return e2;
}

int main(){
int p, a, b, d; cout<<"** ELLPTIC CURVE SIMULATING ELGAMAL **\nEnter p, a, b, d:
";
cin >> p >> a >> b >> d;
struct coord plain;
struct coord e1 = generate(a, b, p); struct coord e2 = mult(d, e1, p);
cout << "E1 " << e1.x << " " << e1.y << endl;
cout << "E2 " << e2.x << " " << e2.y << endl;
int r = 27;
struct coord c1 = mult(r, e1, p);
cout << "C1 " << c1.x << " " << c1.y << endl;
cout<<"\n Enter the number of test case: "; int t; cin>>t;
for(int i=0;i<t;i++){
cout<<"\nENter Coordinates: ";
cin >> plain.x >> plain.y;
struct coord c2 = addn(plain, mult(r, e2, p), p);
cout << "C2 " << c2.x << " " << c2.y << endl;
struct coord decr = addn(c2, mult(-1, mult(d, c1, p), p), p);
cout << "Decrypted " << ((decr.x >= 0) ? (decr.x) : (p + decr.x)) << " " << ((decr.y >= 0)
? (decr.y) : (p + decr.y)) << endl;
}
return 0;
}
OUTPUT:

. Generate keys and Implement 4 basic operations of MD5

#include<bits/stdc++.h> using namespace std;


map<char,string> m;
map<string,char> m1;

string no(string x)
{
for(int i=0;i<x.length();i++)
{ if(x[i]=='1') x[i]='0'; else
x[i]='1';
}
return x;
}

string xo(string a,string b)


{ string r="";
for(int i=0;i<a.length();i++)
{if(a[i]==b[i]) r='0'+r; else r='1'+r;
} return r;
}

string oR(string a,string b)


{ string r=""; for(int i=0;i<a.length();i++) {if((a[i]=='1')||(b[i]=='1')) r='1'+r; else r='0'+r;
} return r;
}

string an(string a,string b)


{ string r=""; for(int i=0;i<a.length();i++) {if(a[i]==b[i]) r=a[i]+r; else r='0'+r;
}
return r;
}

string hex(string a)
{
string hex="",temp;
for(int i=0;i<a.length();)
{
temp=""; for(int k=0;k<4;k++,i++)
{
temp+=a[i];
}
hex+=m1[temp];
}
return hex;
}

int main() {

m['0']="0000";m['1']="0001";m['2']="0010";m['3']="0011";m['4']="0100"
;m['5']="0101";m['6']="0110";m['7']="0111";m['8']="1000";m['9']="1001";
m['A']="1010";m['B']="1011";m['C']="1100";m['D']="1101";
m['E']="1110";m['F']="1111";
m1["0000"]='0';m1["0001"]='1';m1["0010"]='2';
m1["0011"]='3';m1["0100"]='4';m1["0101"]='5';m1["
0110"]='6';m1["0111"]='7';m1["1000"]='8';m1["1001"]='9';
m1["1010"]='A';m1["1011"]='B';m1["1100"]='C';
m1["1101"]='D';m1["1110"]='E';m1["1111"]='F';

long long k[65]; cout<<"Keys:\n";


for(int i=1;i<=64;i++)
{
k[i]=abs(sin(i+1))*pow(2,32); cout<<k[i]<<" ";
}

string a="",b="",c="",d="";
string s1="67452301",s2="EFCDAB89",s3="98BADCFE",s4="10325476";
for(int i=0;i<s1.length();i++)
{
a=m[s1[i]]+a; b=m[s2[i]]+b; c=m[s3[i]]+c;
d=m[s4[i]]+d;
}

//Operation A
string ans=oR(an(b,c),an(no(b),d));
cout<<endl<<"Op A: "<<hex(ans)<<endl;
//B
ans=oR(an(d,b),an(no(d),c));
cout<<"Op B: "<<hex(ans)<<endl;
//C
ans=xo(b,xo(c,d));
cout<<"Op C: "<<hex(ans)<<endl;
//D
ans=xo(c,oR(b,no(d)));
cout<<"Op D: "<<hex(ans)<<endl;
}

Output:
Keys:
3905402710 606105819 3250441966 4118548399 1200080426 2821735955 4249261313
1770035416 2336552879 4294925233 2304563134 1804603682 4254626195 2792965006
1236535329 4129170786 3225465664 643717713 3921069994 3593408605 38016083
3634488961 3889429448 568446438 3275163606 4107603335 1163531501 2850285829
4243563512 1735328473 2368359562 4294588738 2272392833 1839030562 4259657740
2763975236 1272893353 4139469664 3200236656 681279174 3936430074 3572445317
76029189 3654602809 3873151461 530742520 3299628645 4096336452 1126891415
2878612391 4237533241 1700485571 2399980690 4293915773 2240044497 1873313359
4264355552 2734768916 1309151649 4149444226 3174756917 718787259 3951481745
3551202137
Op A: EFCDAB89
Op B: 88888888
Op C: F7B3D591
Op D: 096F6F09

. MD5 hash function

#include<bits/stdc++.h> using namespace std;


map<string,char> m;

int main()
{
m['0']="0000";m['1']="0001";m['2']="0010";m['3']="0011";m['4']="0100"
;m['5']="0101";m['6']="0110";m['7']="0111";m['8']="1000";m['9']="1001";
m['A']="1010";m['B']="1011";m['C']="1100";m['D']="1101";
m['E']="1110";m['F']="1111";
m1["0000"]='0';m1["0001"]='1';m1["0010"]='2';
m1["0011"]='3';m1["0100"]='4';m1["0101"]='5';m1["
0110"]='6';m1["0111"]='7';m1["1000"]='8';m1["1001"]='9';
m1["1010"]='A';m1["1011"]='B';m1["1100"]='C';
m1["1101"]='D';m1["1110"]='E';m1["1111"]='F';
string input="hello";
string pad="",temp="";
int i;
for(i=0;i<input.size();i++) {
int x=(int)(input[i]); temp=""; for(int j=0;j<8;j++)
{
temp=(char)(x%2+'0')+temp;
x=x/2;
}
pad=pad+temp;
}

i=pad.length();

if(i<=447) {
pad+='1';
i++;
}

while(i<448) {
pad+='0';
i++;
}

int tmp=input.length()*8;
temp="";

for(i=0;i<64;i++) {
temp=(char)(tmp%2+'0')+temp;
tmp=tmp/2;
}
pad=pad+temp; string hex=""; temp="";

for(i=0;i<pad.length();) {
temp=""; for(int k=0;k<4;k++,i++)
{
temp+=pad[i];
}
hex+=m[temp];
}
cout<<hex<<endl;
}
Output:
68656C6C6F8000000000000000000000000000000000000000000000000000000000000000
0000 00000000000000000000000000000000000000000000000028
. Append bits to the given input according to SHA-1 and print results in Hexadecimal
Representation.
Input: hello.

#include<bits/stdc++.h>
using namespace std;

int main(){
string msg = "hello";
int data[512] = {0};
int i;
for(int j=0; j<msg.length(); j++){
int bin = msg[j];
i = (j+1)*8;
while(i>j*8){
data[i-1] = (bin)%2;
bin = bin>>1;
//cout<<".";
i--;
}
}

data[8*msg.length()] = 1;
int len = 511;
int num = 8*msg.length();
while(num>0){
data[len] = num%2;
num = num>>1;
len--;
}

/*for(int j=0; j<512; j++){


cout<<data[j];
}
cout<<endl;*/

for(int j=0; j<512; j+=4){


int n = 0;
n = pow(2, 3)*data[j] + pow(2, 2)*data[j+1] + pow(2, 1)*data[j+2] + pow(2,
0)*data[j+3];
if(n==15) cout<<'F';
else if(n==14) cout<<'E';
else if(n==13) cout<<'D';
else if(n==12) cout<<'C';
else if(n==11) cout<<'B';
else if(n==10) cout<<'A';
else cout<<n;
}
cout<<endl;

return 0;
}

Output:
68656C6C6F8000000000000000000000000000000000000000000000000000000000000000
0000 00000000000000000000000000000000000000000000000028
. Implement 4 major operations/processes with give below input and print result in
hexadecimal representation.

#include<bits/stdc++.h>
using namespace std;

int main(){

/*long long int q = pow(2, 32);


for(int i=1; i<=64; i++){
long long int k_i = abs(sin(i))*(float)q;
cout<<k_i<<endl;
}
cout<<endl;*/

int a[8] = {0, 1, 2, 3, 4, 5, 6, 7};


int b[8] = {8, 9, 10, 11, 12, 13, 14, 15};
int c[8] = {15, 14, 13, 12, 11, 10, 9, 8};
int d[8] = {7, 6, 5, 4, 3, 2, 1, 0};
int e[8] = {12, 3, 13, 2, 14, 1, 15, 0};

int A[8], B[8], C[8], D[8];

for(int i=0; i<8; i++){


int n = A[i] = (b[i]&c[i]) | (~b[i]&d[i]&15);
if(n==15) cout<<'F';
else if(n==14) cout<<'E';
else if(n==13) cout<<'D';
else if(n==12) cout<<'C';
else if(n==11) cout<<'B';
else if(n==10) cout<<'A';
else cout<<n;
}
cout<<endl;
for(int i=0; i<8; i++){
int n = B[i] = (b[i]^c[i]^d[i]);
if(n==15) cout<<'F';
else if(n==14) cout<<'E';
else if(n==13) cout<<'D';
else if(n==12) cout<<'C';
else if(n==11) cout<<'B';
else if(n==10) cout<<'A';
else cout<<n;
}
cout<<endl;

for(int i=0; i<8; i++){


int n = C[i] = ((b[i]&c[i]) | (b[i]&d[i]) | (c[i]&d[i]));
if(n==15) cout<<'F';
else if(n==14) cout<<'E';
else if(n==13) cout<<'D';
else if(n==12) cout<<'C';
else if(n==11) cout<<'B';
else if(n==10) cout<<'A';
else cout<<n;
}
cout<<endl;

for(int i=0; i<8; i++){


int n = D[i] = (b[i]^c[i]^d[i]);
if(n==15) cout<<'F';
else if(n==14) cout<<'E';
else if(n==13) cout<<'D';
else if(n==12) cout<<'C';
else if(n==11) cout<<'B';
else if(n==10) cout<<'A';
else cout<<n;
}
cout<<endl;

return 0;
}
OUTPUT:

FEDCBA98
01234567
FEDCBA98
01234567

. Implement 2 round of SHA-1 with given 2 inputs respectively.

#include<bits/stdc++.h>
using namespace std;

void print_hex(int n){


if(n==15) cout<<'F';
else if(n==14) cout<<'E';
else if(n==13) cout<<'D';
else if(n==12) cout<<'C';
else if(n==11) cout<<'B';
else if(n==10) cout<<'A';
else cout<<n;
}

long long int convert_num(int* a){

long long int n = 0;


for(int i=0; i<8; i++){
n += pow(a[i], 7-i);
}

return n;
}

string convert_hex(long long int n){

string hexdec_num="";
char hex[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

while(dec_num>0)
{
r = dec_num % 16;
hexdec_num = hex[r] + hexdec_num;
dec_num = dec_num/16;
}

return hexdec_num;
}

int convert_hex_n(char c){


int n;
if(c =='F') n = 15;
else if(c =='E') n = 14;
else if(c =='D') n = 13;
else if(c =='C') n = 12;
else if(c =='B') n = 11;
else if(c =='A') n = 10;
else return c-48;
}

int main(){

string msg = "hello";


int data[512] = {0};
int i;
for(int j=0; j<msg.length(); j++){
int bin = msg[j];
i = (j+1)*8;
while(i>j*8){
data[i-1] = (bin)%2;
bin = bin>>1;
//cout<<".";
i--;
}
}

data[8*msg.length()] = 1;
int len = 511;
int num = 8*msg.length();
while(num>0){
data[len] = num%2;
num = num>>1;
len--;
}

int w[128];
for(int j=0; j<512; j+=4){
int n = 0;
n = pow(2, 3)*data[j] + pow(2, 2)*data[j+1] + pow(2, 1)*data[j+2] + pow(2,
0)*data[j+3];
w[j/4] = n;
}

long long int q = pow(2, 32);

int a[8] = {0, 1, 2, 3, 4, 5, 6, 7};


int b[8] = {8, 9, 10, 11, 12, 13, 14, 15};
int c[8] = {15, 14, 13, 12, 11, 10, 9, 8};
int d[8] = {7, 6, 5, 4, 3, 2, 1, 0};
int e[8] = {12, 3, 13, 2, 14, 1, 15, 0};

int kt[8] = {15, 14, 13, 12, 11, 10, 9, 8};

int A[8], B[8], C[8], D[8], E[8], F[8];

for(int i=0; i<8; i++){


int n = F[i] = (b[i]&c[i]) | (~b[i]&d[i]&15);
A[i] = a[i]; B[i] = b[i]; C[i] = c[i]; D[i] = d[i]; E[i] = e[i];

}
cout<<endl;

int n;
int temp[8], data_temp[8];;
long long int m = (convert_num(F) + convert_num(E))%q;
string hex_m = convert_hex(m);

for(int i=0; i<8; i++){


temp[i] = convert_hex_n(hex_m[i]);
data_temp[i] = w[i];
}

m = (convert_num(temp) + convert_num(data_temp))%q;
string hex_m = convert_hex(m);
for(int i=0; i<8; i++){
temp[i] = convert_hex_n(hex_m[i]);
data_temp[i] = w[i];
}

m = (convert_num(temp) + convert_num(kt))%q;
string hex_m = convert_hex(m);
for(int i=0; i<8; i++){
temp[i] = convert_hex_n(hex_m[i]);
data_temp[i] = w[i];
}
for(int i=0; i<8; i++){
int n = C[i] = (b[i]^c[i]^d[i]);

}
cout<<endl;

for(int i=0; i<8; i++){


int n = D[i] = (c[i]^(b[i]|~d[i]&15));

}
cout<<endl;

return 0;
}

OUTPUT:
Round1: 9cf5caf6c36f5cccde8c73fad8894c958f4983da
Round2: 1eec5eecf3ddf2d401205eb87055d6595a9bceaf

. PRIMITIVE ROOTS OF A MULTIPLICATIVE GROUP

#include<bits/stdc++.h>
#include<time.h>
using namespace std;
int gcd(int a,int b){
if(!b)
return a;
return gcd(b,a%b);
}
int fastexp(int x,int y, int mod){
int res=1;
while(y){
if(y&1)
res=(res*x)%mod;
x=(x*x)%mod;
y=y>>1;
}
return res;
}
vector<int> find_generator(int prime){
int i;
vector<int> elements, primitives;
for(i=0;i<prime;i++){
if(gcd(prime,i)==1)
elements.push_back(i);
}
int order=elements.size();
for(i=0;i<order;i++){
int j;
vector<bool> p(prime,0);
for(j=0;j<prime;j++){
int t=fastexp(elements[i],j,prime);
p[t]=1;
}
for(j=1;j<prime;j++)
if(p[j]==0)
break;
if(j==prime)
primitives.push_back(elements[i]);
}
return primitives;
}
int main(){
int prime;
cout<<"Enter the value of p"<<endl;
cin>>prime;
vector<int> generators=find_generator(prime);
cout<<"The generators of prime "<<prime<<" are: "<<endl;
for(auto generator:generators)
cout<<generator<<" ";
return 0;
}
OUTPUT:

. Implement Elgamal Digital Signature

#include<bits/stdc++.h>
using namespace std;
int modInverse(int a, int m){
a = a%m;
for (int x=1; x<m; x++)
if ((a*x) % m == 1)
return x;
}
int exp(int b,int e,int m){
int r=1;
while(e>0){
if(e&1)
r=(r*b)%m;
e/=2;
b=(b*b)%m;
}
return r;
}
int main(){
int m,p,e1,d,r;
cout<<"** Elgamal Digital Signature **\nEnter m, p, e1, d ,r: ";
cin>>m>>p>>e1>>d>>r;
int e2=exp(e1,d,p);
int s1=exp(e1,r,p);
int rr=modInverse(r,p-1);
int s2=((m-d*s1)*rr)%(p-1);
while(s2<0)
s2+=p-1;
s2=s2%(p-1);
int v2=(exp(e2,s1,p)*exp(s1,s2,p))%p;
int v1=exp(e1,m,p);
cout<<"\nv1 = "<<v1<<endl<<"v2 = "<<v2<<endl;
if(v1==v2)
cout<<"Accept"<<endl;
else
cout<<"Reject"<<endl;
return 0;
}
OUTPUT:

. ELGAMAL SIMULATED BY ELLIPTIC CURVE CRYPTOGRAPHY

#include<bits/stdc++.h>
using namespace std;
struct coord
{ int x; int y; };
int inverse(int a, int p)
{
for(int i = 1; i < p; i += 1)
if((a * i) % p == 1)
return i;
}
coord generate(int a, int b, int p)
{
vector<int> y_2;
vector<int> x;
for(int i = 0; i < p; i += 1)
{
y_2.push_back((i * i * i + a * i + b) % p);
x.push_back(i);
}
for(int i = 0; i < p; i += 1)
{
for(int j = 0; j < x.size(); j += 1)
{
if(y_2[j] == ((i * i) % p))
{
coord res;
res.x = x[j];
res.y = i;
return res;
} } } }
int find_lambda(struct coord a, struct coord b, int p)
{
int lambda;
if((a.x == b.x) && (a.y == b.y))
{
int nr = (p + 3 * a.x * a.x + 1);int dr = (p + 2 * a.y);
lambda = (p + nr * inverse(dr, p)) % p;
}
else
{
int nr = (b.y - a.y); int dr = (b.x - a.x);
lambda = (p + nr * inverse(dr, p)) % p;
}
return lambda;
}
struct coord addn(struct coord a, struct coord b, int p)
{
struct coord res; int lambda = find_lambda(a, b, p);
res.x = (p + lambda * lambda - a.x - b.x) % p;
res.y = (p + lambda * (a.x - res.x) - a.y) % p;
return res;
}

struct coord mult(int d, struct coord e1, int p)


{
coord e2; int v = d;
struct coord temp;
temp.x = e1.x; temp.y = e1.y;
for(int i = 0; i < v; i += 1)
{
if(temp.x < 0)
temp.x += p;
if(temp.y < 0)
temp.y += p;
if(temp.x == e1.x && (temp.y != e1.y))
{
temp = e1;
i += 2;
}
else temp = addn(temp, e1, p);
}
e2.x = ((temp.x >= 0) ? (temp.x) : (p + temp.x));
e2.y = ((temp.y >= 0) ? (temp.y) : (p + temp.y));
return e2;
}

int main()
{
int p, a, b, d; cout<<"** ELLPTIC CURVE SIMULATING ELGAMAL **\nEnter p, a, b, d:
";
cin >> p >> a >> b >> d;
struct coord plain;
struct coord e1 = generate(a, b, p); struct coord e2 = mult(d, e1, p);
cout << "E1 " << e1.x << " " << e1.y << endl;
cout << "E2 " << e2.x << " " << e2.y << endl;
int r = 27;
struct coord c1 = mult(r, e1, p);
cout << "C1 " << c1.x << " " << c1.y << endl;
cout<<"\n Enter the number of test case: "; int t; cin>>t;
for(int i=0;i<t;i++){
cout<<"\nENter Coordinates: ";
cin >> plain.x >> plain.y;
struct coord c2 = addn(plain, mult(r, e2, p), p);
cout << "C2 " << c2.x << " " << c2.y << endl;
struct coord decr = addn(c2, mult(-1, mult(d, c1, p), p), p);
cout << "Decrypted " << ((decr.x >= 0) ? (decr.x) : (p + decr.x)) << " " << ((decr.y >= 0)
? (decr.y) : (p + decr.y)) << endl;
}
return 0;
}

S-DES
#include <bits/stdc++.h>
using namespace std;

vector<int> permute(vector<int>& key, vector<int>& permutation_key){


vector<int> ret(permutation_key.size());
for(int i=0; i<permutation_key.size(); ++i)
ret[i] = key[permutation_key[i] - 1];
return ret;
}

vector<int> circular_shift(vector<int>& permutation_key, int shift){


int n = permutation_key.size();
int lim = n / 2;
vector<int> ret(n);
for(int i=0; i<lim; ++i)
ret[(i-shift+lim)%lim] = permutation_key[i];
for(int i=0; i<lim; ++i)
ret[lim + (i-shift+lim)%lim] = permutation_key[lim + i];
return ret;
}

vector<int> expand(vector<int>& plain_text){


vector<int> expansion_key = {4, 1, 2, 3, 2, 3, 4, 1};
vector<int> ret(expansion_key.size());
int lim = plain_text.size() / 2;
for(int i=0; i<expansion_key.size(); ++i)
ret[i] = plain_text[lim + expansion_key[i] - 1];
return ret;
}

vector<int> apply_xor(vector<int>& lhs, vector<int>& rhs, int lim){


vector<int> ret(lhs);
for(int i=0; i<lim; ++i)
ret[i] = lhs[i] ^ rhs[i];
return ret;
}

void apply_swap(vector<int>& text){


int n = text.size();
int lim = n / 2;
for(int i=0; i<lim; ++i)
swap(text[i],text[lim+i]);
}

int value(int bit1, int bit2){


int ret = 0;
if(bit2)
ret |= 1;
if(bit1)
ret |= 2;
return ret;
}

vector<int> f_output(vector<int>& key, vector<vector<int> >& s0, vector<vector<int> >&


s1){
vector<int> ret;
int r = value(key[0],key[3]);
int c = value(key[1],key[2]);
int val = s0[r][c];
ret.push_back((int)(val>>1 & 1));
ret.push_back((int)(val & 1));
r = value(key[4],key[7]);
c = value(key[5],key[6]);
val = s1[r][c];
ret.push_back((int)(val>>1 & 1));
ret.push_back((int)(val & 1));
return ret;
}

void fkey(vector<int>& plain_text, vector<int>& key){


vector<vector<int> > s0 = {{1, 0, 3, 2}, {3, 2, 1, 0}, {0, 2, 1, 3}, {3, 1, 3, 2}};
vector<vector<int> > s1 = {{0, 1, 2, 3}, {2, 0, 1, 3}, {3, 0, 1, 0}, {2, 1, 0, 3}};
vector<int> p4 = {2, 4, 3, 1};
int n = plain_text.size();
vector<int> temp = expand(plain_text);
vector<int> fkey = apply_xor(temp,key,n);
vector<int> f = f_output(fkey,s0,s1);
f = permute(f,p4);
plain_text = apply_xor(plain_text,f,n/2);
}

int main() {
int n = 8;
int k = 10;
vector<int> plain_text(n);
vector<int> cipher_text;
vector<int> decipher_text;
vector<int> cipher_key(k);
for(int i=0; i<n; ++i)
cin>>plain_text[i];
for(int i=0; i<k; ++i)
cin>>cipher_key[i];
// Initial Permutation
vector<int> ip = {2, 6, 3, 1, 4, 8, 5, 7};
plain_text = permute(plain_text,ip);

// Key Generation
vector<int> p10 = {3, 5, 2, 7, 4, 10, 1, 9, 8, 6};
vector<int> p8 = {6, 3, 7, 4, 8, 5, 10, 9};
vector<int> key_1, key_2;
key_1 = permute(cipher_key,p10);
key_1 = circular_shift(key_1,1);
key_2 = circular_shift(key_1,2);
key_1 = permute(key_1,p8);
key_2 = permute(key_2,p8);
cout<<"KEY1 = ";
for(int i=0; i<key_1.size(); ++i)
cout<<key_1[i]<<" ";
cout<<endl;
cout<<"KEY2 = ";
for(int i=0; i<key_1.size(); ++i)
cout<<key_2[i]<<" ";
cout<<endl;

// Apply f_k1
fkey(plain_text,key_1);

// Swap left and right parts


apply_swap(plain_text);

// Apply f_k2
fkey(plain_text,key_2);

// Final Permutation
vector<int> fip = {4, 1, 3, 5, 7, 2, 8, 6};
plain_text = permute(plain_text,fip);

// Print final output


for(int i=0; i<plain_text.size(); ++i)
cout<<plain_text[i]<<" ";
cout<<endl;

plain_text = permute(plain_text,ip);
fkey(plain_text,key_2);
apply_swap(plain_text);
fkey(plain_text,key_1);
plain_text = permute(plain_text,fip);
for(int i=0; i<plain_text.size(); ++i)
cout<<plain_text[i]<<" ";
cout<<endl;
return 0;
}

//END OF FILE
/////////////////////////////////////////////ALL THE
BEST//////////////////////////////////////////////////////////////

Das könnte Ihnen auch gefallen