I am trying to convert some Java code to Javacard code, where I cannot use type int or long, but I am running into an issue. The code I have that I want to convert:
void someFunction(short a, short b)
{
int x = (int)((int)a * (int)b);
}
Since Javacard cannot use integer types at all, I tried to convert this using a 'multiplyShorts' function, which looks as following:
public static short[] multiplyShorts(short a, short b)
{
short aHigh = (short)((a >> 8) & 0xFF);
short aLow = (short)(a & 0xFF);
short bHigh = (short)((b >> 8) & 0xFF);
short bLow = (short)(b & 0xFF);
short lowLow = (short)(aLow * bLow);
short highLow = (short)(aHigh * bLow);
short lowHigh = (short)(aLow * bHigh);
short highHigh = (short)(aHigh * bHigh);
short[] result = new short[2];
result[1] = (short)(lowLow & 0xFF);
short carry = (short)((lowLow >> 8) & 0xFF);
short middle = (short)(highLow + lowHigh + carry);
result[1] |= (short)((middle & 0xFF) << 8);
result[0] = (short)((middle >> 8) & 0xFF);
result[0] = (short)(result[0] + highHigh);
return result;
}
This code is working in most cases, but not for all {a,b} ∈ {0...65535}, as example the case of a=0xFFFF and b=0xFFFF I would expect:
result[0] = 0xFFFE = 0b11111111_11111110
result[1] = 0x0001 = 0b00000000_00000001
However, the result I get is:
result[0] = 0xFEFE = 0b11111110_11111110 //Spot the difference on this line
result[1] = 0x0001 = 0b00000000_00000001
Can someone explain me what I am missing here, or provide me any help converting my code?
You can just create the two values using assignSigned
and then call multiply
given my XMas special answer that implements JCInteger
. You probably want to use JCSystem.makeTransientByteArray(CLEAR_ON_RESET)
if you want to use RAM.
There might be a shortcut as the 16 high bits of the integer that is created are always either 0x0000
or 0xFFFF
in your particular situation, but I cannot think of one out of my head, mainly because most of the outcome will rely on the lower bits rather than the higher bits in most situations.
Note that short[] result = new short[2];
creates an array in persistent memory for Java Card classic, something you very likely don't want within a multiply method. It's not just that it puts the result in EEPROM or flash, but also that it will require a call to the garbage manager to clean up.