ICS Lab Manual

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 29

ASSIGNMENT NO:1

Title: Implementation of S-DES

Aim/Problem Statement: Write C++/JAVA/PYTHON/R program to encrypt or decrypt


message using S-DES

Learning Objective: To Learn How to Apply Data Encryption Standard Algorithm to


encryption and decryption of given data.

Theory:
1) Symmetric key cryptography –
Symmetric Key Cryptography also known as Symmetric Encryption is when a secret key is
leveraged for both encryption and decryption functions. This method is the opposite of
Asymmetric Encryption where one key is used to encrypt and another is used to decrypt. During
this process, data is converted to a format that cannot be read or inspected by anyone who does
not have the secret key that was used to encrypt it.
The success of this approach depends on the strength of the random number generator that is used
to create the secret key. Symmetric Key Cryptography is widely used in today’s Internet and
primarily consists of two types of algorithms, Block and Stream. Some common encryption
algorithms include the Advanced Encryption Standard (AES) and the Data Encryption Standard
(DES). This form of encryption is traditionally much faster than Asymmetric however it requires
both the sender and the recipient of the data to have the secret key.

2) S-DES –
Simplified Data Encryption Standard (S-DES) is a simple version of the DES Algorithm. It is
similar to the DES algorithm but is a smaller algorithm and has fewer parameters than DES. It
was made for educational purposes so that understanding DES would become simpler. It is a
block cipher that takes a block of plain text and converts it into ciphertext. It takes a block of 8
bit.
It is a symmetric key cipher i.e., they use the same key for both encryption and decryption. In
this article, we are going to demonstrate key generation for s-des encryption and decryption
algorithm. We take a random 10-bit key and produce two 8-bit keys which will be used for
encryption and decryption.

Key Generation Concept: In the key generation algorithm, we accept the 10-bit key and convert
it into two 8 bit keys. This key is shared between both sender and receiver.

3) Algorithm –

The S-DES encryption algorithm takes an 8-bit block of plaintext (example: 10111101) and a 10-
bit key as input and produces an 8-bit block of ciphertext as output. The S-DES decryption
algorithm takes an 8-bit block of ciphertext and the same 10-bit key used to produce that
ciphertext as input and produces the original 8-bit block of plaintext.
The encryption algorithm involves five functions:

an initial permutation (IP)

a complex function labeled fk, which involves both permutation and substitution operations and
depends on a key input
a simple permutation function that switches (SW) the two halves of the data

the function fk again

a permutation function that is the inverse of the initial permutation


The function fk takes as input not only the data passing through the encryption algorithm, but
also an 8-bit key. Here a 10-bit key is used from which two 8-bit subkeys are generated. The key
is first subjected to a permutation (P10). Then a shift operation is performed. The output of the
shift operation then passes through a permutation function that produces an 8-bit output (P8) for
the first subkey (K1). The output of the shift operation also feeds into another shift and another
instance of P8 to produce the second subkey (K2).

The encryption algorithm can be expressed as a composition composition1 of functions: IP-1 ο


fK2 ο SW ο fk1 ο IP Which can also be written as

Ciphertext = IP-1 (fK2 (SW (fk1 (IP (plaintext)))))

Where

K1 = P8 (Shift (P10 (Key)))


K2 = P8 (Shift (shift (P10 (Key))))

Decryption can be shown as


Plaintext = IP-1 (fK1 (SW (fk2 (IP (ciphertext)))))
1. S-DES key generation

S-DES depends on the use of a 10-bit key shared between sender and receiver. From this key, two
8-bit subkeys are produced for use in particular stages of the encryption and decryption algorithm.
First, permute the key in the following fashion. Let the 10-bit key be designated as (k1, K2, k3,
k4, k5, k6, k7, k8, k9, k10). Then the permutation P10 is defined as:

P10 (k1, K2, k3, k4, k5, k6, k7, k8, k9, k10) = (k3, k5, K2, k7, k4, k10 10, k1, k9, k8, k6) P10 can
be concisely defined by the display:

This table is read from left to right; each position in the table gives the identity of the input bit that
produces the output bit in that position. So the first output bit is bit 3 of the input; the second output
bit is bit 5 of the input, and so on. For example, the key (1010000010) is permuted to (10000
01100). Next, perform a circular left shift (LS-1), or rotation, separately on the first five bits and
the second five bits. In our example, the result is (00001 11000). Next we apply P8, which picks
out and permutes 8 of the 10 bits according to the following rule:

The result is subkey 1 (K1). In our example, this yields (10100100). We then go back to the pair
of 5-bit strings produced by the two LS-1 functions and performs a circular left shift of 2 bit
positions on each string. In our example, the value (00001 11000) becomes (00100 00011). Finally,
P8 is applied again to produce K2. In our example, the result is (01000011).
2. S-DES encryption

Encryption involves the sequential application of five functions.

Initial and Final Permutations

The input to the algorithm is an 8-bit block of plaintext, which we first permute using the IP
function:

This retains all 8 bits of the plaintext but mixes them up.
Consider the plaintext to be 11110011.

Permuted output = 10111101

At the end of the algorithm, the inverse permutation is used:

The Function fk

The most complex component of S-DES is the function fk, which consists of a combination of
permutation and substitution functions. The functions can be expressed as follows. Let L and R be
the leftmost 4 bits and rightmost 4 bits of the 8-bit input to f K, and let F be a mapping (not
necessarily one to one) from 4-bit strings to 4-bit strings. Then we let

