0% found this document useful (0 votes)
6 views

Cryptolabda 5

Uploaded by

Rohith Chanda
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

Cryptolabda 5

Uploaded by

Rohith Chanda
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

Name: C.

Rohith Register No: 21BCE0810

Cryptography and Network Security Lab


ASSESSMENT-5

Name: C. Rohith
Register No: 21BCE0810.
Slot: L13 + L14
Name: C. Rohith Register No: 21BCE0810

1. Implement the following techniques without using standard cryptographic library Functions

• Secure Hash Algorithm (SHA)

• RSA based Digital signature Algorithm

• ElGamal based Digital signature Algorithm

A.

Aim: To implement secure hash algorithm (SHA) without using standard cryptographic library functions in java.

Algorithm:

1. Define the initial hash values (H) and constants (K) for SHA-256.

2. Define the SHA-256 functions:

- `rotr(x, n)`: Right rotate operation.

- `shr(x, n)`: Bitwise right shift operation.

- `ch(x, y, z)`: Choice function.

- `maj(x, y, z)`: Majority function.

- `sigma0(x)`, `sigma1(x)`, `gamma0(x)`, `gamma1(x)`: Helper functions.

3. Implement padding:

- Append a single '1' bit to the message.

- Append '0' bits until the message length is congruent to 448 modulo 512.

- Append the length of the message in bits as a 64-bit big-endian integer.

4. Process the message in 512-bit chunks:

- Break the padded message into 512-bit chunks.

- For each chunk, break it into 32-bit words (big-endian).

- Extend the 16 32-bit words into 64 32-bit words using the SHA-256 expansion function.

5. Initialize working variables (a-h) with the initial hash values.

6. Iterate over each 64-word chunk:

- Perform the SHA-256 compression function on the chunk.

- Update the working variables accordingly.

7. Compute the final hash value by concatenating the working variables' values.

8. Convert the hash value to bytes and return it.


Name: C. Rohith Register No: 21BCE0810

Code:

public class prac {

// Initial hash values for SHA-256


private static final int[] H = {
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
};

// Constants for SHA-256


private static final int[] K = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};

// SHA-256 functions
private static int rotr(int x, int n) {
return (x >>> n) | (x << (32 - n));
}

private static int shr(int x, int n) {


return x >>> n;
}

private static int ch(int x, int y, int z) {


return (x & y) ^ (~x & z);
}

private static int maj(int x, int y, int z) {


return (x & y) ^ (x & z) ^ (y & z);
Name: C. Rohith Register No: 21BCE0810

private static int sigma0(int x) {


return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22);
}

private static int sigma1(int x) {


return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25);
}

private static int gamma0(int x) {


return rotr(x, 7) ^ rotr(x, 18) ^ shr(x, 3);
}

private static int gamma1(int x) {


return rotr(x, 17) ^ rotr(x, 19) ^ shr(x, 10);
}

private static byte[] padding(byte[] message) {


long ml = message.length * 8;
byte[] padding = new byte[(int) ((ml / 512 + 1) * 512 / 8)];
System.arraycopy(message, 0, padding, 0, message.length);
padding[message.length] = (byte) 0b10000000;
for (int i = 8; i > 0; i--) {
padding[padding.length - i] = (byte) (ml >> ((8 - i) * 8));
}
return padding;
}

private static int[] processChunk(byte[] chunk, int[] h) {


int[] w = new int[64];

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


w[i] = ((chunk[i * 4] & 0xFF) << 24) |
((chunk[i * 4 + 1] & 0xFF) << 16) |
((chunk[i * 4 + 2] & 0xFF) << 8) |
(chunk[i * 4 + 3] & 0xFF);
}

for (int i = 16; i < 64; i++) {


w[i] = (gamma1(w[i - 2]) + w[i - 7] + gamma0(w[i - 15]) + w[i - 16])
& 0xFFFFFFFF;
}
Name: C. Rohith Register No: 21BCE0810

int a = h[0], b = h[1], c = h[2], d = h[3], e = h[4], f = h[5], g = h[6],


hh = h[7];

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


int t1 = (hh + sigma1(e) + ch(e, f, g) + K[i] + w[i]) & 0xFFFFFFFF;
int t2 = (sigma0(a) + maj(a, b, c)) & 0xFFFFFFFF;
hh = g;
g = f;
f = e;
e = (d + t1) & 0xFFFFFFFF;
d = c;
c = b;
b = a;
a = (t1 + t2) & 0xFFFFFFFF;
}

