Browse Source

AES stuff, port sending network credentials to new packet format.

Adam Ierymenko 5 years ago
parent
commit
46d3780e89
7 changed files with 209 additions and 194 deletions
  1. 117 112
      node/AES.cpp
  2. 74 59
      node/Membership.cpp
  3. 0 1
      node/Peer.cpp
  4. 7 11
      node/Protocol.cpp
  5. 4 5
      node/Protocol.hpp
  6. 4 5
      node/SelfAwareness.cpp
  7. 3 1
      node/VL1.cpp

+ 117 - 112
node/AES.cpp

@@ -975,133 +975,138 @@ void AES::_initSW(const uint8_t key[32]) noexcept
 void AES::_encryptSW(const uint8_t in[16],uint8_t out[16]) const noexcept
 void AES::_encryptSW(const uint8_t in[16],uint8_t out[16]) const noexcept
 {
 {
 	const uint32_t *const rk = _k.sw.ek;
 	const uint32_t *const rk = _k.sw.ek;
+	const uint32_t m8 = 0xff;
 	uint32_t s0 = readuint32_t(in) ^ rk[0];
 	uint32_t s0 = readuint32_t(in) ^ rk[0];
 	uint32_t s1 = readuint32_t(in + 4) ^ rk[1];
 	uint32_t s1 = readuint32_t(in + 4) ^ rk[1];
 	uint32_t s2 = readuint32_t(in + 8) ^ rk[2];
 	uint32_t s2 = readuint32_t(in + 8) ^ rk[2];
 	uint32_t s3 = readuint32_t(in + 12) ^ rk[3];
 	uint32_t s3 = readuint32_t(in + 12) ^ rk[3];
-	uint32_t t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[4];
-	uint32_t t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[5];
-	uint32_t t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[6];
-	uint32_t t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[7];
-	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[8];
-	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[9];
-	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
-	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
-	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
-	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
-	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
-	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
-	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
-	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
-	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
-	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
-	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
-	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
-	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
-	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
-	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
-	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
-	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
-	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
-	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
-	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
-	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
-	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
-	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
-	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
-	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
-	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
-	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
-	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
-	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
-	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
-	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
-	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
-	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
-	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
-	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
-	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
-	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
-	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
-	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
-	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
-	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
-	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
-	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
-	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
-	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
-	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
-	writeuint32_t(out,(Te2[(t0 >> 24)] & 0xff000000) ^ (Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t3) & 0xff] & 0x000000ff) ^ rk[56]);
-	writeuint32_t(out + 4,(Te2[(t1 >> 24)] & 0xff000000) ^ (Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t0) & 0xff] & 0x000000ff) ^ rk[57]);
-	writeuint32_t(out + 8,(Te2[(t2 >> 24)] & 0xff000000) ^ (Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t1) & 0xff] & 0x000000ff) ^ rk[58]);
-	writeuint32_t(out + 12,(Te2[(t3 >> 24)] & 0xff000000) ^ (Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^ (Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (Te1[(t2) & 0xff] & 0x000000ff) ^ rk[59]);
+	uint32_t t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & m8] ^ Te2[(s2 >> 8) & m8] ^ Te3[s3 & m8] ^ rk[4];
+	uint32_t t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & m8] ^ Te2[(s3 >> 8) & m8] ^ Te3[s0 & m8] ^ rk[5];
+	uint32_t t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & m8] ^ Te2[(s0 >> 8) & m8] ^ Te3[s1 & m8] ^ rk[6];
+	uint32_t t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & m8] ^ Te2[(s1 >> 8) & m8] ^ Te3[s2 & m8] ^ rk[7];
+	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & m8] ^ Te2[(t2 >> 8) & m8] ^ Te3[t3 & m8] ^ rk[8];
+	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & m8] ^ Te2[(t3 >> 8) & m8] ^ Te3[t0 & m8] ^ rk[9];
+	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & m8] ^ Te2[(t0 >> 8) & m8] ^ Te3[t1 & m8] ^ rk[10];
+	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & m8] ^ Te2[(t1 >> 8) & m8] ^ Te3[t2 & m8] ^ rk[11];
+	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & m8] ^ Te2[(s2 >> 8) & m8] ^ Te3[s3 & m8] ^ rk[12];
+	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & m8] ^ Te2[(s3 >> 8) & m8] ^ Te3[s0 & m8] ^ rk[13];
+	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & m8] ^ Te2[(s0 >> 8) & m8] ^ Te3[s1 & m8] ^ rk[14];
+	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & m8] ^ Te2[(s1 >> 8) & m8] ^ Te3[s2 & m8] ^ rk[15];
+	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & m8] ^ Te2[(t2 >> 8) & m8] ^ Te3[t3 & m8] ^ rk[16];
+	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & m8] ^ Te2[(t3 >> 8) & m8] ^ Te3[t0 & m8] ^ rk[17];
+	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & m8] ^ Te2[(t0 >> 8) & m8] ^ Te3[t1 & m8] ^ rk[18];
+	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & m8] ^ Te2[(t1 >> 8) & m8] ^ Te3[t2 & m8] ^ rk[19];
+	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & m8] ^ Te2[(s2 >> 8) & m8] ^ Te3[s3 & m8] ^ rk[20];
+	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & m8] ^ Te2[(s3 >> 8) & m8] ^ Te3[s0 & m8] ^ rk[21];
+	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & m8] ^ Te2[(s0 >> 8) & m8] ^ Te3[s1 & m8] ^ rk[22];
+	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & m8] ^ Te2[(s1 >> 8) & m8] ^ Te3[s2 & m8] ^ rk[23];
+	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & m8] ^ Te2[(t2 >> 8) & m8] ^ Te3[t3 & m8] ^ rk[24];
+	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & m8] ^ Te2[(t3 >> 8) & m8] ^ Te3[t0 & m8] ^ rk[25];
+	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & m8] ^ Te2[(t0 >> 8) & m8] ^ Te3[t1 & m8] ^ rk[26];
+	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & m8] ^ Te2[(t1 >> 8) & m8] ^ Te3[t2 & m8] ^ rk[27];
+	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & m8] ^ Te2[(s2 >> 8) & m8] ^ Te3[s3 & m8] ^ rk[28];
+	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & m8] ^ Te2[(s3 >> 8) & m8] ^ Te3[s0 & m8] ^ rk[29];
+	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & m8] ^ Te2[(s0 >> 8) & m8] ^ Te3[s1 & m8] ^ rk[30];
+	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & m8] ^ Te2[(s1 >> 8) & m8] ^ Te3[s2 & m8] ^ rk[31];
+	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & m8] ^ Te2[(t2 >> 8) & m8] ^ Te3[t3 & m8] ^ rk[32];
+	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & m8] ^ Te2[(t3 >> 8) & m8] ^ Te3[t0 & m8] ^ rk[33];
+	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & m8] ^ Te2[(t0 >> 8) & m8] ^ Te3[t1 & m8] ^ rk[34];
+	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & m8] ^ Te2[(t1 >> 8) & m8] ^ Te3[t2 & m8] ^ rk[35];
+	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & m8] ^ Te2[(s2 >> 8) & m8] ^ Te3[s3 & m8] ^ rk[36];
+	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & m8] ^ Te2[(s3 >> 8) & m8] ^ Te3[s0 & m8] ^ rk[37];
+	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & m8] ^ Te2[(s0 >> 8) & m8] ^ Te3[s1 & m8] ^ rk[38];
+	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & m8] ^ Te2[(s1 >> 8) & m8] ^ Te3[s2 & m8] ^ rk[39];
+	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & m8] ^ Te2[(t2 >> 8) & m8] ^ Te3[t3 & m8] ^ rk[40];
+	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & m8] ^ Te2[(t3 >> 8) & m8] ^ Te3[t0 & m8] ^ rk[41];
+	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & m8] ^ Te2[(t0 >> 8) & m8] ^ Te3[t1 & m8] ^ rk[42];
+	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & m8] ^ Te2[(t1 >> 8) & m8] ^ Te3[t2 & m8] ^ rk[43];
+	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & m8] ^ Te2[(s2 >> 8) & m8] ^ Te3[s3 & m8] ^ rk[44];
+	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & m8] ^ Te2[(s3 >> 8) & m8] ^ Te3[s0 & m8] ^ rk[45];
+	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & m8] ^ Te2[(s0 >> 8) & m8] ^ Te3[s1 & m8] ^ rk[46];
+	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & m8] ^ Te2[(s1 >> 8) & m8] ^ Te3[s2 & m8] ^ rk[47];
+	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & m8] ^ Te2[(t2 >> 8) & m8] ^ Te3[t3 & m8] ^ rk[48];
+	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & m8] ^ Te2[(t3 >> 8) & m8] ^ Te3[t0 & m8] ^ rk[49];
+	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & m8] ^ Te2[(t0 >> 8) & m8] ^ Te3[t1 & m8] ^ rk[50];
+	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & m8] ^ Te2[(t1 >> 8) & m8] ^ Te3[t2 & m8] ^ rk[51];
+	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & m8] ^ Te2[(s2 >> 8) & m8] ^ Te3[s3 & m8] ^ rk[52];
+	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & m8] ^ Te2[(s3 >> 8) & m8] ^ Te3[s0 & m8] ^ rk[53];
+	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & m8] ^ Te2[(s0 >> 8) & m8] ^ Te3[s1 & m8] ^ rk[54];
+	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & m8] ^ Te2[(s1 >> 8) & m8] ^ Te3[s2 & m8] ^ rk[55];
+	const uint32_t m8_24 = 0xff000000;
+	const uint32_t m8_16 = 0x00ff0000;
+	const uint32_t m8_8 = 0x0000ff00;
+	writeuint32_t(out,(Te2[(t0 >> 24)] & m8_24) ^ (Te3[(t1 >> 16) & m8] & m8_16) ^ (Te0[(t2 >> 8) & m8] & m8_8) ^ (Te1[(t3) & m8] & m8) ^ rk[56]);
+	writeuint32_t(out + 4,(Te2[(t1 >> 24)] & m8_24) ^ (Te3[(t2 >> 16) & m8] & m8_16) ^ (Te0[(t3 >> 8) & m8] & m8_8) ^ (Te1[(t0) & m8] & m8) ^ rk[57]);
+	writeuint32_t(out + 8,(Te2[(t2 >> 24)] & m8_24) ^ (Te3[(t3 >> 16) & m8] & m8_16) ^ (Te0[(t0 >> 8) & m8] & m8_8) ^ (Te1[(t1) & m8] & m8) ^ rk[58]);
+	writeuint32_t(out + 12,(Te2[(t3 >> 24)] & m8_24) ^ (Te3[(t0 >> 16) & m8] & m8_16) ^ (Te0[(t1 >> 8) & m8] & m8_8) ^ (Te1[(t2) & m8] & m8) ^ rk[59]);
 }
 }
 
 
 void AES::_decryptSW(const uint8_t in[16],uint8_t out[16]) const noexcept
 void AES::_decryptSW(const uint8_t in[16],uint8_t out[16]) const noexcept
 {
 {
 	const uint32_t *rk = _k.sw.dk;
 	const uint32_t *rk = _k.sw.dk;
 	uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
 	uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
+	const uint32_t m8 = 0xff;
 	s0 = readuint32_t(in) ^ rk[0];
 	s0 = readuint32_t(in) ^ rk[0];
 	s1 = readuint32_t(in + 4) ^ rk[1];
 	s1 = readuint32_t(in + 4) ^ rk[1];
 	s2 = readuint32_t(in + 8) ^ rk[2];
 	s2 = readuint32_t(in + 8) ^ rk[2];
 	s3 = readuint32_t(in + 12) ^ rk[3];
 	s3 = readuint32_t(in + 12) ^ rk[3];
-	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[4];
-	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[5];
-	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[6];
-	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[7];
-	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[8];
-	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[9];
-	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
-	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
-	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
-	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
-	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
-	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
-	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
-	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
-	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
-	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
-	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
-	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
-	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
-	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
-	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
-	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
-	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
-	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
-	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
-	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
-	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
-	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
-	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
-	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
-	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
-	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
-	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
-	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
-	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
-	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
-	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
-	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
-	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
-	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
-	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
-	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
-	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
-	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
-	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
-	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
-	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
-	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
-	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
-	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
-	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
-	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
+	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & m8] ^ Td2[(s2 >>  8) & m8] ^ Td3[s1 & m8] ^ rk[4];
+	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & m8] ^ Td2[(s3 >>  8) & m8] ^ Td3[s2 & m8] ^ rk[5];
+	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & m8] ^ Td2[(s0 >>  8) & m8] ^ Td3[s3 & m8] ^ rk[6];
+	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & m8] ^ Td2[(s1 >>  8) & m8] ^ Td3[s0 & m8] ^ rk[7];
+	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & m8] ^ Td2[(t2 >>  8) & m8] ^ Td3[t1 & m8] ^ rk[8];
+	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & m8] ^ Td2[(t3 >>  8) & m8] ^ Td3[t2 & m8] ^ rk[9];
+	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & m8] ^ Td2[(t0 >>  8) & m8] ^ Td3[t3 & m8] ^ rk[10];
+	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & m8] ^ Td2[(t1 >>  8) & m8] ^ Td3[t0 & m8] ^ rk[11];
+	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & m8] ^ Td2[(s2 >>  8) & m8] ^ Td3[s1 & m8] ^ rk[12];
+	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & m8] ^ Td2[(s3 >>  8) & m8] ^ Td3[s2 & m8] ^ rk[13];
+	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & m8] ^ Td2[(s0 >>  8) & m8] ^ Td3[s3 & m8] ^ rk[14];
+	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & m8] ^ Td2[(s1 >>  8) & m8] ^ Td3[s0 & m8] ^ rk[15];
+	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & m8] ^ Td2[(t2 >>  8) & m8] ^ Td3[t1 & m8] ^ rk[16];
+	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & m8] ^ Td2[(t3 >>  8) & m8] ^ Td3[t2 & m8] ^ rk[17];
+	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & m8] ^ Td2[(t0 >>  8) & m8] ^ Td3[t3 & m8] ^ rk[18];
+	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & m8] ^ Td2[(t1 >>  8) & m8] ^ Td3[t0 & m8] ^ rk[19];
+	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & m8] ^ Td2[(s2 >>  8) & m8] ^ Td3[s1 & m8] ^ rk[20];
+	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & m8] ^ Td2[(s3 >>  8) & m8] ^ Td3[s2 & m8] ^ rk[21];
+	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & m8] ^ Td2[(s0 >>  8) & m8] ^ Td3[s3 & m8] ^ rk[22];
+	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & m8] ^ Td2[(s1 >>  8) & m8] ^ Td3[s0 & m8] ^ rk[23];
+	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & m8] ^ Td2[(t2 >>  8) & m8] ^ Td3[t1 & m8] ^ rk[24];
+	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & m8] ^ Td2[(t3 >>  8) & m8] ^ Td3[t2 & m8] ^ rk[25];
+	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & m8] ^ Td2[(t0 >>  8) & m8] ^ Td3[t3 & m8] ^ rk[26];
+	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & m8] ^ Td2[(t1 >>  8) & m8] ^ Td3[t0 & m8] ^ rk[27];
+	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & m8] ^ Td2[(s2 >>  8) & m8] ^ Td3[s1 & m8] ^ rk[28];
+	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & m8] ^ Td2[(s3 >>  8) & m8] ^ Td3[s2 & m8] ^ rk[29];
+	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & m8] ^ Td2[(s0 >>  8) & m8] ^ Td3[s3 & m8] ^ rk[30];
+	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & m8] ^ Td2[(s1 >>  8) & m8] ^ Td3[s0 & m8] ^ rk[31];
+	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & m8] ^ Td2[(t2 >>  8) & m8] ^ Td3[t1 & m8] ^ rk[32];
+	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & m8] ^ Td2[(t3 >>  8) & m8] ^ Td3[t2 & m8] ^ rk[33];
+	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & m8] ^ Td2[(t0 >>  8) & m8] ^ Td3[t3 & m8] ^ rk[34];
+	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & m8] ^ Td2[(t1 >>  8) & m8] ^ Td3[t0 & m8] ^ rk[35];
+	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & m8] ^ Td2[(s2 >>  8) & m8] ^ Td3[s1 & m8] ^ rk[36];
+	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & m8] ^ Td2[(s3 >>  8) & m8] ^ Td3[s2 & m8] ^ rk[37];
+	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & m8] ^ Td2[(s0 >>  8) & m8] ^ Td3[s3 & m8] ^ rk[38];
+	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & m8] ^ Td2[(s1 >>  8) & m8] ^ Td3[s0 & m8] ^ rk[39];
+	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & m8] ^ Td2[(t2 >>  8) & m8] ^ Td3[t1 & m8] ^ rk[40];
+	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & m8] ^ Td2[(t3 >>  8) & m8] ^ Td3[t2 & m8] ^ rk[41];
+	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & m8] ^ Td2[(t0 >>  8) & m8] ^ Td3[t3 & m8] ^ rk[42];
+	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & m8] ^ Td2[(t1 >>  8) & m8] ^ Td3[t0 & m8] ^ rk[43];
+	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & m8] ^ Td2[(s2 >>  8) & m8] ^ Td3[s1 & m8] ^ rk[44];
+	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & m8] ^ Td2[(s3 >>  8) & m8] ^ Td3[s2 & m8] ^ rk[45];
+	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & m8] ^ Td2[(s0 >>  8) & m8] ^ Td3[s3 & m8] ^ rk[46];
+	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & m8] ^ Td2[(s1 >>  8) & m8] ^ Td3[s0 & m8] ^ rk[47];
+	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & m8] ^ Td2[(t2 >>  8) & m8] ^ Td3[t1 & m8] ^ rk[48];
+	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & m8] ^ Td2[(t3 >>  8) & m8] ^ Td3[t2 & m8] ^ rk[49];
+	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & m8] ^ Td2[(t0 >>  8) & m8] ^ Td3[t3 & m8] ^ rk[50];
+	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & m8] ^ Td2[(t1 >>  8) & m8] ^ Td3[t0 & m8] ^ rk[51];
+	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & m8] ^ Td2[(s2 >>  8) & m8] ^ Td3[s1 & m8] ^ rk[52];
+	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & m8] ^ Td2[(s3 >>  8) & m8] ^ Td3[s2 & m8] ^ rk[53];
+	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & m8] ^ Td2[(s0 >>  8) & m8] ^ Td3[s3 & m8] ^ rk[54];
+	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & m8] ^ Td2[(s1 >>  8) & m8] ^ Td3[s0 & m8] ^ rk[55];
 	rk += 56;
 	rk += 56;
