CRC-64 for an SHA256 hach - crc

hiii,
I have a question , if i calculate a crc for an sha256 hash to get a char with 64bits, Will I have a collision ? it's secure for reverse function ?
thnx

IANAC.
I don't really understand what you mean by "Will I have a collision" - 64 bits can of course never represent 256 bits so yes, very very many of your possible sha256 hashes can collapse to the same 64 bit CRC.
If you just want a shorter value for your hash, I'd suggest folding instead, for example by xor:ing every consecutive byte in your hash with each other.
Or by xor:ing the first half of your 256 bit string with the second half to yield a 128 bit value, and then xor:ing that result's first half with the result's second half again to yield a 64 bit value.
This 64 bit value will of course never be able to represent all the possible values of the 256 bit hash either but it will not be possible to start with this value and calculate a collision for your original 256 bit hash.

Related

Is there any regex to find that a value is hashmap or not?

Is there any regex to find that a value is hashmap or not?
I want to build an PL/SQL function to say that a value is hashed or not?
For e.g
1. TIM 2. F6099C0932D0E2B13286218F99C265975B33FD84
My Regex should have intelligence to tell me that expression 1 (Tim) is not hashmaped.
Whereas expression 2 (F6099C0932D0E2B13286218F99C265975B33FD84) is hashmaped.
A hash is just a number of bits of a particular size. Cryptographic hashes generally have a 256 to 512 bit output size to achieve a security of about 128-256 bits to achieve collision resistance.
Other hashes used in a hash map may be smaller, as collision resistance is usually not required; instead the hash just needs to be well distributed, so that hashed values are distributed equally.
Computers generally only address bytes, not bits. So commonly the hashes are a multiple of 8 bits. Even more generally, they are commonly a power of two, or two or three powers of two added together (160 bits for 128 + 32 bits).
Now to view those well distributed bytes we need to have some kind of way to view these bit values using printable characters. One way to do that is base 64. However, for these relatively short values hexadecimals are usually preferred, and that's what you have in the question.
So can you see if it is a hash value or not? Well, yes and no. You can see with a pretty good likelihood that it is a 40 character hexadecimal value, which represents a 20 bytes or 20 * 8 = 160 bit value. We can also "see" that it is pretty well distributed and that it doesn't encode printable ASCII (as there are values above 7E hex).
Testing with a regex that the contents are (upper or lowercase) hexadecimals is easy enough. That it is 40 characters for 160 bits should be easy as well. However, to test that it is indeed a well distributed value is not really possible with regular expressions. It is even not easy for any program code, as "random" values may now and then look surprisingly non-random. Besides that, not only hashes consist of well distributed byte values. Ciphertext and - of course - random byte values have similar properties.
So, yeah, you can verify that the output format is compatible with a hash value, but testing if it is a hash value is not really possible.
The regexp:
[0-9A-Fa-f]{40}
would of course wipe "Tim" out. You can be 100% sure that "Tim" is not a 160 bit hash value encoded in hexadecimals after all.

crc32 hash default/invalid value?

