SipHash Class — netty Architecture
Architecture documentation for the SipHash class in SipHash.java from the netty codebase.
Entity Profile
Dependency Diagram
graph TD 32c45fc1_8885_8768_58c7_65f5ff579eb7["SipHash"] 81a21231_fa20_3eca_ce30_b02488bcb8a0["SipHash.java"] 32c45fc1_8885_8768_58c7_65f5ff579eb7 -->|defined in| 81a21231_fa20_3eca_ce30_b02488bcb8a0 6b03d8f3_ff63_1286_7bef_b85daf73498a["SipHash()"] 32c45fc1_8885_8768_58c7_65f5ff579eb7 -->|method| 6b03d8f3_ff63_1286_7bef_b85daf73498a 901f01bc_21b3_69fb_38c8_2e3a75334e00["macHash()"] 32c45fc1_8885_8768_58c7_65f5ff579eb7 -->|method| 901f01bc_21b3_69fb_38c8_2e3a75334e00 62ea4b31_3219_5aab_2cc2_04bbec862c0a["sipround()"] 32c45fc1_8885_8768_58c7_65f5ff579eb7 -->|method| 62ea4b31_3219_5aab_2cc2_04bbec862c0a
Relationship Graph
Source Code
codec-classes-quic/src/main/java/io/netty/handler/codec/quic/SipHash.java lines 26–150
final class SipHash {
static final int SEED_LENGTH = 16;
// Make this class allocation free as soon as its constructed.
private final int compressionRounds;
private final int finalizationRounds;
// As specified in https://www.aumasson.jp/siphash/siphash.pdf
private static final long INITIAL_STATE_V0 = 0x736f6d6570736575L; // "somepseu"
private static final long INITIAL_STATE_V1 = 0x646f72616e646f6dL; // "dorandom"
private static final long INITIAL_STATE_V2 = 0x6c7967656e657261L; // "lygenera"
private static final long INITIAL_STATE_V3 = 0x7465646279746573L; // "tedbytes"
private final long initialStateV0;
private final long initialStateV1;
private final long initialStateV2;
private final long initialStateV3;
private long v0;
private long v1;
private long v2;
private long v3;
SipHash(int compressionRounds, int finalizationRounds, byte[] seed) {
if (seed.length != SEED_LENGTH) {
throw new IllegalArgumentException("seed must be of length " + SEED_LENGTH);
}
this.compressionRounds = ObjectUtil.checkPositive(compressionRounds, "compressionRounds");
this.finalizationRounds = ObjectUtil.checkPositive(finalizationRounds, "finalizationRounds");
// Wrap the seed to extract two longs that will be used to generate the initial state.
// Use little-endian as in the paper.
ByteBuffer keyBuffer = ByteBuffer.wrap(seed).order(ByteOrder.LITTLE_ENDIAN);
final long k0 = keyBuffer.getLong();
final long k1 = keyBuffer.getLong();
initialStateV0 = INITIAL_STATE_V0 ^ k0;
initialStateV1 = INITIAL_STATE_V1 ^ k1;
initialStateV2 = INITIAL_STATE_V2 ^ k0;
initialStateV3 = INITIAL_STATE_V3 ^ k1;
}
long macHash(ByteBuffer input) {
v0 = initialStateV0;
v1 = initialStateV1;
v2 = initialStateV2;
v3 = initialStateV3;
int remaining = input.remaining();
int position = input.position();
int len = remaining - (remaining % Long.BYTES);
boolean needsReverse = input.order() == ByteOrder.BIG_ENDIAN;
for (int offset = position; offset < len; offset += Long.BYTES) {
long m = input.getLong(offset);
if (needsReverse) {
// We use little-endian as in the paper.
m = Long.reverseBytes(m);
}
v3 ^= m;
for (int i = 0; i < compressionRounds; i++) {
sipround();
}
v0 ^= m;
}
// Get last bits.
final int left = remaining & (Long.BYTES - 1);
long b = (long) remaining << 56;
assert left < Long.BYTES;
switch (left) {
case 7:
b |= (long) input.get(position + len + 6) << 48;
case 6:
b |= (long) input.get(position + len + 5) << 40;
case 5:
b |= (long) input.get(position + len + 4) << 32;
case 4:
b |= (long) input.get(position + len + 3) << 24;
case 3:
b |= (long) input.get(position + len + 2) << 16;
case 2:
Source
Frequently Asked Questions
What is the SipHash class?
SipHash is a class in the netty codebase, defined in codec-classes-quic/src/main/java/io/netty/handler/codec/quic/SipHash.java.
Where is SipHash defined?
SipHash is defined in codec-classes-quic/src/main/java/io/netty/handler/codec/quic/SipHash.java at line 26.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free