LEA Cipher 암호화/복호화 과정 이해하기

 

LEA Cipher 암호화/복호화 과정 이해하기

블록암호 LEA(Lightweight Encryption Algorithm)는 128비트 데이터 블록을 암호화하는 알고리즘으로 128, 192, 256비트 비밀키를 사용할 수 있으며 요구되는 안전성 기준에 따라 용도가 구분될 수 있다 1. LEA ��

cryptosecurity.tistory.com

LEA Cipher 암호화와 복호화 규격과 구조, 과정을 이해하고 보시길 바랍니다.

 

 

 

LEA.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef _LEA_H_
#define _LEA_H_
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
typedef unsigned char BYTE; //1byte
typedef unsigned long int WORD; //4byte 
 
int ROL(int i, WORD value);
int ROR(int i, WORD value);
void KeySchedule_128(BYTE *K, WORD *RK);
void KeySchedule_192(BYTE *K, WORD *RK);
void KeySchedule_256(BYTE *K, WORD *RK);
void Encrypt(int Nr, WORD *RK, BYTE *P, BYTE *C);
void Decrypt(int Nr, WORD *RK, BYTE *D, BYTE *C);
 
#else
#endif
cs

 

 

LEA.cpp

delta 상수 정하기

1
2
3
4
5
6
7
8
9
10
11
12
#include "LEA.h"
 