I am building a simple string ID system using crc32 to generate 32 bit integer handles from my strings. I'd like to default the hash inside my StringID wrapper class to an invalid index by default, is there a value that crc32 will never generate? Will I have to use a separate flag?
Clarification: I am not interested in language specific answers. I'd simply like to know if there is an integer outside of the crc32 range that can be used to represent an unhashed value.
Thanks!
Is there a value that crc32 will never generate?
No, it will generate any/all values in the range of a 32-bit integer.
Will I have to use a separate flag?
Not necessarily.
If you decide that (e.g.) 0x00000000 means "CRC not set" and non-zero is the CRC value; then after calculating the CRC (but before storing it or checking the stored value) you can do if(CRCvalue == 0) CRCvalue = 0xFFFFFFFF;.
This weakens the CRC by an extremely tiny amount. Specifically, for 2 random pieces of data, for pure CRC32 there's 1 chance in 4294967296 of the CRCs matching, and with "zero means unset" there's 1 chance in 4294967295.000000000232830643654 of the CRCs matching.
There is an easy demonstration to the fact that you can generate any crc32 value, as it is de division mod P (where P is the generator polynomial) in a galois field (which happens to be a field, as real or complex numbers are), you can subtract (this is a XOR operation, so adding and subtracting are indeed the same thing) to your polynomial its modulus, giving a 0 remainder, then you can add to this multiple of the modulus any of all the possible crc32 values to it (as they are already remainders of divisions, their crc32 is just themselves) to get any of the 2^32 possible values.
It is a common practice to add as many zero bits as necessary to complete a full 32 bit word (this appears as a multiplication by a constant value x^32), and then subtract(xor) the remainder to that, making the result a multiple of of the modulus (remember that the addition and subtraction are the same ---a xor operation) and so making the crc32(pol) = 0x0000;
edit(easier to see)
Indeed, each of the possible 2^32 values for crc32, when divided by the generator polynomial, give themselves as a result (they are coprime with the generator polynomial, as are the numbers 1 .. N when doing arithmetic modulo N on integers) so they all are possible results of the crc32() operator.
The crc operation, as implemented in many places, is not that simple... as some implementations initialize the remainder register as 0xffffffff and look for 0xffffffff at termination(indeed, crc32 does this).... If you do the maths, you'll guess the reason for that: Initializing the register to 0x11111111 is equivalent to having a previous remainder of 0xffffffff in a longer string... and looking for 0xffffffff at the end is like appending 0xffffffff to the original string. This has the effect of concatenating the bit string 0xffffffff before and after your string, making the remainder sensible to appends of a string of zeros before and after the crc32 calculated string (altering the string of bits by appending zeros at either side). Anyway, this modification doesn't alter the original algorithm of calculating a polynomial remainder, so any of the 2**32 values are possible also in this case.
No. A CRC-32 can be any 32-bit value. You'll need to indicate an invalid index somewhere else.
My spoof code allows you to choose bit locations in a message to modify and the desired CRC, and will solve for which of those locations to flip to get exactly that CRC.

How does the quality of 128 bit MurmurHash3 change in case of small key length or output truncation?

I have 64bit machine and I want to use 128 bits murmurhash3 due to its speed (MurmurHash3_x64_128 function in https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp).
But the thing is my inputs to this hash function won't be more than 30 bytes long, in which case the for loop in that MurmurHash3_x64_128 function will only iterate once, and then the tail part will be done. In such a scheme, it seems like the mixing wont be that great. Am I right? If not, could you please elaborate why? If yes, what would you suggest the reasonable minimum length of input key to 128 bits murmurhash3, so that hashing is good?
The second thing is about the truncation of the output bits. As far as I understood from the answer https://stackoverflow.com/a/11488383/7056851, although it causes more collision rate due to less output range, slicing the output will still give good hash values if the original hash function is "random" enough. My question is then if the 128 bit murmurhash3 is a good candidate for output truncation. The reason why I am asking this is that I want to use the MurmurHash3_x64_128 for its speed performance but I only need 32-bit hash values so I am planing to separate the 128 bits to 32 bits and get 4 32-bits hash values for a given key. But I am doubtful about how good the resulting hash values are.
One last question is about the endianness. If you look at the comment at line 52 in the link to the source code, it says:
Block read - if your platform needs to do endian-swapping or can only handle aligned reads, do the conversion here
Why does whether the platform is little endian or big endian matter? After all, all the bits are multipled with some constants and rotated and XORed, etc. and what we want from a hash function is basically to map the input keys to the output range, with a uniform distribution. How the endianness change the picture? And even if it changes the picture, what if the input is an array of char? The endianness shouldn't matter at least for such keys as array of chars, should it?
As you can see, I am not very good at analyzing hash functions. Any clear explanation is appreciated.