We now describe the mapping F. The input is a 4-bit number (n1 n2 n3 n4). The first operation is
an expansion/permutation operation:

e.g., R= 1101

E/P output = 11101011


It is clearer to depict the result in this fashion:

The 8-bit subkey K1 = (k11, k12 12, k13 13, k14 14, k15 15, k16 16, k17 17, k18) is added to this
value using exclusive-OR:

The first 4 bits (first row of the preceding matrix) are fed into the S-box S0 to produce a 2- bit
output, and the remaining 4 bits (second row) are fed into S1 to produce another 2-bit output.

These two boxes are defined as follows:

The S-boxes operate as follows. The first and fourth input bits are treated as a 2-bit number that
specify a row of the S-box, and the second and third input bits specify a column of the S-box. The
entry in that row and column, in base 2, is the 2-bit output. For example, if (p0,0 p0,3) = ) (00) and
( p0,1 p0,2) = (10), then the output is from row 0, column 2 of S0, which is 3, or (11) in ) binary.
Similarly, (p1,0 p1,3) and ( p1,1 p1,2) are used to index into a row and column of S1 to produce
an additional 2 bits. Next, the 4 bits produced by S0 and S1 undergo a further permutation as
follows:

The output of P4 is the output of the function F.

3. The Switch Function

The function f K only alters the leftmost 4 bits of the input. The switch function (SW) interchanges
the left and right 4 bits so that the second instance of f K operates on a different 4 bits. In this
second instance, the E/P, S0, S1, and P4 functions are the same. The key input is K2. Finally apply
inverse permutation to get the ciphertext.
4) Advantages –
1. DES has a 56-bit key which raises the possibility of 256 possible keys which make brute
force impossible.
2. The 8 S-boxes used in each round were not made public and even it impossible for any to
discover the design of the s-boxes which makes the attack more impossible.

5) Limitations -
1. The number of rounds in DES increases the complexity of the algorithm.
2. However, the cryptanalysis attack is easier than the brute force attack on DES.

Conclusion :
Thus we have successfully learnt how to apply data encryption standard algorithm to encryption
and decryption of given data using S-DES algorithm.

Code :

SDES.java

import java.io.IOException;

import java.io.InputStream;
import java.io.OutputStream;

public class SDES {

public static String encrypt(String msg, int key) {


int[] keys = getKeys(key);
StringBuilder builder = new StringBuilder(msg.length());
for (int i = 0; i < msg.length(); i++)
builder.append((char)encrypt(msg.charAt(i), keys));

return builder.toString();
}
public static String decrypt(String msg, int key) {
int[] keys = getKeys(key);
StringBuilder builder = new StringBuilder(msg.length());
for (int i = 0; i < msg.length(); i++)
builder.append((char)decrypt(msg.charAt(i), keys));

return builder.toString();
}

static int encrypt(int c, int[] keys) {


int result = f(IP(c), keys[0]);
result = (result << 28) >>> 24 | (result >>> 4);
result = f(result, keys[1]);
return inverseIP(result);
}

static int decrypt(int c, int[] keys) {


int[] newKeys = new int[2];
newKeys[0] = keys[1];
newKeys[1] = keys[0];
return encrypt(c, newKeys);
}
static int f(int plainText, int subKey) {
int L = plainText >>> 4;
int R = plainText << 28 >>> 28;
return (L^F(R, subKey)) << 4 | R;
}

static int P10(int key){


return permutate(key, 4,2,1,9,0,6,3,8,5,7);
}

static int LS(int key) {


return permutate(key, 4,0,1,2,3,9,5,6,7,8);
}

static int P8(int key) {


return permutate(key, 1,0,5,2,6,3,7,4);
}

static int[] getKeys(int key) {


int[] result = new int[2];
int shifted = LS(P10(key));
result[0] = P8(shifted);
shifted = LS(shifted);
result[1] = P8(shifted);
return result;
}

static int IP(int plainText) {


return permutate(plainText, 1,3,0,4,7,5,2,6);
}

static int inverseIP(int cryptoText) {


return permutate(cryptoText, 2, 0, 6, 1, 3, 5, 7, 4);
}
static int permutate(int bits, int... pos) {
int permutatedBits = 0;
for(int i = 0; i < pos.length; i++)
permutatedBits |= ((bits >>> pos[i]) & 1) << i;
return permutatedBits;
}

static int F(int plainText, int subKey) {


int permutation = permutate(plainText, 3,0,1,2,1,2,3,0);
permutation ^= subKey;

int substituted = 0;
int i = ((permutation & (1 << 7)) >>> 6) | (permutation & (1 <<
4)) >>> 4;
int j = ((permutation & (1 << 6)) >>> 5) | (permutation & (1 <<
5)) >>> 5;
substituted |= S0[i][j] << 2;
i = ((permutation & (1 << 3)) >>> 2) | (permutation & 1);
j = ((permutation & (1 << 2)) >>> 1) | (permutation & (1 << 1))
>>> 1;
substituted |= S1[i][j];

return permutate(substituted, 3,1,0,2);


}
private final static int[][] S0 = new int[][] {
{1,0,3,2},
{3,2,1,0},
{0,2,1,3},
{3,1,3,1}
};

private final static int[][] S1 = new int[][] {


{1,1,2,3},
{2,0,1,3},
{3,0,1,0},
{2,1,0,3}
};
public static void main(String[] args)
{
String input, cript, output;
int keyy;
input=new String("hello");
keyy=1234;
System.out.println("input is: "+input);
System.out.println("key is: "+keyy);

cript = encrypt(input,keyy);

System.out.println("encription is: "+cript);

output = decrypt(cript,keyy);

System.out.println("decription is: "+output);


}
}
SDESTest.java
package cryptography;

