2016-06-08 3 views
1

Я хочу использовать блочный шифр Speck для криптографии на моей платформе. Некоторые из кода в C доступны на https://en.wikipedia.org/wiki/Speck_(cipher), но они не предоставляют расшифровки.Застрял на алгоритме дешифрования Speck в C

На данный момент я адаптировал код для реализации Speck 64/128 (64-битный блок и 128-битный ключ) и получил (предположительно) успешное шифрование, теперь я хотел бы расшифровать его снова. Ключ жестко запрограммирован, это просто для бенчмаркинга.

#include <stdint.h> 

#define ROR(x, r) ((x >> r) | (x << (32 - r))) 
#define ROL(x, r) ((x << r) | (x >> (32 - r))) 
#define R(x, y, k) (x = ROR(x, 8), x += y, x ^= k, y = ROL(y, 3), y ^= x) 
#define ROUNDS 27 

void speckEncrypt(uint32_t pt[2], uint32_t ct[2], uint32_t K[2]) { 
    uint32_t y = pt[0], x = pt[1], b = K[0], a = K[1]; 

    R(x, y, b); 
    for (int i = 0; i < ROUNDS - 1; i++) { 
     R(a, b, i); 
     R(x, y, b); 
    } 

    ct[0] = y; 
    ct[1] = x; 
} 

void speckDecrypt(uint32_t pt[2], uint32_t ct[2], uint32_t K[2]) { 
} 

static void speck(uint32_t pt[2]){ 

    uint32_t ct[2]; 

    uint32_t K[4] = {123456789,123456789,123456789,123456789}; 

    printf("Plaintext x: %lu", pt[0]); 
    printf(", Plaintext y: %lu \n", pt[1]); 

    printf("Get key schedule \n"); 

    speckEncrypt(pt, ct, K); 

    printf("Encrypted encr_x: %lu ",ct[0]); 
    printf(", Encrypted encr_y: %lu \n", ct[1]); 

// speckDecrypt(pt, ct, K); 

// printf("Decrypted x: %lu", pt[0]); 
// printf(", Decrypted y: %lu \n", pt[1]); 
} 

Я не преуспеваю в реализации speckDecrypt. Я пробовал искать другие решения, но последовательно терпеть неудачу (например, https://www.multos.com/forums/viewthread/97). Я неопытный с крипто, так кто-нибудь может мне помочь?

Edit:

Я также сделал то же самое для реализации Java, которая использует ключевые расширения. Может ли это быть добавлено к этому? Насколько я могу судить, версия java работает.

public void speck(int subm_x,int subm_y){ 
    byte n = 32; // Word size 
    byte m = 4; // # of key words 
    byte T = 27; // Number of rounds 
    int[] l; // Used in the key generation 
    int[] k; // Stores subkeys 
    int x; // Encrypted x 
    int y; // Encrypted y 
    byte alpha = 8; // Number of shifts, function of n 
    byte beta = 3; // Number of shifts, function of n 

    k = new int[T]; 
    l = new int[2*T]; 

    k[0] = 123456789; //faux random number. Max Int is 2,147,483,647 
    k[1] = 123456789; //faux random number. Max Int is 2,147,483,647 
    k[2] = 123456789; //faux random number. Max Int is 2,147,483,647 
    k[3] = 123456789; //faux random number. Max Int is 2,147,483,647 

    l[m-4] = 1123456789; 
    l[m-3] = 1113456789; 
    l[m-2] = 1111456789; 

    x = subm_x; 
    y = subm_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]; 
    } 
    /* *************** ENCRYPTION ********************* */ 
    for(int i = 0; i < T; i++) { 
     x = (rotateRight(x, alpha) + y)^k[i]; 
     y = rotateLeft(y, beta)^x; 
    } 

    /* *************** DECRYPTION ********************* */   
    for(int i = T-1; i >= 0; i--) { 
     y = rotateRight(x^y, beta); 
     x = rotateLeft((x^k[i]) - y, alpha); 
    } 
    } 

Целью является сопоставление их друг с другом.

ответ

1

Я нашел простую реализацию на https://github.com/madmo/speck/blob/master/speck.c и использую не комбинированную версию (не уверен в различиях).

Это работает и, надеюсь, может помочь другим!

