-1

I am working with BigInteger, and using my function I write a BigInteger of 256 bits to a file (there are 64 such numbers)

public static byte[] toHH2(BigInteger n) {
    byte[] b = new byte[256];

    for(int i = 0; i < 256; i+=8) {
        b[i] = (byte) (n.longValue() >> (248 - i) & 0xff);
    }
    return b;
}

Then I need to read this 256 bit number and write it to a variable. But for some reason, I end up with a maximum of 64 bit numbers, and I need 256, how to fix the error?

var dataSignatureInt = bytesToIntArray(Files.readAllBytes(Path.of("C:\\Users\\User\\IdeaProjects\\CryptoLab1\\src\\crypto\\DigitalSignatureGOST.png")));
for(int i = 0; i < file.length; i+=256) { //file lenght = 16384 
    BigInteger value = BigInteger.valueOf(dataSignatureInt[i]);

    for(int j = 0; j < 256; j++) {
        System.out.println("i = " + i + " j = " + j);
        value = BigInteger.valueOf((value.longValue() << 8) | dataSignatureInt[i + j]);
    }
  • This does not appear to be reading anything from a file. – Scott Hunter Nov 16 '22 at 18:51
  • It reads a number of 64 bits, checked by debugging – Alica Smith Nov 16 '22 at 18:53
  • Read through all answers [here](https://stackoverflow.com/questions/3028380/how-to-convert-biginteger-to-string-in-java) and see if it gives you any ideas. – PM 77-1 Nov 16 '22 at 18:53
  • You realize this is only going to fill in 1 out of every 8 bytes in your array? What's the point in that? – ControlAltDel Nov 16 '22 at 18:54
  • Yes, I understand the error. But how can I make it fill the first 256 bytes of the file into the value variable? – Alica Smith Nov 16 '22 at 19:00
  • I need it to make a BigInt decimal number from the first 256 bytes – Alica Smith Nov 16 '22 at 19:01
  • When you write your BigDecimal, you calculate bytes and write 256 of them. When reading, you convert the byte[] into int[] and process that. Do you realize that an int is 16 bits and would thus consume 2 bytes? With that, your int[] should at most have 128 entries. – Queeg Nov 16 '22 at 19:21

1 Answers1

0

256 bits are 32 bytes, but somehow you do a bit per byte or such.

public static byte[] toHH2(BigInteger n) {
    byte[] b = n.toByteArray(); /// <= 32 bytes in big endian order!
    return Arrays.copyOf(b, 32 - b.length);
    if (b.length < 32) {
        byte[] b2 = new byte[256];
        System.arraycopy(b, 0, b2, 32 - b.length, b.length);
        if (b[0] < 0) { // Do sign extension, if most significant byte negative.
            for (int j = 0; j < 32 - b.length; ++j) {
                b2[j] = -1;
            }
        }
        b = b2;
    }
    return b;
}

For ease I have padded it. Not needed, but it shows that the most significant byte is at index 0 of the bytes.

// Now several such 32 byte arrays are stored in the file.
var dataSignatureInt = Files.readAllBytes(Path.of(
    "C:\\Users\\User\\IdeaProjects\\CryptoLab1\\src\\crypto\\DigitalSignatureGOST.png"));
int numberCount = dataSignatureInt.length / 32;
BigInteger[] numbers = new BigInteger[numberCount];

To split a large byte array into 32 byte subarrays, the class ByteBuffer is ideal.

ByteBuffer buf = ByteBuffer.wrap(dataSignatureInt);
byte[] bytes = new byte[32];
for (int i = 0; i < numberCount; ++i) {
    buf.get(bytes);
    numbers[i] = new BigInteger(bytes);        
}

Last but not least, you could consider using BitSet instead of BigInteger if you are interested in single bits.

BitSet bitSet = new BitSet(256);
byte[] shortenedBytes = bitSet.toByteArray();
bitSet = BitSet.valueOf(shortenedBytes);
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • Thank you! But I didn’t really understand what Do sign extension means, what should I write there? – Alica Smith Nov 16 '22 at 19:40
  • The essence of the task was that I got 64 numbers of 32 bytes each, I had to write them to a file, and then read the bytes of the file elsewhere and turn them into numbers that were originally – Alica Smith Nov 16 '22 at 19:42
  • The problem was that there could be numbers both 247 bits long and exactly 255, that is, I have to make the minimum size 32 bytes so that all numbers fit – Alica Smith Nov 16 '22 at 19:47
  • Okay I'll complete the code. – Joop Eggen Nov 16 '22 at 19:50
  • Probably all positive numbers then, so sign extension is not needed. (Negative numbers are padded to the left with 1 bits.) – Joop Eggen Nov 16 '22 at 20:00
  • Thank you again! But a small error: 'arraycopy(java.lang.Object, int, java.lang.Object, int, int)' in 'java.lang.System' cannot be applied to '(byte[], int, byte[], int)' and Expected 5 arguments but found 4 – Alica Smith Nov 16 '22 at 20:12
  • Corrected: source+index, destination+index, length – Joop Eggen Nov 16 '22 at 23:19