암호화의 취약점 찾기

시간 제한1초메모리 제한128 MB

요약
9개의 XOR 암호화된 32비트 값에서 마지막이 나머지의 체크섬일 때, 캐리 전파를 이용해 비트 단위로 XOR 키를 복원하는 문제입니다.
난이도

보통10점 중 6점

유형
비트 연산, 수학, 시뮬레이션
정답자
아직 제출이 없습니다

문제

암호화하여 전송하고 싶은 데이터가 32비트 부호 없는 정수 8개로 주어진다.

N1 N2 N3 … N8N_1\ N_2\ N_3\ \ldots\ N_8

먼저 이 데이터가 올바른지 확인하기 위한 체크섬(checksum)을 구해 9번째 데이터로 추가한다. (체크섬은 데이터의 무결성을 확인하는 데 자주 쓰이는 방식이다.)

N9=(∑i=18Ni) mod 232N_9 = \left(\sum_{i=1}^{8} N_i\right) \bmod 2^{32}

그다음 32비트 키 KK를 사용해 이 9개의 수를 암호화한다. 암호화는 XOR 연산으로 이루어진다고 하자. (XOR은 데이터 암호화에 자주 쓰이는 연산이다.)

M1=N1⊕K,M2=N2⊕K,…,M9=N9⊕KM_1 = N_1 \oplus K,\quad M_2 = N_2 \oplus K,\quad \ldots,\quad M_9 = N_9 \oplus K

이렇게 만든 9개의 데이터 M1M_1부터 M9M_9까지를 전송하면, KK를 아는 사람은 원래 데이터 N1N_1부터 N8N_8까지를 복원할 수 있다. 그런데 KK를 모르는 사람도 원래 데이터 N1N_1부터 N8N_8까지를 알아낼 수… 있다!

놀랍게도 이 방식에는 취약점이 있다. 그 취약점을 이용하여, 9개의 정수 M1M_1부터 M9M_9까지가 16진수로 주어질 때 키 KK를 구하는 프로그램을 작성하라.

입력

입력의 첫째 줄에 테스트 케이스의 개수 TT가 주어진다. TT는 10001000을 넘지 않는다.

그다음 각 테스트 케이스마다 9개의 정수 M1M_1부터 M9M_9까지가 16진수로 주어진다. 각 16진수는 숫자 0–9와 소문자 a–f로만 표기되며, 앞에 불필요한 0이 붙지 않는다. 한 테스트 케이스의 9개 수가 모두 한 줄에 주어지지 않을 수도 있다.

출력

각 테스트 케이스마다 키 KK를 소문자 16진수로 한 줄에 하나씩 출력한다. 앞에 불필요한 0은 출력하지 않는다.

힌트

스포일러 주의. 핵심은 N9=(∑i=18Ni) mod 232N_9 = \left(\sum_{i=1}^{8} N_i\right) \bmod 2^{32}라는 관계다. 여덟 개의 Ni=Mi⊕KN_i = M_i \oplus K를 더할 때, 각 비트 자리에서 합의 홀짝은 그 자리의 키 비트 kjk_j와 무관하다. 따라서 최하위 비트부터 덧셈의 자리올림을 따라가며 KK의 각 비트를 하나씩 유일하게 결정할 수 있다.

예제2

  1. 예제 1

    입력
    8
    1 1 1 1 1 1 1 1 8
    3 2 3 2 3 2 3 2 6
    3 4 4 7 7 b a 2 2e
    e1 13 ce 28 ca 6 ab 46 a6d
    b08 49e2 6128 f27 8cf2 bc50 7380 7fe1 723b
    4eba eb4 a352 fd14 6ac1 eed1 dd06 bb83 392bc
    ef593c08 847e522f 74c02b9c 26f3a4e1 e2720a01 6fe66007
    7a4e96ad 6ee5cef6 3853cd88
    60202fb8 757d6d66 9c3a9525 fbcd7983 82b9571c ddc54bab 853e52da
    22047c88 e5524401
    
    예상 출력
    0
    2
    6
    1c6
    4924afc7
    ffff95c5
    546991d
    901c4a16
    
  2. 예제 2

    입력
    1
    1234abcc 1234abcf 1234abce 1234abc9 1234abc8 1234abcb 1234abca 1234abc5 1234abe9
    
    예상 출력
    1234abcd