import org.junit.Test;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

import java.io.*;
import java.util.*;

public class SDESTest {


@Test public void P10() {
int key = 0b1010000010;
int result = 0b1000001100;

assertEquals("Wrong permutation", result,


cryptography.SDES.P10(key));
}

@Test public void LS(){


int key = 0b1000001100;
int result = 0b0000111000;

assertEquals("Invalid permutation", result,


cryptography.SDES.LS(key));
}
@Test public void P8(){
int key = 0b0000111000;
int result = 0b10100100;

assertEquals("Invalid permutation", result,


cryptography.SDES.P8(key));
}

@Test public void IP(){


int plainText = 0b11110011;
int result = 0b10111101;

assertEquals("Invalid permutation", result,


cryptography.SDES.IP(plainText));
}

@Test public void inverseIP(){


int plainText = 0b10111101;
int result = 0b11110011;

assertEquals("Invalid permutation", result,


cryptography.SDES.inverseIP(plainText));
}

@Test public void F(){


int plainText = 0b0101;
int subKey = 0b11100100;
int result = 0b1001;

assertEquals(result, cryptography.SDES.F(plainText, subKey));


}

@Test public void getKeys(){


int key = 0b1010000010;
int[] result = new int[] {0b10100100, 0b10010010};

assertArrayEquals(result, cryptography.SDES.getKeys(key));
}

@Test public void encrypt(){


byte msg = 0b00010111;
int[] keys = new int[] {0b10100100, 0b10010010};
int[] oldKeys = new int[] {0b10100100, 0b10010010};

assertEquals(0b00011010, cryptography.SDES.encrypt(msg, keys));


assertArrayEquals(oldKeys, keys);
}

@Test public void decrypt(){


byte cryptoText = 0b00011010;
byte result = 0b00010111;
int[] keys = new int[] {0b10100100, 0b10010010};
int[] oldKeys = new int[] {0b10100100, 0b10010010};

assertEquals(result, cryptography.SDES.decrypt(cryptoText, keys));


assertArrayEquals(oldKeys, keys);
}
@Test public void encryptAndDecryptSymmetry() {
int[] keys = new int[] {0b10100100, 0b10010010};
byte text = 0b1110011;
int[] oldKeys = new int[] {0b10100100, 0b10010010};

assertEquals(text,
cryptography.SDES.decrypt(cryptography.SDES.encrypt(text, keys), keys));
assertArrayEquals(oldKeys, keys);
}

@Test public void encryptAndDecryptStringSymmetry() {


int key = 0b1010000010;
String msg = "abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ";
assertEquals(msg,
cryptography.SDES.decrypt(cryptography.SDES.encrypt(msg, key), key));
}

@Test public void encryptStream() throws IOException {


int key = 0b0100011011;
InputStream in = new ByteArrayInputStream(new byte[] {1,2,3});
OutputStream out = mock(OutputStream.class);
List<Integer> result = new LinkedList<>();
doAnswer(invocation -> result.add(invocation.getArgument(0)))
.when(out)
.write(anyInt());

cryptography.SDES.encrypt(in, out, key);

assertEquals(Arrays.asList(147,218,88), result);
}

@Test public void decryptStream() throws IOException {


int key = 0b0100011011;
InputStream in = new ByteArrayInputStream(new byte[]
{(byte)147,(byte)218,(byte)88});
OutputStream out = mock(OutputStream.class);
List<Integer> result = new LinkedList<>();
doAnswer(invocation -> result.add(invocation.getArgument(0)))
.when(out)
.write(anyInt());

cryptography.SDES.decrypt(in, out, key);

assertEquals(Arrays.asList(1, 2, 3), result);


}
}

Output:

input is: hello

key is: 1234

encription is: ?«QQ¼

decription is: hello


ASSIGNMENT NO: 2

Title: Implementation of S-AES

Aim/Problem Statement: Write C++/JAVA/PYTHON/R program to encrypt or decrypt message


using S-AES

Learning Objective: To Learn How to Apply Advanced Encryption Standard Algorithm to


encryption and decryption of given data.

Theory:
1) Symmetric key Cryptography –
Symmetric Key Cryptography also known as Symmetric Encryption is when a secret key is
leveraged for both encryption and decryption functions. This method is the opposite of
Asymmetric Encryption where one key is used to encrypt and another is used to decrypt. During
this process, data is converted to a format that cannot be read or inspected by anyone who does not
have the secret key that was used to encrypt it.
The success of this approach depends on the strength of the random number generator that is used
to create the secret key. Symmetric Key Cryptography is widely used in today’s Internet and
primarily consists of two types of algorithms, Block and Stream. Some common encryption
algorithms include the Advanced Encryption Standard (AES) and the Data Encryption Standard
(DES). This form of encryption is traditionally much faster than Asymmetric however it requires
both the sender and the recipient of the data to have the secret key.

