📄 skipjackm.nc
字号:
/** * Encrypts a single block (of blockSize) using the key in the keySize. * * @param context holds the module specific opaque data related to the * key (perhaps key expansions). * @param plainBlock a plaintext block of blockSize * @param cipherBlock the resulting ciphertext block of blockSize * * @return Whether the encryption was successful. Possible failure reasons * include not calling init(). */ async command result_t BlockCipher.encrypt(CipherContext * context, uint8_t * plainBlock, uint8_t * cipherBlock) { // prologue 10 pushs = 20 cycles register uint8_t counter = 1; register uint8_t * skey = ((SJContext*)context->context)->skey; register uint16_t w1, w2, w3, w4, tmp; register uint8_t bLeft, bRight; //dumpBuffer("SkipJack.encrypt: plainBlock", plainBlock, 8); c2sM(plainBlock, w1); plainBlock += 2; c2sM(plainBlock, w2); plainBlock += 2; c2sM(plainBlock, w3); plainBlock += 2; c2sM(plainBlock, w4); plainBlock += 2; /* // code if we had expanded key to 128 bytes. this is what the code below // does, but after every 5 operations, it resets the where we are // in the key back to the beginning of the skey. so our loops end up // looking a little funny. while (counter < 9) RULE_A(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); while (counter < 17) RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); while (counter < 25) RULE_A(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); while (counter < 33) RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); */ while (counter < 6) // 5x RULE_A(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); skey = ((SJContext*)context->context)->skey; while (counter < 9) // 3x RULE_A(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); while (counter < 11) // 2x RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); skey = ((SJContext*)context->context)->skey; while (counter < 16) // 5x RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); skey = ((SJContext*)context->context)->skey; // 1x RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); while (counter < 21) // 4x RULE_A(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); skey = ((SJContext*)context->context)->skey; while (counter < 25) // 4x RULE_A(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); // 1x RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); skey = ((SJContext*)context->context)->skey; while (counter < 31) // 5x RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); skey = ((SJContext*)context->context)->skey; while (counter < 33) // 2x RULE_B(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); s2cM(w1, cipherBlock); cipherBlock += 2; s2cM(w2, cipherBlock); cipherBlock += 2; s2cM(w3, cipherBlock); cipherBlock += 2; s2cM(w4, cipherBlock); cipherBlock += 2; dumpBuffer ("SkipJack.encrypt: cipherBlock", cipherBlock - 8, 8); return SUCCESS; } /** * Decrypts a single block (of blockSize) using the key in the keySize. Not * all ciphers will implement this function (since providing encryption * is a useful primitive). * * @param context holds the module specific opaque data related to the * key (perhaps key expansions). * @param cipherBlock a ciphertext block of blockSize * @param plainBlock the resulting plaintext block of blockSize * * @return Whether the decryption was successful. Possible failure reasons * include not calling init() or an unimplimented decrypt function. */ async command result_t BlockCipher.decrypt(CipherContext * context, uint8_t * cipherBlock, uint8_t * plainBlock) { register uint8_t counter = 32; register uint8_t * skey = ((SJContext*)context->context)->skey + 4; register uint16_t w1, w2, w3, w4, tmp; register uint8_t bLeft, bRight; dumpBuffer("SkipJack.decrypt: cipherBlock", plainBlock, 8); c2sM(cipherBlock, w1); cipherBlock += 2; c2sM(cipherBlock, w2); cipherBlock += 2; c2sM(cipherBlock, w3); cipherBlock += 2; c2sM(cipherBlock, w4); /* // code if we had expanded key to 128 bytes. this is what the code below // does, but after every 5 operations, it resets the where we are // in the key back to the beginning of the skey. so our loops end up // looking a little funny. while (counter > 24) RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); while (counter > 16) RULE_A_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); while (counter > 8) RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); while (counter > 0) RULE_A_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); */ while (counter > 30) //2x RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); skey = ((SJContext*)context->context)->skey + 16; while (counter > 25) //5x RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); skey = ((SJContext*)context->context)->skey + 16; //1x RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); while (counter > 20) //4x RULE_A_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); skey = ((SJContext*)context->context)->skey + 16; while (counter > 16) //4x RULE_A_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); //1x RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); skey = ((SJContext*)context->context)->skey + 16; while (counter > 10) //5x RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); skey = ((SJContext*)context->context)->skey + 16; while (counter > 8) // 2x RULE_B_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); while (counter > 5) // 3x RULE_A_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); skey = ((SJContext*)context->context)->skey + 16; while (counter > 0) // 5x RULE_A_INV(skey, w1, w2, w3, w4, counter, tmp, bLeft, bRight ); s2cM(w1, plainBlock); plainBlock += 2; s2cM(w2, plainBlock); plainBlock += 2; s2cM(w3, plainBlock); plainBlock += 2; s2cM(w4, plainBlock); dumpBuffer ("SkipJack.decrypt: plainBlock", plainBlock - 6, 8); return SUCCESS; } /** * Performs the key expansion on the real secret. * * @param secret key */ result_t setupKey (CipherContext * context, uint8_t * key, uint8_t keysize) { int i = 0, m; uint8_t * skey = ((SJContext *)context->context)->skey; // for keys which are smaller than 80 bits, pad with 0 until they reach 80 // bits in size. // note that key expansion is just concatenation. for (; i < 20; i++) { m = i % 10; if ( m >= keysize) skey[i] = 0; else skey[i] = key[m]; } return SUCCESS; } /** * Returns the preferred block size that this cipher operates with. It is * always safe to call this function before the init() call has been made. * * @return the preferred block size for this cipher. In the case where the * cipher operates with multiple block sizes, this will pick one * particular size (deterministically). */ async command uint8_t BlockCipherInfo.getPreferredBlockSize() { return BSIZE; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -