winrar-keygen/README.HOW_DOES_IT_WORK.md
2022-02-09 21:54:39 +08:00

15 KiB

How is "rarreg.key" generated?

WinRAR uses an ECC-based signature algorithm to generate rarreg.key. The algorithm it used is a variant of Chinese SM2 digital signature algorithm. Different to many standard ECDSAs, the curve that WinRAR selected is a curve over composite field ![GF2p15p17-inlined].

1. Composite field ![GF2p15p17-inlined]

Elements in ground field ![GF2p15-inlined] are represented with standard basis, i.e. polynomial basis. The irreducible polynomial is

where each coefficients is in ![GF2-inlined]. If we use

as the standard basis of the ground field, an element ![A-inlined] in ![GF2p15-inlined] can be denoted as


The irreducible polynomial of composite field ![GF2p15p17-inlined] is

where each coefficients is in ![GF2p15-inlined]. If we use

as the standard basis of the composite field, an element ![B-inlined] in ![GF2p15p17-inlined] can be denoted as


For clarity, we use ![D-inlined], which is a 255-bits-long integer to denote an element ![B-inlined] in ![GF2p15p17-inlined]. The map between them is

2. Elliptic curve over ![GF2p15p17-inlined]

The equation of the elliptic curve that WinRAR uses is

The base point ![G-inlined] is

whose order ![n-inlined] is

3. Message hash algorithm

We use

to denote a message whose length is ![l-inlined]. So the SHA1 value of ![M-inlined] should be

where are 5 state values when SHA1 outputs. Generally speaking, the final SHA1 value should be the join of these 5 state values while each of state values is serialized in big-endian.

However, WinRAR doesn't serialize the 5 state values. Instead, it use a big integer ![h-inlined] as the hash of the input message.

4. ECC digital signature algorithm

We use ![k-inlined] to denote private key, ![P-inlined] to denote public key. So there must be

If we use ![h-inlined] to denote the hash of input data, WinRAR use the following algorithm to perform signing:

  1. Generate a random big integer ![Rnd-inlined] which satisfies .

  2. Calculate ![r-inlined]

    where means we take X coordinate of and convert it from ![GF2p15p17-inlined] to a big integer.

    If or , go back to step 1.

  3. Calculate ![s-inlined]

    If , go back to step 1.

  4. Output .

5. WinRAR private key generation algorithm

We use

to denote input data whose length is ![l-inlined]. WinRAR use it to generate private key ![k-inlined].

  1. We use to denote 6 32-bits-long integer. So there is

  2. Let .

  3. If , we calculate SHA1 value of ![T-inlined]. Then assign SHA1 state value to :

    Otherwise, when , we let

  4. Regard as counter, add itself by 1.

    Calculate SHA1:

    We takes the lowest 16 bits of and donote it as .

  5. Repeat step 4 again with 14 times.

  6. After that, we will get . Then output private key

6. The private key and public key of WinRAR

Private key ![k-inlined] is

This private key is generated by the algorithm describled in section 5 where the length of data ![T-inlined] is zero.

Public key ![P-inlined] is

7. Generation of "rarreg.key"

The generation of license file rarreg.key requires 2 arguments:

  1. Username, an ANSI-encoded string, without null-terminator. Denoted as

  2. License type, an ANSI-encoded string, without null-terminator. Denoted as

The following is the algorithm to generate rarreg.key.

  1. Use the algorithm describled in section 5, with argument ![UU-inlined], to generate private key and public key . Then output hexlified public key string with SM2 compressed public key format. The hexlified public key is denoted as ![Temp-inlined].

    The length of ![Temp-inlined] should be 64. If less, pad with '0' until the length is 64.

  2. Let ![Data3-inlined] be

  3. Use the algorithm describled in section 5, with argument ![Data3-inlined], to generate private key and public key . Then output hexlified public key string with SM2 compressed public key format. The hexlified public key is denoted as ![Data0-inlined].

    The length of ![Data0-inlined] should be 64. If less, pad with '0' until the length is 64.

  4. Let ![UID-inlined] be

  5. Use the algorithm describled in section 4, with argument ![LL-inlined] and private key ![k-inlined] describled section 6, to get signature .

    The bit length of and shall not be more than 240. Otherwise, repeat this step.

  6. Convert and to hex-integer string and , without "0x" prefix.

    If the length of or is less than 60, pad character '0' until the length is 60.

  7. Let ![Data1-inlined] be

  8. Let ![Temp-inlined] be

    Use the algorithm describled in section 4, with argument ![Temp-inlined] and private key ![k-inlined] describled section 6, to get signature .

    The bit length of and shall not be more than 240. Otherwise, repeat this step.

  9. Convert and to hex-integer string and , without "0x" prefix.

    If the length of or is less than 60, pad character '0' until the length is 60.

  10. Let ![Data2-inlined] be

  11. Calculate CRC32 value of

    The final checksum the complement of CRC32 value.

    Then convert the checksum to decimal string . If the length is less than 10, pad character '0' until the length is 10.

  12. Let ![Data-inlined] be

  13. Output with format

    • A fixed header "RAR registration data", taking one line.

    • Username, taking one line.

    • License type, taking one line

    • UID, taking one line, with format:

    • Output ![Data-inlined], with 54 characters a line.