From 5d7d9db95601222e59e67fd56f1de5fdb9a17818 Mon Sep 17 00:00:00 2001 From: "[GGSuchao]" <[1500062807@pku.edu.cn]> Date: Tue, 4 Jul 2017 20:01:48 +0800 Subject: [PATCH] add simon --- crypto/simon/build.info | 2 + crypto/simon/simon.c | 461 ++++++++++++++++++++++++++++++++++++++++ include/openssl/simon.h | 65 ++++++ test/simontest.c | 255 ++++++++++++++++++++++ 4 files changed, 783 insertions(+) create mode 100644 crypto/simon/build.info create mode 100644 crypto/simon/simon.c create mode 100644 include/openssl/simon.h create mode 100644 test/simontest.c diff --git a/crypto/simon/build.info b/crypto/simon/build.info new file mode 100644 index 00000000..aa3a93f9 --- /dev/null +++ b/crypto/simon/build.info @@ -0,0 +1,2 @@ +LIBS=../../libcrypto +SOURCE[../../libcrypto]=simon.c diff --git a/crypto/simon/simon.c b/crypto/simon/simon.c new file mode 100644 index 00000000..f17ea5a7 --- /dev/null +++ b/crypto/simon/simon.c @@ -0,0 +1,461 @@ +/* ==================================================================== + * Copyright (c) 2014 - 2017 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + + +#include +#include +#include +#include +#include + +// Cipher Operation Macros +#define shift_one ((x_word << 1) | (x_word >> (word_size - 1))) +#define shift_eight ((x_word << 8) | (x_word >> (word_size - 8))) +#define shift_two ((x_word << 2) | (x_word >> (word_size - 2))) +#define rshift_three(x) (x >> 3) |((x & 0x7) << (word_size - 3)) +#define rshift_one(x) (x >> 1) |((x & 0x1) << (word_size - 1)) + +uint64_t z_arrays[5] = {0b0001100111000011010100100010111110110011100001101010010001011111, + 0b0001011010000110010011111011100010101101000011001001111101110001, + 0b0011001101101001111110001000010100011001001011000000111011110101, + 0b0011110000101100111001010001001000000111101001100011010111011011, + 0b0011110111001001010011000011101000000100011011010110011110001011}; + +// Valid Cipher Parameters +const uint8_t simon_rounds[] = {32, 36, 36, 42, 44, 52, 54, 68, 69, 72}; +const uint8_t simon_block_sizes[] = {32, 48, 48, 64, 64, 96, 96, 128, 128, 128}; +const uint16_t simon_key_sizes[] = {64, 72, 96, 96, 128, 96, 144, 128, 192, 256}; +const uint8_t z_assign[] = {0, 0, 1, 2, 3, 2, 3, 2, 3, 4}; + +uint8_t simon_init(simon_cipher *cipher_object, enum simon_cipher_config_t cipher_cfg, enum mode_t c_mode, void *key, uint8_t *iv, uint8_t *counter) { + + if (cipher_cfg > Simon_256_128 || cipher_cfg < Simon_64_32){ + return -1; + } + + cipher_object->block_size = simon_block_sizes[cipher_cfg]; + cipher_object->key_size = simon_key_sizes[cipher_cfg]; + cipher_object->round_limit = simon_rounds[cipher_cfg]; + cipher_object->cipher_cfg = cipher_cfg; + cipher_object->z_seq = z_assign[cipher_cfg]; + uint8_t word_size = simon_block_sizes[cipher_cfg] >> 1; + uint8_t word_bytes = word_size >> 3; + uint8_t key_words = simon_key_sizes[cipher_cfg] / word_size; + uint64_t sub_keys[4] = {}; + uint64_t mod_mask = ULLONG_MAX >> (64 - word_size); + + + // Setup + int i, j; + for(i = 0; i < key_words; i++) { + memcpy(&sub_keys[i], key + (word_bytes * i), word_bytes); + } + + uint64_t tmp1,tmp2; + uint64_t c = 0xFFFFFFFFFFFFFFFC; + + // Store First Key Schedule Entry + memcpy(cipher_object->key_schedule, &sub_keys[0], word_bytes); + + for(i = 0; i < simon_rounds[cipher_cfg] - 1; i++){ + tmp1 = rshift_three(sub_keys[key_words - 1]); + + if(key_words == 4) { + tmp1 ^= sub_keys[1]; + } + + tmp2 = rshift_one(tmp1); + tmp1 ^= sub_keys[0]; + tmp1 ^= tmp2; + + tmp2 = c ^ ((z_arrays[cipher_object->z_seq] >> (i % 62)) & 1); + + tmp1 ^= tmp2; + + // Shift Sub Words + for(j = 0; j < (key_words - 1); j++){ + sub_keys[j] = sub_keys[j+1]; + } + sub_keys[key_words - 1] = tmp1 & mod_mask; + + // Append sub key to key schedule + memcpy(cipher_object->key_schedule + (word_bytes * (i+1)), &sub_keys[0], word_bytes); + } + + return 0; +} + + +uint8_t simon_encrypt(simon_cipher cipher_object, void *plaintext, void *ciphertext) { + + if (cipher_object.cipher_cfg == simon_64_32) { + simon_encrypt32(cipher_object.key_schedule, plaintext, ciphertext); + } + + else if(cipher_object.cipher_cfg <= simon_96_48) { + simon_encrypt48(cipher_object.round_limit, cipher_object.key_schedule, plaintext, ciphertext); + } + + else if(cipher_object.cipher_cfg <= simon_128_64) { + simon_encrypt64(cipher_object.round_limit, cipher_object.key_schedule, plaintext, ciphertext); + } + + else if(cipher_object.cipher_cfg <= simon_144_96) { + simon_encrypt96(cipher_object.round_limit, cipher_object.key_schedule, plaintext, ciphertext); + } + + else if(cipher_object.cipher_cfg <= simon_256_128) { + simon_encrypt128(cipher_object.round_limit, cipher_object.key_schedule, plaintext, ciphertext); + } + + else return -1; + + return 0; +} + +void simon_encrypt32(uint8_t *key_schedule, uint8_t *plaintext, uint8_t *ciphertext) { + + const uint8_t word_size = 16; + uint16_t y_word = *(uint16_t *)plaintext; + uint16_t x_word = *(((uint16_t *)plaintext) + 1); + uint16_t *round_key_ptr = (uint16_t *)key_schedule; + uint16_t * word_ptr = (uint16_t *)ciphertext; + + + uint8_t i; + + for(i = 0; i < 32; i++) { // Block size 32 has only one round number option + + // Shift, AND , XOR ops + uint16_t temp = (shift_one & shift_eight) ^ y_word ^ shift_two; + + // Feistel Cross + y_word = x_word; + + // XOR with Round Key + x_word = temp ^ *(round_key_ptr + i); + } + // Assemble Ciphertext Output Array + *word_ptr = y_word; + *(word_ptr + 1) = x_word; +} + +void simon_encrypt48(uint8_t round_limit, uint8_t *key_schedule, uint8_t *plaintext, uint8_t *ciphertext) { + + const uint8_t word_size = 24; + + bword_24 intrd = *(bword_24 *)plaintext; + uint32_t y_word = intrd.data; + intrd = *((bword_24 *)(plaintext+3)); + uint32_t x_word = intrd.data; + + uint8_t i; + for(i = 0; i < round_limit; i++) { // Block size 32 has only one round number option + + // Shift, AND , XOR ops + uint32_t temp = (shift_one & shift_eight) ^ y_word ^ shift_two; + + // Feistel Cross + y_word = x_word; + + // XOR with Round Key + x_word = (temp ^ (*((bword_24 *)(key_schedule + (i*3)))).data) & 0xFFFFFF; + } + // Assemble Ciphertext Output Array + intrd.data = y_word; + bword_24 * intrd_ptr = (bword_24 *)ciphertext; + *intrd_ptr = intrd; + + intrd.data = x_word; + intrd_ptr = (bword_24 *)(ciphertext + 3); + *intrd_ptr = intrd; +} + +void simon_encrypt64(uint8_t round_limit, uint8_t *key_schedule, uint8_t *plaintext, uint8_t *ciphertext) { + + const uint8_t word_size = 32; + uint32_t y_word = *(uint32_t *)plaintext; + uint32_t x_word = *(((uint32_t *)plaintext) + 1); + uint32_t *round_key_ptr = (uint32_t *)key_schedule; + uint32_t *word_ptr = (uint32_t *)ciphertext; + + uint8_t i; + for(i = 0; i < round_limit; i++) { // Block size 32 has only one round number option + + // Shift, AND , XOR ops + uint32_t temp = (shift_one & shift_eight) ^ y_word ^ shift_two; + + // Feistel Cross + y_word = x_word; + + // XOR with Round Key + x_word = temp ^ *(round_key_ptr + i); + } + // Assemble Ciphertext Output Array + *word_ptr = y_word; + *(word_ptr + 1) = x_word; +} + +void simon_encrypt96(uint8_t round_limit, uint8_t *key_schedule, uint8_t *plaintext, uint8_t *ciphertext) { + + const uint8_t word_size = 48; + + bword_48 intrd = *(bword_48 *)plaintext; + uint64_t y_word = intrd.data; + intrd = *((bword_48 *)(plaintext+6)); + uint64_t x_word = intrd.data; + + uint8_t i; + for(i = 0; i < round_limit; i++) { + + // Shift, AND , XOR ops + uint64_t temp = (shift_one & shift_eight) ^ y_word ^ shift_two; + + // Feistel Cross + y_word = x_word; + + // XOR with Round Key + x_word = (temp ^ (*((bword_48 *)(key_schedule + (i*6)))).data) & 0xFFFFFFFFFFFF; + } + // Assemble Ciphertext Output Array + intrd.data = y_word; + bword_48 * intrd_ptr = (bword_48 *)ciphertext; + *intrd_ptr = intrd; + + intrd.data = x_word; + intrd_ptr = (bword_48 *)(ciphertext + 6); + *intrd_ptr = intrd; + +} + +void simon_encrypt128(uint8_t round_limit, uint8_t *key_schedule, uint8_t *plaintext, uint8_t *ciphertext) { + + const uint8_t word_size = 64; + uint64_t y_word = *(uint64_t *)plaintext; + uint64_t x_word = *(((uint64_t *)plaintext) + 1); + uint64_t *round_key_ptr = (uint64_t *)key_schedule; + uint64_t *word_ptr = (uint64_t *)ciphertext; + + uint8_t i; + for(i = 0; i < round_limit; i++) { // Block size 32 has only one round number option + + // Shift, AND , XOR ops + uint64_t temp = (shift_one & shift_eight) ^ y_word ^ shift_two; + + // Feistel Cross + y_word = x_word; + + // XOR with Round Key + x_word = temp ^ *(round_key_ptr + i); + } + // Assemble Ciphertext Output Array + *word_ptr = y_word; + *(word_ptr + 1) = x_word; +} + +uint8_t simon_decrypt(simon_cipher cipher_object, void *ciphertext, void *plaintext) { + + if (cipher_object.cipher_cfg == simon_64_32) { + simon_decrypt32(cipher_object.key_schedule, ciphertext, plaintext); + } + + else if(cipher_object.cipher_cfg <= simon_96_48) { + simon_decrypt48(cipher_object.round_limit, cipher_object.key_schedule, ciphertext, plaintext); + } + + else if(cipher_object.cipher_cfg <= simon_128_64) { + simon_decrypt64(cipher_object.round_limit, cipher_object.key_schedule, ciphertext, plaintext); + } + + else if(cipher_object.cipher_cfg <= simon_144_96) { + simon_decrypt96(cipher_object.round_limit, cipher_object.key_schedule, ciphertext, plaintext); + } + + else if(cipher_object.cipher_cfg <= simon_256_128) { + simon_decrypt128(cipher_object.round_limit, cipher_object.key_schedule, ciphertext, plaintext); + } + + else return -1; + + return 0; +} + +void simon_decrypt32(uint8_t *key_schedule, uint8_t *ciphertext, uint8_t *plaintext) { + + const uint8_t word_size = 16; + uint16_t x_word = *(uint16_t *)ciphertext; + uint16_t y_word = *(((uint16_t *)ciphertext) + 1); + uint16_t *round_key_ptr = (uint16_t *)key_schedule; + uint16_t * word_ptr = (uint16_t *)plaintext; + + int8_t i; + for(i = 31; i >= 0; i--) { // Block size 32 has only one round number option + + // Shift, AND , XOR ops + uint16_t temp = (shift_one & shift_eight) ^ y_word ^ shift_two; + + // Feistel Cross + y_word = x_word; + + // XOR with Round Key + x_word = temp ^ *(round_key_ptr + i); + } + // Assemble Plaintext Output Array + *word_ptr = x_word; + *(word_ptr + 1) = y_word; + return; +} + +void simon_decrypt48(uint8_t round_limit, uint8_t *key_schedule, uint8_t *ciphertext, uint8_t *plaintext){ + const uint8_t word_size = 24; + + bword_24 intrd = *(bword_24 *)ciphertext; + uint32_t x_word = intrd.data; + intrd = *((bword_24 *)(ciphertext+3)); + uint32_t y_word = intrd.data; + + int8_t i; + for(i = round_limit -1 ; i >= 0; i--) { + + // Shift, AND , XOR ops + uint32_t temp = (shift_one & shift_eight) ^ y_word ^ shift_two; + + // Feistel Cross + y_word = x_word; + + // XOR with Round Key + x_word = (temp ^ (*((bword_24 *)(key_schedule + (i*3)))).data) & 0xFFFFFF; + } + // Assemble plaintext Output Array + intrd.data = x_word; + bword_24 * intrd_ptr = (bword_24 *)plaintext; + *intrd_ptr = intrd; + + intrd.data = y_word; + intrd_ptr = (bword_24 *)(plaintext + 3); + *intrd_ptr = intrd; + return; +} +void simon_decrypt64(uint8_t round_limit, uint8_t *key_schedule, uint8_t *ciphertext, uint8_t *plaintext){ + const uint8_t word_size = 32; + uint32_t x_word = *(uint32_t *)ciphertext; + uint32_t y_word = *(((uint32_t *)ciphertext) + 1); + uint32_t *round_key_ptr = (uint32_t *)key_schedule; + uint32_t *word_ptr = (uint32_t *)plaintext; + + int8_t i; + for(i = round_limit -1 ; i >= 0; i--) { + + // Shift, AND , XOR ops + uint32_t temp = (shift_one & shift_eight) ^ y_word ^ shift_two; + + // Feistel Cross + y_word = x_word; + + // XOR with Round Key + x_word = temp ^ *(round_key_ptr + i); + } + // Assemble Plaintext Output Array + *word_ptr = x_word; + *(word_ptr + 1) = y_word; + return; +} +void simon_decrypt96(uint8_t round_limit, uint8_t *key_schedule, uint8_t *ciphertext, uint8_t *plaintext){ + const uint8_t word_size = 48; + bword_48 intrd = *(bword_48 *)ciphertext; + uint64_t x_word = intrd.data; + intrd = *((bword_48 *)(ciphertext+6)); + uint64_t y_word = intrd.data; + + int8_t i; + for(i = round_limit - 1; i >= 0; i--) { + + // Shift, AND , XOR ops + uint64_t temp = (shift_one & shift_eight) ^ y_word ^ shift_two; + + // Feistel Cross + y_word = x_word; + + // XOR with Round Key + x_word = (temp ^ (*((bword_48 *)(key_schedule + (i*6)))).data) & 0xFFFFFFFFFFFF; + } + // Assemble Plaintext Output Array + intrd.data = x_word; + bword_48 * intrd_ptr = (bword_48 *)plaintext; + *intrd_ptr = intrd; + + intrd.data = y_word; + intrd_ptr = (bword_48 *)(plaintext + 6); + *intrd_ptr = intrd; + return; +} +void simon_decrypt128(uint8_t round_limit, uint8_t *key_schedule, uint8_t *ciphertext, uint8_t *plaintext){ + const uint8_t word_size = 64; + uint64_t x_word = *(uint64_t *)ciphertext; + uint64_t y_word = *(((uint64_t *)ciphertext) + 1); + uint64_t *round_key_ptr = (uint64_t *)key_schedule; + uint64_t *word_ptr = (uint64_t *)plaintext; + + int8_t i; + for(i = round_limit - 1; i >=0; i--) { + + // Shift, AND , XOR ops + uint64_t temp = (shift_one & shift_eight) ^ y_word ^ shift_two; + + // Feistel Cross + y_word = x_word; + + // XOR with Round Key + x_word = temp ^ *(round_key_ptr + i); + } + // Assemble Plaintext Output Array + *word_ptr = x_word; + *(word_ptr + 1) = y_word; + return; +} diff --git a/include/openssl/simon.h b/include/openssl/simon.h new file mode 100644 index 00000000..49f598ef --- /dev/null +++ b/include/openssl/simon.h @@ -0,0 +1,65 @@ +#ifndef HEADER_SIMON_H +#define HEADER_SIMON_H + +#ifndef CIPHER_CONSTANTS +#define CIPHER_CONSTANTS +enum mode_t { ECB, CTR, CBC, CFB, OFB }; +#endif + +enum simon_cipher_config_t { simon_64_32, + simon_72_48, + simon_96_48, + simon_96_64, + simon_128_64, + simon_96_96, + simon_144_96, + simon_128_128, + simon_192_128, + simon_256_128 +}; + +typedef struct { + enum simon_cipher_config_t cipher_cfg; + uint8_t key_size; + uint8_t block_size; + uint8_t round_limit; + uint8_t init_vector[16]; + uint8_t counter[16]; + uint8_t key_schedule[576]; + uint8_t z_seq; +} simon_cipher; + +typedef struct _bword_24{ + uint32_t data: 24; +} bword_24; + +typedef struct _bword_48{ + uint64_t data: 48; +} bword_48; + + +#ifdef __cplusplus +extern "C"{ +#endif + uint8_t simon_init(simon_cipher *cipher_object, enum simon_cipher_config_t cipher_cfg, enum mode_t c_mode, void *key, uint8_t *iv, uint8_t *counter); + uint8_t simon_encrypt(simon_cipher cipher_object, void *plaintext, void *ciphertext); + uint8_t simon_decrypt(simon_cipher cipher_object, void *ciphertext, void *plaintext); + + void simon_encrypt32(uint8_t *key_schedule, uint8_t *plaintext, uint8_t *ciphertext); + void simon_encrypt48(uint8_t round_limit, uint8_t *key_schedule, uint8_t *plaintext, uint8_t *ciphertext); + void simon_encrypt64(uint8_t round_limit, uint8_t *key_schedule, uint8_t *plaintext, uint8_t *ciphertext); + void simon_encrypt96(uint8_t round_limit, uint8_t *key_schedule, uint8_t *plaintext, uint8_t *ciphertext); + void simon_encrypt128(uint8_t round_limit, uint8_t *key_schedule, uint8_t *plaintext, uint8_t *ciphertext); + + + void simon_decrypt32(uint8_t *key_schedule, uint8_t *ciphertext, uint8_t *plaintext); + void simon_decrypt48(uint8_t round_limit, uint8_t *key_schedule, uint8_t *ciphertext, uint8_t *plaintext); + void simon_decrypt64(uint8_t round_limit, uint8_t *key_schedule, uint8_t *ciphertext, uint8_t *plaintext); + void simon_decrypt96(uint8_t round_limit, uint8_t *key_schedule, uint8_t *ciphertext, uint8_t *plaintext); + void simon_decrypt128(uint8_t round_limit, uint8_t *key_schedule, uint8_t *ciphertext, uint8_t *plaintext); +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/test/simontest.c b/test/simontest.c new file mode 100644 index 00000000..8af92f52 --- /dev/null +++ b/test/simontest.c @@ -0,0 +1,255 @@ +/*==================================================================== + * Copyright (c) 2014 - 2017 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + + +// Simon Tests + + +#include +#include +#include +#include +#include +#include + +int main(int argc, char** argv){ + // Create reuseable cipher objects for each alogirthm type + simon_cipher my_simon_cipher = *(simon_cipher *)malloc(sizeof(simon_cipher)); + + // Create generic tmp variables + uint8_t ciphertext_buffer[16]; + uint32_t result; + + // Initialize IV and Counter Values for Use with Block Modes + uint8_t my_IV[] = {0x32,0x14,0x76,0x58}; + uint8_t my_counter[] = {0x2F,0x3D,0x5C,0x7B}; + int i, error_sum; + error_sum = 0; + + + // Simon 64/32 Test + // Key: 1918 1110 0908 0100 Plaintext: 6565 6877 Ciphertext: c69b e9bb + uint8_t simon64_32_key[] = {0x00, 0x01, 0x08, 0x09, 0x10, 0x11, 0x18, 0x19}; + uint8_t simon64_32_plain[] = {0x77, 0x68, 0x65, 0x65}; + uint8_t simon64_32_cipher[] = {0xBB,0xE9, 0x9B, 0xC6}; + result = simon_init(&my_simon_cipher, simon_64_32, ECB, simon64_32_key, my_IV, my_counter); + simon_encrypt(my_simon_cipher, &simon64_32_plain, &ciphertext_buffer); + for(i = 0; i < 4; i++) { + if (ciphertext_buffer[i] != simon64_32_cipher[i]) + error_sum++; + } + simon_decrypt(my_simon_cipher, &simon64_32_cipher, &ciphertext_buffer); + for(i = 0; i < 4; i++) { + if (ciphertext_buffer[i] != simon64_32_plain[i]) + error_sum++; + } + + + // Simon 72/48 Test + // Key: 121110 0a0908 020100 Plaintext: 612067 6e696c Ciphertext: dae5ac 292cac + uint8_t simon72_48_key[] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12}; + uint8_t simon72_48_plain[] = {0x6c, 0x69, 0x6E, 0x67, 0x20, 0x61}; + uint8_t simon72_48_cipher[] = {0xAC, 0x2C, 0x29, 0xAC, 0xE5, 0xda}; + result = simon_init(&my_simon_cipher, simon_72_48, ECB, simon72_48_key, my_IV, my_counter); + simon_encrypt(my_simon_cipher, &simon72_48_plain, &ciphertext_buffer); + for(i = 0; i < 6; i++) { + if (ciphertext_buffer[i] != simon72_48_cipher[i]) + error_sum++; + } + simon_decrypt(my_simon_cipher, &simon72_48_cipher, &ciphertext_buffer); + for(i = 0; i < 6; i++) { + if (ciphertext_buffer[i] != simon72_48_plain[i]) + error_sum++; + } + + + // Simon 96/48 Test + // Key: 1a1918 121110 0a0908 020100 Plaintext: 726963 20646e Ciphertext: 6e06a5 acf156 + uint8_t simon96_48_key[] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12, 0x18, 0x19, 0x1a}; + uint8_t simon96_48_plain[] = {0x6e, 0x64, 0x20, 0x63, 0x69, 0x72}; + uint8_t simon96_48_cipher[] = {0x56, 0xf1, 0xac, 0xa5, 0x06, 0x6e}; + result = simon_init(&my_simon_cipher, simon_96_48, ECB, simon96_48_key, my_IV, my_counter); + simon_encrypt(my_simon_cipher, &simon96_48_plain, &ciphertext_buffer); + for(i = 0; i < 6; i++) { + if (ciphertext_buffer[i] != simon96_48_cipher[i]) + error_sum++; + } + simon_decrypt(my_simon_cipher, &simon96_48_cipher, &ciphertext_buffer); + for(i = 0; i < 6; i++) { + if (ciphertext_buffer[i] != simon96_48_plain[i]) + error_sum++; + } + + + // Simon 96/64 Test + // Key: 13121110 0b0a0908 03020100 Plaintext: 6f722067 6e696c63 Ciphertext: 5ca2e27f 111a8fc8 + uint8_t simon96_64_key[] = {0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x11, 0x12, 0x13}; + uint8_t simon96_64_plain[] = {0x63, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x72, 0x6f}; + uint8_t simon96_64_cipher[] = {0xc8, 0x8f, 0x1a, 0x11, 0x7f, 0xe2, 0xa2, 0x5c}; + result = simon_init(&my_simon_cipher, simon_96_64, ECB, simon96_64_key, my_IV, my_counter); + simon_encrypt(my_simon_cipher, &simon96_64_plain, &ciphertext_buffer); + for(i = 0; i < 8; i++) { + if (ciphertext_buffer[i] != simon96_64_cipher[i]) + error_sum++; + } + simon_decrypt(my_simon_cipher, &simon96_64_cipher, &ciphertext_buffer); + for(i = 0; i < 8; i++) { + if (ciphertext_buffer[i] != simon96_64_plain[i]) + error_sum++; + } + + + // Simon 128/64 Test + // Key: 1b1a1918 13121110 0b0a0908 03020100 Plaintext: 656b696c 20646e75 Ciphertext: 44c8fc20 b9dfa07a + uint8_t simon128_64_key[] = {0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x11, 0x12, 0x13, 0x18, 0x19, 0x1A, 0x1B}; + uint8_t simon128_64_plain[] = {0x75, 0x6e, 0x64, 0x20, 0x6c, 0x69, 0x6b, 0x65}; + uint8_t simon128_64_cipher[] = {0x7a, 0xa0, 0xdf, 0xb9, 0x20, 0xfc, 0xc8, 0x44}; + result = simon_init(&my_simon_cipher, simon_128_64, ECB, simon128_64_key, my_IV, my_counter); + simon_encrypt(my_simon_cipher, &simon128_64_plain, &ciphertext_buffer); + for(i = 0; i < 8; i++) { + if (ciphertext_buffer[i] != simon128_64_cipher[i]) + error_sum++; + } + simon_decrypt(my_simon_cipher, &simon128_64_cipher, &ciphertext_buffer); + for(i = 0; i < 8; i++) { + if (ciphertext_buffer[i] != simon128_64_plain[i]) + error_sum++; + } + + + // Simon 96/96 Test + // Key: 0d0c0b0a0908 050403020100 Plaintext: 2072616c6c69 702065687420 Ciphertext: 602807a462b4 69063d8ff082 + uint8_t simon96_96_key[] = {0x00, 0x01, 0x02, 0x03,0x04,0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D}; + uint8_t simon96_96_plain[] = {0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x69, 0x6c, 0x6c, 0x61, 0x72, 0x20}; + uint8_t simon96_96_cipher[] = {0x82, 0xf0, 0x8f, 0x3d, 0x06, 0x69, 0xb4, 0x62, 0xa4, 0x07, 0x28, 0x60}; + result = simon_init(&my_simon_cipher, simon_96_96, ECB, simon96_96_key, my_IV, my_counter); + simon_encrypt(my_simon_cipher, &simon96_96_plain, &ciphertext_buffer); + for(i = 0; i < 12; i++) { + if (ciphertext_buffer[i] != simon96_96_cipher[i]) + error_sum++; + } + simon_decrypt(my_simon_cipher, &simon96_96_cipher, &ciphertext_buffer); + for(i = 0; i < 12; i++) { + if (ciphertext_buffer[i] != simon96_96_plain[i]) + error_sum++; + } + + + // Simon 144/96 Test + // Key: 151413121110 0d0c0b0a0908 050403020100 Plaintext: 746168742074 73756420666f Ciphertext: ecad1c6c451e 3f59c5db1ae9 + uint8_t simon144_96_key[] = {0x00, 0x01, 0x02, 0x03,0x04,0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15}; + uint8_t simon144_96_plain[] = {0x6f, 0x66, 0x20, 0x64, 0x75, 0x73, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74}; + uint8_t simon144_96_cipher[] = {0xe9, 0x1a, 0xdb, 0xc5, 0x59, 0x3f, 0x1e, 0x45, 0x6c, 0x1c, 0xad, 0xec}; + result = simon_init(&my_simon_cipher, simon_144_96, ECB, simon144_96_key, my_IV, my_counter); + simon_encrypt(my_simon_cipher, &simon144_96_plain, &ciphertext_buffer); + for(i = 0; i < 12; i++) { + if (ciphertext_buffer[i] != simon144_96_cipher[i]) + error_sum++; + } + simon_decrypt(my_simon_cipher, &simon144_96_cipher, &ciphertext_buffer); + for(i = 0; i < 12; i++) { + if (ciphertext_buffer[i] != simon144_96_plain[i]) + error_sum++; + } + + + // Simon 128/128 Test + // Key: 0f0e0d0c0b0a0908 0706050403020100 Plaintext: 6373656420737265 6c6c657661727420 Ciphertext: 49681b1e1e54fe3f 65aa832af84e0bbc + uint8_t simon128_128_key[] = {0x00, 0x01, 0x02, 0x03,0x04, 0x05, 0x06,0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; + uint8_t simon128_128_plain[] = {0x20, 0x74, 0x72, 0x61, 0x76, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x20, 0x64, 0x65, 0x73, 0x63}; + uint8_t simon128_128_cipher[] = {0xbc, 0x0b, 0x4e, 0xf8, 0x2a, 0x83, 0xaa, 0x65, 0x3f, 0xfe, 0x54, 0x1e, 0x1e, 0x1b, 0x68, 0x49}; + result = simon_init(&my_simon_cipher, simon_128_128, ECB, simon128_128_key, my_IV, my_counter); + simon_encrypt(my_simon_cipher, &simon128_128_plain, &ciphertext_buffer); + for(i = 0; i < 16; i++) { + if (ciphertext_buffer[i] != simon128_128_cipher[i]) + error_sum++; + } + simon_decrypt(my_simon_cipher, &simon128_128_cipher, &ciphertext_buffer); + for(i = 0; i < 16; i++) { + if (ciphertext_buffer[i] != simon128_128_plain[i]) + error_sum++; + } + + + // Simon 192/128 Test + // Key: 1716151413121110 0f0e0d0c0b0a0908 0706050403020100 Plaintext: 206572656874206e 6568772065626972 Ciphertext: c4ac61effcdc0d4f 6c9c8d6e2597b85b + uint8_t simon192_128_key[] = {0x00, 0x01, 0x02, 0x03,0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}; + uint8_t simon192_128_plain[] = {0x72, 0x69, 0x62, 0x65, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20}; + uint8_t simon192_128_cipher[] = {0x5b, 0xb8, 0x97, 0x25, 0x6e, 0x8d, 0x9c, 0x6c, 0x4f, 0x0d, 0xdc, 0xfc, 0xef, 0x61, 0xac, 0xc4}; + result = simon_init(&my_simon_cipher, simon_192_128, ECB, simon192_128_key, my_IV, my_counter); + simon_encrypt(my_simon_cipher, &simon192_128_plain, &ciphertext_buffer); + for(i = 0; i < 16; i++) { + if (ciphertext_buffer[i] != simon192_128_cipher[i]) + error_sum++; + } + simon_decrypt(my_simon_cipher, &simon192_128_cipher, &ciphertext_buffer); + for(i = 0; i < 16; i++) { + if (ciphertext_buffer[i] != simon192_128_plain[i]) + error_sum++; + } + + + // Simon 256/128 Test + // Key: 1f1e1d1c1b1a1918 1716151413121110 0f0e0d0c0b0a0908 0706050403020100 Plaintext: 74206e69206d6f6f 6d69732061207369 Ciphertext: 8d2b5579afc8a3a0 3bf72a87efe7b868 + uint8_t simon256_128_key[] = {0x00, 0x01, 0x02, 0x03,0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1d, 0x1e, 0x1f}; + uint8_t simon256_128_plain[] = {0x69, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6d, 0x6f, 0x6f, 0x6d, 0x20, 0x69, 0x6e, 0x20, 0x74}; + uint8_t simon256_128_cipher[] = {0x68, 0xb8, 0xe7, 0xef, 0x87, 0x2a, 0xf7, 0x3b, 0xa0, 0xa3, 0xc8, 0xaf, 0x79, 0x55, 0x2b, 0x8d}; + result = simon_init(&my_simon_cipher, simon_256_128, ECB, simon256_128_key, my_IV, my_counter); + simon_encrypt(my_simon_cipher, &simon256_128_plain, &ciphertext_buffer); + for(i = 0; i < 16; i++) { + if (ciphertext_buffer[i] != simon256_128_cipher[i]) + error_sum++; + } + simon_decrypt(my_simon_cipher, &simon256_128_cipher, &ciphertext_buffer); + for(i = 0; i < 16; i++) { + if (ciphertext_buffer[i] != simon256_128_plain[i]) + error_sum++; + } + return error_sum; +}