What's bad about shifting a 32-bit variable 32 bits?

I recently picked up a copy of Applied Cryptography by Bruce Schneier and it's been a good read. I now understand how several algorithms outlined in the book work, and I'd like to start implementing a few of them in C.

One thing that many of the algorithms have in common is dividing an x-bit key, into several smaller y-bit keys. For example, Blowfish's key, X, is 64-bits, but you are required to break it up into two 32-bit halves; Xl and Xr.

This is where I'm getting stuck. I'm fairly decent with C, but I'm not the strongest when it comes to bitwise operators and the like.

After some help on IRC, I managed to come up with these two macros:

#define splitup(a, b, c) {b = a >> 32; c = a & 0xffffffff; }
#define combine(a, b, c) {a = (c << 32) | a;}

Where a is 64 bits and b and c are 32 bits. However, the compiler warns me about the fact that I'm shifting a 32 bit variable by 32 bits.

My questions are these:

  • What's bad about shifting a 32-bit variable 32 bits? I'm guessing it's undefined, but these macros do seem to be working.
  • Also, would you suggest I go about this another way?

As I said, I'm fairly familiar with C, but bitwise operators and the like still give me a headache.

EDIT

I figured out that my combine macro wasn't actually combining two 32-bit variables, but simply ORing 0 by a, and getting a as a result. So, on top of my previous questions, I still don't have a method of combining the two 32-bit variables to get a 64-bit one; a suggestion on how to do it would be appreciated.

Yes, it is undefined behaviour.

ISO/IEC 9899:1999 6.5.7 Bitwise shift operators ¶3

The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.

C11 aka ISO/IEC 9899:2011 says the same.

You should first cast b to the target integer type. Another point is that you should put parentheses around the macro parameters to avoid surprises by operator precedences. Additionally, the comma operator is very useful here, allowing you to avoid the braces, so that the macro can be used as a normal command, closed with a semicolon.

#define splitup(a,b,c) ( (b) = (a) >> 32, (c) = (a) & 0xffffffff )
#define combine(a,b,c) ( (a) = ((unsigned long long)(b) << 32) | (c) )

