package org.bouncycastle.pqc.math.linearalgebra; /** * This is a utility class containing data type conversions using big-endian * byte order. * * @see LittleEndianConversions */ public final class BigEndianConversions { /** * Default constructor (private). */ private BigEndianConversions() { // empty } /** * Convert an integer to an octet string of length 4 according to IEEE 1363, * Section 5.5.3. * * @param x the integer to convert * @return the converted integer */ public static byte[] I2OSP(int x) { byte[] result = new byte[4]; result[0] = (byte)(x >>> 24); result[1] = (byte)(x >>> 16); result[2] = (byte)(x >>> 8); result[3] = (byte)x; return result; } /** * Convert an integer to an octet string according to IEEE 1363, Section * 5.5.3. Length checking is performed. * * @param x the integer to convert * @param oLen the desired length of the octet string * @return an octet string of length <tt>oLen</tt> representing the * integer <tt>x</tt>, or <tt>null</tt> if the integer is * negative * @throws ArithmeticException if <tt>x</tt> can't be encoded into <tt>oLen</tt> * octets. */ public static byte[] I2OSP(int x, int oLen) throws ArithmeticException { if (x < 0) { return null; } int octL = IntegerFunctions.ceilLog256(x); if (octL > oLen) { throw new ArithmeticException( "Cannot encode given integer into specified number of octets."); } byte[] result = new byte[oLen]; for (int i = oLen - 1; i >= oLen - octL; i--) { result[i] = (byte)(x >>> (8 * (oLen - 1 - i))); } return result; } /** * Convert an integer to an octet string of length 4 according to IEEE 1363, * Section 5.5.3. * * @param input the integer to convert * @param output byte array holding the output * @param outOff offset in output array where the result is stored */ public static void I2OSP(int input, byte[] output, int outOff) { output[outOff++] = (byte)(input >>> 24); output[outOff++] = (byte)(input >>> 16); output[outOff++] = (byte)(input >>> 8); output[outOff] = (byte)input; } /** * Convert an integer to an octet string of length 8 according to IEEE 1363, * Section 5.5.3. * * @param input the integer to convert * @return the converted integer */ public static byte[] I2OSP(long input) { byte[] output = new byte[8]; output[0] = (byte)(input >>> 56); output[1] = (byte)(input >>> 48); output[2] = (byte)(input >>> 40); output[3] = (byte)(input >>> 32); output[4] = (byte)(input >>> 24); output[5] = (byte)(input >>> 16); output[6] = (byte)(input >>> 8); output[7] = (byte)input; return output; } /** * Convert an integer to an octet string of length 8 according to IEEE 1363, * Section 5.5.3. * * @param input the integer to convert * @param output byte array holding the output * @param outOff offset in output array where the result is stored */ public static void I2OSP(long input, byte[] output, int outOff) { output[outOff++] = (byte)(input >>> 56); output[outOff++] = (byte)(input >>> 48); output[outOff++] = (byte)(input >>> 40); output[outOff++] = (byte)(input >>> 32); output[outOff++] = (byte)(input >>> 24); output[outOff++] = (byte)(input >>> 16); output[outOff++] = (byte)(input >>> 8); output[outOff] = (byte)input; } /** * Convert an integer to an octet string of the specified length according * to IEEE 1363, Section 5.5.3. No length checking is performed (i.e., if * the integer cannot be encoded into <tt>length</tt> octets, it is * truncated). * * @param input the integer to convert * @param output byte array holding the output * @param outOff offset in output array where the result is stored * @param length the length of the encoding */ public static void I2OSP(int input, byte[] output, int outOff, int length) { for (int i = length - 1; i >= 0; i--) { output[outOff + i] = (byte)(input >>> (8 * (length - 1 - i))); } } /** * Convert an octet string to an integer according to IEEE 1363, Section * 5.5.3. * * @param input the byte array holding the octet string * @return an integer representing the octet string <tt>input</tt>, or * <tt>0</tt> if the represented integer is negative or too large * or the byte array is empty * @throws ArithmeticException if the length of the given octet string is larger than 4. */ public static int OS2IP(byte[] input) { if (input.length > 4) { throw new ArithmeticException("invalid input length"); } if (input.length == 0) { return 0; } int result = 0; for (int j = 0; j < input.length; j++) { result |= (input[j] & 0xff) << (8 * (input.length - 1 - j)); } return result; } /** * Convert a byte array of length 4 beginning at <tt>offset</tt> into an * integer. * * @param input the byte array * @param inOff the offset into the byte array * @return the resulting integer */ public static int OS2IP(byte[] input, int inOff) { int result = (input[inOff++] & 0xff) << 24; result |= (input[inOff++] & 0xff) << 16; result |= (input[inOff++] & 0xff) << 8; result |= input[inOff] & 0xff; return result; } /** * Convert an octet string to an integer according to IEEE 1363, Section * 5.5.3. * * @param input the byte array holding the octet string * @param inOff the offset in the input byte array where the octet string * starts * @param inLen the length of the encoded integer * @return an integer representing the octet string <tt>bytes</tt>, or * <tt>0</tt> if the represented integer is negative or too large * or the byte array is empty */ public static int OS2IP(byte[] input, int inOff, int inLen) { if ((input.length == 0) || input.length < inOff + inLen - 1) { return 0; } int result = 0; for (int j = 0; j < inLen; j++) { result |= (input[inOff + j] & 0xff) << (8 * (inLen - j - 1)); } return result; } /** * Convert a byte array of length 8 beginning at <tt>inOff</tt> into a * long integer. * * @param input the byte array * @param inOff the offset into the byte array * @return the resulting long integer */ public static long OS2LIP(byte[] input, int inOff) { long result = ((long)input[inOff++] & 0xff) << 56; result |= ((long)input[inOff++] & 0xff) << 48; result |= ((long)input[inOff++] & 0xff) << 40; result |= ((long)input[inOff++] & 0xff) << 32; result |= ((long)input[inOff++] & 0xff) << 24; result |= (input[inOff++] & 0xff) << 16; result |= (input[inOff++] & 0xff) << 8; result |= input[inOff] & 0xff; return result; } /** * Convert an int array into a byte array. * * @param input the int array * @return the converted array */ public static byte[] toByteArray(final int[] input) { byte[] result = new byte[input.length << 2]; for (int i = 0; i < input.length; i++) { I2OSP(input[i], result, i << 2); } return result; } /** * Convert an int array into a byte array of the specified length. No length * checking is performed (i.e., if the last integer cannot be encoded into * <tt>length % 4</tt> octets, it is truncated). * * @param input the int array * @param length the length of the converted array * @return the converted array */ public static byte[] toByteArray(final int[] input, int length) { final int intLen = input.length; byte[] result = new byte[length]; int index = 0; for (int i = 0; i <= intLen - 2; i++, index += 4) { I2OSP(input[i], result, index); } I2OSP(input[intLen - 1], result, index, length - index); return result; } /** * Convert a byte array into an int array. * * @param input the byte array * @return the converted array */ public static int[] toIntArray(byte[] input) { final int intLen = (input.length + 3) / 4; final int lastLen = input.length & 0x03; int[] result = new int[intLen]; int index = 0; for (int i = 0; i <= intLen - 2; i++, index += 4) { result[i] = OS2IP(input, index); } if (lastLen != 0) { result[intLen - 1] = OS2IP(input, index, lastLen); } else { result[intLen - 1] = OS2IP(input, index); } return result; } }