斑点算法不起作用
Speck algorithm not working
我正在尝试在 java 中实现 Speck 64 位块/128 位密钥 密码。我被困在加密/解密算法上。我的解密算法无法正确解密密文。
我的实现:
加密:
int m = 4; //key words
int T = 27; //rounds
int alpha = 8; //alpha
int beta = 3; //beta
int x,y;
int[] l = new int[2*T], k = new int[T];
/* *************** KEY EXTENSTION ***************** */
for(int i = 0; i < T-1; i++) {
l[i+m-1] = (k[i] + rotateRight(l[i], alpha)) ^ i;
k[i+1] = rotateLeft(k[i], beta) ^ l[i+m-1];
//System.out.println(k[i]);
}
/* *************** ENCRYPTION ********************* */
for(int i = 0; i < T; i++) {
x = (rotateLeft(x, alpha) + y) ^ k[i];
y = rotateRight(y, beta) ^ x;
//System.out.println(y);
}
解密:
/* *************** KEY EXTENSTION ***************** */
for(int i = 0; i < T-1; i++) {
l[i+m-1] = (k[i] + rotateRight(l[i], alpha)) ^ i;
k[i+1] = rotateLeft(k[i], beta) ^ l[i+m-1];
//System.out.println(k[i]);
}
/* *************** DECRYPTION ********************* */
for(int i = T-1; i >= 0; i--) {
y = rotateRight(y, beta) ^ x;
x = (rotateLeft(x, alpha) - y) ^ k[i];
//System.out.println(y);
}
x 和 y 由函数装箱初始化(<- 有点奇怪):
x = boxing(plainText, 0, 1);
y = boxing(plainText, 1, 2);
public static int boxing(int[] content, int i, int count) {
int temp[] = new int[count];
temp[i] |= content[i*4] & 0xff;
temp[i] = temp[i] << 8 | content[i*4+1] & 0xff;
temp[i] = temp[i] << 8 | content[i*4+2] & 0xff;
temp[i] = temp[i] << 8 | content[i*4+3] & 0xff;
//System.out.println(temp[from]);
return temp[i];
}
注意 content 是 8 个字符的 int 数组。
我把解密放在加密之后,所以我可以看看这个算法是否真的有效,但它不是,我不知道为什么。 (在使用解密之前,我将变量重置为正确的值)。
参考资料
- 轻量级分组密码的 SIMON 和 SPECK 系列
https://eprint.iacr.org/2013/404
- Speck 实现(不是我的)
https://github.com/timw/bc-java/blob/feature/simon-speck/core/src/main/java/org/bouncycastle/crypto/engines/SpeckEngine.java
编辑:
旋转函数:
public static int rotateLeft(int number, int amount) {
return number << amount | number >>> (32-amount);
}
public static int rotateRight(int number, int amount) {
return number >>> amount | number << (32-amount);
}
终于想通了。我的解密算法应该是这样的:
for(int i = T-1; i >= 0; i--) {
y = rotateRight(x ^ y, beta);
x = rotateLeft((x ^ k[i]) - y, alpha);
}
而且我不小心在 加密 算法中交换了 旋转函数 。这是正确的形式:
for(int i = 0; i < T; i++) {
x = (rotateRight(x, alpha) + y) ^ k[i];
y = rotateLeft(y, beta) ^ x;
}
我正在尝试在 java 中实现 Speck 64 位块/128 位密钥 密码。我被困在加密/解密算法上。我的解密算法无法正确解密密文。
我的实现:
加密:
int m = 4; //key words int T = 27; //rounds int alpha = 8; //alpha int beta = 3; //beta int x,y; int[] l = new int[2*T], k = new int[T]; /* *************** KEY EXTENSTION ***************** */ for(int i = 0; i < T-1; i++) { l[i+m-1] = (k[i] + rotateRight(l[i], alpha)) ^ i; k[i+1] = rotateLeft(k[i], beta) ^ l[i+m-1]; //System.out.println(k[i]); } /* *************** ENCRYPTION ********************* */ for(int i = 0; i < T; i++) { x = (rotateLeft(x, alpha) + y) ^ k[i]; y = rotateRight(y, beta) ^ x; //System.out.println(y); }
解密:
/* *************** KEY EXTENSTION ***************** */ for(int i = 0; i < T-1; i++) { l[i+m-1] = (k[i] + rotateRight(l[i], alpha)) ^ i; k[i+1] = rotateLeft(k[i], beta) ^ l[i+m-1]; //System.out.println(k[i]); } /* *************** DECRYPTION ********************* */ for(int i = T-1; i >= 0; i--) { y = rotateRight(y, beta) ^ x; x = (rotateLeft(x, alpha) - y) ^ k[i]; //System.out.println(y); }
x 和 y 由函数装箱初始化(<- 有点奇怪):
x = boxing(plainText, 0, 1);
y = boxing(plainText, 1, 2);
public static int boxing(int[] content, int i, int count) {
int temp[] = new int[count];
temp[i] |= content[i*4] & 0xff;
temp[i] = temp[i] << 8 | content[i*4+1] & 0xff;
temp[i] = temp[i] << 8 | content[i*4+2] & 0xff;
temp[i] = temp[i] << 8 | content[i*4+3] & 0xff;
//System.out.println(temp[from]);
return temp[i];
}
注意 content 是 8 个字符的 int 数组。
我把解密放在加密之后,所以我可以看看这个算法是否真的有效,但它不是,我不知道为什么。 (在使用解密之前,我将变量重置为正确的值)。
参考资料
- 轻量级分组密码的 SIMON 和 SPECK 系列 https://eprint.iacr.org/2013/404
- Speck 实现(不是我的)
https://github.com/timw/bc-java/blob/feature/simon-speck/core/src/main/java/org/bouncycastle/crypto/engines/SpeckEngine.java
编辑:
旋转函数:
public static int rotateLeft(int number, int amount) { return number << amount | number >>> (32-amount); } public static int rotateRight(int number, int amount) { return number >>> amount | number << (32-amount); }
终于想通了。我的解密算法应该是这样的:
for(int i = T-1; i >= 0; i--) {
y = rotateRight(x ^ y, beta);
x = rotateLeft((x ^ k[i]) - y, alpha);
}
而且我不小心在 加密 算法中交换了 旋转函数 。这是正确的形式:
for(int i = 0; i < T; i++) {
x = (rotateRight(x, alpha) + y) ^ k[i];
y = rotateLeft(y, beta) ^ x;
}