2) Description of S-AES –
S-AES uses the four types of transformations for encryption and decryption. The encryption
algorithm is referred to as the cipher and the decryption algorithm as the inverse cipher. S-AES is
a non-Feistel cipher, which means that each transformation or group of transformations must be
invertible. In addition, the cipher and the inverse cipher must use these operations in such a way
that they cancel each other. The round keys must also be used in the reverse order. To comply with
this requirement, the transformations occur in a different order in the cipher and the reverse cipher.
3) Algorithm –
First, the order of Sub Nibbles and Shift Rows is changed in the reverse cipher. Second, the order
of Mix Columns and Add Round Key is changed in the reverse cipher. This difference in ordering
is needed to make each transformation in the cipher aligned with its inverse in the reverse cipher.
Consequently, the decryption algorithm as a whole is the inverse of the encryption algorithm. Note
that the round keys are used in the reverse order.

Let’s assume the inputs for the encryption are:


• 16-bit Plaintext, P: 1101 0111 00101000
• 16-bit Key, K: 0100 1010 11110101
Key Generation
The first step is to generate the sub-keys. This is called Key Generation or Key Expansion: The
input key, K, is split into 2 words, w0 and w1:
w0 = 01001010
w1 = 11110101

The first sub-key, Key0, is in fact just the input key: Key0 = w0w1 = K

The other sub-keys are generated as follows:

w2 = w0 XOR 10000000 XOR Sub Nib (RotNib(w1))

(Note: RotNib() is “rotate the nibbles”, which is equivalent to swapping the nibbles)

= 0100 1010 XOR 10000000 XOR SubNib(0101 1111)

(Note: SubNib() is “apply S-Box substitution on nibbles using encryption S-Box”)

= 1100 1010 XOR SubNib(0101 1111)


= 1100 1010 XOR 0001 0111
= 1101 1101

w3 = w2 XORw1
= 1101 1101 XOR 1111 0101
= 0010 1000
w4 = w2 XOR 0011 0000 XORSubNib(RotNib(w3))
= 1101 1101 XOR 0011 0000 XOR SubNib(1000 0010)
= 1110 1101 XOR 0110 1010
= 1000 0111

w5 = w4 XOR w3
= 1000 0111 XOR 0010 1000
= 1010 1111

Now the sub-keys are:

Key0 = w0w1
= 0100 1010 1111 0101

Key1 = w2w3
= 1101 1101 0010 1000

Key2 = w4w5
= 1000 0111 1010 1111

Encryption
Now let’s do the encryption. There is an initial operation (Add Round Key), followed by the main
Round, followed by the final Round. (Note, the main difference in the real DES is that the main
Round is repeated many times).

Remember, the output of each operation is used as the input to the next operation, always operating
on 16-bits. The 16-bits can be viewed as a state matrix of nibbles.

Add Round 0Key

Plaintext XOR Key1


=1101 0111 0010 1000 XOR 0100 1010 1111 0101
=1001 1101 1101 1101

Round1

Nibble Substitution (S-boxes). Each nibble in the input is used in the Encryption S-Box to generate
an output nibble.

Input =1001 1101 1101 1101


Output =0010 1110 1110 1110

Shift Row. Swap 2nd nibble and 4th nibble (note, in this example, it’s not so easy to see since 2nd
and 4th nibbles are the same!)

=0010 1110 1110 1110


Mix Columns. Apply the matrix multiplication with the constant matrix, Me, using GF(24). For
GF(24), the addition operation is simply an XOR, and for the multiplication operation you can use
a lookup table.
Me = 1 4
4 1

S = 0010 1110 = S00’ S01’


1110 1110 S10’ S11’

S’ = Me xS

S00’ =0010 XOR (4 x1110)


=0010 XOR (4 xE)
=0010 XORD
=0010 XOR1101
=1111

S10’ =(4 x 0010) XOR1110


=1000 XOR1110
=0110

S01’ =1110 XOR (4 x1110)


=1110 XOR (4 xE)
=1110 XOR1101
=0011

S11’ =(4 x 1110) XOR1110


=1101 XOR1110
=0011

Output =S00’ S10’ S01’S11’


=1111 0110 0011 0011

Add Round 1 Key.

=1111 0110 0011 0011 XOR


1101 1101 0010 1000
=0010 1011 0001 1011

Final Round

Nibble Substitution (S-boxes)


=1010 0011 0100 0011

Shift Row (2ndand 4th)


=1010 0011 0100 0011

Add Round 2 Key


1010 0011 0100 0011 XOR 1000 0111 1010 1111
=0010 0100 1110 1100

Now we have the final ciphertext.


Ciphertext=0010 0100 1110 1100

Decryption

Now let’s decrypt. Note that we use the same keys generated during the encryption (that is, the
decryptor would generate the round sub-keys using the input key K, using the encryption S-Box).

Add Round 2 Key


0010 0100 1110 1100 XOR 1000 0111 1010 1111
=1010 0011 0100 0011
Inverse Shift Row (same as normal)
=1010 0011 0100 0011
Inverse Nibble Sub (use the inverse or decryption S-box)
=0010 1011 0001 1011
Add Round 1 Key
=0010 1011 0001 1011XOR 1101 1101 0010 1000
=1111 0110 0011 0011

Inverse Mix Columns


S = S00 S01
S10 S11
= 1111 0011
0110 0011
S’ = S00’ S10’ S01’ S11’

= 9 x S00 XOR 2 xS10 9 x S01 XOR 2 xS11


2 x S00 XOR 9 xS10 2 x S01 XOR 9 xS11

S00’ = (9 x 1111) XOR (2 x 0110)


= 9 x F XOR 2 x 6 E XOR C
= 1110 XOR 1100
= 0010
=

S10’ = 2 x 1111 XOR 9 x 0110