-	writeuint32_t(out,(Td4[(t0 >> 24)] << 24) ^ (Td4[(t3 >> 16) & 0xff] << 16) ^ (Td4[(t2 >> 8) & 0xff] << 8) ^ (Td4[(t1) & 0xff]) ^ rk[0]);
-	writeuint32_t(out + 4,(Td4[(t1 >> 24)] << 24) ^ (Td4[(t0 >> 16) & 0xff] << 16) ^ (Td4[(t3 >> 8) & 0xff] << 8) ^ (Td4[(t2) & 0xff]) ^ rk[1]);
-	writeuint32_t(out + 8,(Td4[(t2 >> 24)] << 24) ^ (Td4[(t1 >> 16) & 0xff] << 16) ^ (Td4[(t0 >> 8) & 0xff] << 8) ^ (Td4[(t3) & 0xff]) ^ rk[2]);
-	writeuint32_t(out + 12,(Td4[(t3 >> 24)] << 24) ^ (Td4[(t2 >> 16) & 0xff] << 16) ^ (Td4[(t1 >> 8) & 0xff] << 8) ^ (Td4[(t0) & 0xff]) ^ rk[3]);
+	writeuint32_t(out,(Td4[(t0 >> 24)] << 24) ^ (Td4[(t3 >> 16) & m8] << 16) ^ (Td4[(t2 >> 8) & m8] << 8) ^ (Td4[(t1) & m8]) ^ rk[0]);
+	writeuint32_t(out + 4,(Td4[(t1 >> 24)] << 24) ^ (Td4[(t0 >> 16) & m8] << 16) ^ (Td4[(t3 >> 8) & m8] << 8) ^ (Td4[(t2) & m8]) ^ rk[1]);
+	writeuint32_t(out + 8,(Td4[(t2 >> 24)] << 24) ^ (Td4[(t1 >> 16) & m8] << 16) ^ (Td4[(t0 >> 8) & m8] << 8) ^ (Td4[(t3) & m8]) ^ rk[2]);
+	writeuint32_t(out + 12,(Td4[(t3 >> 24)] << 24) ^ (Td4[(t2 >> 16) & m8] << 16) ^ (Td4[(t1 >> 8) & m8] << 8) ^ (Td4[(t0) & m8]) ^ rk[3]);
 }
 }
 
 
 #ifdef ZT_AES_AESNI
 #ifdef ZT_AES_AESNI