WORD delta[8= {
    0xc3efe9db,
    0x44626b02,
    0x79e27c8a,
    0x78df30ec,
    0x715ea49e,
    0xc785da0a,
    0xe04ef22a,
    0xe5c40957
};
cs

 

Rotate Left & Rotate Right 함수 구현

1
2
3
4
5
6
7
8
9
10
11
//32비트 비트열 x의 i비트 좌측 순환이동
int ROL(int i, WORD value)
{
    return (value << i) | (value >> (32 - i));
}
 
//32비트 비트열 x의 i비트 우측 순환이동
int ROR(int i, WORD value)
{
    return (value >> i) | (value << (32 - i));
}
cs

 

LEA-128 키 스케줄링 함수 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void KeySchedule_128(BYTE *K, WORD *RK)
{
    WORD T[4];
 
    memcpy(T, K, 16); //8*16 = 128
 
    int i;
    for (i = 0; i < 24; i++)
    {
        T[0= ROL(1, T[0+ ROL(i, delta[i % 4]));
        T[1= ROL(3, T[1+ ROL(i + 1, delta[i % 4]));
        T[2= ROL(6, T[2+ ROL(i + 2, delta[i % 4]));
        T[3= ROL(11, T[3+ ROL(i + 3, delta[i % 4]));
        RK[i * 6 + 0= T[0];
        RK[i * 6 + 1= T[1];
        RK[i * 6 + 2= T[2];
        RK[i * 6 + 3= T[1];
        RK[i * 6 + 4= T[3];
        RK[i * 6 + 5= T[1];
    }
}
cs

 

 

LEA-192 키 스케줄링 함수 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void KeySchedule_192(BYTE *K, WORD *RK)
{
    WORD T[6];
 
    memcpy(T, K, 24); //8*24 = 192
 
    int i;
    for (i = 0; i < 28; i++)
    {
        T[0= ROL(1, T[0+ ROL(i, delta[i % 6]));
        T[1= ROL(3, T[1+ ROL(i + 1, delta[i % 6]));
        T[2= ROL(6, T[2+ ROL(i + 2, delta[i % 6]));
        T[3= ROL(11, T[3+ ROL(i + 3, delta[i % 6]));
        T[4= ROL(13, T[4+ ROL(i + 4, delta[i % 6]));
        T[5= ROL(17, T[5+ ROL(i + 5, delta[i % 6]));
        RK[i * 6 + 0= T[0];
        RK[i * 6 + 1= T[1];
        RK[i * 6 + 2= T[2];
        RK[i * 6 + 3= T[3];
        RK[i * 6 + 4= T[4];
        RK[i * 6 + 5= T[5];
    }
}
cs

 

LEA-256 키 스케줄링 함수 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void KeySchedule_256(BYTE *K, WORD *RK)
{
    WORD T[8];
 
    memcpy(T, K, 32); //8*32 = 256
 
    int i;
    for (i = 0; i < 32; i++)
    {
        T[(6 * i + 0) % 8= ROL(1, T[(6 * i + 0) % 8+ ROL(i, delta[i % 8]));
        T[(6 * i + 1) % 8= ROL(3, T[(6 * i + 1) % 8+ ROL(i + 1, delta[i % 8]));
        T[(6 * i + 2) % 8= ROL(6, T[(6 * i + 2) % 8+ ROL(i + 2, delta[i % 8]));
        T[(6 * i + 3) % 8= ROL(11, T[(6 * i + 3) % 8+ ROL(i + 3, delta[i % 8]));
        T[(6 * i + 4) % 8= ROL(13, T[(6 * i + 4) % 8+ ROL(i + 4, delta[i % 8]));
        T[(6 * i + 5) % 8= ROL(17, T[(6 * i + 5) % 8+ ROL(i + 5, delta[i % 8]));
        RK[i * 6 + 0= T[(i * 6 + 0) % 8];
        RK[i * 6 + 1= T[(i * 6 + 1) % 8];
        RK[i * 6 + 2= T[(i * 6 + 2) % 8];
        RK[i * 6 + 3= T[(i * 6 + 3) % 8];
        RK[i * 6 + 4= T[(i * 6 + 4) % 8];
        RK[i * 6 + 5= T[(i * 6 + 5) % 8];
    }
}
cs

 

LEA 암호화 함수 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void Encrypt(int Nr, WORD *RK, BYTE *P, BYTE *C)
{
    WORD X_Round[4]; //32 * 4 =128BIT  
    WORD X_NextRound[4];
 
    memcpy(X_Round, P, 16);
 
    int i, j, k;
    for (i = 0; i < Nr; i++)
    {
        X_NextRound[0= ROL(9, (X_Round[0] ^ RK[i * 6 + 0]) + (X_Round[1] ^ RK[i * 6 + 1]));
        X_NextRound[1= ROR(5, (X_Round[1] ^ RK[i * 6 + 2]) + (X_Round[2] ^ RK[i * 6 + 3]));
        X_NextRound[2= ROR(3, (X_Round[2] ^ RK[i * 6 + 4]) + (X_Round[3] ^ RK[i * 6 + 5]));
        X_NextRound[3= X_Round[0];
 
        memcpy(X_Round, X_NextRound, 16);
    }
 
    memcpy(C, X_NextRound, 16);
}
cs

 

LEA 복호화 함수 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void Decrypt(int Nr, WORD *RK, BYTE *D, BYTE *C)
{
    WORD X_Round[4];
    WORD X_NextRound[4];
    
    memcpy(X_Round, C, 16);
    
    int i;
    for (i = 0; i < Nr; i++)
    {
        X_NextRound[0= X_Round[3];
        X_NextRound[1= (ROR(9, X_Round[0]) - (X_NextRound[0] ^ RK[((Nr - i - 1* 6+ 0])) ^ RK[((Nr - i - 1* 6+ 1];
        X_NextRound[2= (ROL(5, X_Round[1]) - (X_NextRound[1] ^ RK[((Nr - i - 1* 6+ 2])) ^ RK[((Nr - i - 1* 6+ 3];
        X_NextRound[3= (ROL(3, X_Round[2]) - (X_NextRound[2] ^ RK[((Nr - i - 1* 6+ 4])) ^ RK[((Nr - i - 1* 6+ 5];
        
        memcpy(X_Round, X_NextRound, 16);
    }
    
    memcpy(D, X_Round, 16);
}
cs

 

 

main.cpp

LEA 암호화 복호화 테스트 해보기

1. LEA-128 암호화, 복호화 테스트하기

 

Nb : 16, Nk : 16, Nr : 24

Key : 0f 1e 2d 3c 4b 5a 69 78 87 96 a5 b4 c3 d2 e1 f0

Plaintext : 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f

 

다음의 Key로 Plaintext를 암호화 해서 Ciphertext를 구하고, 다시 Ciphertext를 복호화해서 Plaintext를 구해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include "LEA.h"
 
int main()
{
    int i;
 
    BYTE K[16=
    {
        0x0f0x1e0x2d0x3c0x4b0x5a0x690x780x870x960xa50xb40xc30xd20xe10xf0
    };
 
    BYTE P[16=
    {
        0x100x110x120x130x140x150x160x170x180x190x1a0x1b0x1c0x1d0x1e0x1f
    };
 
    WORD RoundKey[144= { 0, };
    BYTE C[16= { 0 };
    BYTE D[16= { 0 };
 
    KeySchedule_128(K, RoundKey);
 
    printf("Key : ");
    for (i = 0; i < 16; i++)
    {
        printf("0x%02x ", K[i]);
    }
    printf("\n\n");
 
    printf("Plaintext :  ");
    for (i = 0; i < 16; i++)
    {
        printf("0x%02x ", P[i]);
    }
    printf("\n\n");
 
    Encrypt(24, RoundKey, P, C);
    printf("Ciphertext : ");
    for (i = 0; i < 16; i++)
    {
        printf("0x%02x ", C[i]);
    }
    printf("\n\n");
 
    Decrypt(24, RoundKey, D, C);
    printf("Plaintext :  ");
    for (i = 0; i < 16; i++)
    {
        printf("0x%02x ", D[i]);
    }
    printf("\n");
 
    return 0;
}
cs

 

==실행결과==

 

 

2. LEA-192 암호화 복호화 테스트하기

 

Nb : 16, Nk : 24, Nr : 28

Key : 0f 1e 2d 3c 4b 5a 69 78 87 96 a5 b4 c3 d2 e1 f0 f0 e1 d2 c3 b4 a5 96 87

Plaintext : 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f

 

다음의 Key로 Plaintext를 암호화 해서 Ciphertext를 구하고, 다시 Ciphertext를 복호화해서 Plaintext를 구해보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include "lea.h"
 
int main()
{
    int i;
 
    BYTE K[24=
    {
        0x0f0x1e0x2d0x3c0x4b0x5a0x690x780x870x960xa50xb40xc30xd20xe10xf00xf00xe10xd20xc30xb40xa50x960x87
    };
 
    
    BYTE P[16=
    {
        0x200x210x220x230x240x250x260x270x280x290x2a0x2b0x2c0x2d0x2e0x2f
    };
 
    WORD RoundKey[168= { 0, };
    BYTE C[16= { 0 };
    BYTE D[16= { 0 };
 
    KeySchedule_192(K, RoundKey);
 
    printf("Key : ");
    for (i = 0; i < 24; i++)
    {
        printf("0x%02x ", K[i]);
    }
    printf("\n\n");
 
    printf("Plaintext :  ");
    for (i = 0; i < 16; i++)
    {
        printf("0x%02x ", P[i]);
    }
    printf("\n\n");
 
    Encrypt(28, RoundKey, P, C);
    printf("Ciphertext : ");
    for (i = 0; i < 16; i++)
    {
        printf("0x%02x ", C[i]);
    }
    printf("\n\n");
 
    Decrypt(28, RoundKey, D, C);
    printf("Plaintext :  ");
    for (i = 0; i < 16; i++)
    {
        printf("0x%02x ", D[i]);
    }
    printf("\n");
 
    return 0;
}
cs

 

==실행결과==

 

 

 

3. LEA-256 암호화, 복호화 테스트하기

 

Nb : 16, Nk : 32, Nr : 32

Key : 0f 1e 2d 3c 4b 5a 69 78 87 96 a5 b4 c3 d2 e1 f0 f0 e1 d2 c3 b4 a5 96 87

Plaintext : 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f

 

다음의 Key로 Plaintext를 암호화 해서 Ciphertext를 구하고, 다시 Ciphertext를 복호화해서 Plaintext를 구해보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include "lea.h"
 
int main()
{
    int i;
    BYTE K[32=
    {
        0x0f0x1e0x2d0x3c0x4b0x5a0x690x780x870x960xa50xb40xc30xd20xe10xf00xf00xe10xd20xc30xb40xa50x960x870x780x690x5a0x4b0x3c0x2d0x1e0x0f
    };
 
    BYTE P[16=
    {
        0x300x310x320x330x340x350x360x370x380x390x3a0x3b0x3c0x3d0x3e0x3f
    };
 
    WORD RoundKey[192= { 0, };
    BYTE C[16= { 0 };
    BYTE D[16= { 0 };
    
    KeySchedule_256(K, RoundKey);
    
    printf("Key : ");
    for (i = 0; i < 32; i++)
    {
        printf("0x%02x ", K[i]);
    }
    printf("\n\n");
 
    printf("Plaintext :  ");
    for (i = 0; i < 16; i++)
    {
        printf("0x%02x ", P[i]);
    }
    printf("\n\n");
 
    Encrypt(32, RoundKey, P, C);
    printf("Ciphertext : ");
    for (i = 0; i < 16; i++)
    {
        printf("0x%02x ", C[i]);
    }
    printf("\n\n");
 
    Decrypt(32, RoundKey, D, C);
    printf("Plaintext :  ");
    for (i = 0; i < 16; i++)
    {
        printf("0x%02x ", D[i]);
    }
    printf("\n");
    return 0;
}
cs

 

==실행결과==

 

 

LEA 암호화, 복호화 전체 c언어 코드 보기

github.com/K-subin/LEA

'Cipher analysis > LEA' 카테고리의 다른 글

LEA Cipher 암호화/복호화 과정 이해하기  (0) 2020.10.14

블록암호 LEA(Lightweight Encryption Algorithm)는 128비트 데이터 블록을 암호화하는 알고리즘으로 128, 192, 256비트 비밀키를 사용할 수 있으며 요구되는 안전성 기준에 따라 용도가 구분될 수 있다

 

1. LEA 규격

LEA를 각 키 길이에 따라 LEA-128, LEA-192, LEA-256으로 구분한다.

  • 블록 길이 : Nb 바이트
  • 비밀키 길이 : Nk 바이트
  • 라운드 수 : Nr

 

LEA 암호화 및 복호화 과정

LEA의 전체적인 동작 과정은 다음과 같다.

 

 

2. LEA 암호화

LEA의 암호화 과정은 k비트 키 K로부터 Nr개의 192비트 암호화용 라운드키 RK_i (0 ≤ i ≤ (Nr - 1))를 생성하는 키 스케줄 함수 KeySchedule_k와, 라운드키 RK_i 및 라운드 함수 Round를 이용하여 128비트 평문 P를 128비트 암호문 C로 변환하는 암호화 함수 Encrypt로 구성된다.

 

2.1. 암호화 키 스케줄

키 K로부터 암호화 과정에 필요한 Nr개의 192비트 암호화 라운드키 RK_i (0 ≤ i ≤ (Nr - 1))들을 생성하는 키 스케줄 과정을 설명한다

 

- 상수

키 스케줄 함수에서 사용되는 32비트 상수들 δ[i] (0 ≤ i ≤ 7)는 다음과 같다

 

- LEA-128 암호화 키 스케줄링

128비트 키 K = (K[0], K[1], … , K[15])에 대해 LEA-128의 암호화를 위해 사용되는 키 스케줄 함수 KeySchedule-128은 24개의 192비트 암호화 라운드키 RK_i = (RK_i[0], RK_i[1], … , RK_i[5]) (0 ≤ i ≤ 23)를 다음 알고리즘3과 같이 생성한다.

이 과정에서 128비트 내부상태 변수 T = (T[0], T[1], T [2], T[3])가 사용된다

 

- LEA-192 암호화 키 스케줄링

192비트 키 K = (K[0], K[1], … , K[23])에 대해 LEA-192의 암호화를 위해 사용되는 키 스케줄 함수 KeySchedule-192는 28개의 192비트 암호화 라운드키 RK_i = (RK_i[0], RK_i[1] , … , RK_i[5]) (0 ≤ i ≤ 27)를 알고리즘4와 같이 생성한다.

이 과정에서 192비트 내부상태 변수 T = (T[0], T[1], … , T[5])가 사용된다.

 

- LEA-256 암호화 키 스케줄링

256비트 키 K = (K[0], K[1], … , K[31])에 대해 LEA-256의 암호화를 위해 사용되는 키 스케줄 함수 KeySchedule2 e5n 6 c는 32개의 192비트 암호화 라운드키 RK_i = (RK_i[0], RK_i[1], … , RK_i[5]) (0 ≤ i ≤ 31)를 알고리즘5와 같이 생성한다.

이 과정에서 256비트 내부상태 변수 T = (T[0], T[1], … , T[7])가 사용된다.

 

 

 

2.2. 암호화 함수

- 암호화 라운드 함수

알고리즘 1에서 i (0 ≤ i ≤ (Nr - 1))번째 라운드의 라운드 함수 Round는 128비트 내부상태 변수 X_i = (X_i[0], X_i[1], X_i[2], X_i[3])와 198비트 라운드키 RK_i = (RK_i[0], RK_i[1], … , RK_i[5])로부터 알고리즘 2를 수행하여 새로운 128비트 내부상태 변수 X_i+1 = (X_(i+1)[0], X_(i+1)[1], X_(i+1)[2], X_(i+1)[3])을 생성한다.

 

- 암호화 함수

LEA의 암호화 함수 Encrypt는 k비트 키 K에 대해 키 스케줄 함수 KeySchedulekenc을 수행하여 생성된 Nr개의 192비트 라운드키 RK_i = (RK_i[0], RK_i[1], … , RK_i[5]) (0 ≤ i ≤ (Nr - 1))와 128비트 평문 P = (P[0], P[1], … , P[15])를 입력받아 알고리즘 1을 수행하여 128비트 암호문 C = (C[0], C[1], … , C[15])를 출력한다.

 

다음은 암호화 과정의 i번째 라운드 함수를 도식화한 것이다.

 

 

 

 

3. LEA 복호화

LEA의 복호화 과정은 k비트 키 K로부터 Nr개의 192비트 복호화용 라운드키 RK_i (0 ≤ i ≤ (Nr - 1))를 생성하는 키 스케줄 함수 KeySchedule_k와, 라운드키 RK_i및 라운드 함수 Round를 이용하여 128비트 암호문 C를 128비트 평문 P로 변환하는 복호화 함수 Decrypt로 구성된다.

 

3.1. 복호화 키 스케줄링

키 K로부터 복호화 과정에 필요한 Nr개의 복호화 라운드키 RK_i (0 ≤ i ≤ (Nr - 1))들을 생성하는 키 스케줄 과정을 설명한다. 암호화 라운드키와 복호화 라운드키는

인 관계를 제외하면 동일한 방법으로 생성되며, 동일한 상수가 사용된다.

 

 

3.2. 복호화 함수

- 복호화 라운드 함수

알고리즘 6에서 i (0 ≤ i ≤ (Nr - 1))번째 라운드의 라운드 함수 Round는 128비트 내부상태 변수 Xi = (Xi[0], Xi[1], Xi[2], Xi[3]) 와 192비트 라운드키 RK_i = (RK_i[0], RK_i[1], … , RK_i[5]) 로 부터 알고리즘 7을 수행하여 새로운 128비트 내부상태 변수 X_(i+1) = (X_(i+1)[0], X_(i+1)[1], X_(i+1)[2], X_(i+1)[3]) 을 생성한다.

 

- 복호화 함수

LEA의 복호화 함수 Decrypt는 k비트 키 K에 대해 키 스케줄 함수 KeySchedule_k을 수행하여 생성된 Nr개의 192비트 라운드키 RK_i = (RK_i[0], RK_i[1], … , RK_i[5]) (0 ≤ i ≤ (Nr - 1)) 와 128비트 암호문 C = (C[0], C[1], … , C[15])를 입력받아 알고리즘 6을 수행하여 128 비트 평문 P = (P[0], P[1], … , P[15])를 출력한다.

 

다음은 복호화 과정의 i번째 라운드 함수를 도식화 한 것이다.

 

 

 

 

출처 : 128비트 블록암호 LEA 규격서, NSR 국가보안기술연구소

'Cipher analysis > LEA' 카테고리의 다른 글

LEA Cipher 암호화, 복호화 C언어로 구현하기  (0) 2020.10.14

+ Recent posts