Claude가 추적한 ECDSA 공개 매개변수의 기원
Claude가 오래된 난수 생성기와 시간값으로 표준 타원곡선 매개변수의 기원을 설명했으며, 이는 암호 해독이 아닌 공개 매개변수의 생성 경위 복원입니다.
쉽게 말하면비유하자면 오래된 사진이 찍힌 시각을 카메라 기종의 버릇으로 되짚은 셈이다. 공개된 숫자가 어떤 난수 생성기(무작위 숫자를 만드는 프로그램)와 어떤 시간값에서 나왔는지 복원한 것이고, 자물쇠를 연 것은 아니다.
- 왜 봐야 하나
- 공개된 값이라도 만든 과정을 남겨두면 수십 년 뒤에도 검증할 수 있고, 모델이 가설을 바꿔 오래된 의문을 좁힐 수 있음을 보여준다. 개인키를 복구하거나 ECDSA를 깬 결과는 아니고, 사용자가 키를 바꿀 일도 아니다.
이 글은 NIST 표준 타원곡선의 공개 매개변수인 seed가 어디서 왔는지 추적한 발견 보고다. Anthropic은 내부 연구 모델이 30분 미만에 NIST 소수체 곡선 5개의 기원을 찾아냈다고 설명한다. 전체 분석에서는 오래된 C 난수 생성기를 시간값으로 초기화하면 NIST·ANSI 곡선의 여러 seed를 재현할 수 있었고, 일부 기준점의 기원도 설명했다. 이는 개인키를 알아내거나 암호를 깬 결과가 아니다. 공개 매개변수 선택의 불투명성을 줄이지만, 건너뛴 후보와 미해결 seed가 남아 있어 완전한 안전성 증명도 아니다.
알아낸 것
- NIST 소수체 곡선 5개와 ANSI 예제 5개의 seed가 모두 'lrand48() >> 23'이라는 같은 패턴을 보였고, 복구한 48비트 상태가 각 seed의 160비트 전체를 다시 만들었다.
- 10개 소수체 seed의 초기값이 1997년 5월에서 1998년 4월 사이의 Unix 타임스탬프로 읽혔다. P-256은 1842번째 후보에서 공개 seed와 맞았다.
- 이진체 seed인 B-163은 설명되지 않았고 P-224·P-256·P-384·P-521의 기준점도 미해결이다. P-256에서 876번째 후보를 건너뛴 이유도 알 수 없다.
한계와 주의할 점
- 복원한 것은 원래 공개돼 있던 곡선 설정값이 어떻게 만들어졌는지다. 비밀키를 알아내거나 암호를 깬 결과가 아니다.
- B-163 곡선의 seed와 네 곡선의 기준점은 아직 설명되지 않았다. 완전한 해답이 아니라 오랜 의문의 상당 부분을 푼 중간 단계로 봐야 한다.
- P-256에서 앞선 후보를 건너뛴 이유는 알 수 없다. 의도적으로 약한 곡선을 골랐을 가능성을 수학적으로 배제한 것은 아니다.
용어 풀이
- ECDSA
- 타원곡선 디지털서명 알고리즘. 타원곡선 위의 이산대수 문제에 기반한 전자서명 표준으로, 이 글에서는 NIST가 채택한 표준 곡선들의 매개변수 기원이 논의된다.
- seed
- 타원곡선의 계수 b를 결정하는 데 사용되는 공개 매개변수. 이 값의 해시로 계수가 정해지며, 그 기원이 오랫동안 의문이었다.
- lrand48
- 1990년대 C 라이브러리에 포함된 선형합동생성기 기반 의사난수 생성기. 48비트 내부 상태에서 상위 31비트를 반환하며, 이 연구에서 seed 생성에 사용된 것으로 밝혀졌다.
- Unix 타임스탬프
- 1970년 1월 1일 00:00:00 UTC부터 경과한 초 단위 시간. lrand48을 초기화하는 시드로 사용되었으며, 복구된 타임스탬프가 1997~1998년 날짜로 해석되었다.
- 선형합동생성기
- x_{n+1} = (a * x_n + c) mod m 형태의 점화식으로 난수를 생성하는 알고리즘. lrand48의 기반이며, 역방향 계산이 쉬워 상태 복구가 가능하다.
- 기준점(base point)
- 타원곡선 암호에서 모든 공개키가 그 배수로 표현되는 고정된 점. seed와 별도로 생성되며, 일부 곡선의 기준점이 FreeLIP 라이브러리의 난수 생성기에서 유래했다.
- FreeLIP
- Arjen Lenstra가 개발한 장정수 연산 패키지. 초기 버전의 NTL 라이브러리에도 같은 코드가 포함되어 있었으며, 일부 기준점 생성에 사용된 난수 생성기를 제공한다.
더 깊이 읽기 읽는 데 약 7분
배경과 문제
ECDSA는 타원곡선 위의 계산을 이용하는 전자서명 방식이다. NIST는 2000년 표준에 여러 곡선을 포함했고, 공개된 seed를 해시해 곡선의 계수 b를 정했다. 문제는 NSA가 제공한 seed 자체를 어떻게 골랐는지 설명하지 않았다는 것이다. P-256의 seed처럼 긴 16진수는 누구나 볼 수 있었지만, 그 숫자를 선택한 과정은 알 수 없었다.
연구자들이 걱정한 것은 공개된 숫자에 비밀스러운 선택 기준이 있었을 가능성이다. 이전 조사와 현상금도 이를 추적했다. 오래된 증언은 직원 이름을 넣은 유머 문구를 해시했을 것이라는 단서를 남겼지만, 당시 기록과 기억이 부족했다. 이 글의 발견은 곡선을 새로 만드는 것이 아니라 이미 사용하던 곡선의 생성 이력을 되찾는 일이다.
기존 접근의 한계
Anthropic 직원들도 처음에는 소문의 문구를 바꾸어 해시하는 접근을 시도했지만 실패했다. Claude에 문제를 맡길 때는 그 단서를 알려주지 않았다. 모델은 문구 대신 당시 소프트웨어가 사용했을 난수 생성기를 의심했다. 가설을 바꾸자 같은 공개 숫자에서 살펴볼 특징도 달라졌다.
여기서 곡선 seed와 난수 생성기의 초기값은 서로 다른 값이다. 곡선 seed는 160비트 공개 출력이고, 생성기의 초기값은 그 출력을 만들기 위해 넣은 시간값이었다. 출력은 임의의 숫자처럼 보여도 오래된 생성기의 구조적 흔적을 남길 수 있다. 따라서 메타데이터가 없다는 사실이 생성 경위를 영원히 복원할 수 없다는 뜻은 아니다.
연구방법을 단계별로
Claude는 소문에 기반한 문구 검색 대신, 1990년대 C 라이브러리에 포함된 의사난수 생성기(PRNG)를 사용했을 것이라고 가정했다. 당시의 PRNG는 출력이 충분히 약해서 그 패턴을 인식할 수 있고, 인식에 성공하면 어떤 생성기가 사용되었는지와 초기화 상태까지 복구할 수 있다. Claude는 각 공개 seed를 한 비트씩 이동하며 인접한 청크가 1990년대 생성기의 연속 출력인지 검사하는 스캐너를 작성했고, 34가지 생성기와 출력 슬라이스 조합을 탐색했다.
스캐너는 생성기와 출력 구간의 조합 34가지를 검사했다. 그중 일부 seed를 32비트 단위로 나누면 맨 위 비트가 계속 0이라는 패턴이 보였다. 이는 48비트 내부 상태에서 상위 31비트만 돌려주는 lrand48의 특징과 맞았다. 연구팀의 설명에 따르면 모델은 출력에서 보이지 않는 17비트의 가능한 값을 대조하고 후속 출력이 맞는지 검사해 네 seed의 상태를 복원했다.
소수체 곡선의 seed는 같은 lrand48 생성기에서 나왔지만 각 출력의 더 적은 비트만 유지했다. Claude는 이 비트들로부터 PRNG의 내부 상태를 복구해야 했는데, 잘린 선형합동생성기의 상태 복구는 Lenstra–Lenstra–Lovász(LLL) 격자 축소 알고리즘으로 푸는 전형적인 격자 문제다. Claude는 seed가 상태의 어떤 비트를 보여주는지 몰랐기 때문에 모든 윈도우에 대해 솔버를 실행했다. 그 결과 NIST 소수체 곡선 5개와 ANSI X9.62 표준의 5개 seed 모두 'lrand48() >> 23'이라는 동일한 패턴을 보였고, 복구된 48비트 상태가 각 seed의 160비트 전체를 재생성했다. 저자들은 긴 출력 전체의 일치를 생성 경위를 뒷받침하는 강한 근거로 본다.
결과와 숫자의 의미
선형합동생성기는 역방향으로도 쉽게 실행되므로, Claude는 각 seed에 대해 상태를 거슬러 올라가 srand48로 초기화되었을 형태, 즉 하위 16비트가 0x330E인 상태에 도달할 때까지 되감았다. 이 형태의 내부 상태는 65,536걸음마다 한 번씩 나오므로 그 자체로는 증거가 되지 않는다. 그러나 10개의 소수체 곡선 seed 모두에서 srand48 초기화 값이 1997년 5월부터 1998년 4월 사이의 Unix 타임스탬프로 해석되었다. 이는 약한 PRNG를 Unix 타임스탬프로 시드했음을 강력히 시사한다.
이진체 곡선 네 개의 초기값은 그대로 읽으면 1984년 2월이지만, 두 배로 하면 1998년 4월 17일이 된다. 그래서 당시 코드가 시간값을 반으로 나누었을 가능성을 제시한다. 이는 저자의 해석이다. 소수체 예인 P-256은 1997년 8월 16일 01:52:34 UTC를 초기값으로 삼았을 때 1842번째 후보에서 공개 seed와 일치한다.
seed와 별개로, 공개키 계산의 출발점인 기준점도 추적했다. P-192와 ANSI 예제 다섯 곡선에서는 FreeLIP의 난수 생성기를 작은 정수로 초기화하고 앞의 출력 일곱 개를 버린 뒤 후보 좌표를 만들면 공개된 기준점의 x좌표가 재현됐다. P-192의 초기 정수는 20000이었다. 모든 곡선의 기준점을 설명한 것은 아니며, 이는 seed 복원과 구분되는 추가 발견이다.
구체적인 예시
P-256을 예로 들면, 시간값 t로 lrand48의 내부 상태를 초기화하고 출력을 차례로 만든다. 소수체 곡선에서는 lrand48() >> 23을 적용한다. 즉 31비트 출력의 하위 23비트를 버리고 상위 8비트를 취한다. 이렇게 얻은 20바이트를 후보 하나로 묶고 다음 20바이트를 다음 후보로 묶는다. 1842번째 묶음이 표준에 적힌 160비트 seed와 일치한다. 재현 가능한 것은 이 공개 숫자의 생성 과정이며, 사용자의 비밀키가 아니다.
기준점 복원에서도 처음 나온 숫자가 곧 답은 아니다. 생성기의 출력 조각을 모아 x좌표 후보를 만들고, 실제 곡선 위의 점이 될 수 있는지 검사하며 반복한다. P-192는 두 번째 시도에서 공개된 x좌표와 맞았다. 원문은 코드와 출력을 함께 제공해 이런 주장을 확인할 수 있게 한다. 이번 해설은 그 자료를 대조했으며 코드를 독립 실행해 재현했다고 주장하지 않는다.
한계와 오해하기 쉬운 점
약한 난수 생성기를 썼다는 사실을 곧바로 ECDSA 취약점으로 해석하면 안 된다. 여기서 복원한 값은 원래 공개된 곡선 매개변수다. 저자들은 단순한 생성법이 드러나 의도적으로 약한 곡선을 숨겨 골랐다는 의혹이 줄었다고 해석한다. 그러나 생성 경위에 대한 신뢰 증가와 암호 전체의 안전성 증명은 다른 주장이다.
남은 의문도 구체적이다. P-256의 1842번째 후보보다 앞선 876번째 후보도 적합한 곡선을 만들 수 있는데 건너뛴 이유를 모른다. 다른 실행에서도 적합한 후보를 몇 개 건너뛰었다. 시도한 시간값의 총수나 선택 기준은 숫자만으로 알 수 없다. 저자들은 건너뛴 후보가 적다는 점에서 약한 곡선을 의도적으로 골랐을 가능성을 낮게 보지만, 그 가능성을 수학적으로 배제한 것은 아니다.
또한 다섯 번째 이진체 seed인 B-163은 Claude가 시도한 어떤 것과도 맞지 않아 여전히 설명되지 않았다. P-224, P-256, P-384, P-521의 기준점과 NIST 이진 곡선들의 기준점이 어떻게 생성되었는지도 밝혀지지 않았다. 따라서 이 연구는 완전한 해답이 아니라, 오랜 미스터리의 상당 부분을 해소한 중간 단계로 보아야 한다. 일반 사용자가 키를 변경하거나 다른 조치를 취할 필요는 없다고 저자들은 명시한다.
실제로 어떻게 활용할까
이 사례는 공개 매개변수의 생성 과정도 재현할 수 있게 남기는 것이 신뢰에 도움이 된다는 점을 보여준다. 수십 년 뒤라도 코드와 출력이 연결되면 막연한 의심을 검증 가능한 질문으로 바꿀 수 있다. 일반 사용자에게 키 변경 등 조치가 필요하다는 발견은 아니며, 원문도 별도 조치를 요구하지 않는다.
또한 이 연구는 오래된 암호학적 미스터리를 해결하는 데 AI 모델이 어떻게 기여할 수 있는지 보여주는 사례다. Claude는 기존의 실패한 접근법을 반복하지 않고, 생성 소프트웨어의 동작을 예측하고 약한 PRNG의 통계적 특징을 식별하는 새로운 각도를 취했다. 이는 암호학적 분석에서 가설 전환과 패턴 탐색의 중요성을 보여주며, 유사한 미해결 문제에 대한 방법론적 참고가 될 수 있다. 다만 이는 특정 발견 사례이며 일반적인 추론 속도나 성공률의 벤치마크로 해석해서는 안 된다.
원문에서 확인한 근거 4곳
- NIST P-256 곡선의 seed는 1997년 8월 16일 01:52:34 UTC의 Unix 타임스탬프로 초기화된 lrand48 생성기에서 1842번째 후보로 출력되었다.Code to reproduce the seeds
- 10개의 소수체 곡선 seed 모두에서 srand48 초기화 값이 1997년 5월부터 1998년 4월 사이의 Unix 타임스탬프로 해석되었다.How it was found
- P-192와 5개의 ANSI X9.62 예제 곡선의 기준점은 FreeLIP의 난수 생성기를 작은 정수로 시드하고 출력 7개를 버린 뒤 26비트 출력으로 x 좌표를 생성하는 방식으로 만들어졌다.Claude found some base points too
- B-163 seed는 Claude가 시도한 어떤 것과도 맞지 않아 여전히 설명되지 않았으며, P-224, P-256, P-384, P-521의 기준점 생성 방법도 밝혀지지 않았다.Open questions
10월 17일(토) 정리 · AI가 쓰고 원문과 대조
AI 목록