Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.bouncycastle.crypto.macs;
  
Implementation of SipHash as specified in "SipHash: a fast short-input PRF", by Jean-Philippe Aumasson and Daniel J. Bernstein (https://131002.net/siphash/siphash.pdf).

"SipHash is a family of PRFs SipHash-c-d where the integer parameters c and d are the number of compression rounds and the number of finalization rounds. A compression round is identical to a finalization round and this round function is called SipRound. Given a 128-bit key k and a (possibly empty) byte string m, SipHash-c-d returns a 64-bit value..."

 
 public class SipHash
     implements Mac
 {
     protected final int cd;
 
     protected long k0k1;
     protected long v0v1v2v3;
 
     protected long m = 0;
     protected int wordPos = 0;
     protected int wordCount = 0;

    
SipHash-2-4
 
     public SipHash()
     {
         // use of 'this' confuses the flow analyser on earlier JDKs.
         this. = 2;
         this. = 4;
     }

    
SipHash-c-d

Parameters:
c the number of compression rounds
d the number of finalization rounds
 
     public SipHash(int cint d)
     {
         this. = c;
         this. = d;
     }
 
     public String getAlgorithmName()
     {
         return "SipHash-" +  + "-" + ;
     }
 
     public int getMacSize()
     {
         return 8;
     }
 
     public void init(CipherParameters params)
         throws IllegalArgumentException
     {
         if (!(params instanceof KeyParameter))
         {
             throw new IllegalArgumentException("'params' must be an instance of KeyParameter");
         }
         KeyParameter keyParameter = (KeyParameter)params;
         byte[] key = keyParameter.getKey();
         if (key.length != 16)
         {
             throw new IllegalArgumentException("'params' must be a 128-bit key");
         }
 
         this. = Pack.littleEndianToLong(key, 0);
         this. = Pack.littleEndianToLong(key, 8);
 
         reset();
     }
 
     public void update(byte input)
         throws IllegalStateException
     {
          >>>= 8;
          |= (input & 0xffL) << 56;
 
         if (++ == 8)
         {
             processMessageWord();
              = 0;
         }
     }
 
     public void update(byte[] inputint offsetint length)
         throws DataLengthException,
         IllegalStateException
     {
         int i = 0, fullWords = length & ~7;
        if ( == 0)
        {
            for (; i < fullWordsi += 8)
            {
                 = Pack.littleEndianToLong(inputoffset + i);
                processMessageWord();
            }
            for (; i < length; ++i)
            {
                 >>>= 8;
                 |= (input[offset + i] & 0xffL) << 56;
            }
             = length - fullWords;
        }
        else
        {
            int bits =  << 3;
            for (; i < fullWordsi += 8)
            {
                long n = Pack.littleEndianToLong(inputoffset + i);
                 = (n << bits) | ( >>> -bits);
                processMessageWord();
                 = n;
            }
            for (; i < length; ++i)
            {
                 >>>= 8;
                 |= (input[offset + i] & 0xffL) << 56;
                if (++ == 8)
                {
                    processMessageWord();
                     = 0;
                }
            }
        }
    }
    public long doFinal()
    {
        // NOTE: 2 distinct shifts to avoid "64-bit shift" when wordPos == 0
         >>>= ((7 - ) << 3);
         >>>= 8;
         |= ((( << 3) + ) & 0xffL) << 56;
        processMessageWord();
         ^= 0xffL;
        applySipRounds();
        long result =  ^  ^  ^ ;
        reset();
        return result;
    }
    public int doFinal(byte[] outint outOff)
    {
        long result = doFinal();
        Pack.longToLittleEndian(resultoutoutOff);
        return 8;
    }
    public void reset()
    {
         =  ^ 0x736f6d6570736575L;
         =  ^ 0x646f72616e646f6dL;
         =  ^ 0x6c7967656e657261L;
         =  ^ 0x7465646279746573L;
         = 0;
         = 0;
         = 0;
    }
    protected void processMessageWord()
    {
        ++;
         ^= ;
        applySipRounds();
         ^= ;
    }
    protected void applySipRounds(int n)
    {
        long r0 = r1 = r2 = r3 = ;
        for (int r = 0; r < n; ++r)
        {
            r0 += r1;
            r2 += r3;
            r1 = rotateLeft(r1, 13);
            r3 = rotateLeft(r3, 16);
            r1 ^= r0;
            r3 ^= r2;
            r0 = rotateLeft(r0, 32);
            r2 += r1;
            r0 += r3;
            r1 = rotateLeft(r1, 17);
            r3 = rotateLeft(r3, 21);
            r1 ^= r2;
            r3 ^= r0;
            r2 = rotateLeft(r2, 32);
        }
         = r0 = r1 = r2 = r3;
    }
    protected static long rotateLeft(long xint n)
    {
        return (x << n) | (x >>> -n);
    }
New to GrepCode? Check out our FAQ X