h[0] = (h[0] + a) & 0xFFFFFFFF;


h[1] = (h[1] + b) & 0xFFFFFFFF;
h[2] = (h[2] + c) & 0xFFFFFFFF;
h[3] = (h[3] + d) & 0xFFFFFFFF;
h[4] = (h[4] + e) & 0xFFFFFFFF;
h[5] = (h[5] + f) & 0xFFFFFFFF;
h[6] = (h[6] + g) & 0xFFFFFFFF;
h[7] = (h[7] + hh) & 0xFFFFFFFF;

return h;
}

public static byte[] sha256(byte[] message) {


message = padding(message);
int[] h = H.clone();
byte[] chunks = new byte[64];

for (int i = 0; i < message.length / 64; i++) {


System.arraycopy(message, i * 64, chunks, 0, 64);
h = processChunk(chunks, h);
}

byte[] hash = new byte[32];


for (int i = 0; i < 8; i++) {
hash[i * 4] = (byte) (h[i] >> 24);
hash[i * 4 + 1] = (byte) (h[i] >> 16);
hash[i * 4 + 2] = (byte) (h[i] >> 8);
hash[i * 4 + 3] = (byte) (h[i]);
}
Name: C. Rohith Register No: 21BCE0810

return hash;
}

public static void main(String[] args) {


String message = "Hello, world!";
byte[] hash = sha256(message.getBytes());
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
System.out.println("SHA-256 Hash: " + hexString.toString());
}
}

Screenshot:
Name: C. Rohith Register No: 21BCE0810
Name: C. Rohith Register No: 21BCE0810

Output:

(i) For hello world:

(ii) For 21BCE0810:

Result: We have successfully implemented Secure Hash Algorithm (SHA) without using standard library in java.
Name: C. Rohith Register No: 21BCE0810

Aim: To implement RSA based Digital signature Algorithm without using standard cryptographic library in java.

Algorithm:

Key Generation:

1. Generate two large random prime numbers, `p` and `q`.

2. Calculate the modulus `n` as the product of `p` and `q`.

3. Calculate Euler's totient function `phi(n)` as `(p - 1) * (q - 1)`.

4. Choose a public exponent `e` such that `1 < e < phi(n)` and `e` is coprime with `phi(n)`.

5. Calculate the private exponent `d` as the modular multiplicative inverse of `e` modulo `phi(n)`.

Signing:

1. Convert the message `M` into an integer `m`.

2. Calculate the signature `S` using the private key `(d, n)` by computing `S = m^d mod n`.

Verification:

1. Convert the message `M` into an integer `m`.

2. Obtain the received signature `S` from the sender.

3. Calculate `m'` using the public key `(e, n)` by computing `m' = S^e mod n`.

4. If `m'` equals `m`, the signature is verified.


Name: C. Rohith Register No: 21BCE0810

Code:

import java.math.BigInteger;
import java.security.SecureRandom;

public class prac {

private static BigInteger p;


private static BigInteger q;
private static BigInteger n;
private static BigInteger phi;
private static BigInteger e;
private static BigInteger d;

private static final int BIT_LENGTH = 1024;


private static final int CERTAINTY = 50;
private static final SecureRandom random = new SecureRandom();

private static void generateKeyPair() {


p = BigInteger.probablePrime(BIT_LENGTH, random);
q = BigInteger.probablePrime(BIT_LENGTH, random);
n = p.multiply(q); // modulus
phi = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
e = BigInteger.valueOf(65537);
d = e.modInverse(phi);
}

private static BigInteger sign(byte[] message) {


BigInteger m = new BigInteger(1, message);
return m.modPow(d, n);
}

private static boolean verify(byte[] message, BigInteger signature) {


BigInteger m = new BigInteger(1, message);
BigInteger mVerify = signature.modPow(e, n);
return m.equals(mVerify);
}

public static void main(String[] args) {

generateKeyPair();
Name: C. Rohith Register No: 21BCE0810

String originalMessage = "Hello, world!";


byte[] messageBytes = originalMessage.getBytes();

BigInteger signature = sign(messageBytes);

boolean isVerified = verify(messageBytes, signature);

// Output result
System.out.println("Original Message: " + originalMessage);
System.out.println("Signature: " + signature.toString());
System.out.println("Signature Verified: " + isVerified);
}
}

Screenshot:
Name: C. Rohith Register No: 21BCE0810

