Last Updated: 2026-04-15
Note
이 문서는 아직 공상 단계입니다. 추상적이며 충분히 구체적이지 않습니다.
Note
스펙에 구멍이 숭숭 뚫려 있습니다. 저는 부족하니 피드백을 부탁드려요!
Note
이 문서의 모든 고유명사는 확정된 것이 아닙니다. 제가 이름짓는 걸 잘 못 합니다.
물론 "문제집 프로토콜" 이라는 이름도 마찬가지입니다. 네이밍 센스가 좀...
문제집 프로토콜(가제) 는 여러 프로그래밍 문제풀이 사이트를 하나의 연합처럼 묶는 프로토콜입니다.
각각의 사이트들은 나름대로의 프로그래밍 문제집을 만듭니다. 한 사이트의 문제집은 다른 사이트 회원들도 풀 수 있고,
푼 문제들을 '랭크 인증 서버'에 검사받으면 랭크를 딸 수 있는 시스템입니다.
이 문서에서는 아래 요소를 설명합니다.
왜?
문제풀이 서버
사용자와 아이덴티티
서버 간의 상호작용
랭크 인증 서버
작은 사이트는 풀잎과 같아서 관심만 가져주고 전기세만 내면 비교적 쉽게 운영할 수 있습니다.
반면 매우매우 큰 사이트는 그에 따르는 큰 유지 비용을 요구합니다.
그 중에서도 온라인 저지 류의 사이트들은 특히 채점 및 컴파일에 상대적으로 많은 컴퓨팅 자원을 요구하는 편입니다.
따라서 큰 온라인 저지 사이트를 운영하는것은 자본이 없다면 매우 도전적인 일이 됩니다.
반대로 작은 사이트들이 여러 개 있는 상황에서는, 여러 사이트에 분산된 여러 계정이 서로 이어지지 않게 됩니다.
따라서 문제풀이가 불편해지고 실력 지표를 한 곳에서 알기도 어렵게 됩니다.
이 프로토콜의 목적은 '작은 서버'들을 모아서 '큰 서버 하나'처럼 쓸 수 있게 하는 것입니다.
Note
TODO: 서버 식별자는 어떻게? - 도메인? ID? 공개키?
문제풀이 서버 는, "문제집 프로토콜"을 따르는 한 사이트입니다.
문제풀이 서버는 클 수도 있고, 개인이 다락방에서 운영하는 사이트만큼 작을 수도 있습니다.
한 문제풀이 서버 는 아래와 같은 것들을 소유합니다.
고유한 인증 키
ECDSA 공개키/비밀키 쌍입니다. 공개키만 공개되며, 무언가를 전자서명할 때 사용합니다.
여러 문제
여러 명의 아이덴티티
문제 는 문제 식별자와 문제 설명을 필수적으로 가집니다.
또한, 문제는 한 문제풀이 서버에 종속됩니다.
문제 에는 답안 을 제출할 수 있습니다. 제출된 답안은, 문제를 소유하는 서버가 채점 합니다.
채점 과정은 전적으로 해당 문제풀이 서버가 처리하며, 채점을 어떻게 해야 하는지는 본 문서에서 정의하지 않습니다.
채점 된 답안은, 그 결과에 따라 다음과 같이 처리됩니다:
답안이 틀렸을 경우:
제출자에게 답안이 틀렸음을 알려줍니다. 이유가 제공될 수도 있습니다.
답안이 맞았을 경우:
제출자에게 답안이 맞았음을 알려줍니다.
동시에, 제출자에게 풀이 증표 를 발급하여 줍니다.
Note
TODO: "서명하여"를 제대로 정의할 필요 있음
풀이 증표 란, 어떤 아이덴티티가 특정 문제를 풀었음을 인증하여 주는 짧은 텍스트입니다.
최소한 다음과 같은 정보를 담은 JSON을 문제풀이 서버의 인증 키 로 서명하여 발급합니다.
identity: 아이덴티티의 UUID
server: 서버 식별자
problem: 문제 식별자
solved_at: 문제를 해결한 시각
Note
TODO: 서로 다른 서버가 충돌하는 UUID를 발급한다면?
Note
TODO: 차라리 아이덴티티 생성 기능까지 랭크 인증 서버에게 넘겨주는 게 맞지 않을까?
참여하고자 하는 사용자는, 원하는 문제풀이 서버 를 하나 골라서 가입해야 합니다.
이 경우 문제풀이 서버 는 자기 서버의 인증키로 서명된 아이덴티티 를 발급해 줍니다.
아이덴티티 는 서버의 인증키로 서명된 짧은 JSON 텍스트이며, 최소한 다음과 같은 정보를 담고 있습니다.
uuid: UUIDv7
username: 닉네임
server: 서버 식별자
이외에도 avatar_url이나 bio 등 다른 정보들을 담을 수 있습니다.
"문제집 프로토콜"을 따르는 문제풀이 서버는, 아래와 같이 다른 문제풀이 서버들과 상호작용할 수 있습니다.
한 서버가 다른 서버의 인증 키 (ECDSA 공개 키)를 받아옵니다.
한 서버가 다른 서버로부터 문제 목록을 받아옵니다.
한 서버가 다른 서버로부터 문제 정보를 받아옵니다. 아래 정보를 전달합니다.
한 서버가 다른 서버로 문제에 대한 답안을 제출합니다. 아래 정보를 서버 인증키로 서명하여 전달합니다.
문제 ID
제출자의 아이덴티티
unix timestamp (현재 시각)
nonce (32바이트 미만의 임의 문자열)
답안 내용
한 서버가 다른 서버로부터 특정한 아이덴티티의 정보를 얻어옵니다. 아래 정보를 전달합니다.
중앙에 문제/유저 랭크를 계산하는 큰 '랭크 서버'를 둔다 (solved.ac를 생각해봅시다)
'랭크 서버'도 서명용 공개키를 가지고 있어서, 한 유저의 특정시점 랭크를 인증할 수 있다
랭크 인증 서버 는 어떤 아이덴티티가 가진 문제풀이 증표 를 검사하여, 랭크 를 발급해주는 서버입니다.
랭크 인증 서버 는 되도록 유명한 서버 하나를 주력으로 쓰기로 합니다.
랭크 인증 서버 는 우선 알려진 문제 들의 난이도(등급)을 결정합니다. 문제들의 난이도는 아이덴티티의 랭크를 계산하는 근거가 됩니다.
랭크 인증 서버 에 아이덴티티와 문제해결 증표 들을 제출하면, 랭크 인증 서버 는 그 정보를 바탕으로 랭크를 계산,
해당 아이덴티티가 특정 랭크에 속함을 인증하는 증표를 발급해 줍니다. 이 증표는 랭크 인증 서버의 인증키로 서명됩니다.
'랭크 서버'는 나름대로 '신뢰할 수 있는 서버'의 문제와 기여만 신뢰한다 (신뢰 여부는 랭크서버 운영자가 정해요)
특히 기여에는 서로 다른 여러 (신뢰할 수 있는) 서버가 필요
아직 신뢰하지 않는 서버의 문제 는, 랭크 계산에 포함되지 않는다
이사 기능
구상
Online 방법
Offline 방법
잠깐...
그냥 유저 데이터에 키 박을 거면, 그것 자체가 식별자가 되게 하면 안 될까?
그러면 키를 들고 통째로 옮기면... 아닌가... 여러 서버에 같은 사람이 있게 되려나... 상관없나?
그냥 인증까지 랭크서버한테 맡겨버리면 안될까? 모든 것을 랭크서버에게 맡기기?