| lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
|
Open Source and information security mailing list archives
| ||
|
Message-ID: <CAOLP8p7Qy6mWdRaUwNp3PYzNgADiXeAJunt0h0XANpDOOZJBjw@mail.gmail.com> Date: Sun, 9 Feb 2014 09:04:53 -0500 From: Bill Cox <waywardgeek@...il.com> To: discussions@...sword-hashing.net Subject: Fwd: [PHC] multiply-hardening (Re: NoelKDF ready for submission) Gary thought a reply to the list might make sense... I don't know how many readers we have that would benefit, but in any case, here's my response to Gary's request for an explanation of the multiply by a constant stuff I wrote: ---------- Forwarded message ---------- From: Bill Cox <waywardgeek@...il.com> Date: Sun, Feb 9, 2014 at 8:59 AM Subject: Re: [PHC] multiply-hardening (Re: NoelKDF ready for submission) To: "Gary W. Hvizdak" <gary.hvizdak@....rr.com> That last part is about the complexity of multiplication with a constant as one operand vs two variables. We build multipliers in silicon much the way you do it by hand, with rows of partial products that we then add together to get a result. The partial products are either 0 or the upper value shifted left some distance, since we only multiply by 0 or 1. Adding the partial products together is easily done with "carry save adders", which are just adders with and AND gate on one input, so that we either add 0 or the value shifted by some distance. This would normally take 32 32-bit carry-save adders to do a 32x32 multiply. Some genius figured out that you can build a subtractor just as easily as an adder, and that with an XOR gate on the input, you can build an adder/subtractor that can do either. With clever encoding of one operand, called "Booth encoding", you can do a 32x32 multiply with only 16 adder/subtractors, cutting the area almost in half while making it faster. With one operand as a constant, we can pre-compute the optimal way to have the non-constant operand shifted and added/subtracted. For example, any multiply by a constant with only 2 bits set to 1 can be implemented with a single adder. For example 12*a = (8 + 4)*a = 8*a + 4*a = (a << 3) + (a << 2). If I want to compute 15*a, I can do it as 15*a = (16 - 1)*a = 16*a - a = (a << 4) - a. Shifting in hardware is free. You just move the wires. So, multiplication by 15 takes one subtractor. You don't have to do power-of-two decomposition of a constant. We do that because shifting is free. For example, to compute 13*a we can first compute 3*a = (a << 1) + a. We then can compute (16-3)*a = (a << 4) - 3*a. This requires an adder and a subtractor. In general, if we can find a way to add and subtract and shift numbers starting with 1 that add up to a constant, we only need the number of adder/subtractors used to build a multiplier by that constant. That's why it's an interesting problem to find the minimum number required for any given constant. I wrote a quick inefficient hack to do it. Samual pointed out a standard program used to do it that runs much faster. In any case, multiplication by a constant is too fast in custom hardware compared to multiplying two variables, so I'm not switching to the hash function Alexander suggested. Bill
Powered by blists - more mailing lists