encrypt.c 4.67 KB
Newer Older
KNOT team committed
1 2 3 4 5 6
#include"auxFormat.h"

#define aead_RATE (128 / 8)
#define PR0_ROUNDS 100
#define PR_ROUNDS 52
#define PRF_ROUNDS 56
Zhao Xuefeng committed
7 8 9 10 11 12
void Initialize(u32 *s, const unsigned char *npub, const unsigned char *k) {
	packU128FormatToFourPacket(s, npub);
	packU128FormatToFourPacket(s + 4, npub + 16);
	packU128FormatToFourPacket(s + 8, k);
	packU128FormatToFourPacket(s + 12, k + 16);
	P512(s, constant7Format_aead, PR0_ROUNDS);
KNOT team committed
13
}
Zhao Xuefeng committed
14
void ProcessAssocData(u32 *s, const u8* ad, unsigned long long adlen) {
KNOT team committed
15
	u32 dataFormat[4] = { 0 };
Zhao Xuefeng committed
16
	u8 tempData[16] = { 0 };
KNOT team committed
17 18 19 20 21 22 23
	if (adlen) {
		while (adlen >= aead_RATE) {
			packU128FormatToFourPacket(dataFormat, ad);
			s[0] ^= dataFormat[0];
			s[1] ^= dataFormat[1];
			s[2] ^= dataFormat[2];
			s[3] ^= dataFormat[3];
Zhao Xuefeng committed
24
			P512(s, constant7Format_aead, PR_ROUNDS);
KNOT team committed
25 26 27 28 29 30 31 32 33 34 35
			adlen -= aead_RATE;
			ad += aead_RATE;
		}
		memset(tempData, 0, sizeof(tempData));
		memcpy(tempData, ad, adlen * sizeof(unsigned char));
		tempData[adlen] = 0x01;
		packU128FormatToFourPacket(dataFormat, tempData);
		s[0] ^= dataFormat[0];
		s[1] ^= dataFormat[1];
		s[2] ^= dataFormat[2];
		s[3] ^= dataFormat[3];
Zhao Xuefeng committed
36
		P512(s, constant7Format_aead, PR_ROUNDS);
KNOT team committed
37 38
	}
	s[15] ^= 0x80000000;
Zhao Xuefeng committed
39 40 41 42 43
}
void ProcessPlaintext(u32 *s, const u8* m, unsigned long long mlen,
		unsigned char *c) {
	u32 dataFormat[4] = { 0 };
	u8 tempData[16] = { 0 };
KNOT team committed
44 45 46 47 48 49 50 51
	if (mlen) {
		while (mlen >= aead_RATE) {
			packU128FormatToFourPacket(dataFormat, m);
			s[0] ^= dataFormat[0];
			s[1] ^= dataFormat[1];
			s[2] ^= dataFormat[2];
			s[3] ^= dataFormat[3];
			unpackU128FormatToFourPacket(c, s);
Zhao Xuefeng committed
52
			P512(s, constant7Format_aead, PR_ROUNDS);
KNOT team committed
53 54 55 56 57 58
			mlen -= aead_RATE;
			m += aead_RATE;
			c += aead_RATE;
		}
		memset(tempData, 0, sizeof(tempData));
		memcpy(tempData, m, mlen * sizeof(unsigned char));
Zhao Xuefeng committed
59
		tempData[mlen] = 0x01;
KNOT team committed
60 61 62 63 64 65 66
		packU128FormatToFourPacket(dataFormat, tempData);
		s[0] ^= dataFormat[0];
		s[1] ^= dataFormat[1];
		s[2] ^= dataFormat[2];
		s[3] ^= dataFormat[3];
		unpackU128FormatToFourPacket(tempData, s);
		memcpy(c, tempData, mlen * sizeof(unsigned char));
Zhao Xuefeng committed
67
		//c += mlen;
KNOT team committed
68
	}
Zhao Xuefeng committed
69 70 71 72
}

