Skip to content

Instantly share code, notes, and snippets.

@Dabsunter
Created July 25, 2019 19:58
Show Gist options
  • Save Dabsunter/4ae8cf4908a432f133a7a0bf0215a4bd to your computer and use it in GitHub Desktop.
Save Dabsunter/4ae8cf4908a432f133a7a0bf0215a4bd to your computer and use it in GitHub Desktop.

How is "rarreg.key" generated?

WinRAR uses an ECC-based signature algorithm to generate rarreg.key. The algorithm it used is a varient 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment