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

Cns Lab Assignment

The document provides a series of implementations for various cryptographic and data manipulation techniques, including an 8-bit LFSR with XOR feedback, a 4-round Feistel cipher, a P-box simulation, and stream XOR encryption using LFSR-generated keystreams. Each section includes code snippets in C, input parameters, and expected output results. The techniques cover pseudo-random number generation, bit-level permutations, and encryption methods, demonstrating practical applications in cryptography and data processing.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Cns Lab Assignment

The document provides a series of implementations for various cryptographic and data manipulation techniques, including an 8-bit LFSR with XOR feedback, a 4-round Feistel cipher, a P-box simulation, and stream XOR encryption using LFSR-generated keystreams. Each section includes code snippets in C, input parameters, and expected output results. The techniques cover pseudo-random number generation, bit-level permutations, and encryption methods, demonstrating practical applications in cryptography and data processing.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 27

1. Implement a configurable 8-bit LFSR with XOR feedback.

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 lfsr = 0xB2;

int tap_positions[] = {7, 5, 4, 3};

uint8_t sequence[NUM_STATES];

printf("Generated LFSR States:\n");

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

sequence[i] = lfsr;

printf("State %2d: 0x%02X\n", i + 1, lfsr);

uint8_t feedback = 0;

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

feedback ^= (lfsr >> (7 - tap_positions[j])) & 1;

lfsr = (lfsr << 1) | feedback;

bool repeats = false;

for (int i = 0; i < NUM_STATES - 1 && !repeats; i++) {

for (int j = i + 1; j < NUM_STATES; j++) {

if (sequence[i] == sequence[j]) {

repeats = true;

printf("\nSequence repeats: 0x%02X at positions %d and %d\n", sequence[i], i +


1, j + 1);

break;

}
}

if (!repeats) {

printf("\nNo repetitions found in the first %d states.\n", NUM_STATES);

return 0;

3. Input:

Initial state = 0xB2, tap positions = bits 7, 5, 4, 3 (zero-indexed from left)

4. Output:

Generated LFSR States:


State 1: 0xB2
State 2: 0x65
State 3: 0xCA
State 4: 0x95
State 5: 0x2B
State 6: 0x56
State 7: 0xAC
State 8: 0x58
State 9: 0xB0
State 10: 0x61
State 11: 0xC3
State 12: 0x87
State 13: 0x0E
State 14: 0x1C
State 15: 0x39
State 16: 0x73
State 17: 0xE6
State 18: 0xCD
State 19: 0x9B
State 20: 0x37

No repetitions found in the first 20 states.


2. Design a 4-round Feistel cipher using user-defined keys and
permutations.
1. Description:
Implement a 4-round Feistel cipher on an 8-bit plaintext using XOR and a custom
permutation with user-defined 4-bit keys.

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};

uint8_t L = (plaintext >> 4) & 0x0F;


uint8_t R = plaintext & 0x0F;

printf("Initial Plaintext: 0x%02X\n", plaintext);


printf("Initial L: 0x%X, R: 0x%X\n", L, R);

for (int round = 0; round < 4; round++) {


uint8_t temp = R;
uint8_t f_out = feistel_function(R, keys[round], perm);
R = L ^ (f_out & 0x0F);
L = temp;

printf("After Round %d: L = 0x%X, R = 0x%X\n", round + 1, L, R);


}

uint8_t ciphertext = (L << 4) | (R & 0x0F);


printf("Final Ciphertext: 0x%02X\n", ciphertext);
return 0;
}
3. Input:
Plaintext = 8 bits, Keys = {0x3, 0x5, 0x7, 0x2}, Permutation = [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>

uint8_t apply_pbox(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;
}

void print_binary(uint8_t byte) {


for (int i = 7; i >= 0; i--) {
printf("%d", (byte >> i) & 1);
}
}

int main() {
uint8_t input = 0b10110100;
int permutation[8] = {7, 6, 0, 2, 5, 4, 3, 1};

printf("Original Input: ");


print_binary(input);
printf("\n");

uint8_t output = apply_pbox(input, permutation);

printf("Permuted Output: ");


print_binary(output);
printf("\n");

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];

uint8_t permuted = apply_permutation(input, perm);

generate_inverse(perm, inverse_perm);
uint8_t restored = apply_permutation(permuted, inverse_perm);

printf("Original Input: ");


print_binary4(input);
printf("\n");

printf("After Permutation:");
print_binary4(permuted);
printf("\n");

printf("After Inverse: ");


print_binary4(restored);
printf("\n");
}
3. Input:
Input: 0b1101
Permutation: [3, 0, 2, 1]

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];

printf("Generated Pseudo-random Bytes:\n");

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


uint8_t byte = 0;

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


uint8_t feedback = 0;
for (int t = 0; t < 2; t++) {
feedback ^= (lfsr >> (7 - taps[t])) & 1;
}

lfsr = (lfsr << 1) | feedback;


byte = (byte << 1) | (lfsr & 1);
}

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:

