0% found this document useful (0 votes)
3 views27 pages

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
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)
3 views27 pages

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
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/ 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