По желанию, моя реализация (как процесс Contiki):

#include <stdint.h> 
#define SPECK_TYPE uint32_t 
#define SPECK_ROUNDS 27 
#define SPECK_KEY_LEN 4 

#define ROR(x, r) ((x >> r) | (x << ((sizeof(SPECK_TYPE) * 8) - r))) 
#define ROL(x, r) ((x << r) | (x >> ((sizeof(SPECK_TYPE) * 8) - r))) 

#ifdef SPECK_32_64 
#define R(x, y, k) (x = ROR(x, 7), x += y, x ^= k, y = ROL(y, 2), y ^= x) 
#define RR(x, y, k) (y ^= x, y = ROR(y, 2), x ^= k, x -= y, x = ROL(x, 7)) 
#else 
#define R(x, y, k) (x = ROR(x, 8), x += y, x ^= k, y = ROL(y, 3), y ^= x) 
#define RR(x, y, k) (y ^= x, y = ROR(y, 3), x ^= k, x -= y, x = ROL(x, 8)) 
#endif 

void speck_expand(SPECK_TYPE const K[static SPECK_KEY_LEN], SPECK_TYPE S[static SPECK_ROUNDS]) 
{ 
    SPECK_TYPE i, b = K[0]; 
    SPECK_TYPE a[SPECK_KEY_LEN - 1]; 

    for (i = 0; i < (SPECK_KEY_LEN - 1); i++) 
    { 
     a[i] = K[i + 1]; 
    } 
    S[0] = b; 
    for (i = 0; i < SPECK_ROUNDS - 1; i++) { 
     R(a[i % (SPECK_KEY_LEN - 1)], b, i); 
     S[i + 1] = b; 
    } 
} 

void speck_encrypt(SPECK_TYPE const pt[static 2], SPECK_TYPE ct[static 2], SPECK_TYPE const K[static SPECK_ROUNDS]) 
{ 
    SPECK_TYPE i; 
    ct[0]=pt[0]; ct[1]=pt[1]; 

    for(i = 0; i < SPECK_ROUNDS; i++){ 
     R(ct[1], ct[0], K[i]); 
    } 
} 

void speck_decrypt(SPECK_TYPE const ct[static 2], SPECK_TYPE pt[static 2], SPECK_TYPE const K[static SPECK_ROUNDS]) 
{ 
    SPECK_TYPE i; 
    pt[0]=ct[0]; pt[1]=ct[1]; 

    for(i = 0; i < SPECK_ROUNDS; i++){ 
     RR(pt[1], pt[0], K[(SPECK_ROUNDS - 1) - i]); 
    } 
} 

PROCESS_THREAD(eval_crypto_process, ev, data) 
{ 
    PROCESS_BEGIN(); 
    printf("eval_crypto_process\n"); 

    while(1){ 
     printf("Waiting.\n"); 

     static struct etimer timer; 
     etimer_set(&timer, 5*CLOCK_CONF_SECOND); 
     PROCESS_WAIT_UNTIL(etimer_expired(&timer)); 
     printf("Starting crypto.\n"); 

     PORTB ^= _BV(PB5); 
     PORTB ^= _BV(PB6); 

     uint32_t plain[2] = {987654321,987654321}; 
     uint32_t key[4] = {123456789, 123456789, 123456789, 123456789}; 

     SPECK_TYPE buffer[2] = {0}; 
     SPECK_TYPE enc[2] = {0}; 

     SPECK_TYPE exp[SPECK_ROUNDS]; 

     speck_expand(key, exp); 

//  printf("Plaintext x: %lu", plain[0]); 
//  printf(", Plaintext y: %lu \n", plain[1]); 

     speck_encrypt(plain, enc, exp); 

//  printf("Encrypted encr_x: %lu ",enc[0]); 
//  printf(", Encrypted encr_y: %lu \n", enc[1]); 

     speck_decrypt(enc, buffer, exp); 

//  printf("Decrypted x: %lu", buffer[0]); 
//  printf(", Decrypted y: %lu \n", buffer[1]); 

     PORTB ^= _BV(PB5); 
     PORTB ^= _BV(PB6); 

     printf("finished crypto.\n"); 
    } 

    PROCESS_END(); 
} 
Смежные вопросы