void Finalize_GenerateTag(u32 *s, unsigned char *c) {
	P512(s, constant7Format_aead, PRF_ROUNDS);
KNOT team committed
73 74
	// return tag
	unpackU128FormatToFourPacket(c, s);
Zhao Xuefeng committed
75
	unpackU128FormatToFourPacket(c + 16, s + 4);
KNOT team committed
76
}
Zhao Xuefeng committed
77 78 79 80 81 82 83 84 85
int Finalize_VerifyTag(u32 *s, const unsigned char *c, unsigned char *m,
		unsigned long long *mlen) {
	u8 tempU8[32] = { 0 };
	P512(s, constant7Format_aead, PRF_ROUNDS);
	unpackU128FormatToFourPacket(tempU8, s);
	unpackU128FormatToFourPacket(tempU8 + 16, s + 4);
	if (memcmp((void*) tempU8, (void*) (c), CRYPTO_ABYTES)) {
		memset(m, 0, sizeof(unsigned char) * (*mlen));
		*mlen = 0;
KNOT team committed
86 87
		return -1;
	}
Zhao Xuefeng committed
88 89 90 91 92 93 94
	return 0;
}
void ProcessCiphertext(u32 *s, unsigned char *m, const unsigned char *c,
		unsigned long long clen) {
	u32 dataFormat[8] = { 0 };
	u32 dataFormat_1[4] = { 0 };
	u8 i, tempU8[64] = { 0 };
KNOT team committed
95 96
	if (clen) {
		while (clen >= aead_RATE) {
Zhao Xuefeng committed
97 98 99 100 101
			packU128FormatToFourPacket(dataFormat, c);
			dataFormat_1[0] = s[0] ^ dataFormat[0];
			dataFormat_1[1] = s[1] ^ dataFormat[1];
			dataFormat_1[2] = s[2] ^ dataFormat[2];
			dataFormat_1[3] = s[3] ^ dataFormat[3];
KNOT team committed
102
			unpackU128FormatToFourPacket(m, dataFormat_1);
Zhao Xuefeng committed
103 104 105 106 107
			s[0] = dataFormat[0];
			s[1] = dataFormat[1];
			s[2] = dataFormat[2];
			s[3] = dataFormat[3];
			P512(s, constant7Format_aead, PR_ROUNDS);
KNOT team committed
108 109 110 111 112
			clen -= aead_RATE;
			m += aead_RATE;
			c += aead_RATE;
		}
		unpackU128FormatToFourPacket(tempU8, s);
Zhao Xuefeng committed
113
		for (i = 0; i < clen; ++i, ++m, ++c) {
KNOT team committed
114 115 116 117 118 119
			*m = tempU8[i] ^ *c;
			tempU8[i] = *c;
		}
		tempU8[i] ^= 0x01;
		packU128FormatToFourPacket(s, tempU8);
	}
Zhao Xuefeng committed
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
}

int crypto_aead_encrypt(unsigned char *c, unsigned long long *clen,
		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) {
	u32 s[16] = { 0 };
	*clen = mlen + CRYPTO_ABYTES;
	//initialization
	Initialize(s, npub, k);
	// process associated data

	ProcessAssocData(s, ad, adlen);

	ProcessPlaintext(s, m, mlen, c);

KNOT team committed
137
	// finalization
Zhao Xuefeng committed
138
	Finalize_GenerateTag(s, c + mlen);
KNOT team committed
139
	return 0;
Zhao Xuefeng committed
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
}
int crypto_aead_decrypt(unsigned char *m, unsigned long long *mlen,
		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) {
	u32 s[16] = { 0 };
	if (clen < CRYPTO_ABYTES)
		return -1;
	*mlen = clen - CRYPTO_ABYTES;
	//initialization
	Initialize(s, npub, k);
	ProcessAssocData(s, ad, adlen);
	ProcessCiphertext(s, m, c, clen - CRYPTO_ABYTES);
	// finalization		
	return Finalize_VerifyTag(s, c + clen - CRYPTO_KEYBYTES, m, mlen);
}