package com.zackehh.siphash; import static com.zackehh.siphash.SipHashConstants.DEFAULT_C; import static com.zackehh.siphash.SipHashConstants.DEFAULT_D; import static com.zackehh.siphash.SipHashConstants.INITIAL_V0; import static com.zackehh.siphash.SipHashConstants.INITIAL_V1; import static com.zackehh.siphash.SipHashConstants.INITIAL_V2; import static com.zackehh.siphash.SipHashConstants.INITIAL_V3; /** * Main entry point for SipHash, providing a basic hash * interface. Assuming you have your full String to hash, * you can simply provide it to ${@link SipHash#hash(byte[])}. * * This class can be initialized and stored in case the * developer wishes to use the same key over and over again. * * This avoids the overhead of having to create the initial * key over and over again. * *
* {@code
* List inputs = Arrays.asList("input1", "input2", "input3");
* SipHash hasher = new SipHash("this key is mine".getBytes());
* for (int i = 0; i < inputs.size(); i++) {
* hasher.hash(inputs.get(i));
* }
* }
*
*/
public class SipHash {
/**
* The values of SipHash-c-d, to determine which of the SipHash
* family we're using for this hash.
*/
private final int c, d;
/**
* Initial seeded value of v0.
*/
private final long v0;
/**
* Initial seeded value of v1.
*/
private final long v1;
/**
* Initial seeded value of v2.
*/
private final long v2;
/**
* Initial seeded value of v3.
*/
private final long v3;
/**
* Accepts a 16 byte key input, and uses it to initialize
* the state of the hash. This uses the default values of
* c/d, meaning that we default to SipHash-2-4.
*
* @param key a 16 byte key input
*/
public SipHash(byte[] key){
this(key, DEFAULT_C, DEFAULT_D);
}
/**
* Accepts a 16 byte key input, and uses it to initialize
* the state of the hash. This constructor allows for
* providing the c/d values, allowing the developer to
* select any of the SipHash family to use for hashing.
*
* @param key a 16 byte key input
* @param c the number of compression rounds
* @param d the number of finalization rounds
*/
public SipHash(byte[] key, int c, int d){
this.c = c;
this.d = d;
SipHashKey hashKey = new SipHashKey(key);
this.v0 = (INITIAL_V0 ^ hashKey.k0);
this.v1 = (INITIAL_V1 ^ hashKey.k1);
this.v2 = (INITIAL_V2 ^ hashKey.k0);
this.v3 = (INITIAL_V3 ^ hashKey.k1);
}
/**
* The basic hash implementation provided in the library.
* Assuming you have your full input, you can provide it and
* it will be hashed based on the values which were provided
* to the constructor of this class.
*
* @param data the bytes to hash
* @return a ${@link SipHashResult} instance
*/
public SipHashResult hash(byte[] data) {
SipHashDigest digest = new SipHashDigest(v0, v1, v2, v3, c, d);
for (byte aData : data) {
digest.update(aData);
}
return digest.finish();
}
}