{ "cells": [ { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "# From Longhorn 4074\n", "# Any version that accepts TCP8W-T8PQJ-WWRRH-QH76C-99FBW will work\n", "key_data = {\n", " \"p\": 7181106593102322766813520532476531209871483588988471009176871145241389568314039093657656718839885029493125387894856821599452867350054864568294961595970889,\n", " \"a\": 1,\n", " \"b\": 0,\n", " \"B\": [\n", " 520282615406607935808830413235837609227529008118239433194891765554084261177667142590192616462797266047427714603514505726507565809100858610756034340614180,\n", " 4557046395510954851157569206449480560848332315791566919607580280750304632075435589109908909351625686398512699199297926705742962219032991805095344264722444\n", " ],\n", " \"K\": [\n", " 1748427561645745685508888890965804844329037567281415535239953290167653001827496844268667372126127464466687812723744919132659150838866693283679107969476861,\n", " 6808711632346399211426562555523956018872055718394662707289722207520029794097689415773036615424757895159410496488301598927496012713658489637493990459415502\n", " ],\n", " \"order\": 4633201844252750473,\n", " \"private_key\": 4329540238250287790\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Product Key Generator, run above cell first" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10928323 10928323 2003509697754295848 6615195716181683752\n", "868186915 868186915 878552257861989116 5490238276289377020\n", "446954708 446954708 776512975037445878 776512975037445878\n", "353785506 353785506 1772257197849916146 6383943216277304050\n", "1598465793 1598465793 385978941068063200 4997664959495451104\n", "1118655069 1118655069 374356218385227934 374356218385227934\n", "52 531faff484f609e 42ad525d d2\n", "CH89R-TPQRK-GPJMW-7KTYQ-F8PJD\n" ] } ], "source": [ "import hashlib\n", "\n", "# p = order of field Fp\n", "# Fp = Galois field of order p\n", "# E = Elliptic curve y^2 = x^3 + ax + b over Fp\n", "# B = generator on E\n", "# K = inverse of public key\n", "# order = order of E\n", "# Ro = Ring Z/orderZ\n", "\n", "p = key_data[\"p\"]\n", "Fp = GF(p)\n", "E = EllipticCurve(Fp, [0, 0, 0, key_data[\"a\"], key_data[\"b\"]])\n", "B = E.point(key_data[\"B\"])\n", "K = E.point(key_data[\"K\"])\n", "order = key_data[\"order\"]\n", "Ro = Integers(order)\n", "private_key = -key_data[\"private_key\"] % order\n", "\n", "# OS Family of product key\n", "# x64 VLK - 652\n", "# x64 Retail - 306\n", "os_family = 105\n", "\n", "# Key alphabet\n", "KCHARS = \"BCDFGHJKMPQRTVWXY2346789\"\n", "\n", "def int_to_bytes(n, l=None):\n", " n = int(n)\n", " \n", " if not l:\n", " l = (n.bit_length() + 7) // 8\n", " \n", " return n.to_bytes(l, byteorder=\"little\")\n", "\n", "def encode_pkey(n):\n", " out = \"\"\n", " \n", " for i in range(25):\n", " out = KCHARS[n % 24] + out\n", " n //= 24\n", " \n", " out = \"-\".join([out[i:i+5] for i in range(0, len(out), 5)])\n", " return out\n", "\n", "os_family <<= 1\n", "\n", "while True:\n", " k = getrandbits(512)\n", " prefix = getrandbits(32) & 0x3ff\n", " \n", " r = k * B\n", " x, y = r.xy()\n", "\n", " mde = hashlib.sha1(b\"\\x79\" + int_to_bytes(os_family, 2) + int_to_bytes(x, 64) + int_to_bytes(y, 64)).digest()\n", " e = int.from_bytes(mde[:4], byteorder=\"little\")\n", " e &= 0x7fffffff\n", " \n", " mdh = hashlib.sha1(b\"\\x5d\" + int_to_bytes(os_family, 2) + int_to_bytes(e, 4) + int_to_bytes(prefix, 4)).digest()\n", " h1 = int.from_bytes(mdh[:4], byteorder=\"little\")\n", " h2 = int.from_bytes(mdh[4:8], byteorder=\"little\") >> 2\n", " h2 &= 0x3fffffff\n", " h = h2 << 32 | h1\n", " b = Ro(-h * private_key)\n", " \n", " try:\n", " s = Ro(b)\n", " s = int((-b + sqrt(b^2 + 4 * Ro(k))) / 2)\n", " except:\n", " continue\n", " \n", " if s % 2 == 1:\n", " s += order\n", " \n", " if (s * (s * B + h * K)) != (s * (s * B + int(b) * B)):\n", " continue\n", " \n", " raw_pkey = prefix << 104 | s << 42 | e << 11 | os_family\n", " \n", " print((raw_pkey >> 11) & 0x7fffffff, e, (raw_pkey >> 42) & 0x3fffffffffffffff, s)\n", " \n", " # I could fix whatever bug made this necessary, but it works so I don't care\n", " if ((raw_pkey >> 11) & 0x7fffffff) != e or ((raw_pkey >> 42) & 0x3fffffffffffffff) != s:\n", " continue\n", " \n", " if (raw_pkey >> 32) & 0xffffffff < 0x40000000:\n", " break\n", "\n", "print(hex(prefix)[2:], hex(s)[2:], hex(e)[2:], hex(os_family)[2:])\n", "print(encode_pkey(raw_pkey))\n", "pkey = encode_pkey(raw_pkey)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Product Key Verifier (must run above cell first)" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Product Key (dashes optional): TCP8W-T8PQJ-WWRRH-QH76C-99FBW\n", "TCP8W-T8PQJ-WWRRH-QH76C-99FBW\n", "318 3e550ae1709773d8 6674d45a ce\n", "f0ce4281d7695e3\n", "110001100011111001010101000010101110000101110000100101110111001111011000110011001110100110101000101101000011001110\n", "110001100011111001010101000010101110000101110000100101110111001111011000110011001110100110101000101101000011001110\n", "1718932570 1718932570 True\n" ] } ], "source": [ "def decode_pkey(k):\n", " k = k.replace(\"-\", \"\")\n", " out = 0\n", " \n", " for c in k:\n", " out *= 24\n", " out += KCHARS.index(c)\n", " \n", " return out\n", "\n", "pkey = input(\"Product Key (dashes optional): \")\n", "print(pkey)\n", "raw_key = decode_pkey(pkey)\n", "\n", "osf = raw_key & 0x7ff\n", "e = (raw_key >> 11) & 0x7fffffff\n", "s = (raw_key >> 42) & 0x3fffffffffffffff\n", "pf = (raw_key >> 104) & 0x3ff\n", "\n", "mdh = hashlib.sha1(b\"\\x5d\" + int_to_bytes(osf, 2) + int_to_bytes(e, 4) + int_to_bytes(pf, 4)).digest()\n", "h1 = int.from_bytes(mdh[:4], byteorder=\"little\")\n", "h2 = int.from_bytes(mdh[4:8], byteorder=\"little\") >> 2\n", "h2 &= 0x3fffffff\n", "h = h2 << 32 | h1\n", "\n", "print(hex(pf)[2:], hex(s)[2:], hex(e)[2:], hex(osf)[2:])\n", "print(hex(h)[2:])\n", "print(bin(raw_key)[2:])\n", "print(bin(pf << 104 | s << 42 | e << 11 | osf)[2:])\n", "\n", "v = s * (s * B + h * K)\n", "x, y = v.xy()\n", "\n", "mde = hashlib.sha1(b\"\\x79\" + int_to_bytes(osf, 2) + int_to_bytes(x, 64) + int_to_bytes(y, 64)).digest()\n", "ep = int.from_bytes(mde[:4], byteorder=\"little\")\n", "ep &= 0x7fffffff\n", "\n", "print(e, ep, e == ep)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "71" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "0x8e/2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "SageMath 9.0", "language": "sage", "name": "sagemath" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 4 }