= 2 x F XOR 9 x 6
= D XOR 3
= 1101 XOR 0011
= 1110
S01’ = 9 x 0011 XOR 2 x 0011
= 9 x 3 XOR 2 x 3
= 8 XOR 6
= 1000 XOR 0110
= 1110

S11’ =2 x 0011 XOR 9 x0011


=1110

Output=0010 1110 1110 1110

Inverse Shift Row


=0010 1110 1110 1110

Inverse Nibble Sub


=1001 1101 1101 1101

Add Round 0 Key


= 1001 1101 1101 1101 XOR
0100 1010 1111 0101
= 1101 0111 0010 1000
Plaintext = 1101 0111 0010 1000
Original = 1101 0111 0010 1000

4) Advantages –
1. As it is implemented in both hardware and software, it is most robust security protocol.
2. It uses higher length key sizes such as 128, 192 and 256 bits for encryption. Hence it makes
AES algorithm more robust against hacking.
3. It is most common security protocol used for wide various of applications such as wireless
communication, financial transactions, e-business, encrypted data storage etc.
4. It is one of the most spread commercial and open-source solutions used all over the world.
5. No one can hack your personal information.
6. For 128 bit, about 2128 attempts are needed to break. This makes it very difficult to hack it
as a result it is very safe protocol.

5) Limitations –
1. It uses too simple algebraic structure.
Every block is always encrypted in the same way.
Hard to implement with software.
AES in counter mode is complex to implement in software taking both performance and
security into considerations.

Conclusion :
Thus, we have successfully implemented S-AES algorithm.

Code :
S_AES.py
# S boxe
sbox = [9, 4, 10, 11, 13, 1, 8, 5, 6, 2, 0, 3, 12, 14, 15, 7]

def convertNumToAsciiBit(x): # coverts decimal to binary


y = ""
for i in range(len(x)):
val = ord(x[i])
j=7
ans = ""
while j >= 0:
w = val // (pow(2, j))
ans += str(w)
val = val % (pow(2, j))
j -= 1
y += ans
return y

def convertAsciiToChar(x): # converts ASCII value to char


y = ""
for i in range(0, len(x), 8):
ans = 0
for j in range(8):
ans += int(x[i + j]) * pow(2, 7 - j)
if i == len(x) - 8:
if chr(ans) != '#':
y += chr(ans)
else:
y += chr(ans)
return y

def keyExpansion(key): # generates 2 round keys


x = [key[:4], key[4:8], key[8:12], key[12:16]]
for i in range(4): # binary to decimal for each nible
x[i] = list(map(int, x[i]))
x[i] = x[i][0] * 8 + x[i][1] * 4 + x[i][2] * 2 + x[i][3]
keylist = [x[0], x[1], x[2], x[3]]
for i in range(2):
w2 = [0, 0, 0, 0]
if i == 0:
val = 8 # rcon for first round
else:
val = 3 # rcon for 2nd round
w2[0] = keylist[4 * i] ^ val ^ (sbox[keylist[4 * i + 3]])
w2[1] = keylist[4 * i + 1] ^ 0 ^ (sbox[keylist[4 * i + 2]])
w2[2] = w2[0] ^ keylist[4 * i + 2]
w2[3] = w2[1] ^ keylist[4 * i + 3]
keylist.append(w2[0])
keylist.append(w2[1])
keylist.append(w2[2])
keylist.append(w2[3])
return keylist # has all 3 sub-keys

def getByteFromBit(x):# converts binary to bytes


y = []
i=0
while i < (len(x)):
y.append(8 * x[i] + 4 * x[i + 1] + 2 * x[i + 2] + x[i + 3])
i += 4
return y

def mixCols(y): # applies Mix-Columns


w = []
for i in range(len(y)):
val = y[i] * 4
if val >= 32:
val ^= 38
if val >= 16:
val ^= 19
w.append(val)
ans = [0, 0, 0, 0]
ans[0] = y[0] ^ w[1]
ans[1] = y[1] ^ w[0]
ans[2] = y[2] ^ w[3]
ans[3] = y[3] ^ w[2]
return ans

def convertByteToBit(y): # converts byte value to binary


cipher = []
for i in range(len(y)):
val = y[i]
val1 = val // 8
cipher.append(val1)
val = val % 8
val1 = val // 4
cipher.append(val1)
val = val % 4
val1 = val // 2
cipher.append(val1)
val1 = val % 2
cipher.append(val1)
cipher = list(map(str, cipher))
return "".join(cipher)
def mult(x, y):
val = x * y
if y == 2:
if val >= 32:
val ^= 38
if val >= 16:
val ^= 19
else:
val = x * 8
if val >= 64:
val ^= 76
if val >= 32:
val ^= 38
if val >= 16:
val ^= 19
val ^= x
return val

def inverseMixCols(y): # applies inverse Mix-Columns


w = [0, 0, 0, 0]
w[0] = mult(y[0], 9) ^ mult(y[1], 2)
w[1] = mult(y[1], 9) ^ mult(y[0], 2)
w[2] = mult(y[2], 9) ^ mult(y[3], 2)
w[3] = mult(y[3], 9) ^ mult(y[2], 2)
return w

def aesDecrypt(y, keylist): # applies Decryption Algorithm


j=2
for i in range(len(y)):
y[i] ^= keylist[4 * j + i]
j=1
while j >= 0:
y[1], y[3] = y[3], y[1]
for i in range(len(y)):
y[i] = sbox.index(y[i])
for i in range(len(y)):
y[i] ^= keylist[4 * j + i]
if j != 0:
y = inverseMixCols(y)
j -= 1
return convertByteToBit(y)

