7

Tôi cần triển khai nhanh nhất có thể khi dịch chuyển bit trái của mảng 16 byte trong JavaCard.Thay đổi bit nhanh của mảng byte - khóa con CMAC

Tôi đã thử mã này:

private static final void rotateLeft(final byte[] output, final byte[] input) { 
     short carry = 0; 
     short i = (short) 16; 
     do { 
      --i; 
      carry = (short)((input[i] << 1) | carry); 
      output[i] = (byte)carry; 
      carry = (short)((carry >> 8) & 1); 
     } while (i > 0); 
} 

Bất kỳ ý tưởng làm thế nào để cải thiện performace? Tôi đã suy nghĩ về một số Util.getShort(...)Util.setShort(...) phép thuật, nhưng tôi đã không quản lý để làm cho nó hoạt động nhanh hơn sau đó thực hiện ở trên.

Đây là một phần của tính toán con CMAC subkeys và nó được thực hiện khá thường xuyên, không may. Trong trường hợp bạn biết một số cách nhanh hơn để tính toán các khóa con CMAC (cả hai khóa con trong một vòng lặp hoặc một cái gì đó tương tự), xin vui lòng, cho tôi biết.

+0

Tôi thu thập JavaCard được xen kẽ? Nếu vậy thì tôi khuyên bạn nên xem xét mã byte được tạo ra và tối ưu hóa với tập lệnh có sẵn trong đầu. Ví dụ tôi nghi ngờ ints có thể là thích hợp hơn để quần short, và vòng lặp đó unrolling có thể đạt được bạn một vài chu kỳ. Ngoài ra, tôi nghi ngờ rằng bạn sẽ làm nhiều hơn một phép tính số học chính xác mở rộng để có thể chuyển sang một số nguyên rộng hơn sớm để xử lý nhanh hơn và chuyển đổi lại mảng 8 bit ở cuối. – doynax

+0

@doynax không có 'int' hoặc' long' trong JavaCard ... 'byte' và' short' là tất cả những gì bạn có. – vojta

+0

Xin lỗi về điều đó, âm thanh như một môi trường đặc biệt làm tê liệt. Mặc dù vậy, quan điểm của tôi vẫn đứng vững, theo dõi mã byte được tạo để đảm bảo rằng trình biên dịch không quyết định tạo ra các lệnh 'i2s' không cần thiết trên các kết quả trung gian ngắn-nhưng-không-thực sự. – doynax

Trả lời

3

Khi nói đến tốc độ, độ dài đã biết, phiên bản được mã hóa cứng là nhanh nhất (nhưng xấu xí). Nếu bạn cần thay đổi nhiều hơn một bit, hãy đảm bảo cập nhật mã cho phù hợp.

output[0] = (byte)((byte)(input[0] << 1) | (byte)((input[1] >> 7) & 1)); 
output[1] = (byte)((byte)(input[1] << 1) | (byte)((input[2] >> 7) & 1)); 
output[2] = (byte)((byte)(input[2] << 1) | (byte)((input[3] >> 7) & 1)); 
output[3] = (byte)((byte)(input[3] << 1) | (byte)((input[4] >> 7) & 1)); 
output[4] = (byte)((byte)(input[4] << 1) | (byte)((input[5] >> 7) & 1)); 
output[5] = (byte)((byte)(input[5] << 1) | (byte)((input[6] >> 7) & 1)); 
output[6] = (byte)((byte)(input[6] << 1) | (byte)((input[7] >> 7) & 1)); 
output[7] = (byte)((byte)(input[7] << 1) | (byte)((input[8] >> 7) & 1)); 
output[8] = (byte)((byte)(input[8] << 1) | (byte)((input[9] >> 7) & 1)); 
output[9] = (byte)((byte)(input[9] << 1) | (byte)((input[10] >> 7) & 1)); 
output[10] = (byte)((byte)(input[10] << 1) | (byte)((input[11] >> 7) & 1)); 
output[11] = (byte)((byte)(input[11] << 1) | (byte)((input[12] >> 7) & 1)); 
output[12] = (byte)((byte)(input[12] << 1) | (byte)((input[13] >> 7) & 1)); 
output[13] = (byte)((byte)(input[13] << 1) | (byte)((input[14] >> 7) & 1)); 
output[14] = (byte)((byte)(input[14] << 1) | (byte)((input[15] >> 7) & 1)); 
output[15] = (byte)(input[15] << 1); 

Và sử dụng mảng byte RAM!

+0

Cảm ơn bạn! Tuy nhiên, tôi nghĩ bạn dùng quá nhiều ...Bạn chỉ có thể truyền kết quả cuối cùng và giữ int càng lâu càng tốt. – vojta

+0

Chỉ cần lưu ý: đáng ngạc nhiên, việc bỏ vòng lặp không phải là nhanh nhất nói chung, ngay cả khi nói đến các hướng dẫn lắp ráp mức thấp. –

+0

@AntonSamsonov Làm cách nào có thể? – vojta

2

Nó có thể giúp lưu các khóa con CMAC khi ký nhiều lần bằng cùng một khóa (nghĩa là cùng khóa phiên DESFire EV1). Các khóa con luôn giống nhau cho khóa đã cho. Tôi nghĩ rằng câu trả lời của David có thể nhanh hơn nếu nó sử dụng hai biến cục bộ để cache các giá trị được đọc hai lần từ cùng một offset của mảng đầu vào (từ các quan sát của tôi trên JCOP, truy cập mảng là khá đắt ngay cả đối với mảng tạm thời). .

EDIT: Tôi có thể cung cấp việc thực hiện sau đây mà không thay đổi 4 bit đúng sử dụng ngắn (32-bit int biến cho card hỗ trợ nó sẽ là thậm chí nhanh hơn):

short pom=0; // X000 to be stored next 
short pom2; // loaded value 
short pom3; // 0XXX to be stored next 
short curOffset=PARAMS_TRACK2_OFFSET; 
while(curOffset<16) { 
    pom2=Util.getShort(mem_PARAMS, curOffset); 
    pom3=(short)(pom2>>>4); 
    curOffset=Util.setShort(mem_RAM, curOffset, (short)(pom|pom3)); 
    pom=(short)(pom2<<12); 
} 

Hãy coi chừng, mã này là thừa cùng offsets trong nguồn và đích.

Bạn có thể bỏ vòng lặp này và sử dụng các tham số liên tục nếu muốn.

Các vấn đề liên quan