ksjsb/core/reward_sign.py
2026-07-30 20:25:56 +08:00

102 lines
3.0 KiB
Python

"""KWSG 10418 reward body `sign` helpers."""
from __future__ import annotations
import time
from .enc_data import ZT_OUTER_CONFIGS
from .sig3 import (
KWSG_10418_DEFAULT_STATE_SOURCE,
KWSG_10418_SAMPLE_SESSION_SEED,
KWSG_10418_SIGN_PREFIX8,
KWSG_10418_SIGN_PREFIX_CODE,
kwsg_10418_digest24,
kwsg_10418_prefix8,
load_kwsg_10418_sign_tables,
)
KWSG_10418_SIGN_HMAC_KEY = (
b"ndjrNsJq6F6Qk8uavcZT56G2RSsbbeTQX6ROeIdpXAUUm5Xh3BlJtIWZv2ibwyVD"
)
def _input_to_bytes(value: str | bytes | bytearray) -> bytes:
if isinstance(value, str):
return value.encode("utf-8")
return bytes(value)
def _kwsg_10418_sign_tables_or_load(
t1: bytes | None,
t2: bytes | None,
) -> tuple[bytes, bytes]:
if t1 is None and t2 is None:
return load_kwsg_10418_sign_tables()
if t1 is None or t2 is None:
raise ValueError("t1 and t2 must be provided together")
return t1, t2
def kwsg_10418_reward_sign_from_digest_hex(digest_hex48: str, sdk_id: str) -> str:
"""由 `10418` 内部 24-byte digest 生成 reward body `sign`。"""
digest = bytes.fromhex(digest_hex48)
if len(digest) != 24:
raise ValueError("10418 digest must be 24 bytes / 48 hex")
cfg = ZT_OUTER_CONFIGS[sdk_id]
body = bytes(b ^ cfg["xor_key"][i & 0x0F] for i, b in enumerate(digest))
return (cfg["head8"] + body).hex()
def kwsg_10418_reward_sign(
input_value: str | bytes | bytearray,
sdk_id: str,
counter: int,
unix_time: int | None = None,
t1: bytes | None = None,
t2: bytes | None = None,
state_source: int = KWSG_10418_DEFAULT_STATE_SOURCE,
prefix8: bytes | None = None,
session_seed: int = KWSG_10418_SAMPLE_SESSION_SEED,
) -> str:
"""生成 reward body `sign` 的 64hex。"""
if unix_time is None:
unix_time = int(time.time())
t1, t2 = _kwsg_10418_sign_tables_or_load(t1, t2)
if prefix8 is None:
prefix8 = kwsg_10418_prefix8(KWSG_10418_SIGN_PREFIX_CODE, session_seed)
digest_hex = kwsg_10418_digest24(
_input_to_bytes(input_value),
counter,
unix_time,
t1,
t2,
state_source,
prefix8,
KWSG_10418_SIGN_HMAC_KEY,
).hex()
return kwsg_10418_reward_sign_from_digest_hex(digest_hex, sdk_id)
def kwsg_10418_reward_sign_to_digest_hex(sign_hex64: str, sdk_id: str) -> str:
"""反解 reward body `sign`,返回内部 24-byte digest 的 48hex。"""
raw = bytes.fromhex(sign_hex64)
if len(raw) != 32:
raise ValueError("10418 reward sign must be 32 bytes / 64 hex")
cfg = ZT_OUTER_CONFIGS[sdk_id]
if raw[:8] != cfg["head8"]:
raise ValueError("unexpected 10418 reward sign head8")
body = raw[8:]
digest = bytes(b ^ cfg["xor_key"][i & 0x0F] for i, b in enumerate(body))
return digest.hex()
__all__ = [
"KWSG_10418_SIGN_HMAC_KEY",
"KWSG_10418_SIGN_PREFIX8",
"KWSG_10418_SIGN_PREFIX_CODE",
"kwsg_10418_reward_sign",
"kwsg_10418_reward_sign_from_digest_hex",
"kwsg_10418_reward_sign_to_digest_hex",
]