Home / Class/ SipHash Class — netty Architecture

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:

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