def aesEncrypt(y, keylist): # applies Encryption Algorithm


for i in range(len(y)):
y[i] ^= keylist[i % 4]
for i in range(1, 3):
for j in range(len(y)):
y[j] = sbox[y[j]]
y[1], y[3] = y[3], y[1]
if i != 2:
y = mixCols(y)
for j in range(len(y)):
y[j] = y[j] ^ keylist[4 * i + j]
return convertByteToBit(y)

if __name__ == "__main__":
print("Enter the plaintext : ") # any length char input
x = input()
print("Enter the key : ") # char input of length 2
key = input()
if len(key) != 2:
print("BAD KEY : Should be 16 bits")
exit(0)
key = convertNumToAsciiBit(key)
keylist = keyExpansion(key)
if len(x) % 2 != 0:
x += '#' # filler - #
x = convertNumToAsciiBit(x)
x = list(map(int, x))
i=0
cipher = ""
while i < len(x) - 1:
y = getByteFromBit(x[i:i + 16])
cipher += aesEncrypt(y, keylist)
i += 16
print("Cipher text after encryption is : ")
print(cipher)
print(convertAsciiToChar(cipher))
x = list(map(int, cipher))
i=0
plaintext = ""
while i < len(x) - 1:
y = getByteFromBit(x[i:i + 16])
plaintext += aesDecrypt(y, keylist)
i += 16
print("Plain text after decryption is : ")
print(plaintext)
print(convertAsciiToChar(plaintext))
Output:

Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 22:20:52) [MSC v.1916 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license()" for more information.
>>>
= RESTART: C:\Users\Mihir\AppData\Local\Programs\Python\Python37-32\S_AES.py =

Enter the plaintext :


hello sir
Enter the key :
50
Cipher text after encryption is:
101101110001011101101100100111001010010011101111101100000111101011111100010110
01
·lœ¤ï°züY
Plain text after decryption is:
011010000110010101101100011011000110111100100000011100110110100101110010001000
11
hello sir
>>>
ASSIGNMENT NO:3

Title: Implementation of Diffie-Hellman key exchange

Aim/Problem Statement: Write C++/JAVA/PYTHON/R program to exchange key using


Diffie-Hellman key exchange

Learning Objective: To Learn How to Apply Diffie-Hellman key exchange Algorithm to


exchange a key.

Theory:
1) Description of Diffie-Hellman Algorithm –
The Diffie–Hellman (DH) Algorithm is a key-exchange protocol that enables two parties
communicating over public channel to establish a mutual secret without it being transmitted over
the Internet. DH enables the two to use a public key to encrypt and decrypt their conversation or
data using symmetric cryptography.
DH is generally explained by two sample parties, Alice and Bob, initiating a dialogue. Each has a
piece of information they want to share, while preserving its secrecy. To do that they agree on a
public piece of benign information that will be mixed with their privileged information as it
travels over an insecure channel. Their secrets are mixed with the public information, or public
key, and as the secrets are exchanged the information they want to share is commingled with the
common secret. As they decipher the other’s message, they can extract the public information
and with knowledge of their own secret, deduce the new information that was carried along.
While seemingly uncomplicated in this method’s description, when long number strings are used
for private and public keys, decryption by an outside party trying to eavesdrop is mathematically
infeasible even with considerable resources.

2) Algorithm –
The algorithm in itself is very simple. Let's assume that Alice wants to establish a shared secret
with Bob.
i. Alice and Bob agree on a prime number, p, and a base, g, in advance. For our example,
let's assume that p=23 and g=5.

ii. Alice chooses a secret integer a value is 6 and computes A = g^a mod p. In this example,
A has the value of 8.

iii. Bob chooses a secret integer b whose value is 15 and computes B = g^b mod p. In this
example, B has the value of 19.

iv. Alice sends A to Bob and Bob sends B to Alice.

v. To obtain the shared secret, Alice computes s = B^a mod p. In this example, Alice
obtains the value of s=2

vi. To obtain the shared secret, Bob computes s = A^b mod p. In this example, Bob obtains
the value of s=2.

vii. The algorithm is secure because the values of a and b, which are required to derive s are
not transmitted across the wire at all.
3) Example –

Step 1: Alice and Bob get public numbers P = 23, G = 9

Step 2: Alice selected a private key a = 4 and Bob selected a private key b = 3

Step 3: Alice and Bob compute public values


Alice : x = (9^4 mod 23) = (6561 mod 23) = 6
Bob : y = (9^3 mod 23) = (729 mod 23) = 16

Step 4: Alice and Bob exchange public numbers

Step 5: Alice receives public key y =16 and Bob receives public key x = 6

Step 6: Alice and Bob compute symmetric keys


Alice : ka = y^a mod p = 65536 mod 23 = 9
Bob : kb = x^b mod p = 216 mod 23 = 9

Step 7: 9 is the shared secret.

4) Advantages –
1. The sender and receiver have no prior knowledge of each other.
2. Communication can take place through an insecure channel.
3. Sharing of secret key is safe.

5) Limitations –
1. Lack of authentication procedure.
2. Algorithm can be used only for symmetric key exchange.
3. As there is no authentication involved, it is vulnerable to man-in-the-middle attack.
4. As it is computationally intensive, it is expensive in terms of resources and CPU
performance time.
5. Encryption of information cannot be performed with the help of this algorithm.
6. Digital signature cannot be signed using Diffie-Hellman algorithm.

