encrypt.c 6.33 KB
Newer Older
lwc-tester committed
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
#include "api.h"

typedef unsigned char u8;
typedef unsigned long long u64;
typedef long long i64;

static const u8 constant7[127] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x41,
		0x03, 0x06, 0x0c, 0x18, 0x30, 0x61, 0x42, 0x05, 0x0a, 0x14, 0x28, 0x51,
		0x23, 0x47, 0x0f, 0x1e, 0x3c, 0x79, 0x72, 0x64, 0x48, 0x11, 0x22, 0x45,
		0x0b, 0x16, 0x2c, 0x59, 0x33, 0x67, 0x4e, 0x1d, 0x3a, 0x75, 0x6a, 0x54,
		0x29, 0x53, 0x27, 0x4f, 0x1f, 0x3e, 0x7d, 0x7a, 0x74, 0x68, 0x50, 0x21,
		0x43, 0x07, 0x0e, 0x1c, 0x38, 0x71, 0x62, 0x44, 0x09, 0x12, 0x24, 0x49,
		0x13, 0x26, 0x4d, 0x1b, 0x36, 0x6d, 0x5a, 0x35, 0x6b, 0x56, 0x2d, 0x5b,
		0x37, 0x6f, 0x5e, 0x3d, 0x7b, 0x76, 0x6c, 0x58, 0x31, 0x63, 0x46, 0x0d,
		0x1a, 0x34, 0x69, 0x52, 0x25, 0x4b, 0x17, 0x2e, 0x5d, 0x3b, 0x77, 0x6e,
		0x5c, 0x39, 0x73, 0x66, 0x4c, 0x19, 0x32, 0x65, 0x4a, 0x15, 0x2a, 0x55,
		0x2b, 0x57, 0x2f, 0x5f, 0x3f, 0x7f, 0x7e, 0x7c, 0x78, 0x70, 0x60, 0x40 };
#define sbox(a, b, c, d, e, f, g, h)                                                                            \
{                                                                                                                             \
	t1 = ~a; t2 = b & t1;t3 = c ^ t2; h = d ^ t3; t5 = b | c; t6 = d ^ t1; g = t5 ^ t6; t8 = b ^ d; t9 = t3 & t6; e = t8 ^ t9; t11 = g & t8; f = t3 ^ t11; \
}

#define ARR_SIZE(a) (sizeof((a))/sizeof((a[0])))
#define LOTR1281(a,b,n) (((a)<<(n))|((b)>>(64-n)))
#define LOTR1282(a,b,n) (((b)<<(n))|((a)>>(64-n)))

lwc-tester committed
27 28 29 30 31 32 33 34 35
#define EXT_BYTE(x,n) ((u8)((u64)(x)>>(8*(n))))
#define INS_BYTE(x,n) ((u64)(x)<<(8*(n)))
#define U64BIG(x) (x)

#define RATE (128 / 8)
#define PR0_ROUNDS 100
#define PR_ROUNDS 52
#define PRF_ROUNDS 56

lwc-tester committed
36
#define ROUND512(i) ({\
lwc-tester committed
37 38 39 40 41 42 43 44 45 46 47
		x00^=constant7[i];\
		sbox(x00, x10, x20, x30, b00, b10, b20, b30);\
		sbox(x01, x11, x21, x31, b01, b11, b21, b31);\
		x00=b00;\
		x10=LOTR1281(b10,b11,1);\
		x20=LOTR1281(b20,b21,16);\
		x30=LOTR1281(b30,b31,25);\
		x01=b01;\
		x11=LOTR1282(b10,b11,1);\
		x21=LOTR1282(b20,b21,16);\
		x31=LOTR1282(b30,b31,25);\