+ 74 - 59
node/Membership.cpp

@@ -38,70 +38,85 @@ Membership::~Membership()
 
 
 void Membership::pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const int64_t now,const Address &peerAddress,const NetworkConfig &nconf)
 void Membership::pushCredentials(const RuntimeEnvironment *RR,void *tPtr,const int64_t now,const Address &peerAddress,const NetworkConfig &nconf)
 {
 {
-	Buf outp;
-#if 0
-	const Capability *sendCaps[ZT_MAX_NETWORK_CAPABILITIES];
-	unsigned int sendCapCount = 0;
-	for(unsigned int c=0;c<nconf.capabilityCount;++c)
-		sendCaps[sendCapCount++] = &(nconf.capabilities[c]);
+	if (!nconf.com) // sanity check
+		return;
 
 
-	const Tag *sendTags[ZT_MAX_NETWORK_TAGS];
-	unsigned int sendTagCount = 0;
-	for(unsigned int t=0;t<nconf.tagCount;++t)
-		sendTags[sendTagCount++] = &(nconf.tags[t]);
+	SharedPtr<Buf> outp(new Buf());
+	Protocol::Header &ph = outp->as<Protocol::Header>();
 
 
-	const CertificateOfOwnership *sendCoos[ZT_MAX_CERTIFICATES_OF_OWNERSHIP];
-	unsigned int sendCooCount = 0;
-	for(unsigned int c=0;c<nconf.certificateOfOwnershipCount;++c)
-		sendCoos[sendCooCount++] = &(nconf.certificatesOfOwnership[c]);
+	unsigned int capPtr = 0,tagPtr = 0,cooPtr = 0;
+	bool sendCom = true;
+	bool complete = false;
+	while (!complete) {
+		ph.packetId = Protocol::getPacketId();
+		peerAddress.copyTo(ph.destination);
+		RR->identity.address().copyTo(ph.source);
+		ph.flags = 0;
+		ph.verb = Protocol::VERB_NETWORK_CREDENTIALS;
 
 
-	unsigned int capPtr = 0;
-	unsigned int tagPtr = 0;
-	unsigned int cooPtr = 0;
-	bool sendCom = (bool)(nconf.com);
-	while ((capPtr < sendCapCount)||(tagPtr < sendTagCount)||(cooPtr < sendCooCount)||(sendCom)) {
-		Packet outp(peerAddress,RR->identity.address(),Packet::VERB_NETWORK_CREDENTIALS);
+		int outl = sizeof(Protocol::Header);
 
 
 		if (sendCom) {
 		if (sendCom) {
 			sendCom = false;
 			sendCom = false;
-			nconf.com.serialize(outp);
+			outp->wO(outl,nconf.com);
 		}
 		}
-		outp.append((uint8_t)0x00);
+		outp->wI(outl,(uint8_t)0);
 
 
-		const unsigned int capCountAt = outp.size();
-		outp.addSize(2);
-		unsigned int thisPacketCapCount = 0;
-		while ((capPtr < sendCapCount)&&((outp.size() + sizeof(Capability) + 16) < ZT_PROTO_MAX_PACKET_LENGTH)) {
-			sendCaps[capPtr++]->serialize(outp);
-			++thisPacketCapCount;
-		}
-		outp.setAt(capCountAt,(uint16_t)thisPacketCapCount);
+		if ((outl + ZT_CAPABILITY_MARSHAL_SIZE_MAX + 2) < ZT_PROTO_MAX_PACKET_LENGTH) {
+			void *const capCountAt = outp->b + outl;
+			outl += 2;
+			unsigned int capCount = 0;
+			while (capPtr < nconf.capabilityCount) {
+				outp->wO(outl,nconf.capabilities[capPtr++]);
+				++capCount;
+				if ((outl + ZT_CAPABILITY_MARSHAL_SIZE_MAX) >= ZT_PROTO_MAX_PACKET_LENGTH)
+					break;
+			}
+			Utils::storeBigEndian(capCountAt,(uint16_t)capCount);
 
 
-		const unsigned int tagCountAt = outp.size();
-		outp.addSize(2);
-		unsigned int thisPacketTagCount = 0;
-		while ((tagPtr < sendTagCount)&&((outp.size() + sizeof(Tag) + 16) < ZT_PROTO_MAX_PACKET_LENGTH)) {
-			sendTags[tagPtr++]->serialize(outp);
-			++thisPacketTagCount;
-		}
-		outp.setAt(tagCountAt,(uint16_t)thisPacketTagCount);
+			if ((outl + ZT_TAG_MARSHAL_SIZE_MAX + 4) < ZT_PROTO_MAX_PACKET_LENGTH) {
+				void *const tagCountAt = outp->b + outl;
+				outl += 2;
+				unsigned int tagCount = 0;
+				while (tagPtr < nconf.tagCount) {
+					outp->wO(outl,nconf.tags[tagPtr++]);
+					++tagCount;
+					if ((outl + ZT_TAG_MARSHAL_SIZE_MAX) >= ZT_PROTO_MAX_PACKET_LENGTH)
+						break;
+				}
+				Utils::storeBigEndian(tagCountAt,(uint16_t)tagCount);
 
 
-		// No revocations, these propagate differently
-		outp.append((uint16_t)0);
+				outp->wI(outl,(uint16_t)0); // no revocations sent here as these propagate differently
 
 
-		const unsigned int cooCountAt = outp.size();
-		outp.addSize(2);
-		unsigned int thisPacketCooCount = 0;
-		while ((cooPtr < sendCooCount)&&((outp.size() + sizeof(CertificateOfOwnership) + 16) < ZT_PROTO_MAX_PACKET_LENGTH)) {
-			sendCoos[cooPtr++]->serialize(outp);
-			++thisPacketCooCount;
+				if ((outl + ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX + 2) < ZT_PROTO_MAX_PACKET_LENGTH) {
+					void *const cooCountAt = outp->b + outl;
+					outl += 2;
+					unsigned int cooCount = 0;
+					while (cooPtr < nconf.certificateOfOwnershipCount) {
+						outp->wO(outl,nconf.certificatesOfOwnership[cooPtr++]);
+						++cooCount;
+						if ((outl + ZT_CERTIFICATEOFOWNERSHIP_MARSHAL_SIZE_MAX) >= ZT_PROTO_MAX_PACKET_LENGTH)
+							break;
+					}
+					Utils::storeBigEndian(cooCountAt,(uint16_t)cooCount);
+
+					complete = true;
+				} else {
+					outp->wI(outl,(uint16_t)0);
+				}
+			} else {
+				outp->wI(outl,(uint16_t)0);
+				outp->wI(outl,(uint16_t)0);
+				outp->wI(outl,(uint16_t)0);
+			}
+		} else {
+			outp->wI(outl,(uint64_t)0); // four zero 16-bit integers
 		}
 		}
-		outp.setAt(cooCountAt,(uint16_t)thisPacketCooCount);
 
 
-		outp.compress();
-		RR->sw->send(tPtr,outp,true);
+		if (outl > sizeof(Protocol::Header)) {
+			outl = Protocol::compress(outp,outl);
+		}
 	}
 	}
-#endif
 
 
 	_lastPushedCredentials = now;
 	_lastPushedCredentials = now;
 }
 }
