openGPMP
Open Source Mathematics Package
rc4.cpp
Go to the documentation of this file.
1 /*************************************************************************
2  *
3  * Project
4  * _____ _____ __ __ _____
5  * / ____| __ \| \/ | __ \
6  * ___ _ __ ___ _ __ | | __| |__) | \ / | |__) |
7  * / _ \| '_ \ / _ \ '_ \| | |_ | ___/| |\/| | ___/
8  *| (_) | |_) | __/ | | | |__| | | | | | | |
9  * \___/| .__/ \___|_| |_|\_____|_| |_| |_|_|
10  * | |
11  * |_|
12  *
13  * Copyright (C) Akiel Aries, <akiel@akiel.org>, et al.
14  *
15  * This software is licensed as described in the file LICENSE, which
16  * you should have received as part of this distribution. The terms
17  * among other details are referenced in the official documentation
18  * seen here : https://akielaries.github.io/openGPMP/ along with
19  * important files seen in this project.
20  *
21  * You may opt to use, copy, modify, merge, publish, distribute
22  * and/or sell copies of the Software, and permit persons to whom
23  * the Software is furnished to do so, under the terms of the
24  * LICENSE file. As this is an Open Source effort, all implementations
25  * must be of the same methodology.
26  *
27  *
28  *
29  * This software is distributed on an AS IS basis, WITHOUT
30  * WARRANTY OF ANY KIND, either express or implied.
31  *
32  ************************************************************************/
33 
34 /*
35  * This file shows the implementation of the Rivest Cipher 4 (RC4)
36  * encryption algorithm created by Ron Rivest using either a
37  * traditional swap method or with the XOR operator
38  */
39 #include <cmath>
40 #include <cstdlib>
41 #include <iostream>
42 #include <openGPMP/nt/rc4.hpp>
43 #include <sstream>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <string>
48 
49 void gpmp::RC4::byte_swap(uint8_t *a, uint8_t *b) {
50  uint8_t swapped = *a;
51  swapped = *a;
52  *a = *b;
53  *b = swapped;
54 }
55 
56 void gpmp::RC4::trad_swap(unsigned char *a, unsigned char *b) {
57  int swapped = *a;
58  *a = *b;
59  *b = swapped;
60 }
61 
62 void gpmp::RC4::XOR_swap(unsigned char *a, unsigned char *b) {
63  *a ^= *b;
64  *b ^= *a;
65  *a ^= *b;
66 }
67 
68 void gpmp::RC4::KSA(char *key, unsigned char *S, int swap_type) {
69  uint32_t len = strlen(key);
70  int j = 0;
71 
72  for (int i = 0; i < BYTE_LIMIT; i++) {
73  S[i] = i;
74  }
75 
76  for (int i = 0; i < BYTE_LIMIT; i++) {
77  j = (j + S[i] + key[i % len]) & BITS;
78 
79  // choose swap algorithm based off swap_type
80  if (swap_type == 0) {
81  XOR_swap(&S[i], &S[j]);
82  } else if (swap_type == 1) {
83  trad_swap(&S[i], &S[j]);
84  } else if (swap_type == 2) {
85  byte_swap(&S[i], &S[j]);
86  }
87  }
88 }
89 
90 void gpmp::RC4::PRGA(unsigned char *S,
91  char *plaintext,
92  unsigned char *ciphertext,
93  int swap_type) {
94  int i = 0;
95  int j = 0;
96 
97  for (size_t n = 0, len = strlen(plaintext); n < len; n++) {
98  i = (i + 1) & BITS;
99  j = (j + S[i]) & BITS;
100 
101  // choose swap algorithm based off swap_type
102  if (swap_type == 0) {
103  XOR_swap(&S[i], &S[j]);
104  } else if (swap_type == 1) {
105  trad_swap(&S[i], &S[j]);
106  } else if (swap_type == 2) {
107  byte_swap(&S[i], &S[j]);
108  }
109 
110  uint32_t rnd = S[(S[i] + S[j]) & BITS];
111 
112  ciphertext[n] = rnd ^ plaintext[n];
113  }
114 }
115 
116 std::string
117 gpmp::RC4::store_hash(char *plaintext, unsigned char *hashtext, int swap_type) {
118  // length of our plaintext
119  size_t len = strlen((char *)plaintext);
120  // for snprintf declare a buffer
121  char buffer[len + 1];
122  size_t size = sizeof(buffer);
123 
124  // initialize empty string
125  std::string stored_text = "";
126 
127  // traverse the hashtext appending each block to a string
128  for (size_t index = 0; index < len; index++) {
129  if (swap_type == 0) {
130  snprintf(buffer, size, "|x%02hhx|", hashtext[index]);
131  }
132  // to format our hash to a string for future manipulation
133  else {
134  snprintf(buffer, size, "%02hhX", hashtext[index]);
135  }
136  // append the declared string
137  stored_text += std::string(buffer);
138  }
139  return stored_text;
140 }
141 
142 unsigned char *gpmp::RC4::compute(char *key,
143  char *plaintext,
144  unsigned char *ciphertext,
145  int swap_type) {
146  if (ciphertext == NULL) {
147  throw std::runtime_error("[-] Error Allocating Memory");
148  }
149 
150  // check for swap types 1-3
151  if (0 <= swap_type && swap_type <= 2) {
152  unsigned char S[BYTE_LIMIT];
153  KSA(key, S, swap_type);
154  PRGA(S, plaintext, ciphertext, swap_type);
155  }
156 
157  else if (swap_type > 2) {
158  throw std::runtime_error("[-] Invalid swap_type");
159  }
160 
161  return ciphertext;
162 }
void PRGA(unsigned char *S, char *plaintext, unsigned char *ciphertext, int swap_type)
Definition: rc4.cpp:90
std::string store_hash(char *plaintext, unsigned char *hashtext, int swap_type)
Definition: rc4.cpp:117
void XOR_swap(unsigned char *a, unsigned char *b)
Definition: rc4.cpp:62
void byte_swap(uint8_t *a, uint8_t *b)
Definition: rc4.cpp:49
void trad_swap(unsigned char *a, unsigned char *b)
Definition: rc4.cpp:56
unsigned char * compute(char *key, char *plaintext, unsigned char *hashtext, int swap_type)
Definition: rc4.cpp:142
void KSA(char *key, unsigned char *S, int swap_type)
Definition: rc4.cpp:68
#define BITS
Definition: rc4.hpp:62
#define BYTE_LIMIT
Definition: rc4.hpp:63