Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
RRC_steganography — # 증명 가능한 보안 언어 스테가노그래피 회전 범위 코딩을 통해 LLM 생성 텍스트에 비밀 메시지를 은닉하는 증명 가능한 보안 언어 스테가노그래피. 임베드, 추출, 왕복 검증 스크립트를 포함합니다. | Kitploit
도구/GitHubGitHub/ryehr/rrc_steganography
SteganographyCryptographyMachine LearningPapers & ResearchLearning & EducationAI Security
GitHubryehr/rrc_steganography

RRC_steganography

# 증명 가능한 보안 언어 스테가노그래피 회전 범위 코딩을 통해 LLM 생성 텍스트에 비밀 메시지를 은닉하는 증명 가능한 보안 언어 스테가노그래피. 임베드, 추출, 왕복 검증 스크립트를 포함합니다.

저장소 보기
61801개월 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

RRC 스테가노그래피

Rotation Range-Coding (RRC) 스테가노그래피 — 대규모 언어 모델이 생성한 자연어 텍스트에 비밀 메시지를 삽입하는 효율적이고 증명 가능하게 안전한 언어적 스테가노그래피 기법.

논문: Efficient Provably Secure Linguistic Steganography via Range Coding (ACL 2026)

작동 방식

단계설명
삽입 (알고리즘 3)비밀 메시지를 십진수 값으로 변환하고, LM의 확률 분포와 PRNG가 생성한 오프셋에 따라 축소되는 구간 내에서 반복적으로 회전시킨다. 각 회전 단계마다 하나의 토큰이 생성된다.
추출 (알고리즘 4)스테고텍스트에 대해 LM을 다시 실행하여 구간 경계를 복원한 뒤, 역회전하여 원래의 십진수 값으로 되돌리고 이진화한다.

회전 메커니즘은 기본 범위 코딩 스테가노그래피의 두 가지 문제를 해결한다:

  1. 확률 분포 보존 — 회전된 비밀 값은 각 구간 내에서 균등하게 분포하므로, 토큰 선택이 원래의 LM 분포를 따른다.
  2. 새로운 무작위성 — 각 단계마다 새로운 PRNG 오프셋을 사용하여 무작위성 재사용을 방지한다.

저장소 구조

.
├── rrc_core.py        # 알고리즘 3과 4, 모든 진입점에서 공유
├── RRC_embed.py       # 삽입 CLI
├── RRC_extract.py     # 추출 CLI (복구 정확도 보고)
├── test_roundtrip.py  # 여러 메시지 길이에 걸친 왕복 테스트
├── fastest_embed.py   # 삽입 속도 벤치마크
├── 0.Prompts.tsv      # 1000개의 프롬프트 (C4 시퀀스의 처음 ~10 단어)
└── requirements.txt

인코더와 디코더는 루프의 별도 복사본을 보유하는 대신 rrc_core.py를 공유한다. 양측은 비트 단위로 일치해야 하며, 독립적으로 유지 관리되는 두 복사본 간의 차이는 검사 시에는 결코 드러나지 않고 오직 왕복 실패로만 나타난다.

요구 사항

  • Python >= 3.10
  • PyTorch >= 2.0
  • Transformers >= 4.35 (5.x까지 테스트됨)
pip install -r requirements.txt

빠른 시작

1. 정확성 검증

python test_roundtrip.py                                  # GPT-2, 32/128/512 bits
python test_roundtrip.py --model meta-llama/Llama-2-7b-hf

2. 삽입

python RRC_embed.py \
    --language_model meta-llama/Llama-2-7b-hf \
    --bit_length 128 --key 42 --top_k -1

3. 추출

python RRC_extract.py \
    --language_model meta-llama/Llama-2-7b-hf \
    --bit_length 128 --key 42 \
    --input_file 1.RC_decimal_Llama-2-7b-hf_bit128.tsv

