encrypt.c 4.95 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
Wentao Zhang committed
7 8 9 10 11 12 13 14 15 16
/*

#define PR0_ROUNDS 76
#define PR_ROUNDS 56
#define PRF_ROUNDS 60

#define PR0_ROUNDS 76
#define PR_ROUNDS 40
#define PRF_ROUNDS 44
 * */
Zhao Xuefeng committed
17 18 19 20 21 22
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
23 24
}

Zhao Xuefeng committed
25
void ProcessAssocData(u32 *s, const u8* ad, unsigned long long adlen) {
KNOT team committed
26 27 28 29 30 31 32 33 34

	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
35
			P384(s, constant7Format, PR_ROUNDS);
KNOT team committed
36 37 38
			adlen -= aead_RATE;
			ad += aead_RATE;
		}
Zhao Xuefeng committed
39 40
		memset(tempData, 0, sizeof(tempData));	
		memcpy(tempData, ad, adlen * sizeof(unsigned char));
KNOT team committed
41 42 43 44 45
		tempData[adlen] = 0x01;
		packU96FormatToThreePacket(dataFormat, tempData);
		s[0] ^= dataFormat[0];
		s[1] ^= dataFormat[1];
		s[2] ^= dataFormat[2];
Zhao Xuefeng committed
46
		P384(s, constant7Format, PR_ROUNDS);
KNOT team committed
47 48
	}
	s[9] ^= 0x80000000;
Zhao Xuefeng committed
49 50 51 52 53 54

}
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
55 56 57 58 59 60 61
	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
62
			P384(s, constant7Format, PR_ROUNDS);
KNOT team committed
63 64 65 66 67
			mlen -= aead_RATE;
			m += aead_RATE;
			c += aead_RATE;
		}
		memset(tempData, 0, sizeof(tempData));
Zhao Xuefeng committed
68
		memcpy(tempData, m, mlen * sizeof(unsigned char));
KNOT team committed
69 70 71 72 73 74
		tempData[mlen] = 0x01;
		packU96FormatToThreePacket(dataFormat, tempData);
		s[0] ^= dataFormat[0];
		s[1] ^= dataFormat[1];
		s[2] ^= dataFormat[2];
		unpackU96FormatToThreePacket(tempData, s);
Zhao Xuefeng committed
75
		memcpy(c, tempData, mlen * sizeof(unsigned char));
KNOT team committed
76 77
		c += mlen;
	}
Zhao Xuefeng committed
78 79 80 81
}

void Finalize_GenerateTag(u32 *s, unsigned char *c) {
	P384(s, constant7Format, PRF_ROUNDS);
KNOT team committed
82 83
	// return tag
	unpackU96FormatToThreePacket(c, s);
Zhao Xuefeng committed
84 85 86 87 88 89 90 91 92 93 94 95 96 97
	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
98 99
	return 0;
}
Zhao Xuefeng committed
100 101
void ProcessCiphertext(u32 *s, unsigned char *m, const unsigned char *c, unsigned long long clen)
{
KNOT team committed
102 103
	u32 dataFormat[6] = { 0 };
	u32 dataFormat_1[3] = { 0 };
Wentao Zhang committed
104
	u8 tempData[48] = { 0 },tempU8[48] = { 0 };
KNOT team committed
105 106 107 108 109 110 111 112 113 114
	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
115
			P384(s, constant7Format, PR_ROUNDS);
KNOT team committed
116 117 118 119 120
			clen -= aead_RATE;
			m += aead_RATE;
			c += aead_RATE;
		}
		unpackU96FormatToThreePacket(tempU8, s);
Wentao Zhang committed
121 122 123 124 125 126 127 128 129
		  memset(tempData, 0, sizeof(tempData));
		  memcpy(tempData, c, clen * sizeof(unsigned char));
		  tempData[clen] = 0x01;
		  U32BIG(((u32*)tempU8)[0]) ^= U32BIG(((u32* )tempData)[0]);
		  U32BIG(((u32*)tempU8)[1]) ^= U32BIG(((u32* )tempData)[1]);
		  U32BIG(((u32*)tempU8)[2]) ^= U32BIG(((u32* )tempData)[2]);
		  memcpy(m, tempU8, clen * sizeof(unsigned char));
		  memcpy(tempU8, tempData, clen * sizeof(unsigned char));
		  c += clen;
KNOT team committed
130 131
		packU96FormatToThreePacket(s, tempU8);
	}
Zhao Xuefeng committed
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146

}
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
147 148
	return 0;
}
Zhao Xuefeng committed
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164

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);
}