32 bit CRC with some inputs set to zero. Is this less accurate than dummy data?

Sorry if I should be able to answer this simple question myself!
I am working on an embedded system with a 32bit CRC done in hardware for speed. A utility exists that I cannot modify that initially takes 3 inputs (words) and returns a CRC.
If a standard 32 bit was implemented, would generating a CRC from a 32 bit word of actual data and 2 32 bit words comprising only of zeros produce a less reliable CRC than if I just made up/set some random values for the last 2 32?
Depending on the CRC/polynomial, my limited understanding of CRC would say the more data you put in the less accurate it is. But don't zero'd data reduce accuracy when performing the shifts?
Using zeros will be no different than some other value you might pick. The input word will be just as well spread among the CRC bits either way.
I agree with Mark Adler that zeros are mathematically no worse than other numbers. However, if the utility you can't change does something bad like set the initial CRC to zero, then choose non-zero pad words. An initial CRC=0 + Data=0 + Pads=0 produces a final CRC=0. This is technically valid, but routinely getting CRC=0 is undesirable for data integrity checking. You could compensate for a problem like this with non-zero pad characters, e.g. pad = -1.

Hash 16-bit integer to a 256-bit space efficiently

It sounds weird to be going bigger, but that's what I'm trying to do. I want to take the entire sequence of 16-bit integers and hash each one in such a way that it maps to 256-bit space uniformly.
The reason for this is that I'm trying to put a subset of the 16-bit number space into a 256-bit bloom filter, for fast membership testing.
I could use some well-known hashing function on each integer, but I'm looking for an extremely efficient implementation (just a few instructions) so that this runs well in a GPU shader program. I feel like the fact that the hash input is known to be only 16-bits can inform the hash function is designed somehow, but I am failing to see the solution.
Any ideas?
EDITS
Based on the responses, my original question is confusing. Sorry about that. I will try to restate it with a more concrete example:
I have a subset S1 of n numbers from the set S, which is in the range (0, 2^16-1). I need to represent this subset S1 with a 256-bit bloom filter constructed with a single hashing function. The reason for the bloom filter is a space consideration. I've chosen a 256-bit bloom filter because it fits my space requirements, and has a low enough probability of false positives. I'm looking to find a very simple hashing function that can take a number from set S and represent it in 256 bits such that each bit has roughly equal probability of being 1 or 0.
The reason for the requirement of simplicity in the hashing function is that this hashing function is going to have to run thousands of times per pixel, so anywhere where I can trim instructions is a win.
If you multiply (using uint32_t) a 16 bit value by prime (or for that matter any odd number) p between 2^31 and 2^32, then you "probably" smear the results fairly evenly across the 32 bit space. Then you might want to add another prime value, to prevent 0 mapping to 0 (you want each bit to have an equal probability of being 0 or 1, only one input value in 2^256 should have output all zeros, and since there are only 2^16 inputs that means you want none of them to have output all zeros).
So that's how to expand 16 bits to 32 with one operation (plus whatever instructions are needed to load the constant). Use four different values p1 ... p4 to get 256 bits, and run some tests with different p values to find good ones (i.e. those that produce not too many more false positives than what you expect for your Bloom filter given the size of the set you're encoding and assuming an ideal hashing function). For example I'm pretty sure -1 is a bad p-value.
No matter how good the values you'll see some correlations, though: for example as I've described it above the lowest bit of all 4 separate values will be equal, which is a pretty serious dependency. So you probably want a couple more "mixing" operations. For example you might say that each byte of the final output shall be the XOR of two of the bytes of what I've described (and not two least-siginficant bytes!), just to get rid of the simple arithmetic relations.
Unless I've misunderstood the question, though, this is not how a Bloom filter usually works. Usually you want your hash to produce an exact fixed number of set bits for each input, and all the arithmetic to compute the false positive rate relies on this. That's why for a Bloom filter 256 bits in size you'd normally have k 8-bit hashes, not one 256-bit hash. k is normally rather less than half the size of the filter in bits (the optimal value is the number of bits per value in the filter, times ln(2) which is about 0.7). So normally you don't want the probability of each bit being 1 to be anything like as high as 0.5.
The reason is that once you've ORed as few as 4 such 256-bit values together, almost all the bits in your filter are set (15 in 16 of them). So you're looking at a lot of false positives already.
But if you've done the math and you're happy with a single hash function producing a variable number of set bits averaging half of them, then fair enough. Or is the double-occurrence of the number 256 just a coincidence, because k happens to be 32 for the set size you have chosen and you're actually using the 256-bit hash as 32 8-bit hashes?
[Edit: your comment clarifies this, but anyway k should not get so high that you need 256 bits of hash in total. Clearly there's no point in this case using a Bloom filter with more than 16 bits per value (i.e fewer than 16 values), since using the same amount of space you could just list the values, and have a false positive rate of 0. A filter with 16 bits per value gives a false positive rate of something like 1 in 2200. Even there, optimal k is only 23, that is you should set 23 bits in the filter for each value in the set. If you expect the sets to be bigger than 16 values then you want to set fewer bits for each element, and you'll get a higher false positive rate.]
I believe there is some confusion in the question as posed. I will first try to clear up any inconsistencies I've noticed above.
OP originally states that he is trying to map a smaller space into a larger one. If this is truly the case, then the use of the bloom filter algorithm is unnecessary. Instead, as has been suggested in the comments above, the identity function is the only "hash" function necessary to set and test each bit. However, I make the assertion that this is not really what the OP is looking for. If so, then the OP must be storing 2^256 bits in memory (based on how the question is stated) in order for the space of 16-bit integers (i.e. 2^16) to be smaller than his set size; this is an unreasonable amount of memory to be using and is highly unlikely to be the case.
Therefore, I make the assumption that the problem constraints are as follows: we have a 256-bit bit vector in which we want to map the space of 16-bit integers. That is, we have 256 bits available to map 2^16 possible different integers. Thus, we are not actually mapping into a larger space, but, instead, a much smaller space. Similarly, it does appear (again, as previously pointed out in the comments above) that the OP is requesting a single hash function. If this is the case, there is clear misunderstanding about how bloom filters work.
Bloom filters typically use a set of hash independent hash functions to reduce false positives. Without going into too much detail, every input to the bloom filter runs through all n hash functions and then the resulting index in the bit vector is tested for each function. If all indices tested are set to 1, then the value may be in the set (with proper collisions in all n hash functions or overlap, false positives will occur). Moreover, if any of the indices is set to 0, then the value is absolutely not in the set. With this in mind, it is important to notice that an entirely saturated bloom filter has no benefit. That is, every query to the bloom filter will return that the item is in the set.
Hash Function Concerns
Now, back to the OP's original question. It is likely going to be best to use known hashing algorithms (since these are mathematically difficult to write and "rolling your own" typically doesn't end well). If you are worried about efficiency down to clock-cycles, implement the algorithm yourself in the appropriate assembly language for your architecture to reduce running time for each hash function. Remember, algorithmically, hash functions should run in O(1) time, so they should not contribute too much overhead if implemented properly. To start you off, I would recommend considering the modified bernstein hash. I have written a version for your specific case below (mostly for example purposes):
unsigned char modified_bernstein(short key)
{
unsigned ret = key & 0xff;
ret = 33 * ret ^ (key >> 8);
return ret % 256; // Try to do some modulo math to keep it in range
}
The bernstein method I have adapted generally runs as a function of the number of bytes of the input. Since a short type is 2 bytes or 16-bits, I have removed any variables and loops from the algorithm and simply performed some bit twiddling to get at each byte. Finally, an unsigned char can return a value in the range of [0,256) which forces the hash function to return a valid index in the bit vector.