인코더는 삽입한 비밀과 이를 운반한 토큰 id를 기록하므로, 추출은 복구율을 보고한다. 두 가지 수신자 모델이 평가된다:

  • ids — 수신자에게 토큰 시퀀스가 주어진다. 이는 코딩 기법을 분리한다. 100% 미만이면 수치적 또는 논리적 결함이다.
  • text — 수신자에게 디토큰화된 문자열이 주어지고 이를 다시 토큰화한다. 이는 텍스트 채널이 요구하는 방식이다. 재토큰화가 항상 송신자의 분절을 재현하지는 않으므로 이는 하한이다. 두 측정값 사이의 격차는 코딩 기법이 아니라 토큰화 모호성을 나타낸다. Llama-2-7b에서 128비트 기준: ids는 100%, text는 ~91%.

중요: 송신자와 수신자는 언어 모델, 키, 비트 길이, top-k 설정을 공유해야 하며, 동일한 하드웨어와 라이브러리 버전에서 실행해야 한다. 수치적 요구 사항을 참조하라.

CLI 인수

RRC_embed.py와 RRC_extract.py가 공유:

인수기본값설명
--language_modelmeta-llama/Llama-3.1-8BHuggingFace 모델 id
--bit_length128비밀 메시지 길이 (비트)
--top_k-1Top-k 절단; -1 = 전체 어휘
--key42대칭 키 K (PRNG 시드)
--precision_margin402**bit_length에 필요한 것 이상의 십진수 자릿수
--max_ctx_len3900KV-캐시 윈도우
--deviceautocuda 또는 cpu

RRC_embed.py는 또한 --prompts, --output, --limit, --seed, --max_tokens, --resume, --no_verify, 그리고 프롬프트 집합을 여러 프로세스에 분할하기 위한 --part / --part_max를 받는다 (GPU당 하나씩 --part 0,1,2와 함께 --part_max 3).

RRC_extract.py는 또한 --input_file, --mode {ids,text,both}, --limit, --verbose를 받는다.

수치적 요구 사항

RRC는 폭 2**l의 구간을 폭 ~1로 좁히므로, 복구된 값은 2**l배의 상대 오차에 민감하다: 128비트에서 체인 어디에서든 1e-16의 상대적 섭동은 0.5의 허용 오차에 대해 결과를 ~1e22만큼 이동시킨다. 추출은 점진적으로 저하되지 않는다 — 메시지를 반환하거나 아니면 무관한 비트를 반환한다. Llama-2-7b에서 측정:

설정확률의 상대적 섭동추출
동일한 batch-1 디코드 반복0 (비트 단위 동일)작동
batch 2 / 8 / 16에서 동일한 행~1e-2실패
프롬프트 좌측 패딩~1e-2실패
증분 디코딩 대신 한 번의 teacher-forced 패스~4e-3실패

두 가지 결과가 구현을 형성한다. 배칭이 불가능하므로 시퀀스는 한 번에 하나씩 처리된다. 그리고 수신자는 모든 토큰을 미리 보유하고 있음에도 불구하고, 스테고텍스트를 단일 순방향 패스로 채점하는 대신 송신자의 증분 디코딩을 단계별로 재현한다. 두 지름길 모두 ~9배 빠르게 측정되며 어느 것도 확률을 보존하지 않는다.

로짓 이후의 모든 것은 float64이며 CPU와 GPU에서 비트 단위로 동일한 경계를 생성하므로, 순방향 패스가 스테고텍스트를 하드웨어에 묶는 유일한 단계이다.

십진 정밀도

정밀도는 메시지 길이로부터 ceil(bit_length * log10(2)) + margin으로 도출되며 다른 무엇보다 먼저 설정된다. 이는 메시지에 따라 확장된다: 2**256은 78자리가 필요하고 2**8192는 2466자리가 필요하다.