Conclusion :
Thus, we have successfully implemented Diffie-Hellman Key Exchange Algorithm.

Code :
Diffie.java

import java.lang.*;
import java.lang.Math.*;
import java.util.*;
import java.io.*;

public class diffie{

public static double power(double a, double b, double P)


{
if (b == 1)
return a;
else
return ((Math.pow(a, b)) % P);
}

//Driver program
public static void main(String[] args)
{
double G, x, a, y, b, ka, kb, P;

// Both the persons will be agreed upon the


// public keys G and P
P = 23; // A prime number P is taken
System.out.println("The value of P : "+ P);

G = 9; // A primitve root for P, G is taken


System.out.println("The value of G : "+ G);

// Alice will choose the private key a


a = 4; // a is the chosen private key
System.out.println("The private key a for Alice : "+ a);
x = power(G, a, P); // gets the generated key

// Bob will choose the private key b


b = 3; // b is the chosen private key
System.out.println("The private key b for Bob : "+ b);
y = power(G, b, P); // gets the generated key

// Generating the secret key after the exchange


// of keys
ka = power(y, a, P); // Secret key for Alice
kb = power(x, b, P); // Secret key for Bob

System.out.println("Secret key for the Alice is : "+ ka);


System.out.println("Secret Key for the Bob is : "+ kb);

Output :

The value of P : 23.0

The value of G : 9.0

The private key a for Alice : 4.0

The private key b for Bob : 3.0

Secret key for the Alice is : 9.0

Secret Key for the Bob is : 9.0


ASSIGNMENT NO:4

Title: Implementation of RSA.

Aim/Problem Statement: Write C++/JAVA/PYTHON/R program to encrypt or decrypt


message using S-AES

Learning Objective: To Learn How to Apply RSA Algorithm to encryption and decryption of
given data.

Theory:
1) Public key Cryptography –
Public key cryptography is a class of cryptographic protocols based on algorithms. This method
of cryptography requires two separate keys, one that is private or secret, and one that is public.
Public key cryptography uses a pair of keys to encrypt and decrypt data to protect it against
unauthorized access or use. Network users receive a public and private key pair from certification
authorities. If other users want to encrypt data, they get the intended recipient’s public key from a
public directory. This key is used to encrypt the message, and to send it to the recipient. When the
message arrives, the recipient decrypts it using a private key, to which no one else has access.

Challenges - Several private key cryptography methods are a great deal faster than the public key
encryption method that currently is available. One way of overcoming this challenge with public
key cryptography is to combine it with secret key systems to offer the security advantages of the
public key system and the speed of the secret (private) key system. Another challenge associated
with public key cryptography is that it has been susceptible to attacks through spoofed or
compromised certification authorities. When these attacks take place, cyber criminals impersonate
nearly anyone by choosing a public key certificate from the compromised authority. This allows
cyber criminals to connect a public key to the name of another user.

Benefits - The increased data security provided by public key cryptography is its main benefit.
Public key cryptography remains the most secure protocol (over private key cryptography) because
users never need to transmit or reveal their private keys to anyone, which lessens the chances of
cyber criminals discovering an individual’s secret key during the transmission. Public key
cryptography also provides digital signatures that cannot be repudiated. Public key cryptography
requires each user to be responsible for protecting his private key, whereas private key systems
require users to share secret keys and perhaps even trust third parties for transmission. With the
secret key system, it is possible for senders to claim the shared secret key was compromised by
one of the parties involved in the process.

2) Description of RSA Algorithm –


In 1978, Ron Rivest, Adi Shamir, and Leonard Adelman introduced a cryptographic algorithm,
which was essentially to replace the less secure National Bureau of Standards (NBS) algorithm.
Most importantly, RSA implements a public-key cryptosystem, as well as digital signatures.
RSA is motivated by the published works of Diffie and Hellman from several years before, who
described the idea of such an algorithm, but never truly developed it.

The idea of RSA is based on the fact that it is difficult to factorize a large integer. The public key
consists of two numbers where one number is multiplication of two large prime numbers. And
private key is also derived from the same two prime numbers. So if somebody can factorize the
large number, the private key is compromised. Therefore encryption strength totally lies on the
key size and if we double or triple the key size, the strength of encryption increases
exponentially. RSA keys can be typically 1024 or 2048 bits long, but experts believe that 1024
bit keys could be broken in the near future. But till now it seems to be an infeasible task.

Introduced at the time when the era of electronic email was expected to soon arise, RSA
implemented two important ideas: 1. Public-key encryption. This idea omits the need for a
“courier” to deliver keys to recipients over another secure channel before transmitting the
originally-intended message. In RSA, encryption keys are public, while the decryption keys are
not, so only the person with the correct decryption key can decipher an encrypted message.
Everyone has their own encryption and decryption keys. The keys must be made in such a way
that the decryption key may not be easily deduced from the public encryption key. 2. Digital
signatures. The receiver may need to verify that a transmitted message actually originated from
the sender (signature), and didn’t just come from there (authentication). This is done using the
sender’s decryption key, and the signature can later be verified by anyone, using the
corresponding public encryption key. Signatures therefore cannot be forged. Also, no signer can
later deny having signed the message.

This is not only useful for electronic mail, but for other electronic transactions and transmissions,
such as fund transfers. The security of the RSA algorithm has so far been validated, since no
known attempts to break it have yet been successful, mostly due to the difficulty of factoring
large numbers n = pq, where p and q are large prime numbers.