Additional casts may be necessary for `splitup to silence warnings about precision loss by over-paranoid compilers.

#define splitup(a,b,c) ( (b) = (unsigned long)((a) >> 32), (c) = (unsigned long)((a) & 0xffffffff) )

And please don't even think about using your self-written encryption for production code.

What, What is COVID-19. Coronaviruses are a large family of viruses that cause respiratory infections. These can range from the common cold to more  Quickly send and receive WhatsApp messages right from your computer.

Shifting a 32-bit value by 32 bits or more is undefined in C and C++. One of the reasons it was left undefined is that on some hardware platforms the 32-bit shift instruction only takes into account 5 lowest bits of the supplied shift count. This means that whatever shift count you pass, it will be interpreted modulo 32. Attempting to shift by 32 on such platform will actually shift by 0, i.e. not shift at all.

The language authors did not want to burden the compilers written for such platform with the task of analyzing the shift count before doing the shift. Instead, the language specification says that the behavior is undefined. This means that if you want to get a 0 value from a 32-bit shift by 32 (or more), it is up to you to recognize the situation and process it accordingly.

What you need to know about coronavirus (COVID-19), What you should know about COVID-19 to protect yourself and others. Know about COVID-19. • Coronavirus (COVID-19) is an illness caused by a virus that can  noun the true nature or identity of something, or the sum of its characteristics: a lecture on the whats and hows of crop rotation.

what's bad about shifting a 32-bit variable 32 bits?

Its better to assign 0 to n-bit integer than to shift it by n-bits.

Example:

 0 0 1 0 1 ----- 5 bit Integer  
 0 1 0 1 0 ----- 1st shift  
 1 0 1 0 0 ----- 2nd shift  
 0 1 0 0 0 ----- 3rd shift  
 1 0 0 0 0 ----- 4th shift  
 0 0 0 0 0 ----- 5th shift (all the bits are shifted!)  

I still don't have a method of combining the two 32-bit variables to get a 64-bit one

Consider: a is 64 bit, b and c are 32 bit

a = b;
a = a << 32; //Note: a is 64 bit
a = a | c;

COVIDSafe app, macOS Catalina gives users even more of what they love. Dedicated apps for music, TV, and podcasts, a whole new class of Mac apps, and Sidecar. what definition: 1. used to ask for information about people or things: 2. used in questions that show you are…. Learn more.

Unless this is some "reinventing the wheel to understand how it works" project, don't implement your own crypto functions.

Ever.

It's hard enough to use the available algorithms to work (and to choose the right one), don't shoot yourself in the foot by putting in production some home grown cryptor API. Chances are your encryption won't encrypt

What, MyPlate is a reminder to find your healthy eating style and build it throughout your lifetime. Everything you eat and drink matters. The right mix can help you be​  whatever: adverb at all , of any description , of any kind or sort , whatsoever , whichever

What's bad about shifting a 32-bit variable 32 bits?

In addition to what have been already said, the 32nd bit is the sign bit, and you may get sign extension to preserve the sing, thereby losing significant bits.

[PDF] Coronavirus Fact Sheet, What 'Less Lethal' Weapons Actually Do. Rubber bullets and tear gas are not as innocuous as they sound. By Kelsey D. Atherton on June 23,  WhatsApp Messenger: More than 2 billion people in over 180 countries use WhatsApp to stay in touch with friends and family, anytime and anywhere. WhatsApp is free and offers simple, secure, reliable messaging and calling, available on phones all over the world.

macOS Catalina, P!nk's official music video for 'So What'. Click to listen to P!nk on Spotify: http://​smarturl.it Duration: 3:46 Posted: 25 Oct 2009 This is the ORIGINAL "What What (In the Butt)" video. The South Park version aired over a year after we made this video. There's been a lot of confusion about this.

What is MyPlate?, What Is My IP? WhatIsMyIP.com® is the industry leader in providing REAL IP address information. We provide IP address tools that allow users to perform an Internet Speed Test, IP address lookup, proxy detection, IP Whois Lookup, and more.

What 'Less Lethal' Weapons Actually Do, Seen a font in use and want to know what it is? Upload an image to WhatTheFont to find the closest matches in our database.

Comments
  • +1, awesome question, thanks for taking the time to format it correctly and welcome to Stack Overflow!
  • By the way, I bet your combine macro is supposed to be ORing with b, not a, right?
  • It is probably worth pointing out that "some platforms" in this case includes x86.
  • unbelievable... compilers should "compensate" for underlying hardware architecture "limits"... what if it would exist a processor not implementing bit shift (odd!!) at all? the whole result of >> or << would be undefined?! funny...
  • @ShinTakezou: Some programs needs to evaluate x << (y & 31). Sometimes programs need y >= 32 ? 0 : x << y. Some will be equally happy with either result. If the Standard mandated either behavior, then compilers for at least some platforms would have to generate needless code for programs that didn't care which result they received. Worse, when programs needing the opposite kind of result are run on platforms which would "naturally" return what the program wanted, programmers would have to write code to overcome effects of the the unwanted extra code introduced by the compiler.
  • @ShinTakezou: C compilers do have to compensate a lot for various hardware peculiarities. There are many places in C language spec that introduce a gap between language requirements and typical hardware behavior. By nature of the language (e.g. it is not Java), a performance-oriented compromise is needed. Apparently, the authors decided that in this case it should gravitate closer towards the hardware side of things. I don't know the exact arguments that supported this decision, but one can definitely say that bit-shift is a low-level operation that would benefit from the best performance.
  • five years later, two answers… nice! I think that if you are going to do "heavy" bits stuff on a specific uncommon hardware/platform, then the safer approach would be to stick to assembly (maybe use inline assembly functions or similar), if you can (and I believe you usually can…), so you are sure about what you are doing—provided you know enough of that CPU… otherwise back to pure C and eyes opened…
  • Oh, okay. So my combine macro was ORing 0 by a to get a; which, if I'm correct, means it wasn't actually combining the two 32-bit variables to make one 64-bit variable. darn.
  • Thanks for the tip, but this is one of those "reinventing the wheel to understand how it works" projects. :)
  • OK then, but don't forget to destroy the code when you're done :D
  • Actually it's the bit 31 which is the sign bit (i.e. 1u<<31). But in any case, this is irrelevant for unsigned types.