그 임계값 미만의 정밀도는 깔끔하게 실패하지 않는다. 비밀 값의 하위 자릿수가 반올림되어 사라지고, 구간이 몇 개의 토큰 내에 붕괴하며 종료 테스트가 조기에 발동하므로, 실행이 완료되고 산술적으로 도달 불가능한 수치를 보고할 수 있다. 메시지 길이에 관계없이 정밀도를 50자리로 고정하면:

bits50자리에서의 활용률완료된 샘플도출된 정밀도 사용 시
256157.05%8/20100.17%
512299.67%9/20102.48%
1024660.91%7/10102.58%
20481046.40%1/598.18%
40962483.92%3/3, 오류 미발생100.87%
81924766.49%1/299.07%

--precision_margin은 도출된 최소값 위의 여유분을 조정한다; 최소값 자체는 강제된다.

검증된 종료

알고리즘 3은 (L + R) / 2 - d_s가 (-0.5, 0.5]에 들어갈 때 멈춘다. 이 테스트는 구간이 1보다 좁을 때 발동할 수 있으며, 그때 윈도우 [mid - 0.5, mid + 0.5)는 이를 운반하는 구간보다 넓다. 역회전은 구간 폭에 대한 등거리 변환이므로, 절단을 가로지르는 윈도우는 수신자를 d_s로부터 전체 구간만큼 떨어뜨린다.

따라서 송신자는 중단을 확정하기 전에 수신자의 역회전을 재현하고, 재현이 비밀을 반환하지 않으면 또 다른 토큰을 방출한다. 재현은 순수 Decimal 작업이므로 (순방향 패스의 ~20 ms에 대해 ~0.05 ms) 가드는 측정 가능한 비용이 들지 않는다. --no_verify는 이를 비활성화한다.

Llama-2-7b에서 측정:

bits가드 없이 복구됨가드 사용 시
128291/300 (97.0%)300/300
51264/65 (98.5%)40/40
102420/2020/20
204810/1010/10

128비트에서 가드는 0.095%의 추가 생성 토큰을 소모했다. 1024와 2048비트의 샘플은 비율을 한정하기에 너무 적으므로 — 3% 비율에서 0/20이 그렇지 않은 경우보다 더 유력한 결과이다 — 더 긴 메시지가 다르게 작동한다는 증거가 되지 않는다. 가드 사용 시 370/370이 복구되었다.

가드 없이는 송신자가 차이를 구별할 수 없다: 성공을 보고하고 무관한 비트로 디코딩되는 스테고텍스트를 방출한다. 비율은 추첨에 따라 달라진다; 한 99-프롬프트 실행에서는 아무것도 나타나지 않았는데, 이는 3% 비율에서 약 5%의 확률로 발생하며, 재실행 시 정확히 재현된다. 동일한 샘플이 45에서 200자리까지 모든 작동 정밀도에서 실패하므로, 이 동작은 산술이 아니라 종료 테스트에서 비롯된다.

가드는 이를 비활성화한 상태로 삽입하고 실제 추출기를 실행하여 정답과 대조 검증되었다: 가드가 표시하는 샘플은 정확히 수신자가 실패하는 샘플이며, 거짓 양성도 없고 누락도 없다.

성능 노트

LM 순방향 패스는 Llama-2-7b에서 생성 단계의 95–97%를 차지하며, 7B fp16 모델의 batch-1 디코딩은 메모리 대역폭 루프라인에 위치한다 (측정된 ~18.7 ms에 대해 토큰당 ~13.5 ms). 따라서 삽입 속도는 모델의 디코딩 속도를 따르며, 코딩 자체는 이에 거의 영향을 미치지 않는다.

더 작은 모델에서는 순방향 패스가 더 이상 지배적이지 않고 단계별 CPU 작업이 가시화된다. GPT-2에서 128비트, 공유 머신에서 셀당 100개 메시지로 종단 간 측정:

torch CPU 스레드bits/s
11320, 1205
161232, 756
20 (torch 기본값)352

