I am working on a VHDL implementation of the SHA-256 hash function.
I have some 32-bit unsigned signals defined as such:
SIGNAL a, b : UNSIGNED (31 downto 0);
Within the specifications of the SHA-256 algorithm, it says addition must be performed modulo 2^32 in order to retain the 32-bit size in case of an overflow. Now, according to the answer to this question, it sounds like overflow is already handled with modular addition in VHDL:
There is no overflow handling, the overflow carry is simply lost. Thus the result is simply the integer result of your operation modulo 2^MAX.
I have 2 questions:
In my case, MAX = 31 so does that mean that any addition operation I perform on a and b will be modded with 2^31?
I need to perform addition modulo 2^32 which obviously doesn't make sense since I am working with 32-bit numbers and 2^32 is one bit too large. So is it somehow implied that I should actually be modding with 2^31?
You are fine with unsigned(31 downto 0). The 2^MAX in the post you reference is an error and should read 2^length. The length of 31 downto 0 is 32.
Think about it, 31 downto 0 can represent numbers from 0 to 2^32-1, it wouldn't make much sense if any addition of that range would be modulo 2^31 if you can represent larger numbers!
I'm not sure I understand your second question, but addition modulo 2^32 yields results in the range of 0 to 2^32-1. 2^32 is illegal, thus it's quite fine that you can't represent it with your unsigned.
Related
With reference to this article:
https://www.digikey.com/eewiki/display/microcontroller/CRC+Basics
The polynomial key is an important part of the CRC. Keys are not just random polynomials; they are generated using a set of mathematical formulas and are intended to increase the number of mistakes that the CRC process identifies. The polynomial is typically defined by the network protocol or external device. Since there is a well-established set of keys available, the processes for defining keys is not discussed here.
I understand how the calculation of CRC with a given polynomial key, however, how does one generate the polynomial key, and to ensure it can catch as much error as possible with a given set of protocal?
I assume the polynomial key has something to do with:
data lengh
data speed
others?
The part about using mathematical formulas to generate CRC polynomials is somewhat misleading. The number of 1 bits in a CRC polynomial is the maximum possible Hamming distance (HD)for the polynomial, and generally the actual Hamming distance will be less depending on the data length. The maximum bit error detection is the Hamming distance - 1.
Generally CRC polynomials that detect a higher number of bits are the product of multiple prime polynomials. For example, for a 32 bit CRC that can detect up to 7 errors for data + crc length = 1024 bits, the 33 bit CRC polynomial 0x1f1922815 = 0x787*0x557*0x465*0x3*0x3. The 0x3 factor will detect any odd number of bit errors, so the CRC needs to detect all possible 6 bit errors in 1024 bits.
I'm not aware of a formula to determine the maximum bit error detection, and generally a somewhat optimized brute force search is done. As an example, say a 32 bit CRC polynomial is being checked to see if it can detect all 6 bit errors for data + crc length of 1024 bits, the number of possible 6 bit error patterns in 1024 bits is comb(1024,6) = 1,577,953,087,760,896. To reduce this to something reasonable, the number of possible 3 bit errors, comb(1024,3) = 178,433,024, is used to create a large table, each entry containing the CRC and 3 bit indexes. The table is sorted, and then used to check for collisions where a 3 bit pattern's CRC is the same as a different 3 bit pattern's CRC. A check for failure for 4 bit patterns will also be needed (checking for collisions between two different 2 bit patterns).
Generally as the data length gets smaller, the maximum number of error bits guaranteed to be detected increases. Here is a link to a bunch of CRC polynomials and their error detection capability.
https://users.ece.cmu.edu/~koopman/crc/crc32.html
The notes page explains the table entries:
http://users.ece.cmu.edu/~koopman/crc/notes.html
In a VHDL assignment, I have to make an ALU which outputs the result of the subtraction and two's complement and some other operations on 16bit inputs. In a way that the rtl code is compared with the functional one.
In the functional code, I have used arithmetic operations like "+", "-" and ..., but in the rtl, I have used structural VHDL. That is why I have to be accurate so the results of these codes show the same output. I don't know what parts of the codes might be useful to share.
I am working on a vhdl code that subtracts two "signed" numbers (signed in two's complement format) in the structural form. Normally for subtracting two unsigned numbers, we change the second one to two's complement and add the numbers.
But, now that we have signed numbers, say we want to subtract two 16 bit signed numbers that the last MSB is the sign bit. How does two's complement work here? (Looking at here), if I want to have a - b (a and b are signed numbers) I should have:
a + (two's complement b)
or
a + (not b)?
(a and b are signed in two's complement format)
I have a question regarding the non-linearity of the CRC32 in gnuradio.
I am working on a project where i need a linear CRC32 meaning that: crc(a xor b) = crc(a) xor crc(b), where a and b represent a packet.
The implementation of CRC32 in gnuradio is by default non-linear so i had to modify the code to make it linear.
I did some research on the theory behind CRC and i found out 2 reasons behind a non-linear CRC implementation:
1- with a linear CRC, we can have the same CRC for 2 different packets of zeros, for example crc(0000 0000) = crc(00000 00 00000). So if i add additional zeroes to a packet containing only zeros, well, the CRC will nont be able to detect the errors(additional zeros).
2- the second reason is that with a linear CRC, if i add zeros to the beginning of a packet, the CRC won't be able to detect the errors. for example: crc(10010 1101) = crc(0000 1000 1101)
Now my question is:
When transmitting packets between two USRPs, bits could have errors(due to bad SNR for example), so a bit "1" could become a bit "0" and vice versa. However, I don't think that bits could be added (like the two cases stated above) to the packets and thus the reasons of implementing a non-linear CRC should not apply to gnuradio.
So why do we have a non-linear CRC in gnuradio by default?
And, if i use a linear CRC when trasmitting between two USRP, would that be a problem?
Thank you,
Such CRCs are still linear, just with an added constant. As an analogy, y = a x is linear, but so is y = a x + b, where b is a non-zero constant.
In this case, crc(a xor b) xor crc(a) xor crc(b) is a constant for all equal length messages a and b. That constant is crc(0), i.e. the CRC of all zeros of that same message length.
There is absolutely no problem whatsoever with this sort of linearity, and in fact it has benefits. In particular, a change in the message that adds a prefix of zeros would be detected as an error.
I'm currently building a 16 bit ALU using Logisim (ie logic gates only), and am stuck on a division process. I am currently just using the simple standard "division algorithm loop" (as shown below):
Read input values;
Compare input values. Wait until comparison process has finished;
If A<B go to step 10. If A≥B, go to next step;
Subtract B from A;
Wait until subtraction process has finished;
Add one to count;
Wait until counting process has finished;
Write value from subtraction process to input;
Go to step 1;
Answer is count remainder A
This, however, takes a very long time for processes with large answers (repeating a 300 tick cycle 65,000 times isn't fun).
I'm just wondering if there are similar algorithms which are quicker (that exclusively use addition and/or subtraction and/or multiplication and any boolean logic) that could be implemented using logic gates.
Any help or ideas would be greatly appreciated!
Fraser
Use long-division. In binary, there is no multiplication, since the quotient at each bit position can only be 1 or 0. So it can be implemented as a conditional subtract (subtract if result non-negative) and shift.
That's just a crude outline, of course.
A typical approach for a 32/16:16+16 division would be to have the dividend stored in a pair of 16-bit registers (which get updated during operation) and the divisor in its own register (which doesn't). Sixteen times, subtract the upper 17 bits of the dividend from the divisor; if a borrow results, discard the result and shift the divisor left one place, putting a 0 into the lsb. If no borrow results, store the result into the divisor while shifting it left, but put a 1 into the lsb. After sixteen such steps, the lower 16 bits of the dividend register will hold the quotient, and the upper 16 bits will hold the remainder. Note that this operation will only work if the quotient is representable in 16 bits. Note also that on a processor which implements 32/16:16+16 division in this fashion, one may conveniently divide arbitrarily-large numbers by a 16-bit quantity, since the upper 16 bits of dividend for each step should be the remainder from the previous step.
My current textbook (Information Security: Principles and Practice by Mark Stamp) discusses how to determine the CRC of data via long-division, using XOR instead of subtraction to determine the remainder.
If our divisor has N-bits, we append (N-1) 0 bits to the dividend (the data) and then use long-division with XOR to solve for the CRC.
For example:
Divisor: 10011
Dividend: 10101011
101010110000 / 10011 = 10110110 R 1010, where 1010 = CRC
I'm able to perform this computation fine. However, the book mentions that in the case of the divisor being 10011, it's easy to find collisions.
I'm missing something here -- why is it easier to find a collision when the divisor is 10011?
See http://en.wikipedia.org/wiki/Cyclic_redundancy_check#Designing_CRC_polynomials for more details.
10011 corresponds to polynomial x^5+x+1 which is irreducible. And, using such codes decreases the chance of collisions.