- sdk/qs 平台模块(安卓参数指纹匿名搜索)+ sdk/apis/qs 取流: 匿名 30s 试听,登录态走签名 track_v2 + spade key AES-CTR 解密 - /login/qs/qr 抖音扫码登录(授权后 sessionid 解锁完整曲目) - /stream/qs/:id 解密流代理,/url 返回的相对地址按请求 host 补全 - 回归测试覆盖 kw 双通道(VIP 真音频/降级链)与 qs 试听;start.bat 去掉 SOURCE_ENABLED 直启
48 lines
1.3 KiB
TypeScript
48 lines
1.3 KiB
TypeScript
const ROUNDS = 72;
|
|
const MASK64 = 0xffffffffffffffffn;
|
|
|
|
const Z4 = 0x3dc94c3a046d678bn;
|
|
|
|
function getBit(value: bigint, position: number): bigint {
|
|
return (value >> BigInt(position)) & 1n;
|
|
}
|
|
|
|
function rotateLeft64(v: bigint, n: bigint): bigint {
|
|
return ((v << n) | (v >> (64n - n))) & MASK64;
|
|
}
|
|
|
|
function rotateRight64(v: bigint, n: bigint): bigint {
|
|
return ((v << (64n - n)) | (v >> n)) & MASK64;
|
|
}
|
|
|
|
function keyExpansion(key: readonly [bigint, bigint, bigint, bigint]): bigint[] {
|
|
const k: bigint[] = [key[0] & MASK64, key[1] & MASK64, key[2] & MASK64, key[3] & MASK64];
|
|
|
|
for (let i = 4; i < ROUNDS; i++) {
|
|
let tmp = rotateRight64(k[i - 1]!, 3n);
|
|
tmp ^= k[i - 3]!;
|
|
tmp ^= rotateRight64(tmp, 1n);
|
|
k.push((~k[i - 4]! ^ tmp ^ getBit(Z4, (i - 4) % 62) ^ 3n) & MASK64);
|
|
}
|
|
return k;
|
|
}
|
|
|
|
export function simonEncrypt(
|
|
plaintext: readonly [bigint, bigint],
|
|
key: readonly [bigint, bigint, bigint, bigint],
|
|
): [bigint, bigint] {
|
|
const k = keyExpansion(key);
|
|
|
|
let x = plaintext[0] & MASK64;
|
|
let y = plaintext[1] & MASK64;
|
|
|
|
for (let i = 0; i < ROUNDS; i++) {
|
|
const tmp = y;
|
|
const f = rotateLeft64(y, 1n) & rotateLeft64(y, 8n);
|
|
y = (x ^ f ^ rotateLeft64(y, 2n) ^ k[i]!) & MASK64;
|
|
x = tmp;
|
|
}
|
|
|
|
return [x, y];
|
|
}
|