QuicConnectionId::Hash adoption of SipHash

This CL rolls back cl/258561852 which was itself a rollback of cl/258413870. QuicConnectionIdTest.Hash was failing on 32bit platforms and has now been fixed.

Instead of simply XORing the connection ID bits, QuicConnectionId::Hash now uses SipHash with a random key generated once per process lifetime. This prevents attackers from crafting connection IDs to make them all land in the same data structure hash bucket.

gfe-relnote: QuicConnectionId uses SipHash, protected by gfe2_restart_flag_quic_connection_id_use_siphash
PiperOrigin-RevId: 258782229
Change-Id: I019c85ba2cde0447764306b87f12323d6867acb0
diff --git a/quic/core/quic_connection_id_test.cc b/quic/core/quic_connection_id_test.cc
index 1d290fc..0d4b190 100644
--- a/quic/core/quic_connection_id_test.cc
+++ b/quic/core/quic_connection_id_test.cc
@@ -89,6 +89,23 @@
   EXPECT_NE(connection_id64_1.Hash(), connection_id64_2.Hash());
   EXPECT_NE(connection_id64_1.Hash(), connection_id64_3.Hash());
   EXPECT_NE(connection_id64_2.Hash(), connection_id64_3.Hash());
+
+  // Verify that any two all-zero connection IDs of different lengths never
+  // have the same hash.
+  if (sizeof(connection_id64_1.Hash()) < sizeof(uint64_t) &&
+      !GetQuicRestartFlag(quic_connection_id_use_siphash)) {
+    // The old hashing algorithm returns 0 for all-zero connection IDs on
+    // 32bit platforms.
+    return;
+  }
+  const char connection_id_bytes[kQuicMaxConnectionIdLength] = {};
+  for (uint8_t i = 0; i < kQuicMaxConnectionIdLength - 1; ++i) {
+    QuicConnectionId connection_id_i(connection_id_bytes, i);
+    for (uint8_t j = i + 1; j < kQuicMaxConnectionIdLength; ++j) {
+      QuicConnectionId connection_id_j(connection_id_bytes, j);
+      EXPECT_NE(connection_id_i.Hash(), connection_id_j.Hash());
+    }
+  }
 }
 
 TEST_F(QuicConnectionIdTest, AssignAndCopy) {