lwc-tester committed
48 49
})
int crypto_aead_encrypt(unsigned char *c, unsigned long long *clen,
lwc-tester committed
50 51 52 53
	const unsigned char *m, unsigned long long mlen,
	const unsigned char *ad, unsigned long long adlen,
	const unsigned char *nsec, const unsigned char *npub,
	const unsigned char *k) {
lwc-tester committed
54 55 56 57 58 59 60 61

	u64 b01, b11, b21, b31, b00, b10, b20, b30;
	u64 t1, t2, t3, t5, t6, t8, t9, t11;
	u64 x30, x20, x10, x00, x31, x21, x11, x01;

	u64 rlen, i;

	// initialization
lwc-tester committed
62 63 64 65 66 67 68 69
	x00 = U64BIG(((u64*)npub)[0]);
	x01 = U64BIG(((u64*)npub)[1]);
	x10 = U64BIG(((u64*)npub)[2]);
	x11 = U64BIG(((u64*)npub)[3]);
	x20 = U64BIG(((u64*)k)[0]);
	x21 = U64BIG(((u64*)k)[1]);
	x30 = U64BIG(((u64*)k)[2]);
	x31 = U64BIG(((u64*)k)[3]);
lwc-tester committed
70 71 72 73 74 75 76 77

	for (i = 0; i < PR0_ROUNDS; i++) {
		ROUND512(i);
	}
	// process associated data
	if (adlen) {
		rlen = adlen;
		while (rlen >= RATE) {
lwc-tester committed
78 79
			x00 ^= U64BIG(((u64*)ad)[0]);
			x01 ^= U64BIG(((u64*)ad)[1]);
lwc-tester committed
80 81 82 83 84 85 86 87 88 89 90 91
			for (i = 0; i < PR_ROUNDS; i++) {
				ROUND512(i);
			}
			rlen -= RATE;
			ad += RATE;
		}
		for (i = 0; i < rlen; ++i, ++ad)
			if (i < 8)
				x00 ^= INS_BYTE(*ad, i);
			else
				x01 ^= INS_BYTE(*ad, i - 8);
		if (rlen < 8)
lwc-tester committed
92
			x00 ^= INS_BYTE(0x01, rlen);
lwc-tester committed
93
		else
lwc-tester committed
94
			x01 ^= INS_BYTE(0x01, (rlen - 8));
lwc-tester committed
95 96 97 98 99

		for (i = 0; i < PR_ROUNDS; i++) {
			ROUND512(i);
		}
	}
lwc-tester committed
100 101
	x31 ^= 0x8000000000000000;

lwc-tester committed
102 103 104 105
	// process plaintext
	rlen = mlen;
	if (rlen) {
		while (rlen >= RATE) {
lwc-tester committed
106 107 108 109
			x00 ^= U64BIG(((u64*)m)[0]);
			x01 ^= U64BIG(((u64*)m)[1]);
			((u64*)c)[0] = U64BIG(x00);
			((u64*)c)[1] = U64BIG(x01);
lwc-tester committed
110 111 112 113 114 115 116 117 118 119 120 121 122 123

			for (i = 0; i < PR_ROUNDS; i++) {
				ROUND512(i);
			}
			rlen -= RATE;
			m += RATE;
			c += RATE;
		}

		for (i = 0; i < rlen; ++i, ++m, ++c) {
			if (i < 8) {
				x00 ^= INS_BYTE(*m, i);
				*c = EXT_BYTE(x00, i);

lwc-tester committed
124 125
			}
			else {
lwc-tester committed
126
				x01 ^= INS_BYTE(*m, i - 8);
lwc-tester committed
127
				*c = EXT_BYTE(x01, i - 8);
lwc-tester committed
128 129 130 131

			}
		}
		if (rlen < 8)
lwc-tester committed
132
			x00 ^= INS_BYTE(0x01, rlen);
lwc-tester committed
133
		else
lwc-tester committed
134 135
			x01 ^= INS_BYTE(0x01, (rlen - 8));

lwc-tester committed
136 137 138 139 140 141
	}
	// finalization
	for (i = 0; i < PRF_ROUNDS; i++) {
		ROUND512(i);
	}
	// return tag
lwc-tester committed
142 143 144 145
	((u64*)c)[0] = U64BIG(x00);
	((u64*)c)[1] = U64BIG(x01);
	((u64*)c)[2] = U64BIG(x10);
	((u64*)c)[3] = U64BIG(x11);
lwc-tester committed
146 147 148 149 150
	*clen = mlen + CRYPTO_KEYBYTES;
	return 0;
}

