mirror of
https://github.com/status-im/status-keycard.git
synced 2025-01-22 11:39:58 +00:00
make right shift work on both simulator and JavaCard
This commit is contained in:
parent
f134be461c
commit
b2543239aa
@ -360,13 +360,13 @@ public class WalletApplet extends Applet {
|
||||
|
||||
for (short i = GENERATE_MNEMONIC_TMP_OFF; i < entLen; i += 2) {
|
||||
short w = Util.getShort(apduBuffer, i);
|
||||
Util.setShort(apduBuffer, outOff, (short)((short)(((short)(vp | ((short) (w >>> rShift)))) >>> 5) & (short) 0x7ff));
|
||||
Util.setShort(apduBuffer, outOff, logicrShift((short) (vp | logicrShift(w, rShift)), (short) 5));
|
||||
outOff += 2;
|
||||
rShift += 5;
|
||||
vp = (short) (w << (16 - rShift));
|
||||
|
||||
if (rShift >= 11) {
|
||||
Util.setShort(apduBuffer, outOff, (short)((short) (vp >>> 5) & (short) 0x7ff));
|
||||
Util.setShort(apduBuffer, outOff, logicrShift(vp, (short) 5));
|
||||
outOff += 2;
|
||||
rShift = (short) (rShift - 11);
|
||||
vp = (short) (w << (16 - rShift));
|
||||
@ -381,6 +381,20 @@ public class WalletApplet extends Applet {
|
||||
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, outLen);
|
||||
}
|
||||
|
||||
// This works on simulator AND on JavaCard. Since we do not do a lot of these operations, the performance hit is non-existent
|
||||
private short logicrShift(short v, short amount) {
|
||||
if (amount == 0) return v; // short circuit on 0
|
||||
short tmp = (short) (v & 0x7fff);
|
||||
|
||||
if (tmp == v) {
|
||||
return (short) (v >>> amount);
|
||||
}
|
||||
|
||||
tmp = (short) (tmp >>> amount);
|
||||
|
||||
return (short) ((short)((short) 0x4000 >>> (short) (amount - 1)) | tmp);
|
||||
}
|
||||
|
||||
private void sign(APDU apdu) {
|
||||
apdu.setIncomingAndReceive();
|
||||
|
||||
|
@ -30,6 +30,7 @@ import java.security.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.apache.commons.codec.digest.DigestUtils.sha256;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@DisplayName("Test the Wallet Applet")
|
||||
@ -560,18 +561,33 @@ public class WalletAppletTest {
|
||||
}
|
||||
|
||||
private void assertMnemonic(int expectedLength, byte[] data) {
|
||||
short[] shorts = new short[data.length/2];
|
||||
short[] shorts = new short[data.length / 2];
|
||||
assertEquals(expectedLength, shorts.length);
|
||||
ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN).asShortBuffer().get(shorts);
|
||||
|
||||
boolean[] bits = new boolean[11 * shorts.length];
|
||||
int i = 0;
|
||||
|
||||
for (short mIdx : shorts) {
|
||||
assertTrue(mIdx >= 0 && mIdx < 2048);
|
||||
for (int j = 0; j < 11; ++j) {
|
||||
bits[i++] = (mIdx & (1 << (10 - j))) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: the checksum should be validated. The problem is that the simulator should generate wrong values because of
|
||||
// the bitwise operator extends the type to int, while JavaCard does not support int at all. If we make it work on
|
||||
// the simulator then the code will not convert to CAP file at all. This means that the checksum can be tested only
|
||||
// on a real card.
|
||||
data = new byte[bits.length / 33 * 4];
|
||||
|
||||
for (i = 0; i < bits.length / 33 * 32; ++i) {
|
||||
data[i / 8] |= (bits[i] ? 1 : 0) << (7 - (i % 8));
|
||||
}
|
||||
|
||||
byte[] check = sha256(data);
|
||||
|
||||
for (i = bits.length / 33 * 32; i < bits.length; ++i) {
|
||||
if ((check[(i - bits.length / 33 * 32) / 8] & (1 << (7 - (i % 8))) ^ (bits[i] ? 1 : 0) << (7 - (i % 8))) != 0) {
|
||||
fail("Checksum is invalid");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Sign.SignatureData signMessage(byte[] message) throws Exception {
|
||||
|
Loading…
x
Reference in New Issue
Block a user