처리량은 코딩 경로의 어떤 것이 아니라 CPU 스레드 경합에 의해 좌우되며, 멀티스레드 수치는 실행마다 재현되지 않는다. 따라서 모든 진입점은 torch.set_num_threads(1)을 호출한다: 여기서 각 CPU 연산은 단일 어휘 크기의 패스로, 스레드 풀에서 이득을 얻기에는 너무 작고 풀이 다른 작업과 경합할 때 크게 손실되기에 충분히 크다. 이는 예측 가능성을 얻는 것이지 유휴 머신에서의 속도 향상이 아니다.

나머지 단계별 선택은 개별적으로 저렴하며 한 스레드에서 종단 간 처리량을 측정 가능하게 변화시키지 않는다; 비용이 들지 않기 때문에 선택된다:

  • 엔트로피는 별도의 GPU 커널과 동기화 대신, 단계가 이미 필요로 하는 확률의 호스트 복사본에서 감소된다. 이는 보고되는 통계이며 인코딩에 피드백되지 않는다.
  • 후보 선택은 단조 경계 술어를 이진 탐색하여, 스캔된 후보당 하나가 아니라 단계당 ~15개의 Decimal 곱셈을 평가한다. 이는 최악의 경우를 한정한다; 프로파일링에서 선형 스캔은 인덱스 2923에 도달했다.
  • 경계는 토큰당 어휘 크기의 텐서를 할당하는 대신 미리 할당된 버퍼에 기록된다.
  • 생성이 토큰 예산을 초과하는 프롬프트는 새로운 비밀로 재시도하는 대신 건너뛴다: 예산은 프롬프트의 엔트로피에 의존하므로 메시지를 다시 뽑아도 결과가 바뀌지 않는다.
  • 로짓은 토크나이저와 정렬하기 위해 min(config.vocab_size, len(tokenizer.vocab))로 슬라이스된다. 이는 임베딩 행렬을 재할당하지 않고 모델 객체를 그대로 두는데, 이는 동일한 모델이 여러 실행에 걸쳐 공유될 때 중요하다.

측정된 처리량

128비트 메시지, 전체 어휘, temperature 1.0, RTX 6000 Ada, CPU 스레드 하나, 그 외에는 유휴 GPU. 모델당 100개 메시지 (Llama-2-7b는 60개), 모두 왕복되고 검사됨:

modelembedextracttokens/msgutilisation
GPT-21386 bits/s1385 bits/s22.399.4%
OPT-1.3b754 bits/s753 bits/s30.498.7%
Llama-2-7b183 bits/s183 bits/s45.498.9%

추출은 삽입 속도로 실행되는데, 둘 다 토큰당 하나의 순방향 패스를 수행하고 역회전 체인은 그 옆에서 무시할 수준이기 때문이다.

처리량은 GPU의 다른 작업에 둔감하다 — 완전히 로드된 카드에서도 동일한 수치가 몇 퍼센트 이내로 나온다 — 왜냐하면 워크로드는 장치를 포화시키는 어떤 것이 아니라 지연에 묶인 단일 토큰 순방향 패스의 체인이기 때문이다. ~6%의 실행 간 변동은 추출된 프롬프트에서 비롯된다: bits/s는 bit_length / time이고 시간은 메시지가 필요로 하는 토큰에 따라 확장되므로, 더 낮은 엔트로피의 프롬프트 샘플은 더 느리게 읽힌다.

기술 노트: Decimal 모듈로

Python의 Decimal %는 절단 나눗셈을 사용하며 음수 나머지를 반환할 수 있다 (Decimal('-19672') % Decimal('65536')은 45864가 아니라 -19672를 준다). 역회전은 진정한 모듈로를 요구하므로, decimal_mod는 내림 나눗셈 의미론을 사용한다:

def decimal_mod(a, m):
    return a - m * (a / m).to_integral_value(rounding=ROUND_FLOOR)

인용

도구 다운로드