Generated Pseudo-random Bytes:


0xA7 0x4E 0x9D 0x3A 0x74 0xE9 0xD3 0xA7 0x4E 0x9D
6. Stream XOR Encryption Using LFSR Keystream
1. Description:
Encrypt a plaintext using stream cipher logic with an LFSR-generated keystream and XOR
operation.
2. Code:
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#define TAP1 7
#define TAP2 5

uint8_t next_lfsr_byte(uint8_t *lfsr) {


uint8_t byte = 0;
for (int i = 0; i < 8; i++) {
uint8_t bit = (((*lfsr >> (7 - TAP1)) & 1) ^ ((*lfsr >> (7 - TAP2)) & 1));
*lfsr = ((*lfsr << 1) | bit);
byte = (byte << 1) | (bit & 1);
}
return byte;
}

int main() {
char plaintext[] = "CRYPTO";
uint8_t ciphertext[sizeof(plaintext)];
uint8_t lfsr = 0xE7;

printf("Plaintext: %s\n", plaintext);


printf("Encrypted (Hex): ");

for (int i = 0; i < strlen(plaintext); i++) {


uint8_t keystream = next_lfsr_byte(&lfsr);
ciphertext[i] = plaintext[i] ^ keystream;
printf("0x%02X ", ciphertext[i]);
}

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;

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


nibbles[i] = (word >> ((3 - i) * 4)) & 0xF;
}

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


result |= ((nibbles[perm[i]] & 0xF) << ((3 - i) * 4));
}

printf("Original Word: 0x%04X\n", word);


printf("Permuted Word: 0x%04X\n", result);

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>

uint8_t next_lfsr_bit(uint8_t *lfsr, int tap1, int tap2) {


uint8_t bit = ((*lfsr >> (7 - tap1)) & 1) ^ ((*lfsr >> (7 - tap2)) & 1);
*lfsr = (*lfsr << 1) | bit;
return *lfsr & 1;
}

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("Keystream (16 bits): ");

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


uint8_t bit1 = next_lfsr_bit(&lfsr1, tap1_1, tap1_2);
uint8_t bit2 = next_lfsr_bit(&lfsr2, tap2_1, tap2_2);
uint8_t xor_bit = bit1 ^ bit2;
keystream = (keystream << 1) | xor_bit;
printf("%d", xor_bit);
}

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

void print_matrix(uint8_t matrix[SIZE][SIZE]) {


for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
printf("%02X ", matrix[i][j]);
}
printf("\n");
}
}

int main() {
uint8_t matrix[SIZE][SIZE] = {
{0x11, 0x12, 0x13, 0x14},
{0x21, 0x22, 0x23, 0x24},
{0x31, 0x32, 0x33, 0x34},
{0x41, 0x42, 0x43, 0x44}
};

int row_perm[SIZE] = {2, 0, 3, 1};


uint8_t permuted[SIZE][SIZE];

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


for (int j = 0; j < SIZE; j++) {
permuted[i][j] = matrix[row_perm[i]][j];
}
}

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};

int len = strlen(plaintext);


strcpy(encrypted, plaintext);

printf("Plaintext: %s\n", plaintext);

for (int i = 0; i < len; i += BLOCK_SIZE) {


char temp[BLOCK_SIZE];
for (int j = 0; j < BLOCK_SIZE; j++) {
if (i + block_perm[j] < len) {
temp[j] = plaintext[i + block_perm[j]];
} else {
temp[j] = '\0';
}
}
for (int j = 0; j < BLOCK_SIZE; j++) {
if (i + j < len) {
encrypted[i + j] = temp[j];
}
}
}

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>

uint16_t rol(uint16_t x, int n) {


return (x << n) | (x >> (16 - n));
}

uint16_t ror(uint16_t x, int n) {


return (x >> n) | (x << (16 - n));
}

int main() {
uint16_t x = 0x1234;
int n = 4;

uint16_t rotated_left = rol(x, n);


uint16_t rotated_back = ror(rotated_left, n);

printf("Original : 0x%04X\n", x);


printf("ROL(%d) : 0x%04X\n", n, rotated_left);
printf("ROR(%d) : 0x%04X\n", n, rotated_back);

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

void modular_addition(uint16_t A[], uint16_t B[], uint16_t result[]) {


for (int i = 0; i < SIZE; i++) {
result[i] = (A[i] + B[i]) & 0xFFFF; // modulo 2^16
}
}

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);

printf("Modular Addition Results:\n");


for (int i = 0; i < SIZE; i++) {
printf("A[%d] + B[%d] mod 2^16 = 0x%04X\n", i, i, result[i]);
}

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>

uint16_t rol(uint16_t x, int n) {


return (x << n) | (x >> (16 - n));
}

uint16_t ror(uint16_t x, int n) {


return (x >> n) | (x << (16 - n));
}

