Cns Lab Assignment
Cns Lab Assignment
1. Description:
Implement an 8-bit LFSR using XOR feedback with configurable tap positions and generate
20 states to check for repetition.
2. Code:
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#define NUM_STATES 20
int main() {
uint8_t sequence[NUM_STATES];
sequence[i] = lfsr;
uint8_t feedback = 0;
if (sequence[i] == sequence[j]) {
repeats = true;
break;
}
}
if (!repeats) {
return 0;
3. Input:
4. Output:
2. Code:
#include <stdio.h>
#include <stdint.h>
uint8_t apply_permutation(uint8_t input, int perm[8]) {
uint8_t output = 0;
for (int i = 0; i < 8; i++) {
uint8_t bit = (input >> (7 - perm[i])) & 1;
output |= (bit << (7 - i));
}
return output;
}
uint8_t feistel_function(uint8_t half, uint8_t key, int perm[8]) {
uint8_t result = half ^ key;
return apply_permutation(result, perm);
}
int main() {
uint8_t plaintext = 0b11010110;
uint8_t keys[4] = {0x3, 0x5, 0x7, 0x2};
int perm[8] = {2, 0, 3, 1, 6, 4, 7, 5};
4. Output:
Initial Plaintext: 0xD6
Initial L: 0xD, R: 0x6
After Round 1: L = 0x6, R = 0xE
After Round 2: L = 0xE, R = 0x8
After Round 3: L = 0x8, R = 0x1
After Round 4: L = 0x1, R = 0x2
Final Ciphertext: 0x12
3. Bit-level Permutation Box (P-box) Simulation
1. Description:
Simulate a P-box that permutes the bits of an 8-bit input using a specified bit
position mapping.
2. Code:
#include <stdio.h>
#include <stdint.h>
int main() {
uint8_t input = 0b10110100;
int permutation[8] = {7, 6, 0, 2, 5, 4, 3, 1};
return 0;
}
3. Input:
Input bits = 0b10110100, Permutation = [7, 6, 0, 2, 5, 4, 3, 1]
4. Output:
Original Input: 10110100
Permuted Output: 00111010
4. Reversible Permutation Function and Inverse
1. Description:
Implement a 4-bit reversible permutation function and its inverse to verify restoration of
original data.
2. Code:
#include <stdio.h>
#include <stdint.h>
uint8_t apply_permutation(uint8_t input, int perm[4]) {
uint8_t output = 0;
for (int i = 0; i < 4; i++) {
uint8_t bit = (input >> (3 - perm[i])) & 1;
output |= (bit << (3 - i));
}
return output;
}
void generate_inverse(int perm[4], int inverse[4]) {
for (int i = 0; i < 4; i++) {
inverse[perm[i]] = i;
}
}
void print_binary4(uint8_t value) {
for (int i = 3; i >= 0; i--) {
printf("%d", (value >> i) & 1);
}
}
void main() {
uint8_t input = 0b1101;
int perm[4] = {3, 0, 2, 1};
int inverse_perm[4];
generate_inverse(perm, inverse_perm);
uint8_t restored = apply_permutation(permuted, inverse_perm);
printf("After Permutation:");
print_binary4(permuted);
printf("\n");
4. Output:
Original Input: 1101
After Permutation:1101
After Inverse: 1101
5. LFSR-based Pseudo-Random Number Generator
1. Description:
Implement a pseudo-random number generator using an 8-bit LFSR with specified seed and
tap positions.
2. Code:
#include <stdio.h>
#include <stdint.h>
#define NUM_BYTES 10
int main() {
uint8_t lfsr = 0xA3;
int taps[] = {7, 5};
uint8_t prng[NUM_BYTES];
prng[i] = byte;
printf("0x%02X ", byte);
}
printf("\n");
return 0;
}
3. Input:
Seed: 0xA3 (binary 10100011)
Taps: [7, 5] (zero-indexed from left)
4. Output:
#define TAP1 7
#define TAP2 5
int main() {
char plaintext[] = "CRYPTO";
uint8_t ciphertext[sizeof(plaintext)];
uint8_t lfsr = 0xE7;
printf("\n");
return 0;
}
3. Input:
Plaintext: "CRYPTO"
LFSR State: 0xE7 (binary 11100111)
Tap Positions: [7, 5] (zero-indexed from left)
4. Output:
Plaintext: CRYPTO
Encrypted (Hex): 0x0D 0xCF 0x63 0x24 0xBD 0x9C
7. Nibble-Level Permutation of a 16-bit Word
1. Description:
Perform a permutation on 4 nibbles of a 16-bit word and recombine to form a new 16-bit
output.
2. Code:
#include <stdio.h>
#include <stdint.h>
int main() {
uint16_t word = 0xABCD;
int perm[4] = {3, 1, 2, 0};
uint8_t nibbles[4];
uint16_t result = 0;
return 0;
}
3. Input:
Word: 0xABCD
Nibble Permutation: [3, 1, 2, 0]
(Move nibble 3 to position 0, nibble 1 to 1, etc.)
4. Output:
Original Word: 0xABCD
Permuted Word: 0xDBCA
8. Parallel LFSRs for Keystream Generation
1. Description:
Simulate two parallel LFSRs and XOR their outputs to generate a 16-bit keystream.
2. Code:
#include <stdio.h>
#include <stdint.h>
int main() {
uint8_t lfsr1 = 0xF0;
uint8_t lfsr2 = 0x3C;
int tap1_1 = 7, tap1_2 = 4;
int tap2_1 = 5, tap2_2 = 2;
uint16_t keystream = 0;
printf("\n");
return 0;
}
3. Input:
LFSR1: 0xF0, Taps1: [7, 4]
LFSR2: 0x3C, Taps2: [5, 2]
4. Output:
Keystream (16 bits): 0111111000111111
9. Row Permutation on a 4×4 Matrix (Image Pixels Simulation)
1. Description:
Apply a row-level permutation to simulate pixel rearrangement in a 4×4 image matrix.
2. Code:
#include <stdio.h>
#include <stdint.h>
#define SIZE 4
int main() {
uint8_t matrix[SIZE][SIZE] = {
{0x11, 0x12, 0x13, 0x14},
{0x21, 0x22, 0x23, 0x24},
{0x31, 0x32, 0x33, 0x34},
{0x41, 0x42, 0x43, 0x44}
};
printf("Original Matrix:\n");
print_matrix(matrix);
printf("\nPermuted Matrix:\n");
print_matrix(permuted);
return 0;
}
3. Input:
a. Matrix:
0x11 0x12 0x13 0x14
0x21 0x22 0x23 0x24
0x31 0x32 0x33 0x34
0x41 0x42 0x43 0x44
b. Row Permutation: [2, 0, 3, 1]
4. Output:
Original Matrix:
11 12 13 14
21 22 23 24
31 32 33 34
41 42 43 44
Permuted Matrix:
31 32 33 34
11 12 13 14
41 42 43 44
21 22 23 24
10.Block Permutation Cipher
1. Description:
Encrypt a plaintext by dividing it into blocks and applying a fixed permutation to each block.
2. Code:
#include <stdio.h>
#include <string.h>
#define BLOCK_SIZE 4
int main() {
char plaintext[] = "ABCDEFGH";
char encrypted[9];
int block_perm[BLOCK_SIZE] = {2, 0, 3, 1};
encrypted[len] = '\0';
printf("Encrypted: %s\n", encrypted);
return 0;
}
3. Input:
Plaintext: "ABCDEFGH"
Block Size: 4
Block Permutation: [2, 0, 3, 1]
4. Output:
Plaintext: ABCDEFGH
Encrypted: CADBGEHF
11.ROL and ROR (Rotate Left/Right) and Their Inverse Relationship
1. Description:
Perform rotate left (ROL) and rotate right (ROR) operations on a 16-bit value and verify that
they are inverses.
2. Code:
#include <stdio.h>
#include <stdint.h>
int main() {
uint16_t x = 0x1234;
int n = 4;
if (rotated_back == x) {
printf("Success: ROR(ROL(X, %d), %d) == X\n", n, n);
} else {
printf("Failure: Inverse relationship not verified.\n");
}
return 0;
}
3. Input:
X = 0x1234
Rotate amount = 4
4. Output:
Original : 0x1234
ROL(4) : 0x2341
ROR(4) : 0x1234
Success: ROR(ROL(X, 4), 4) == X
12.Modular Addition of Two Arrays
1. Description:
Perform element-wise modular addition of two 5-element arrays using modulo 216 and print
the result.
2. Code:
#include <stdio.h>
#include <stdint.h>
#define SIZE 5
int main() {
uint16_t A[SIZE] = {0x1111, 0x2222, 0x3333, 0x4444, 0x5555};
uint16_t B[SIZE] = {0xAAAA, 0xBBBB, 0xCCCC, 0xDDDD, 0xEEEE};
uint16_t result[SIZE];
modular_addition(A, B, result);
return 0;
}
3. Input:
A[] = {0x1111, 0x2222, 0x3333, 0x4444, 0x5555}
B[] = {0xAAAA, 0xBBBB, 0xCCCC, 0xDDDD, 0xEEEE}
4. Output:
Modular Addition Results:
A[0] + B[0] mod 2^16 = 0xBBBB
A[1] + B[1] mod 2^16 = 0xDDDD
A[2] + B[2] mod 2^16 = 0xFFFF
A[3] + B[3] mod 2^16 = 0x2221
A[4] + B[4] mod 2^16 = 0x4443
13.Simulate a 2-Round ARX Block with Custom Rotations
1. Description:
Perform 2 rounds of an ARX (Addition, Rotation, XOR) block cipher using specified rotate
amounts.
2. Code:
#include <stdio.h>
#include <stdint.h>
int main() {
uint16_t X = 0x1357;
uint16_t Y = 0x2468;
int ROL_amt = 7;
int ROR_amt = 3;
X = (X + Y) & 0xFFFF;
X = rol(X, ROL_amt);
Y = Y ^ X;
Y = ror(Y, ROR_amt);
printf("After Round 1: X = 0x%04X, Y = 0x%04X\n", X, Y);
X = (X + Y) & 0xFFFF;
X = rol(X, ROL_amt);
Y = Y ^ X;
Y = ror(Y, ROR_amt);
printf("After Round 2: X = 0x%04X, Y = 0x%04X\n", X, Y);
return 0;
}
3. Input:
X = 0x1357
Y = 0x2468
ROL = 7, ROR = 3
4. Output:
Initial Values: X = 0x1357, Y = 0x2468
After Round 1: X = 0xDF9B, Y = 0x7F7E
After Round 2: X = 0x8CAF, Y = 0x3E7A
14.Perform ARX with User-Defined Round Keys
1. Description:
Simulate two rounds of an ARX (Addition, Rotation, XOR) block using round keys in each
round.
2. Code:
#include <stdio.h>
#include <stdint.h>
#define ROL_AMOUNT 5
#define ROR_AMOUNT 2
int main() {
uint16_t X = 0xAAAA;
uint16_t Y = 0xBBBB;
uint16_t K1 = 0x1111;
uint16_t K2 = 0x2222;
uint16_t Y1 = Y ^ K1;
arx_round(&X, &Y1);
printf("After Round 1: X = 0x%04X, Y1 = 0x%04X\n", X, Y1);
uint16_t Y2 = Y ^ K2;
arx_round(&X, &Y2);
printf("After Round 2: X = 0x%04X, Y2 = 0x%04X\n", X, Y2);
return 0;
}
3. Input:
X = 0xAAAA
Y = 0xBBBB
K1 = 0x1111, K2 = 0x2222
ARX operations use ROL = 5 and ROR = 2
4. Output:
Initial: X = 0xAAAA, Y = 0xBBBB
After Round 1: X = 0xAA8A, Y1 = 0x0008
After Round 2: X = 0x8468, Y2 = 0x477C
15.ARX Operation on 32-bit Values with User-Defined Shifts
1. Description:
Perform an ARX (Addition, Rotation, XOR) operation on 32-bit values with specified ROL and
ROR amounts.
2. Code:
#include <stdio.h>
#include <stdint.h>
uint32_t rol32(uint32_t x, int n) {
return (x << n) | (x >> (32 - n));
}
printf("After ARX:\n");
printf("X = 0x%08X\n", X);
printf("Y = 0x%08X\n", Y);
return 0;
}
3. Input:
X = 0xCAFEBABE
Y = 0xDEADBEEF
ROL = 10, ROR = 8
4. Output:
Initial: X = 0xCAFEBABE, Y = 0xDEADBEEF
After ARX:
X = 0xB1E6B6A6
Y = 0x496F4B08
16.Compare ARX Output for Small vs Large Rotation Values
1. Description:
Compare results of ARX operations using small and large ROL/ROR values on 16-bit inputs.
2. Code:
#include <stdio.h>
#include <stdint.h>
int main() {
uint32_t X = 0xCAFEBABE;
uint32_t Y = 0xDEADBEEF;
int rol_amt = 10;
int ror_amt = 8;
printf("After ARX:\n");
printf("X = 0x%08X\n", X);
printf("Y = 0x%08X\n", Y);
return 0;
}
3. Input:
X = 0x0F0F, Y = 0xF0F0
Case A: ROL = 1, ROR = 2
Case B: ROL = 12, ROR = 13
4. Output:
Case A (ROL=1, ROR=2):
X = 0xFFFF, Y = 0xC3C3
Case B (ROL=12, ROR=13):
X = 0xFFFF, Y = 0x7878
17.Encrypt a 4-Element Array Using Repeated ARX Rounds
1. Description:
Apply 3 rounds of ARX to each element of an array using a fixed key and given ROL/ROR
values.
2. Code:
#include <stdio.h>
#include <stdint.h>
void encrypt_array(uint16_t arr[], int size, uint16_t key, int rol_amt, int ror_amt) {
for (int i = 0; i < size; i++) {
for (int r = 0; r < 3; r++) {
arx_round(&arr[i], key, rol_amt, ror_amt);
}
}
}
int main() {
uint16_t plaintext[] = {0x1234, 0x5678, 0x9ABC, 0xDEF0};
uint16_t key = 0x1A2B;
int size = 4;
int rol_amt = 3;
int ror_amt = 2;
printf("Original Array:\n");
for (int i = 0; i < size; i++) {
printf("0x%04X ", plaintext[i]);
}
printf("\nEncrypted Array:\n");
for (int i = 0; i < size; i++) {
printf("0x%04X ", plaintext[i]);
}
printf("\n");
return 0;
}
3. Input:
plaintext[] = {0x1234, 0x5678, 0x9ABC, 0xDEF0}
key = 0x1A2B, ROL = 3, ROR = 2
4. Output:
Original Array:
0x1234 0x5678 0x9ABC 0xDEF0
Encrypted Array:
0x664B 0x7994 0x1BA6 0x2D80
18.Design a round function that combines ARX with masking.
1. Description:
Perform a round function that includes ROL, ROR, modular addition, and bitwise masking.
2. Code:
#include <stdio.h>
#include <stdint.h>
int main() {
uint16_t X = 0x5A5A;
uint16_t Y = 0xA5A5;
uint16_t mask = 0x0F0F;
3. Input:
X = 0x5A5A
Y = 0xA5A5
Mask = 0x0F0F
4. Output:
Result = 0xF0F0
19.Create a menu-driven ARX tool.
1. Description:
Create a menu-driven program to perform ARX-related operations (ROL, ROR, Add, Full ARX)
using user inputs and switch-case.
2. Code:
#include <stdio.h>
#include <stdint.h>
void menu() {
printf("\nARX TOOL MENU:\n");
printf("1. Rotate Left (ROL)\n");
printf("2. Rotate Right (ROR)\n");
printf("3. Modular Addition\n");
printf("4. Full ARX Round\n");
printf("Enter your choice: ");
}
int main() {
uint16_t X, Y, result;
int choice, shift;
menu();
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter shift for ROL: ");
scanf("%d", &shift);
result = rol(X, shift);
printf("ROL Result: 0x%04X\n", result);
break;
case 2:
printf("Enter shift for ROR: ");
scanf("%d", &shift);
result = ror(X, shift);
printf("ROR Result: 0x%04X\n", result);
break;
case 3:
result = (X + Y) & 0xFFFF;
printf("Addition Result: 0x%04X\n", result);
break;
case 4:
printf("Enter ROL shift: ");
int rol_shift, ror_shift;
scanf("%d", &rol_shift);
printf("Enter ROR shift: ");
scanf("%d", &ror_shift);
result = (rol((X + Y) & 0xFFFF, rol_shift)) ^ Y;
result = ror(result, ror_shift);
printf("ARX Result: 0x%04X\n", result);
break;
default:
printf("Invalid choice!\n");
}
return 0;
}
3. Input:
Enter value of X (hex): 0x1234
Enter value of Y (hex): 0x5678
ARX TOOL MENU:
1. Rotate Left (ROL)
2. Rotate Right (ROR)
3. Modular Addition
4. Full ARX Round
Enter your choice: 4
Enter ROL shift: 3
Enter ROR shift: 2
4. Output:
ARX Result: 0xC4C6
20. Perform differential analysis of ARX.
1. Description:
Analyze how a 1-bit difference in inputs affects the ARX output by comparing two input pairs.
2. Code:
#include <stdio.h>
#include <stdint.h>
int main() {
uint16_t X1 = 0xAAAA, Y1 = 0x5555;
uint16_t X2 = X1 ^ 0x0001;
uint16_t Y2 = Y1 ^ 0x0001;
return 0;
}
3. Input:
X1 = 0xAAAA, Y1 = 0x5555
X2 = 0xAAAA ^ 0x0001 = 0xAAAB
Y2 = 0x5555 ^ 0x0001 = 0x5554
ROL = 5, ROR = 3
4. Output:
ARX(X1, Y1) = 0x5555
ARX(X2, Y2) = 0x7555
Difference = 0x2000