102 lines
3.0 KiB
Python
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",
|
|
]
|