Output:

(i) For hello world:

(ii) For 21BCE0810

Result: We have successfully implemented RSA based Digital signature Algorithm without using standard
cryptographic library in java.
Name: C. Rohith Register No: 21BCE0810

Aim: To implement ElGamal based Digital signature Algorithm without using standard cryptographic library in java.

Algorithm:

Key Generation:

1. Generate a large prime number \( p \).

2. Find a generator \( g \) for the multiplicative group \( \mathbb{Z}_p^* \).

3. Choose a random integer \( x \) such that \( 1 < x < p - 1 \).

4. Compute the public key \( y = g^x \mod p \).

Signature Generation:

1. Choose a random integer \( k \) such that \( 1 < k < p - 1 \) and \( \text{gcd}(k, p - 1) = 1 \).

2. Compute \( r = g^k \mod p \).

3. Compute \( s = (H(m) - x \cdot r) \cdot k^{-1} \mod (p - 1) \), where \( H(m) \) is the hash of the message \( m \).

Signature Verification:

1. Compute \( v_1 = (g^{H(m)} \cdot y^r) \mod p \).

2. If \( v_1 = r \), the signature is verified.

Code:

import java.math.BigInteger;
import java.security.SecureRandom;

public class prac {

private static final SecureRandom random = new SecureRandom();

private static BigInteger p; // large prime


private static BigInteger g; // generator
private static BigInteger x; // private key
private static BigInteger y; // public key

private static void generateKeyPair() {

p = BigInteger.probablePrime(1024, random);

g = findGenerator();
Name: C. Rohith Register No: 21BCE0810

x = new BigInteger(p.bitLength() - 1, random);

y = g.modPow(x, p);
}

private static BigInteger findGenerator() {

for (BigInteger i = BigInteger.valueOf(2);


i.compareTo(p.subtract(BigInteger.ONE)) < 0; i = i.add(BigInteger.ONE)) {
if (i.modPow(p.subtract(BigInteger.ONE), p).equals(BigInteger.ONE)) {
return i;
}
}
return null; // No generator found
}

private static BigInteger[] sign(byte[] message) {


BigInteger k;
BigInteger r;
BigInteger s;
do {

k = new BigInteger(p.bitLength() - 1, random);


} while (!k.gcd(p.subtract(BigInteger.ONE)).equals(BigInteger.ONE));

r = g.modPow(k, p);

BigInteger h = new BigInteger(1, message);


BigInteger xr = x.multiply(r);
BigInteger hxr = h.subtract(xr);
BigInteger kInv = k.modInverse(p.subtract(BigInteger.ONE));
s = hxr.multiply(kInv).mod(p.subtract(BigInteger.ONE));

return new BigInteger[]{r, s};


}

private static boolean verify(byte[] message, BigInteger[] signature) {


BigInteger r = signature[0];
BigInteger s = signature[1];
Name: C. Rohith Register No: 21BCE0810

if (r.compareTo(BigInteger.ONE) < 0 ||
r.compareTo(p.subtract(BigInteger.ONE)) >= 0 ||
s.compareTo(BigInteger.ONE) < 0 ||
s.compareTo(p.subtract(BigInteger.ONE)) >= 0) {
return false;
}

BigInteger h = new BigInteger(1, message);


BigInteger w = s.modInverse(p.subtract(BigInteger.ONE));

BigInteger u1 = h.multiply(w).mod(p.subtract(BigInteger.ONE));
BigInteger u2 = r.multiply(w).mod(p.subtract(BigInteger.ONE));

BigInteger v1 = g.modPow(u1, p).multiply(y.modPow(u2, p)).mod(p);

return v1.equals(r);
}

public static void main(String[] args) {

generateKeyPair();
String originalMessage = "Hello, world!";
byte[] messageBytes = originalMessage.getBytes();
BigInteger[] signature = sign(messageBytes);
boolean isVerified = verify(messageBytes, signature);
System.out.println("Original Message: " + originalMessage);
System.out.println("Signature (r): " + signature[0]);
System.out.println("Signature (s): " + signature[1]);
System.out.println("Signature Verified: " + isVerified);
}
}

Screenshot:
Name: C. Rohith Register No: 21BCE0810
Name: C. Rohith Register No: 21BCE0810

Output:

(i) For hello world:

Result: We have successfully implemented ElGamal based Digital signature Algorithm without using standard
cryptographic library in java.

You might also like