int crypto_aead_decrypt(unsigned char *m, unsigned long long *mlen,
lwc-tester committed
151 152 153
	unsigned char *nsec, const unsigned char *c, unsigned long long clen,
	const unsigned char *ad, unsigned long long adlen,
	const unsigned char *npub, const unsigned char *k) {
lwc-tester committed
154 155 156 157 158 159 160 161 162 163

	*mlen = 0;
	if (clen < CRYPTO_KEYBYTES)
		return -1;
	u64 rlen, i;

	u64 b01, b11, b21, b31, b00, b10, b20, b30;
	u64 t1, t2, t3, t5, t6, t8, t9, t11;
	u64 x30, x20, x10, x00, x31, x21, x11, x01;
	// initialization
lwc-tester committed
164 165 166 167 168 169 170 171
	x00 = U64BIG(((u64*)npub)[0]);
	x01 = U64BIG(((u64*)npub)[1]);
	x10 = U64BIG(((u64*)npub)[2]);
	x11 = U64BIG(((u64*)npub)[3]);
	x20 = U64BIG(((u64*)k)[0]);
	x21 = U64BIG(((u64*)k)[1]);
	x30 = U64BIG(((u64*)k)[2]);
	x31 = U64BIG(((u64*)k)[3]);
lwc-tester committed
172 173 174 175 176 177 178 179

	for (i = 0; i < PR0_ROUNDS; i++) {
		ROUND512(i);
	}
	// process associated data
	if (adlen) {
		rlen = adlen;
		while (rlen >= RATE) {
lwc-tester committed
180 181
			x00 ^= U64BIG(((u64*)ad)[0]);
			x01 ^= U64BIG(((u64*)ad)[1]);
lwc-tester committed
182 183 184 185 186 187 188 189 190 191 192 193
			for (i = 0; i < PR_ROUNDS; i++) {
				ROUND512(i);
			}
			rlen -= RATE;
			ad += RATE;
		}
		for (i = 0; i < rlen; ++i, ++ad)
			if (i < 8)
				x00 ^= INS_BYTE(*ad, i);
			else
				x01 ^= INS_BYTE(*ad, i - 8);
		if (rlen < 8)
lwc-tester committed
194
			x00 ^= INS_BYTE(0x01, rlen);
lwc-tester committed
195
		else
lwc-tester committed
196
			x01 ^= INS_BYTE(0x01, (rlen - 8));
lwc-tester committed
197 198 199 200 201

		for (i = 0; i < PR_ROUNDS; i++) {
			ROUND512(i);
		}
	}
lwc-tester committed
202
	x31 ^= 0x8000000000000000;
lwc-tester committed
203 204 205 206
	// process plaintext
	rlen = clen - CRYPTO_KEYBYTES;
	if (rlen) {
		while (rlen >= RATE) {
lwc-tester committed
207 208 209 210
			((u64*)m)[0] = U64BIG(x00) ^ ((u64*)c)[0];
			((u64*)m)[1] = U64BIG(x01) ^ ((u64*)c)[1];
			x00 = U64BIG(((u64*)c)[0]);
			x01 = U64BIG(((u64*)c)[1]);
lwc-tester committed
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226

			for (i = 0; i < PR_ROUNDS; i++) {
				ROUND512(i);
			}
			rlen -= RATE;
			m += RATE;
			c += RATE;
		}

		for (i = 0; i < rlen; ++i, ++m, ++c) {
			if (i < 8) {

				*m = EXT_BYTE(x00, i) ^ *c;
				x00 &= ~INS_BYTE(0xff, i);
				x00 |= INS_BYTE(*c, i);

lwc-tester committed
227 228 229
			}
			else {
				*m = EXT_BYTE(x01, i - 8) ^ *c;
lwc-tester committed
230 231 232 233 234 235
				x01 &= ~INS_BYTE(0xff, i - 8);
				x01 |= INS_BYTE(*c, i - 8);

			}
		}
		if (rlen < 8)
lwc-tester committed
236
			x00 ^= INS_BYTE(0x01, rlen);
lwc-tester committed
237
		else
lwc-tester committed
238
			x01 ^= INS_BYTE(0x01, (rlen - 8));
lwc-tester committed
239 240 241 242 243 244 245 246

	}
	// finalization
	for (i = 0; i < PRF_ROUNDS; i++) {
		ROUND512(i);
	}
	// return -1 if verification fails

lwc-tester committed
247 248
	if (((u64*)c)[0] != U64BIG(x00) || ((u64*)c)[1] != U64BIG(x01)
		|| ((u64*)c)[2] != U64BIG(x10) || ((u64*)c)[3] != U64BIG(x11))
lwc-tester committed
249 250 251 252 253 254
		return -1;
	// return plaintext
	*mlen = clen - CRYPTO_KEYBYTES;
	return 0;
}