File: cryptonite_rc4.c

package info (click to toggle)
haskell-cryptonite 0.20-5
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 2,936 kB
  • ctags: 1,963
  • sloc: ansic: 31,728; haskell: 10,183; makefile: 3
file content (63 lines) | stat: -rw-r--r-- 1,413 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/* initial implementation by
 *   Peter White <peter@janrain.com>
 */

/* C Standard includes */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>

/* Local include */
#include "cryptonite_rc4.h"

/* Swap array elements i=State[i] and b=State[j]. */
static void swap(uint8_t *i, uint8_t *j)
{
	uint8_t temp;

	temp = *i;
	*i = *j;
	*j = temp;
}

/* Key scheduling algorithm. Swap array elements based on the key. */
void cryptonite_rc4_init(uint8_t *key, uint32_t keylen, struct rc4_ctx *ctx)
{
	uint32_t i, j;
	memset(ctx, 0, sizeof(struct rc4_ctx));

	/* initialize context */
	for (i = 0; i < 256; i++)
		ctx->state[i] = i;
	for (i = j = 0; i < 256; i++) {
		j = (j + ctx->state[i] + key[i % keylen]) % 256;
		swap(&ctx->state[i], &ctx->state[j]);
	}
}

/* Combine the stream generated by the rc4 with some input */
void cryptonite_rc4_combine(struct rc4_ctx *ctx, uint8_t *input, uint32_t len, uint8_t *output)
{
	uint32_t i = ctx->i;
	uint32_t j = ctx->j;
	uint32_t m;
	uint8_t si, sj;

	/* The RC4 algorithm */
	for (m = 0; m < len; m++) {
		i = (i + 1) & 0xff;
		si = ctx->state[i];
		j = (j + si) & 0xff;
		sj = ctx->state[j];
		/* swap(&state[i], &state[j]); */
		ctx->state[i] = sj;
		ctx->state[j] = si;
		/* Xor the key stream value into the input */
		*output++ = *input++ ^ (ctx->state[(si + sj) & 0xff]);
	}

	/* Output new S-box indices */
	ctx->i = i;
	ctx->j = j;
}