int main() {
uint16_t X = 0x1357;
uint16_t Y = 0x2468;
int ROL_amt = 7;
int ROR_amt = 3;

printf("Initial Values: 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 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

uint16_t rol(uint16_t x, int n) {


return (x << n) | (x >> (16 - n));
}

uint16_t ror(uint16_t x, int n) {


return (x >> n) | (x << (16 - n));
}

void arx_round(uint16_t *X, uint16_t *Y) {


*X = (*X + *Y) & 0xFFFF;
*X = rol(*X, ROL_AMOUNT);
*Y ^= *X;
*Y = ror(*Y, ROR_AMOUNT);
}

int main() {
uint16_t X = 0xAAAA;
uint16_t Y = 0xBBBB;
uint16_t K1 = 0x1111;
uint16_t K2 = 0x2222;

printf("Initial: X = 0x%04X, Y = 0x%04X\n", X, Y);

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));
}

uint32_t ror32(uint32_t x, int n) {


return (x >> n) | (x << (32 - n));
}

void arx32(uint32_t *X, uint32_t *Y, int rol_amt, int ror_amt) {


*X = (*X + *Y);
*X = rol32(*X, rol_amt);
*Y = *Y ^ *X;
*Y = ror32(*Y, ror_amt);
}
int main() {
uint32_t X = 0xCAFEBABE;
uint32_t Y = 0xDEADBEEF;
int rol_amt = 10;
int ror_amt = 8;

printf("Initial: X = 0x%08X, Y = 0x%08X\n", X, Y);

arx32(&X, &Y, rol_amt, ror_amt);

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>

uint32_t rol32(uint32_t x, int n) {


return (x << n) | (x >> (32 - n));
}

uint32_t ror32(uint32_t x, int n) {


return (x >> n) | (x << (32 - n));
}

void arx32(uint32_t *X, uint32_t *Y, int rol_amt, int ror_amt) {


*X = (*X + *Y);
*X = rol32(*X, rol_amt);
*Y = *Y ^ *X;
*Y = ror32(*Y, ror_amt);
}

int main() {
uint32_t X = 0xCAFEBABE;
uint32_t Y = 0xDEADBEEF;
int rol_amt = 10;
int ror_amt = 8;

printf("Initial: X = 0x%08X, Y = 0x%08X\n", X, Y);

arx32(&X, &Y, rol_amt, ror_amt);

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>

#define ROL(x, n) (((x) << (n)) | ((x) >> (16 - (n))))


#define ROR(x, n) (((x) >> (n)) | ((x) << (16 - (n))))

void arx_round(uint16_t *x, uint16_t key, int rol_amt, int ror_amt) {


*x = (*x + key) & 0xFFFF;
*x = ROL(*x, rol_amt);
*x ^= key;
*x = ROR(*x, ror_amt);
}

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]);
}

encrypt_array(plaintext, size, key, rol_amt, ror_amt);

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>

uint16_t rol(uint16_t x, int n) {


return (x << n) | (x >> (16 - n));
}

uint16_t ror(uint16_t x, int n) {


return (x >> n) | (x << (16 - n));
}

uint16_t round_function(uint16_t X, uint16_t Y, uint16_t mask) {


uint16_t a = rol(X, 4);
uint16_t b = ror(Y, 4);
uint16_t result = (a + b) & 0xFFFF;
return result ^ mask;
}

int main() {
uint16_t X = 0x5A5A;
uint16_t Y = 0xA5A5;
uint16_t mask = 0x0F0F;

uint16_t output = round_function(X, Y, mask);

printf("Result = 0x%04X\n", output);


return 0;
}

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>

uint16_t rol(uint16_t x, int n) {


return (x << n) | (x >> (16 - n));
}

uint16_t ror(uint16_t x, int n) {


return (x >> n) | (x << (16 - n));
}

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;

printf("Enter value of X (hex): ");


scanf("%hx", &X);

printf("Enter value of Y (hex): ");


scanf("%hx", &Y);

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>

#define ROL(x, n) (((x) << (n)) | ((x) >> (16 - (n))))


#define ROR(x, n) (((x) >> (n)) | ((x) << (16 - (n))))

uint16_t arx(uint16_t X, uint16_t Y, int rol_amt, int ror_amt) {


uint16_t result = (X + Y) & 0xFFFF;
result = ROL(result, rol_amt);
result ^= Y;
result = ROR(result, ror_amt);
return result;
}

int main() {
uint16_t X1 = 0xAAAA, Y1 = 0x5555;
uint16_t X2 = X1 ^ 0x0001;
uint16_t Y2 = Y1 ^ 0x0001;

int rol_amt = 5, ror_amt = 3;

uint16_t out1 = arx(X1, Y1, rol_amt, ror_amt);


uint16_t out2 = arx(X2, Y2, rol_amt, ror_amt);

printf("ARX(X1, Y1) = 0x%04X\n", out1);


printf("ARX(X2, Y2) = 0x%04X\n", out2);
printf("Difference = 0x%04X\n", out1 ^ out2);

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

You might also like