3) Algorithm –
Generating Public Key :
Select two prime no's. Suppose P = 53 and Q = 59.
Now First part of the Public key: n = P*Q = 3127.
We also need a small exponent say e:
But e must be An integer. Not be a factor of n.
1 < e <Φ(n) [Φ(n) is discussed below],
Let us now consider it to be equal to 3.
Our Public Key is made of n and e

Generating Private Key:


We need to calculate Φ(n) :
Such that,
Φ(n) = (P-1)(Q-1) so, Φ(n) = 3016
Now calculate Private Key, d :
d = (k*Φ(n) + 1) / e for some integer k
For k = 2, value of d is 2011.

Now we are ready with our


Public Key ( n = 3127 and e = 3) and
Private Key(d = 2011)

Now we will encrypt “HI”:


Convert letters to numbers: H = 8 and I = 9 Thus
Encrypted Data c = 89e mod n.
Thus our Encrypted Data comes out to be 1394
Now we will decrypt 1394:
Decrypted Data = cd mod n.
Thus our Encrypted Data comes out to be 89

8 = H and I = 9 i.e. "HI".

4) Example –
Step-1: Choose two prime number p and q. Let take p = 3 and q = 11
Step-2: Compute the value of n and \phi
It is given as, n = p \times q and \phi = (p-1) \times (q-1)
Here in the example,
n = 3 \times 11 = 33
\phi = (3-1) \times (11-1) = 2 \times 10 = 20
Step-3: Find the value of e (public key)
Choose e, such that e should be co-prime. Co-prime means it should not multiply by
factors of \phi and also not divide by \phi
Factors of \phi are, 20 = 5 \times 4 = 5 \times 2 \times 2 so e should not multiply by 5 and
2 and should not divide by 20.
So, primes are 3, 7, 11, 17, 19…, as 3 and 11 are taken choose e as 7
Therefore, e = 7
Step-4: Compute the value of d (private key)
The condition is given as,
gcd(\phi, e) = \phi x +ey = 1 where y is the value of d.
To compute the value of d,
Form a table with four columns i.e., a, b, d, and k.
Initialize a = 1, b = 0, d = \phi, k = – in first row.
Initialize a = 0, b = 1, d = e, k = \frac{\phi}{e} in second row.
From the next row, apply following formulas to find the value of next a, b, d, and k,
which is given as
a_{i} = a_{i-2} - (a_{i-1} \times k_{i-1})
b_{i} = b_{i-2} - (b_{i-1} \times k_{i-1})
d_{i} = d_{i-2} - (d_{i-1} \times k_{i-1})
k_{i} = \frac{d_{i-2}}{d_{i-1}}
As soon as, d = 1, stop the process and check for the below condition
if b > \phi
b = b \mod \phi
if b < 0
b = b + \phi

For a given example, the table will be,

A B D K
1 0 20 –
0 1 7 2
1 -2 6 1
-1 3 1 –

As in the above table d = 1, stop the process and check for the condition given for the b
\therefore b = 3
To verify that b is correct, the above condition should satisfy, i.e.
gcd(\phi, e) = \phi x + ey = (20 \times -1) + (7 \times 3) = 1. Hence d is correct.
Step-5: Do the encryption and decryption
Encryption is given as,
c = t^{e}\mod n
Decryption is given as,
t = c^{d}\mod n
For the given example, suppose t = 2, so
Encryption is c = 2^{7}\mod 33 = 29
Decryption is t = 29^{3}\mod 33 = 2
Therefore, in the final, p = 3, q = 11, \phi = 20, n = 33, e = 7 and d = 3

5) Advantages –
1. RSA is stronger than any other symmetric key algorithm.
2. RSA has overcome the weakness of symmetric algorithm i.e. authenticity and
confidentiality.

6) Limitations -
1. RSA has too much computation.

Conclusion : Thus, we successfully implemented RSA Algorithm.

Code :

RSA1.java
import java.util.*;
import java.lang.*;

class RSA1
{
//to find gcd
public static double gcd(double a, double h)
{
double temp;
while(true)
{
temp = a%h;
if(temp==0)
return h;
a = h;
h = temp;
}
}

public static void main(String[] args)


{
//2 random prime numbers
double p = 3;
double q = 7;
double n=p*q;
double count;
double totient = (p-1)*(q-1);

//public key
//e stands for encrypt
double e = 2;

//for checking co-prime which satisfies e>1


while(e<totient){
count = gcd(e,totient);
if(count==1)
break;
else
e++;
}

//private key
//d stands for decrypt
double d;

//k can be any arbitrary value


double k = 2;

//choosing d such that it satisfies d*e = 1 + k * totient


d = (1 + (k*totient))/e;
double msg = 12;
double c = Math.pow(msg,e);
double m = Math.pow(c,d);
c= c%n;
m= m%n;

System.out.println("Message data = "+msg);


System.out.println("p = "+p);
System.out.println("q = "+q);
System.out.println("n = pq = "+n);
System.out.println("totient = "+totient);
System.out.println("e = "+e);
System.out.println("d = "+d);
System.out.println("Encrypted data = "+c);
System.out.println("Original Message Sent = "+m);

}
}
Output :

Message data = 12.0


p = 3.0
q = 7.0
n = pq = 21.0
totient = 12.0
e = 5.0
d = 5.0
Encrypted data = 3.0
Original Message Sent = 12.0

You might also like