@@ -117,13 +132,13 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
 {
 {
 	const int64_t newts = com.timestamp();
 	const int64_t newts = com.timestamp();
 	if (newts <= _comRevocationThreshold) {
 	if (newts <= _comRevocationThreshold) {
-		RR->t->credentialRejected(tPtr,com.networkId(),sourcePeerIdentity.address(),com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
+		RR->t->credentialRejected(tPtr,0xd9992121,com.networkId(),sourcePeerIdentity.address(),com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
 		return ADD_REJECTED;
 		return ADD_REJECTED;
 	}
 	}
 
 
 	const int64_t oldts = _com.timestamp();
 	const int64_t oldts = _com.timestamp();
 	if (newts < oldts) {
 	if (newts < oldts) {
-		RR->t->credentialRejected(tPtr,com.networkId(),sourcePeerIdentity.address(),com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
+		RR->t->credentialRejected(tPtr,0xd9928192,com.networkId(),sourcePeerIdentity.address(),com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
 		return ADD_REJECTED;
 		return ADD_REJECTED;
 	}
 	}
 	if ((newts == oldts)&&(_com == com))
 	if ((newts == oldts)&&(_com == com))
@@ -131,13 +146,13 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
 
 
 	switch(com.verify(RR,tPtr)) {
 	switch(com.verify(RR,tPtr)) {
 		default:
 		default:
-			RR->t->credentialRejected(tPtr,com.networkId(),sourcePeerIdentity.address(),com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
+			RR->t->credentialRejected(tPtr,0x0f198241,com.networkId(),sourcePeerIdentity.address(),com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
 			return Membership::ADD_REJECTED;
 			return Membership::ADD_REJECTED;
 		case Credential::VERIFY_OK:
 		case Credential::VERIFY_OK:
 			_com = com;
 			_com = com;
 			return ADD_ACCEPTED_NEW;
 			return ADD_ACCEPTED_NEW;
 		case Credential::VERIFY_BAD_SIGNATURE:
 		case Credential::VERIFY_BAD_SIGNATURE:
-			RR->t->credentialRejected(tPtr,com.networkId(),sourcePeerIdentity.address(),com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_SIGNATURE_VERIFICATION_FAILED);
+			RR->t->credentialRejected(tPtr,0xbaf0aaaa,com.networkId(),sourcePeerIdentity.address(),com.id(),com.timestamp(),ZT_CREDENTIAL_TYPE_COM,ZT_TRACE_CREDENTIAL_REJECTION_REASON_SIGNATURE_VERIFICATION_FAILED);
 			return ADD_REJECTED;
 			return ADD_REJECTED;
 		case Credential::VERIFY_NEED_IDENTITY:
 		case Credential::VERIFY_NEED_IDENTITY:
 			return ADD_DEFERRED_FOR_WHOIS;
 			return ADD_DEFERRED_FOR_WHOIS;
@@ -158,7 +173,7 @@ static ZT_ALWAYS_INLINE Membership::AddCredentialResult _addCredImpl(
 	C *rc = remoteCreds.get(cred.id());
 	C *rc = remoteCreds.get(cred.id());
 	if (rc) {
 	if (rc) {
 		if (rc->timestamp() > cred.timestamp()) {
 		if (rc->timestamp() > cred.timestamp()) {
-			RR->t->credentialRejected(tPtr,nconf.networkId,sourcePeerIdentity.address(),cred.id(),cred.timestamp(),C::credentialType(),ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
+			RR->t->credentialRejected(tPtr,0x40000001,nconf.networkId,sourcePeerIdentity.address(),cred.id(),cred.timestamp(),C::credentialType(),ZT_TRACE_CREDENTIAL_REJECTION_REASON_OLDER_THAN_LATEST);
 			return Membership::ADD_REJECTED;
 			return Membership::ADD_REJECTED;
 		}
 		}
 		if (*rc == cred)
 		if (*rc == cred)
@@ -167,13 +182,13 @@ static ZT_ALWAYS_INLINE Membership::AddCredentialResult _addCredImpl(
 
 
 	const int64_t *const rt = revocations.get(Membership::credentialKey(C::credentialType(),cred.id()));
 	const int64_t *const rt = revocations.get(Membership::credentialKey(C::credentialType(),cred.id()));
 	if ((rt)&&(*rt >= cred.timestamp())) {
 	if ((rt)&&(*rt >= cred.timestamp())) {
-		RR->t->credentialRejected(tPtr,nconf.networkId,sourcePeerIdentity.address(),cred.id(),cred.timestamp(),C::credentialType(),ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
+		RR->t->credentialRejected(tPtr,0x24248124,nconf.networkId,sourcePeerIdentity.address(),cred.id(),cred.timestamp(),C::credentialType(),ZT_TRACE_CREDENTIAL_REJECTION_REASON_REVOKED);
 		return Membership::ADD_REJECTED;
 		return Membership::ADD_REJECTED;
 	}
 	}
 
 
 	switch(cred.verify(RR,tPtr)) {
 	switch(cred.verify(RR,tPtr)) {
 		default:
 		default:
-			RR->t->credentialRejected(tPtr,nconf.networkId,sourcePeerIdentity.address(),cred.id(),cred.timestamp(),C::credentialType(),ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
+			RR->t->credentialRejected(tPtr,0x01feba012,nconf.networkId,sourcePeerIdentity.address(),cred.id(),cred.timestamp(),C::credentialType(),ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
 			return Membership::ADD_REJECTED;
 			return Membership::ADD_REJECTED;
 		case 0:
 		case 0:
 			if (!rc)
 			if (!rc)
@@ -193,7 +208,7 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
 	int64_t *rt;
 	int64_t *rt;
 	switch(rev.verify(RR,tPtr)) {
 	switch(rev.verify(RR,tPtr)) {
 		default:
 		default:
-			RR->t->credentialRejected(tPtr,nconf.networkId,sourcePeerIdentity.address(),rev.id(),0,ZT_CREDENTIAL_TYPE_REVOCATION,ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
+			RR->t->credentialRejected(tPtr,0x938fffff,nconf.networkId,sourcePeerIdentity.address(),rev.id(),0,ZT_CREDENTIAL_TYPE_REVOCATION,ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
 			return ADD_REJECTED;
 			return ADD_REJECTED;
 		case 0: {
 		case 0: {
 			const ZT_CredentialType ct = rev.typeBeingRevoked();
 			const ZT_CredentialType ct = rev.typeBeingRevoked();
@@ -215,7 +230,7 @@ Membership::AddCredentialResult Membership::addCredential(const RuntimeEnvironme
 					}
 					}
 					return ADD_ACCEPTED_REDUNDANT;
 					return ADD_ACCEPTED_REDUNDANT;
 				default:
 				default:
-					RR->t->credentialRejected(tPtr,nconf.networkId,sourcePeerIdentity.address(),rev.id(),0,ZT_CREDENTIAL_TYPE_REVOCATION,ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
+					RR->t->credentialRejected(tPtr,0x0bbbb1a4,nconf.networkId,sourcePeerIdentity.address(),rev.id(),0,ZT_CREDENTIAL_TYPE_REVOCATION,ZT_TRACE_CREDENTIAL_REJECTION_REASON_INVALID);
 					return ADD_REJECTED;
 					return ADD_REJECTED;
 			}
 			}
 		}
 		}

+ 0 - 1
node/Peer.cpp

@@ -17,7 +17,6 @@
 #include "Peer.hpp"
 #include "Peer.hpp"
 #include "Topology.hpp"
 #include "Topology.hpp"
 #include "Node.hpp"
 #include "Node.hpp"
-#include "Network.hpp"
 #include "SelfAwareness.hpp"
 #include "SelfAwareness.hpp"
 #include "InetAddress.hpp"
 #include "InetAddress.hpp"
 #include "Protocol.hpp"
 #include "Protocol.hpp"

+ 7 - 11
node/Protocol.cpp

@@ -81,7 +81,7 @@ uint64_t getPacketId() noexcept
 #endif
 #endif
 }
 }
 
 
-void armor(Buf &pkt,unsigned int packetSize,const uint8_t key[ZT_PEER_SECRET_KEY_LENGTH],uint8_t cipherSuite) noexcept
+void armor(Buf &pkt,int packetSize,const uint8_t key[ZT_PEER_SECRET_KEY_LENGTH],uint8_t cipherSuite) noexcept
 {
 {
 	Protocol::Header &ph = pkt.as<Protocol::Header>();
 	Protocol::Header &ph = pkt.as<Protocol::Header>();
 	ph.flags = (ph.flags & 0xc7U) | ((cipherSuite << 3U) & 0x38U); // flags: FFCCCHHH where CCC is cipher
 	ph.flags = (ph.flags & 0xc7U) | ((cipherSuite << 3U) & 0x38U); // flags: FFCCCHHH where CCC is cipher
@@ -123,25 +123,21 @@ void armor(Buf &pkt,unsigned int packetSize,const uint8_t key[ZT_PEER_SECRET_KEY
 	}
 	}
 }
 }
 
 
-unsigned int compress(SharedPtr<Buf> &pkt,unsigned int packetSize) noexcept
+int compress(SharedPtr<Buf> &pkt,int packetSize) noexcept
 {
 {
 	if (packetSize <= 128)
 	if (packetSize <= 128)
 		return packetSize;
 		return packetSize;
 
 
-	SharedPtr<Buf> pkt2(Buf::get());
+	SharedPtr<Buf> pkt2(new Buf());
 	if (!pkt2) return packetSize;
 	if (!pkt2) return packetSize;
 
 
-	const unsigned int uncompressedLen = packetSize - ZT_PROTO_PACKET_PAYLOAD_START;
-	const int compressedLen = LZ4_compress_fast(
-		reinterpret_cast<const char *>(pkt->b + ZT_PROTO_PACKET_PAYLOAD_START),
-		reinterpret_cast<char *>(pkt2->b + ZT_PROTO_PACKET_PAYLOAD_START),
-		(int)uncompressedLen,
-		ZT_BUF_MEM_SIZE - ZT_PROTO_PACKET_PAYLOAD_START);
-	if ((compressedLen > 0)&&(compressedLen < (int)uncompressedLen)) {
+	const int uncompressedLen = packetSize - ZT_PROTO_PACKET_PAYLOAD_START;
+	const int compressedLen = LZ4_compress_fast(reinterpret_cast<const char *>(pkt->b + ZT_PROTO_PACKET_PAYLOAD_START),reinterpret_cast<char *>(pkt2->b + ZT_PROTO_PACKET_PAYLOAD_START),uncompressedLen,ZT_BUF_MEM_SIZE - ZT_PROTO_PACKET_PAYLOAD_START);
+	if ((compressedLen > 0)&&(compressedLen < uncompressedLen)) {
 		memcpy(pkt2->b,pkt->b,ZT_PROTO_PACKET_PAYLOAD_START);
 		memcpy(pkt2->b,pkt->b,ZT_PROTO_PACKET_PAYLOAD_START);
 		pkt.swap(pkt2);
 		pkt.swap(pkt2);
 		pkt->as<Protocol::Header>().verb |= ZT_PROTO_VERB_FLAG_COMPRESSED;
 		pkt->as<Protocol::Header>().verb |= ZT_PROTO_VERB_FLAG_COMPRESSED;
-		return (unsigned int)compressedLen + ZT_PROTO_PACKET_PAYLOAD_START;
+		return compressedLen + ZT_PROTO_PACKET_PAYLOAD_START;
 	}
 	}
 
 
 	return packetSize;
 	return packetSize;

+ 4 - 5
node/Protocol.hpp

@@ -81,8 +81,8 @@
  * --------------------------------------------------------------------------------------------------------------------
  * --------------------------------------------------------------------------------------------------------------------
  */
  */
 
 
-/**
- * Protocol version -- incremented only for major changes
+/*
+ * Protocol versions
  *
  *
  * 1  - 0.2.0 ... 0.2.5
  * 1  - 0.2.0 ... 0.2.5
  * 2  - 0.3.0 ... 0.4.5
  * 2  - 0.3.0 ... 0.4.5
@@ -296,7 +296,6 @@ enum Verb
 
 
 	/**
 	/**
 	 * Announcement of a node's existence and vitals:
 	 * Announcement of a node's existence and vitals:
-	 *   [... HMAC-384 starts here ...]
 	 *   <[1] protocol version>
 	 *   <[1] protocol version>
 	 *   <[1] software major version>
 	 *   <[1] software major version>
 	 *   <[1] software minor version>
 	 *   <[1] software minor version>
@@ -1060,7 +1059,7 @@ uint64_t getPacketId() noexcept;
  * @param key Key to use for encryption (not per-packet key)
  * @param key Key to use for encryption (not per-packet key)
  * @param cipherSuite Cipher suite to use for AEAD encryption or just MAC
  * @param cipherSuite Cipher suite to use for AEAD encryption or just MAC
  */
  */
-void armor(Buf &pkt,unsigned int packetSize,const uint8_t key[ZT_PEER_SECRET_KEY_LENGTH],uint8_t cipherSuite) noexcept;
+void armor(Buf &pkt,int packetSize,const uint8_t key[ZT_PEER_SECRET_KEY_LENGTH],uint8_t cipherSuite) noexcept;
 
 
 /**
 /**
  * Attempt to compress packet payload
  * Attempt to compress packet payload
@@ -1074,7 +1073,7 @@ void armor(Buf &pkt,unsigned int packetSize,const uint8_t key[ZT_PEER_SECRET_KEY
  * @param packetSize Total size of packet in bytes (including headers)
  * @param packetSize Total size of packet in bytes (including headers)
  * @return New size of packet after compression or original size of compression wasn't helpful
  * @return New size of packet after compression or original size of compression wasn't helpful
  */
  */
-unsigned int compress(SharedPtr<Buf> &pkt,unsigned int packetSize) noexcept;
+int compress(SharedPtr<Buf> &pkt,int packetSize) noexcept;
 
 
 } // namespace Protocol
 } // namespace Protocol
 } // namespace ZeroTier
 } // namespace ZeroTier

+ 4 - 5
node/SelfAwareness.cpp

@@ -11,11 +11,6 @@
  */
  */
 /****/
 /****/
 
 
-#include <cstdlib>
-#include <cstring>
-
-#include <set>
-
 #include "Constants.hpp"
 #include "Constants.hpp"
 #include "SelfAwareness.hpp"
 #include "SelfAwareness.hpp"
 #include "RuntimeEnvironment.hpp"
 #include "RuntimeEnvironment.hpp"
@@ -23,6 +18,10 @@
 #include "Peer.hpp"
 #include "Peer.hpp"
 #include "Trace.hpp"
 #include "Trace.hpp"
 
 
+#include <cstdlib>
+#include <cstring>
+#include <set>
+
 // Entry timeout -- make it fairly long since this is just to prevent stale buildup
 // Entry timeout -- make it fairly long since this is just to prevent stale buildup
 #define ZT_SELFAWARENESS_ENTRY_TIMEOUT 300000
 #define ZT_SELFAWARENESS_ENTRY_TIMEOUT 300000
 
 

+ 3 - 1
node/VL1.cpp

@@ -342,7 +342,9 @@ void VL1::onRemotePacket(void *const tPtr,const int64_t localSocket,const InetAd
 			return;
 			return;
 		}
 		}
 
 
-		// Decompress packet payload if compressed.
+		// Decompress packet payload if compressed. For additional safety decompression is
+		// only performed on packets whose MACs have already been validated. (Only HELLO is
+		// sent without this, and HELLO doesn't benefit from compression.)
 		if ((ph->verb & ZT_PROTO_VERB_FLAG_COMPRESSED) != 0) {
 		if ((ph->verb & ZT_PROTO_VERB_FLAG_COMPRESSED) != 0) {
 			if (!authenticated) {
 			if (!authenticated) {
 				RR->t->incomingPacketDropped(tPtr,0x390bcd0a,ph->packetId,0,identityFromPeerPtr(peer),path->address(),hops,verb,ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET);
 				RR->t->incomingPacketDropped(tPtr,0x390bcd0a,ph->packetId,0,identityFromPeerPtr(peer),path->address(),hops,verb,ZT_TRACE_PACKET_DROP_REASON_MALFORMED_PACKET);