Rust로 Zstandard 발표
요약
Zstandard(zstd) 알고리즘의 Rust 재구현과 관련하여, 메모리 안전성을 확보하기 위한 Rust 전환의 가치와 crate 명명 규칙에 대해 논의합니다. 특히 암호화 라이브러리 구현 시 보안 결함을 방지하기 위한 Rust 도입의 중요성을 강조합니다.
핵심 포인트
- 메모리 안전성을 위한 Rust 재구현은 구현 결함 방지에 매우 가치 있음
- 암호 알고리즘 자체보다 파싱 및 버퍼 관리 등 비암호화 코드의 안전성이 중요
- Rust crate 명명 규칙(-sys, -rs 등)에 대한 혼선과 그 배경 설명
- 기존 C 라이브러리를 감싸는 -sys crate와 Rust 재구현체의 차이점
정말 반가운 소식임. 며칠 전 의존성 하나 때문에 zstd 빌드를 하려고 libc-dev를 끌어와야 했고, 누가 Rust로 진지하게 재구현해 본 적이 있는지 궁금했음
커뮤니티에서 널리 채택되면 좋겠음
WireGuard 기반 프로젝트를 Rust로 만들고 있어서 여러 Rust 암호화 라이브러리를 가져오고 있음. 메모리 안전성이라는 분명한 장점은 있지만, 오래된 C 라이브러리와 달리 전부 보안 감사를 받은 건 아님
결국 궁금한 건 이런 알고리즘들을 Rust로 다시 쓰는 게 그만한 비용을 감수할 가치가 있느냐는 것임
충분히 가치 있음. 암호는 알고리즘 자체가 깨지는 경우보다 구현 결함 때문에 우회되는 경우가 훨씬 많음
파싱, 프로토콜 상태, 버퍼 관리 같은 “지루한” 비암호화 코드가 제대로 동작해야 시스템이 안전해짐. 공격자는 임의 코드 실행이 되는 마법 패킷을 보낼 수 있다면, 수천 년 걸릴 해독을 수십 년으로 줄이는 고급 암호분석이나 타이밍 부채널에 매달리지 않음
프로젝트의 성능 요구가 너무 빡빡하지 않고 FFI를 조금 감수할 수 있다면, Rust에서 Go 암호화 스택을 쓰는 것도 가능함
양쪽 모두 메모리 안전하고, 좁은 unsafe FFI 경계만 두면 된다는 장점이 있음. Go 암호화 라이브러리는 현재 Rust, 더 정확히는 crates.io 생태계에서 제공되는 것보다 더 성숙해 있음
-sys와 -rs-sys 접미사를 언제 써야 하는지 문서로 정리된 설명을 아는 사람이 있는지 궁금함. 직감으로는 -sys가 Rust로 작성되지 않은 시스템 라이브러리를 감싸는 crate용이라고 생각했음
그런데 그 틀에서는 -rs-sys 접미사가 잘 이해되지 않으니, 내 직감이 틀렸던 듯함. 권위 있는 출처를 아는 사람이 있을까?
이 패키지 이름은 상상 가능한 수준으로 거의 최악에 가깝게 지어졌음. 이름을 이루는 네 부분 중 세 부분이 틀렸거나 바람직하지 않음 -sys: 오래되고 널리 쓰이는 관례이며 https://doc.rust-lang.org/cargo/reference/… 에 설명돼 있음. 하지만 이 crate에는 전혀 맞지 않음 lib: 라이브러리라는 건 이미 알고 있고, Rust에서는 이 접두사가 관례적이지 않으며, 위 링크에서도 *-sys와 함께 반쯤 직접적으로 피하라고 짚고 있음. libzstd-sys라면 liblibzstd에 링크할 것으로 기대될 수 있음. 덧붙이면 Rust와 무관하게 실제로 이중 lib 이름을 본 적도 있음 *-rs: https://rust-lang.github.io/api-guidelines/naming.html 에서 말하듯 “모든 crate는 Rust다! 사용자에게 계속 이것을 상기시킬 필요는 없다”
-sys crate들은 보통 매우 날것의 C식 인터페이스를 노출하고, 내부에 unsafe 코드가 많으며, 대개 외부 라이브러리를 빌드하거나 링크함 -rs-sys 이름은 덜 일관되게 쓰이는 걸 봤음. Rust crate 안에 다시 포장된 외부 코드를 빌드하는 라이브러리, 예컨대 아직 C 부분이 남아 있는 미완성 Rust 구현이나 sys crate를 위한 Rust 지원 코드에 쓰이는 듯함
나름의 논리는 있음 libzstd는 원래 이름임. C 라이브러리는 이름에 lib를 포함하는 경향이 있고, Rust/Cargo 관례에 맞게 바꾸는 대신 참조용으로 그대로 둔 것임 -rs는 Facebook의 C 구현과 구분하기 위한 Rust 재작성판 표시임. 여러 Rust 프로젝트에서 흔히 쓰는 일반 접미사이고, Python 라이브러리들이 pysomething 식으로 이름 짓는 것과 비슷함 -sys는 이 구현이 unsafe C API를 노출하는 드롭인 대체품이기 때문임. Cargo 사용자 입장에서는 Rust 라이브러리가 아님. Rust 인터페이스가 없고, C 함수로 된 C 코드처럼 호출함
그러니 -rs-sys가 아니라 libzstd-rs의 -sys 버전임
왜 ruzstd보다 이걸 택해야 함? 기존 crate에 투자하는 편이 더 낫지 않을까?
ruzstd는 압축이 아직 완전히 구현되지 않았음 1:1 포팅은 다른 코드베이스 위에서 똑같이 빠르고 완전한 압축기를 어떻게 만들지 다시 알아내는 대신, 비교적 곧은 코드 변환으로 비슷한 속도와 기능 동등성을 확보할 수 있게 해줌
“C 참조 구현은 Meta가 관리하며, 기여하려면 Meta와 기여자 계약에 서명해야 한다”
최근에 알게 된 재미있는 사실인데, Facebook이 관리하는 참조 zstd 구현도 LLM으로 코딩되고 있고 openssl의 의존성이기도 해서, 대안이 더 많아지는 건 전적으로 찬성함
“기본 설정에서 우리 구현의 압축 해제 성능은 C 참조 구현보다 몇 퍼센트 느리다”
이 프로젝트에 대해 알아야 할 건 이게 전부임
그 문장이 어떤 의미로 다가왔는지 조금 더 설명해 줄 수 있을까?
참고로 인용한 문장 바로 뒤에는 이런 내용이 이어짐
“다만 unsafe-performance-experimental 기능 플래그를 켜면 C 성능과 같아지기 때문에, 이 성능 저하는 정당화할 수 있다고 봅니다. 이 플래그는 입력 데이터가 자료구조 인덱싱에 쓰이는 네 곳에서 경계 검사 4개를 비활성화합니다. 대부분의 사용자에게 약 3% 성능 저하는 메모리 안전성 향상을 위한 받아들일 만한 비용일 가능성이 큽니다. 정말 마지막 성능까지 필요하다면 본인 책임하에 이 플래그를 켤 수 있습니다. 이 네 위치에서의 동작은 경계 검사를 하지 않는 C와 같으며, 많은 프로덕션 시스템에서 문제없이 동작하는 것으로 보입니다”
AI 자동 생성 콘텐츠
본 콘텐츠는 GeekNews의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기