# 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  .
## 1. Composite field  
Elements in ground field  are represented with standard basis, i.e. polynomial basis. The irreducible polynomial is
where each coefficients is in . If we use
as the standard basis of the ground field, an element  in  can be denoted as
---
The irreducible polynomial of composite field   is
where each coefficients is in . If we use
as the standard basis of the composite field, an element  in   can be denoted as
---
For clarity, we use  , which is a 255-bits-long integer to denote an element  in  . The map between them is
## 2. Elliptic curve over  
The equation of the elliptic curve that WinRAR uses is
The base point  is
A [verification example](README.VERIFY_Point_G.md) of the base point  on the curve.
whose order  is
## 3. Message hash algorithm
We use
to denote a message whose length is . So the SHA1 value of  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  as the hash of the input message.
## 4. ECC digital signature algorithm
We use  to denote private key,  to denote public key. So there must be
If we use  to denote the hash of input data, WinRAR use the following algorithm to perform signing:
1. Generate a random big integer  which satisfies .
2. Calculate 
where  means we take X coordinate of  and convert it from   to a big integer.
If  or , go back to step 1.
3. Calculate 
If , go back to step 1.
4. Output .
## 5. WinRAR private key generation algorithm
We use
to denote input data whose length is . WinRAR use it to generate private key .
1. We use  to denote 6 32-bits-long integer. So there is
2. Let .
3. If , we calculate SHA1 value of . 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  is
This private key is generated by the algorithm describled in section 5 where the length of data  is zero.
Public key  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 , 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 .
The length of  should be 64. If less, pad with `'0'` until the length is 64.
2. Let  be
3. Use the algorithm describled in section 5, with argument , 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 .
The length of  should be 64. If less, pad with `'0'` until the length is 64.
4. Let  be
5. Use the algorithm describled in section 4, with argument  and private key  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  be
8. Let  be
Use the algorithm describled in section 4, with argument  and private key  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  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  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 , with 54 characters a line.