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

#define aead_RATE (96 / 8)
#define PR0_ROUNDS 76
#define PR_ROUNDS 40
#define PRF_ROUNDS 44
Zhao Xuefeng committed
7 8 9 10 11 12
void Initialize(u32 *s, const unsigned char *npub, const unsigned char *k) {
	packU96FormatToThreePacket(s, npub);
	packU96FormatToThreePacket(s + 3, npub + 12);
	packU96FormatToThreePacket(s + 6, k);
	packU96FormatToThreePacket(s + 9, k + 12);
	P384(s, constant7Format, PR0_ROUNDS);
KNOT team committed
13 14
}

Zhao Xuefeng committed
15
void ProcessAssocData(u32 *s, const u8* ad, unsigned long long adlen) {
KNOT team committed
16 17 18 19 20 21 22 23 24

	u32 dataFormat[3] = { 0 };
	u8 tempData[12] = { 0 };
	if (adlen) {
		while (adlen >= aead_RATE) {
			packU96FormatToThreePacket(dataFormat, ad);
			s[0] ^= dataFormat[0];
			s[1] ^= dataFormat[1];
			s[2] ^= dataFormat[2];
Zhao Xuefeng committed
25
			P384(s, constant7Format, PR_ROUNDS);
KNOT team committed
26 27 28
			adlen -= aead_RATE;
			ad += aead_RATE;
		}
Zhao Xuefeng committed
29 30
		memset(tempData, 0, sizeof(tempData));	
		memcpy(tempData, ad, adlen * sizeof(unsigned char));
KNOT team committed
31 32 33 34 35
		tempData[adlen] = 0x01;
		packU96FormatToThreePacket(dataFormat, tempData);
		s[0] ^= dataFormat[0];
		s[1] ^= dataFormat[1];
		s[2] ^= dataFormat[2];
Zhao Xuefeng committed
36
		P384(s, constant7Format, PR_ROUNDS);
KNOT team committed
37 38
	}
	s[9] ^= 0x80000000;
Zhao Xuefeng committed
39 40 41 42 43 44

}
void ProcessPlaintext(u32 *s, const u8* m, unsigned long long mlen, unsigned char *c) {

	u32 dataFormat[3] = { 0 };
	u8 tempData[12] = { 0 };
KNOT team committed
45 46 47 48 49 50 51
	if (mlen) {
		while (mlen >= aead_RATE) {
			packU96FormatToThreePacket(dataFormat, m);
			s[0] ^= dataFormat[0];
			s[1] ^= dataFormat[1];
			s[2] ^= dataFormat[2];
			unpackU96FormatToThreePacket(c, s);
Zhao Xuefeng committed
52
			P384(s, constant7Format, PR_ROUNDS);
KNOT team committed
53 54 55 56 57
			mlen -= aead_RATE;
			m += aead_RATE;
			c += aead_RATE;
		}
		memset(tempData, 0, sizeof(tempData));
Zhao Xuefeng committed
58
		memcpy(tempData, m, mlen * sizeof(unsigned char));
KNOT team committed
59 60 61 62 63 64
		tempData[mlen] = 0x01;
		packU96FormatToThreePacket(dataFormat, tempData);
		s[0] ^= dataFormat[0];
		s[1] ^= dataFormat[1];
		s[2] ^= dataFormat[2];
		unpackU96FormatToThreePacket(tempData, s);
Zhao Xuefeng committed
65
		memcpy(c, tempData, mlen * sizeof(unsigned char));
KNOT team committed
66 67
		c += mlen;
	}
Zhao Xuefeng committed
68 69 70 71
}

void Finalize_GenerateTag(u32 *s, unsigned char *c) {
	P384(s, constant7Format, PRF_ROUNDS);
KNOT team committed
72 73
	// return tag
	unpackU96FormatToThreePacket(c, s);
Zhao Xuefeng committed
74 75 76 77 78 79 80 81 82 83 84 85 86 87
	unpackU96FormatToThreePacket(c + 12, s + 3);

}
int Finalize_VerifyTag(u32 *s, const unsigned char *c, unsigned char *m, unsigned long long *mlen) {
	u8 tempU8[32] = { 0 };
	P384(s, constant7Format, PRF_ROUNDS);
	// return tag	
	unpackU96FormatToThreePacket(tempU8, s);
	unpackU96FormatToThreePacket(tempU8 + 12, s + 3);
	if (memcmp((void*)tempU8, (void*)(c), CRYPTO_ABYTES)) {
		memset(m, 0, sizeof(unsigned char) * (*mlen));
		*mlen = 0;
		return -1;
	}
KNOT team committed
88 89
	return 0;
}
Zhao Xuefeng committed
90 91
void ProcessCiphertext(u32 *s, unsigned char *m, const unsigned char *c, unsigned long long clen)
{
KNOT team committed
92 93
	u32 dataFormat[6] = { 0 };
	u32 dataFormat_1[3] = { 0 };
Zhao Xuefeng committed
94
	u8 i,tempU8[48] = { 0 };
KNOT team committed
95 96 97 98 99 100 101 102 103 104
	if (clen) {
		while (clen >= aead_RATE) {
			packU96FormatToThreePacket(dataFormat, c);
			dataFormat_1[0] = s[0] ^ dataFormat[0];
			dataFormat_1[1] = s[1] ^ dataFormat[1];
			dataFormat_1[2] = s[2] ^ dataFormat[2];
			unpackU96FormatToThreePacket(m, dataFormat_1);
			s[0] = dataFormat[0];
			s[1] = dataFormat[1];
			s[2] = dataFormat[2];
Zhao Xuefeng committed
105
			P384(s, constant7Format, PR_ROUNDS);
KNOT team committed
106 107 108 109 110 111 112 113 114 115 116 117 118
			clen -= aead_RATE;
			m += aead_RATE;
			c += aead_RATE;
		}
		unpackU96FormatToThreePacket(tempU8, s);
		for (i = 0; i < clen; ++i, ++m, ++c)
		{
			*m = tempU8[i] ^ *c;
			tempU8[i] = *c;
		}
		tempU8[i] ^= 0x01;
		packU96FormatToThreePacket(s, tempU8);
	}
Zhao Xuefeng committed
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133

}
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[12] = { 0 };
	*clen = mlen + CRYPTO_ABYTES;
	// initialization
	Initialize(s, npub, k);
	// process associated data
	ProcessAssocData(s, ad, adlen);
	ProcessPlaintext(s, m, mlen, c);
	Finalize_GenerateTag(s, c + mlen);
KNOT team committed
134 135
	return 0;
}
Zhao Xuefeng committed
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151

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[12] = { 0 };
	*mlen = clen - CRYPTO_ABYTES;
	if (clen < CRYPTO_ABYTES)
		return -1;
	Initialize(s, npub, k);
	// process associated data
	ProcessAssocData(s, ad, adlen);
	ProcessCiphertext(s, m, c, clen - CRYPTO_ABYTES);
	// finalization	
	return Finalize_VerifyTag(s, c + clen - CRYPTO_KEYBYTES, m, mlen);
}