0

Alright, I'll keep this plain & simple.

I'm working on a brute implementation of SHA-256 in Java, and to keep the class methods conducive to other classes in the app, I've decided to I/O the data as an array of 32-bit integers (int). Obviously, these kinds of uses rely heavily on use of bitwise operators, so how do I accomplish bitwise shifting across an array of ints, as such:

Given an array of data, suppose:

 int[16] data;

where the first 14 integers' worth of data is filled with 0x0000000, for the purposes of conversation, but the lowest two are filled respectively:

 data[14] = 0x12345678;
 data[15] = 0x01ABCDEF;

How do I accomplish a leftwise shift so that if shifted left by two,

 data[13] = 0x00000012;
 data[14] = 0x34567801;
 data[15] = 0xABCDEF00;

Anyone got any ideas?

ecfedele
  • 306
  • 3
  • 15
  • When you shift, also OR in the correct bits from the next int. For example, `data[15] = (data[15] << 2) | (data[14] >>> 30)` – harold Nov 16 '13 at 10:55
  • 1
    Perhaps use a BigInteger and create an API "to keep the class methods conducive to other classes in the app". BigInteger has methods like `shiftLeft(int n)` see http://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html – Ron Nov 16 '13 at 10:57
  • @RonE - Is it possible to construct a `BigInteger` instance from a int array? The Oracle literature only supplies examples using a byte array. Does the 32- versus 8-bit nature make a difference during construction? – ecfedele Nov 16 '13 at 11:00
  • @blasthash If you receive your data as an int[16] then write a method that converts it to a byte[64] – Ron Nov 16 '13 at 11:03
  • Or just shift them like I said. It's not hard. – harold Nov 16 '13 at 11:04
  • OP didn't say it was a circular shift. Even if it is, it's still trivial. – harold Nov 16 '13 at 11:06
  • Yes, obviously everyone knows everything about SHA-256. Anyway, you only need to save data[15], not the entire thing. – harold Nov 16 '13 at 11:08
  • @RonE well ok. But are you sure it's true? OP said in a comment that it's for the padding stage, and I don't really see why that should be a circular shift. The rest of the algorithm has rotations, but they're on 32bit integers. – harold Nov 16 '13 at 11:23
  • @harold I think you're right, OP should explain the usage more clearly in the question. – Ron Nov 16 '13 at 11:30
  • You can convert the int array to bytes with `ByteBuffer buffer = ByteBuffer.allocate(data.length * 4); buffer.asIntBuffer().put(data); byte[] bytes = buffer.array();` – VGR Nov 16 '13 at 11:30

2 Answers2

0

1) Write a helper method to convert your int[16] data to byte[64] bytedata.

2) Create a BigInteger using the constructor BigInteger(byte[] val)

3) Bitshift using shiftLeft(int n) and shiftRight(int n)

4) Write a helper method to convert your byte[64] bytedata back to int[16] data. See byte array to Int Array here

Other useful methods in BigInteger include clearBit(int n), setBit(int n), flipBit(int n), and testBit(int n)

Community
  • 1
  • 1
Ron
  • 1,450
  • 15
  • 27
-1

For bitwise shift left:

`x << n` is the same as `x *= 2^n`  

To see the overflowing bit (MSB): x / (2^32) >= 1 //Since we are using an 32 bit int


Likewise, for bitwise shift right:

`x >> n` is the same as `x /= 2^n`  

To see the overflowing bit (LSB): x % 2

Append the overflowing bit to the adjacent int by adding or subtracting set values. You should really use a BigInteger like I mentioned in my comment, anything else will require an implementation where you read and append the bits moving between array locations yourself.

Ron
  • 1,450
  • 15
  • 27
  • Is it possible to 'downconvert' back to a int array from BigInteger? If you've read the algo, the stage I'm implementing is the _padding_ stage, where an arbitrary number of bits are appended to the end of the value to establish the number at 512-bit. Most of the other processing in the algorithm though, is by _direct_ relation of specific 32-bit segments in the array to constants or functions, so I'd prefer to be able to retain the ease of that capacity. – ecfedele Nov 16 '13 at 11:08
  • I could do it by shifting right 32, then back 32 to get 32 bits truncated and divide, but that's a roundabout and inefficient method. – ecfedele Nov 16 '13 at 11:10
  • @blasthash Yes, use `toByteArray()` and write a helper function to convert to an int array. Java is about layers and chaining, use modular pieces to achieve your goal. – Ron Nov 16 '13 at 11:10