mirror of
https://github.com/bitcookies/winrar-keygen.git
synced 2026-03-11 09:35:31 +00:00
🔑 Release WinRAR Keygen
Release WinRAR Keygen
This commit is contained in:
commit
5b4f60d116
59 changed files with 3342 additions and 0 deletions
3
.vs/ProjectSettings.json
Normal file
3
.vs/ProjectSettings.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"CurrentProjectSetting": "无配置"
|
||||
}
|
||||
7
.vs/VSWorkspaceState.json
Normal file
7
.vs/VSWorkspaceState.json
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"ExpandedNodes": [
|
||||
""
|
||||
],
|
||||
"SelectedNode": "\\winrar-keygen.sln",
|
||||
"PreviewInSolutionExplorer": false
|
||||
}
|
||||
BIN
.vs/slnx.sqlite
Normal file
BIN
.vs/slnx.sqlite
Normal file
Binary file not shown.
BIN
.vs/winrar-keygen/v16/.suo
Normal file
BIN
.vs/winrar-keygen/v16/.suo
Normal file
Binary file not shown.
BIN
.vs/winrar-keygen/v16/Browse.VC.db
Normal file
BIN
.vs/winrar-keygen/v16/Browse.VC.db
Normal file
Binary file not shown.
BIN
.vs/winrar-keygen/v16/ipch/AutoPCH/c0f0bdcf41a1ec98/_TMAIN.ipch
Normal file
BIN
.vs/winrar-keygen/v16/ipch/AutoPCH/c0f0bdcf41a1ec98/_TMAIN.ipch
Normal file
Binary file not shown.
324
BigInteger.hpp
Normal file
324
BigInteger.hpp
Normal file
|
|
@ -0,0 +1,324 @@
|
|||
#pragma once
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <gmp.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <stdexcept>
|
||||
|
||||
class BigInteger {
|
||||
private:
|
||||
mpz_t _Value;
|
||||
public:
|
||||
|
||||
BigInteger() noexcept {
|
||||
mpz_init(_Value);
|
||||
}
|
||||
|
||||
template<typename __IntegerType>
|
||||
BigInteger(__IntegerType SmallInteger) noexcept {
|
||||
// __IntegerType must be a integer type, i.e. char, int, unsigned long...
|
||||
static_assert(std::is_integral<__IntegerType>::value);
|
||||
|
||||
if constexpr (std::is_signed<__IntegerType>::value) {
|
||||
mpz_init_set_sx(_Value, SmallInteger);
|
||||
} else {
|
||||
mpz_init_set_ux(_Value, SmallInteger);
|
||||
}
|
||||
}
|
||||
|
||||
BigInteger(bool IsNegative, const void* lpBuffer, size_t cbBuffer, bool UseLittleEndian) noexcept {
|
||||
mpz_init(_Value);
|
||||
mpz_import(_Value, cbBuffer, UseLittleEndian ? -1 : 1, sizeof(unsigned char), 0, 0, lpBuffer);
|
||||
if (IsNegative)
|
||||
mpz_neg(_Value, _Value);
|
||||
}
|
||||
|
||||
BigInteger(bool IsNegative, const std::vector<uint8_t>& Buffer, bool UseLittleEndian) noexcept {
|
||||
mpz_init(_Value);
|
||||
mpz_import(_Value, Buffer.size(), UseLittleEndian ? -1 : 1, sizeof(unsigned char), 0, 0, Buffer.data());
|
||||
if (IsNegative)
|
||||
mpz_neg(_Value, _Value);
|
||||
}
|
||||
|
||||
BigInteger(const char* lpszValue) noexcept {
|
||||
mpz_init_set_str(_Value, lpszValue, 0);
|
||||
}
|
||||
|
||||
BigInteger(const std::string& szValue) noexcept {
|
||||
mpz_init_set_str(_Value, szValue.c_str(), 0);
|
||||
}
|
||||
|
||||
BigInteger(const BigInteger& Other) noexcept {
|
||||
mpz_init(_Value);
|
||||
mpz_set(_Value, Other._Value);
|
||||
}
|
||||
|
||||
BigInteger(BigInteger&& Other) noexcept {
|
||||
mpz_init(_Value);
|
||||
mpz_swap(_Value, Other._Value);
|
||||
}
|
||||
|
||||
BigInteger& operator=(const BigInteger& Other) noexcept {
|
||||
if (this != &Other) {
|
||||
mpz_set(_Value, Other._Value);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigInteger& operator=(BigInteger&& Other) noexcept {
|
||||
if (this != &Other) {
|
||||
mpz_swap(_Value, Other._Value);
|
||||
mpz_clear(Other._Value);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename __IntegerType>
|
||||
BigInteger& operator=(__IntegerType SmallInteger) noexcept {
|
||||
// __IntegerType must be a integer type, i.e. char, int, unsigned long...
|
||||
static_assert(std::is_integral<__IntegerType>::value);
|
||||
|
||||
if constexpr (std::is_signed<__IntegerType>::value) {
|
||||
mpz_set_sx(_Value, SmallInteger);
|
||||
} else {
|
||||
mpz_set_ux(_Value, SmallInteger);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigInteger& operator=(const char* lpszValue) noexcept {
|
||||
mpz_init_set_str(_Value, lpszValue, 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const BigInteger& Other) const noexcept {
|
||||
return mpz_cmp(_Value, Other._Value) == 0;
|
||||
}
|
||||
|
||||
bool operator!=(const BigInteger& Other) const noexcept {
|
||||
return mpz_cmp(_Value, Other._Value) != 0;
|
||||
}
|
||||
|
||||
bool operator<(const BigInteger& Other) const noexcept {
|
||||
return mpz_cmp(_Value, Other._Value) < 0;
|
||||
}
|
||||
|
||||
bool operator<=(const BigInteger& Other) const noexcept {
|
||||
auto d = mpz_cmp(_Value, Other._Value);
|
||||
return d < 0 || d == 0;
|
||||
}
|
||||
|
||||
bool operator>(const BigInteger& Other) const noexcept {
|
||||
return mpz_cmp(_Value, Other._Value) > 0;
|
||||
}
|
||||
|
||||
bool operator>=(const BigInteger& Other) const noexcept {
|
||||
auto d = mpz_cmp(_Value, Other._Value);
|
||||
return d > 0 || d == 0;
|
||||
}
|
||||
|
||||
BigInteger operator-() const noexcept {
|
||||
BigInteger Result;
|
||||
mpz_neg(Result._Value, _Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
BigInteger operator+(const BigInteger& Other) const noexcept {
|
||||
BigInteger Result;
|
||||
mpz_add(Result._Value, _Value, Other._Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
BigInteger& operator+=(const BigInteger& Other) noexcept {
|
||||
mpz_add(_Value, _Value, Other._Value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigInteger operator-(const BigInteger& Other) const noexcept {
|
||||
BigInteger Result;
|
||||
mpz_sub(Result._Value, _Value, Other._Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
BigInteger& operator-=(const BigInteger& Other) noexcept {
|
||||
mpz_sub(_Value, _Value, Other._Value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigInteger operator*(const BigInteger& Other) const noexcept {
|
||||
BigInteger Result;
|
||||
mpz_mul(Result._Value, _Value, Other._Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
BigInteger& operator*=(const BigInteger& Other) noexcept {
|
||||
mpz_mul(_Value, _Value, Other._Value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigInteger operator/(const BigInteger& Other) const noexcept {
|
||||
BigInteger Result;
|
||||
mpz_fdiv_q(Result._Value, _Value, Other._Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
BigInteger& operator/=(const BigInteger& Other) noexcept {
|
||||
mpz_fdiv_q(_Value, _Value, Other._Value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigInteger operator%(const BigInteger& Other) const noexcept {
|
||||
BigInteger Result;
|
||||
mpz_fdiv_r(Result._Value, _Value, Other._Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
BigInteger& operator%=(const BigInteger& Other) noexcept {
|
||||
mpz_fdiv_r(_Value, _Value, Other._Value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigInteger operator~() const noexcept {
|
||||
BigInteger Result;
|
||||
mpz_com(Result._Value, _Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
BigInteger operator&(const BigInteger& Other) const noexcept {
|
||||
BigInteger Result;
|
||||
mpz_and(Result._Value, _Value, Other._Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
BigInteger& operator&=(const BigInteger& Other) noexcept {
|
||||
mpz_and(_Value, _Value, Other._Value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigInteger operator|(const BigInteger& Other) const noexcept {
|
||||
BigInteger Result;
|
||||
mpz_ior(Result._Value, _Value, Other._Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
BigInteger& operator|=(const BigInteger& Other) noexcept {
|
||||
mpz_ior(_Value, _Value, Other._Value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigInteger operator^(const BigInteger& Other) const noexcept {
|
||||
BigInteger Result;
|
||||
mpz_xor(Result._Value, _Value, Other._Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
BigInteger& operator^=(const BigInteger& Other) noexcept {
|
||||
mpz_xor(_Value, _Value, Other._Value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigInteger& operator++() noexcept {
|
||||
mpz_add_ui(_Value, _Value, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigInteger operator++(int) noexcept {
|
||||
BigInteger Result(*this);
|
||||
mpz_add_ui(_Value, _Value, 1);
|
||||
return Result;
|
||||
}
|
||||
|
||||
BigInteger& operator--() noexcept {
|
||||
mpz_sub_ui(_Value, _Value, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigInteger operator--(int) noexcept {
|
||||
BigInteger Result(*this);
|
||||
mpz_sub_ui(_Value, _Value, 1);
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool IsZero() const noexcept {
|
||||
return mpz_sgn(_Value) == 0;
|
||||
}
|
||||
|
||||
bool IsPositive() const noexcept {
|
||||
return mpz_sgn(_Value) > 0;
|
||||
}
|
||||
|
||||
bool IsNegative() const noexcept {
|
||||
return mpz_sgn(_Value) < 0;
|
||||
}
|
||||
|
||||
bool IsOne() const noexcept {
|
||||
return mpz_cmp_si(_Value, 1) == 0;
|
||||
}
|
||||
|
||||
BigInteger& Load(bool IsNegative, const void* lpBuffer, size_t cbBuffer, bool UseLittleEndian) noexcept {
|
||||
mpz_import(_Value, cbBuffer, UseLittleEndian ? -1 : 1, sizeof(uint8_t), 0, 0, lpBuffer);
|
||||
if (IsNegative)
|
||||
mpz_neg(_Value, _Value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigInteger& Load(bool IsNegative, const std::vector<uint8_t> Buffer, bool UseLittleEndian) noexcept {
|
||||
mpz_import(_Value, Buffer.size(), UseLittleEndian ? -1 : 1, sizeof(uint8_t), 0, 0, Buffer.data());
|
||||
if (IsNegative)
|
||||
mpz_neg(_Value, _Value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void DumpAbs(void* lpBuffer, size_t cbBuffer, bool UseLittleEndian) const {
|
||||
size_t bit_size = mpz_sizeinbase(_Value, 2);
|
||||
size_t storage_size = (bit_size + 7) / 8;
|
||||
if (cbBuffer >= storage_size) {
|
||||
size_t bytes_written;
|
||||
mpz_export(lpBuffer, &bytes_written, UseLittleEndian ? -1 : 1, sizeof(uint8_t), 0, 0, _Value);
|
||||
memset(reinterpret_cast<unsigned char*>(lpBuffer) + bytes_written, 0, cbBuffer - bytes_written);
|
||||
} else {
|
||||
throw std::length_error("Insufficient buffer.");
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uint8_t> DumpAbs(bool UseLittleEndian) const noexcept {
|
||||
size_t bit_size = mpz_sizeinbase(_Value, 2);
|
||||
size_t storage_size = (bit_size + 7) / 8;
|
||||
std::vector<uint8_t> bytes(storage_size);
|
||||
mpz_export(bytes.data(), nullptr, UseLittleEndian ? -1 : 1, sizeof(uint8_t), 0, 0, _Value);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
size_t BitLength() const noexcept {
|
||||
return mpz_sizeinbase(_Value, 2);
|
||||
}
|
||||
|
||||
bool TestBit(size_t i) const noexcept {
|
||||
return mpz_tstbit(_Value, i) != 0;
|
||||
}
|
||||
|
||||
void SetBit(size_t i) noexcept {
|
||||
mpz_setbit(_Value, i);
|
||||
}
|
||||
|
||||
std::string ToString(size_t Base, bool LowerCase) const {
|
||||
if (2 <= Base && Base <= 10 + 26) {
|
||||
int base = LowerCase ? static_cast<int>(Base) : -static_cast<int>(Base);
|
||||
std::string s(mpz_sizeinbase(_Value, base) + 2, '\x00');
|
||||
|
||||
mpz_get_str(s.data(), base, _Value);
|
||||
|
||||
while (s.back() == '\x00') {
|
||||
s.pop_back();
|
||||
}
|
||||
|
||||
return s;
|
||||
} else {
|
||||
throw std::invalid_argument("Invalid base value.");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
314
EllipticCurveGF2m.hpp
Normal file
314
EllipticCurveGF2m.hpp
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
#pragma once
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include "BigInteger.hpp"
|
||||
|
||||
template<typename __FieldType>
|
||||
class EllipticCurveGF2m {
|
||||
private:
|
||||
// y^2 + xy = x^3 + Ax^2 + B
|
||||
|
||||
__FieldType _A;
|
||||
__FieldType _B;
|
||||
|
||||
void _VerifyParameters() const {
|
||||
if (_B.IsZero()) {
|
||||
throw std::invalid_argument("B cannot be zero.");
|
||||
}
|
||||
}
|
||||
public:
|
||||
|
||||
class Point {
|
||||
friend EllipticCurveGF2m<__FieldType>;
|
||||
private:
|
||||
const EllipticCurveGF2m<__FieldType>& _Curve;
|
||||
__FieldType _X;
|
||||
__FieldType _Y;
|
||||
|
||||
void _VerifyParameters() const {
|
||||
auto Left = _Y.SquareValue() + _X * _Y;
|
||||
auto Right = (_X + _Curve._A) * _X.SquareValue() + _Curve._B;
|
||||
if (Left != Right) {
|
||||
throw std::invalid_argument("New point is not on the curve specified.");
|
||||
}
|
||||
}
|
||||
public:
|
||||
|
||||
Point(const EllipticCurveGF2m<__FieldType>& Curve) noexcept :
|
||||
_Curve(Curve) {}
|
||||
|
||||
Point(const EllipticCurveGF2m<__FieldType>& Curve, const void* pbX, size_t cbX, const void* pbY, size_t cbY) :
|
||||
_Curve(Curve),
|
||||
_X(pbX, cbX),
|
||||
_Y(pbY, cbY)
|
||||
{
|
||||
_VerifyParameters();
|
||||
}
|
||||
|
||||
Point(const EllipticCurveGF2m<__FieldType>& Curve, const __FieldType& X, const __FieldType& Y) :
|
||||
_Curve(Curve), _X(X), _Y(Y)
|
||||
{
|
||||
_VerifyParameters();
|
||||
}
|
||||
|
||||
Point operator-() const noexcept {
|
||||
return Point(_X, _X + _Y);
|
||||
}
|
||||
|
||||
Point& operator=(const Point& Other) {
|
||||
if (&_Curve == &Other._Curve || _Curve == Other._Curve) {
|
||||
_X = Other._X;
|
||||
_Y = Other._Y;
|
||||
return *this;
|
||||
} else {
|
||||
throw std::invalid_argument("Not on the same curve.");
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const Point& Other) const noexcept {
|
||||
if (&_Curve == &Other._Curve || _Curve == Other._Curve) {
|
||||
return _X == Other._X && _Y == Other._Y;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator!=(const Point& Other) const noexcept {
|
||||
if (&_Curve == &Other._Curve || _Curve == Other._Curve) {
|
||||
return _X != Other._X || _Y != Other._Y;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const __FieldType& GetX() const noexcept {
|
||||
return _X;
|
||||
}
|
||||
|
||||
const __FieldType& GetY() const noexcept {
|
||||
return _Y;
|
||||
}
|
||||
|
||||
bool IsAtInfinity() const noexcept {
|
||||
return _X.IsZero() && _Y.IsZero();
|
||||
}
|
||||
|
||||
Point& Double() noexcept {
|
||||
if (IsAtInfinity() == false) {
|
||||
auto m = _Y / _X + _X;
|
||||
|
||||
// NewX = m ^ 2 + m + a
|
||||
__FieldType NewX = m.SquareValue();
|
||||
NewX += m;
|
||||
NewX += _Curve._A;
|
||||
|
||||
// NewY = X ^ 2 + (m + 1) * NewX
|
||||
_Y = m.AddOne();
|
||||
_Y *= NewX;
|
||||
_Y += _X.Square();
|
||||
|
||||
_X = NewX;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Point ValueOfDouble() const noexcept {
|
||||
Point Result(_Curve);
|
||||
|
||||
if (IsAtInfinity() == false) {
|
||||
// m = X + Y / X
|
||||
auto m = _Y / _X + _X;
|
||||
|
||||
// NewX = m ^ 2 + m + a
|
||||
Result._X = m.SquareValue();
|
||||
Result._X += m;
|
||||
Result._X += _Curve._A;
|
||||
|
||||
// NewY = X ^ 2 + (m + 1) * NewX
|
||||
Result._Y = m.AddOne();
|
||||
Result._Y *= Result._X;
|
||||
Result._Y += _X.SquareValue();
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
Point operator+(const Point& Other) const {
|
||||
if (&_Curve == &Other._Curve || _Curve == Other._Curve) {
|
||||
if (IsAtInfinity()) {
|
||||
return Other;
|
||||
} else {
|
||||
if (this == &Other || _X == Other._X) {
|
||||
return ValueOfDouble();
|
||||
} else {
|
||||
Point Result(_Curve);
|
||||
|
||||
// m = (Y0 + Y1) / (X0 + X1)
|
||||
auto m = (_Y + Other._Y) / (_X + Other._X);
|
||||
|
||||
// NewX = m ^ 2 + m + X0 + X1 + a
|
||||
Result._X = m.SquareValue();
|
||||
Result._X += m;
|
||||
Result._X += _X;
|
||||
Result._X += Other._X;
|
||||
Result._X += _Curve._A;
|
||||
|
||||
// NewY = m * (X0 + NewX) + NewX + Y0
|
||||
Result._Y = _X + Result._X;
|
||||
Result._Y *= m;
|
||||
Result._Y += Result._X;
|
||||
Result._Y += _Y;
|
||||
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw std::invalid_argument("Not on the same curve.");
|
||||
}
|
||||
}
|
||||
|
||||
Point& operator+=(const Point& Other) {
|
||||
if (&_Curve == &Other._Curve || _Curve == Other._Curve) {
|
||||
if (IsAtInfinity()) {
|
||||
_X = Other._X;
|
||||
_Y = Other._Y;
|
||||
} else {
|
||||
if (this == &Other || _X == Other._X) {
|
||||
Double();
|
||||
} else {
|
||||
Point Result(_Curve);
|
||||
|
||||
// m = (Y0 + Y1) / (X0 + X1)
|
||||
auto m = (_Y + Other._Y) / (_X + Other._X);
|
||||
|
||||
// NewX = m ^ 2 + m + X0 + X1 + a
|
||||
__FieldType NewX = m.SquareValue();
|
||||
NewX += m;
|
||||
NewX += _X;
|
||||
NewX += Other._X;
|
||||
NewX += _Curve._A;
|
||||
|
||||
// NewY = m * (X0 + NewX) + NewX + Y0
|
||||
_X += NewX;
|
||||
_X *= m;
|
||||
_X += NewX;
|
||||
_Y += _X;
|
||||
|
||||
_X = NewX;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
} else {
|
||||
throw std::invalid_argument("Not on the same curve.");
|
||||
}
|
||||
}
|
||||
|
||||
Point operator-(const Point& Other) const {
|
||||
Point Result = -Other;
|
||||
Result += *this;
|
||||
return Result;
|
||||
}
|
||||
|
||||
Point& operator-=(const Point& Other) {
|
||||
return *this += -Other;
|
||||
}
|
||||
|
||||
Point operator*(const BigInteger N) const noexcept {
|
||||
Point Result(_Curve);
|
||||
Point temp(*this);
|
||||
size_t bit_length = N.BitLength();
|
||||
|
||||
for (size_t i = 0; i < bit_length; ++i) {
|
||||
if (N.TestBit(i) == true)
|
||||
Result += temp;
|
||||
temp.Double();
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
Point operator*=(const BigInteger N) noexcept {
|
||||
Point Result(_Curve);
|
||||
size_t bit_length = N.BitLength();
|
||||
|
||||
for (size_t i = 0; i < bit_length; ++i) {
|
||||
if (N.TestBit(i) == true)
|
||||
Result += *this;
|
||||
Double();
|
||||
}
|
||||
|
||||
*this = Result;
|
||||
}
|
||||
|
||||
// SEC 1: Elliptic Curve Cryptography
|
||||
// 2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion
|
||||
std::vector<uint8_t> Dump() const noexcept {
|
||||
if (IsAtInfinity()) {
|
||||
std::vector<uint8_t> bytes = { 0x00 };
|
||||
return bytes;
|
||||
} else {
|
||||
std::vector<uint8_t> bytes = { 0x04 };
|
||||
std::vector<uint8_t> xbytes = _X.Dump();
|
||||
std::vector<uint8_t> ybytes = _Y.Dump();
|
||||
std::reverse(xbytes.begin(), xbytes.end()); // to big endian
|
||||
std::reverse(ybytes.begin(), ybytes.end()); // to big endian
|
||||
bytes.insert(bytes.end(), xbytes.begin(), xbytes.end());
|
||||
bytes.insert(bytes.end(), ybytes.begin(), ybytes.end());
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
|
||||
// SEC 1: Elliptic Curve Cryptography
|
||||
// 2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion
|
||||
std::vector<uint8_t> DumpCompressed() const noexcept {
|
||||
if (IsAtInfinity()) {
|
||||
std::vector<uint8_t> bytes = { 0x00 };
|
||||
return bytes;
|
||||
} else {
|
||||
std::vector<uint8_t> bytes(1);
|
||||
std::vector<uint8_t> xbytes = _X.Dump();
|
||||
std::vector<uint8_t> zbytes = (_Y / _X).Dump();
|
||||
|
||||
if (zbytes[0] & 1) {
|
||||
bytes[0] = 0x03;
|
||||
} else {
|
||||
bytes[0] = 0x02;
|
||||
}
|
||||
|
||||
std::reverse(xbytes.begin(), xbytes.end()); // to big endian
|
||||
bytes.insert(bytes.end(), xbytes.begin(), xbytes.end());
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
EllipticCurveGF2m(const __FieldType& A, const __FieldType& B) : _A(A), _B(B) {
|
||||
_VerifyParameters();
|
||||
}
|
||||
|
||||
EllipticCurveGF2m(const void* pbA, size_t cbA, const void* pbB, size_t cbB) : _A(pbA, cbA), _B(pbB, cbB) {
|
||||
_VerifyParameters();
|
||||
}
|
||||
|
||||
bool operator==(const EllipticCurveGF2m<__FieldType>& Other) const noexcept {
|
||||
return _A == Other._A && _B == Other._B;
|
||||
}
|
||||
|
||||
bool operator!=(const EllipticCurveGF2m<__FieldType>& Other) const noexcept {
|
||||
return _A != Other._A || _B != Other._B;
|
||||
}
|
||||
|
||||
Point GetInfinityPoint() const noexcept {
|
||||
return Point(*this);
|
||||
}
|
||||
|
||||
Point GetPoint(const __FieldType& X, const __FieldType& Y) const {
|
||||
return Point(*this, X, Y);
|
||||
}
|
||||
|
||||
Point GetPoint(const void* pbX, size_t cbX, const void* pbY, size_t cbY) const {
|
||||
return Point(*this, pbX, cbX, pbY, cbY);
|
||||
}
|
||||
};
|
||||
226
GaloisField.hpp
Normal file
226
GaloisField.hpp
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
#pragma once
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include <type_traits>
|
||||
|
||||
struct GaloisFieldInitByZero {};
|
||||
struct GaloisFieldInitByOne {};
|
||||
struct GaloisFieldInitByElement {};
|
||||
struct GaloisFieldInitByDump {};
|
||||
|
||||
template<typename __FieldTraits>
|
||||
class GaloisField {
|
||||
public:
|
||||
static constexpr size_t BitSizeValue = __FieldTraits::BitSizeValue;
|
||||
static constexpr size_t DumpSizeValue = __FieldTraits::DumpSizeValue;
|
||||
private:
|
||||
static_assert(std::is_pod<typename __FieldTraits::ElementType>::value == true);
|
||||
|
||||
typename __FieldTraits::ElementType _Val;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 26495) // disable uninitialized warning
|
||||
#endif
|
||||
struct NoInitialization {};
|
||||
GaloisField(NoInitialization) noexcept {};
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
public:
|
||||
GaloisField() noexcept {
|
||||
__FieldTraits::SetZero(_Val);
|
||||
}
|
||||
|
||||
GaloisField(GaloisFieldInitByZero) noexcept {
|
||||
__FieldTraits::SetZero(_Val);
|
||||
}
|
||||
|
||||
GaloisField(GaloisFieldInitByOne) noexcept {
|
||||
__FieldTraits::SetOne(_Val);
|
||||
}
|
||||
|
||||
GaloisField(GaloisFieldInitByElement, const typename __FieldTraits::ElementType& Element) {
|
||||
__FieldTraits::Verify(Element);
|
||||
_Val = Element;
|
||||
}
|
||||
|
||||
GaloisField(GaloisFieldInitByDump, const void* pbBuffer, size_t cbBuffer) {
|
||||
__FieldTraits::Load(_Val, pbBuffer, cbBuffer);
|
||||
}
|
||||
|
||||
template<typename __Dummy = std::enable_if<BitSizeValue <= sizeof(uintptr_t) * 8>::type>
|
||||
GaloisField(GaloisFieldInitByDump, uintptr_t SerializedValue) {
|
||||
__FieldTraits::Load(_Val, SerializedValue);
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits>& operator=(const typename __FieldTraits::ElementType& Element) {
|
||||
__FieldTraits::Verify(Element);
|
||||
_Val = Element;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename __Dummy = std::enable_if<BitSizeValue <= sizeof(uintptr_t) * 8>::type>
|
||||
GaloisField<__FieldTraits>& operator=(uintptr_t SerializedValue) {
|
||||
__FieldTraits::Load(_Val, SerializedValue);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool IsZero() const noexcept {
|
||||
return __FieldTraits::IsZero(_Val);
|
||||
}
|
||||
|
||||
bool IsOne() const noexcept {
|
||||
return __FieldTraits::IsOne(_Val);
|
||||
}
|
||||
|
||||
bool operator==(const GaloisField<__FieldTraits>& Other) const noexcept {
|
||||
return __FieldTraits::IsEqual(_Val, Other._Val);
|
||||
}
|
||||
|
||||
bool operator!=(const GaloisField<__FieldTraits>& Other) const noexcept {
|
||||
return __FieldTraits::IsEqual(_Val, Other._Val) == false;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits> operator+(const GaloisField<__FieldTraits>& Other) const noexcept {
|
||||
GaloisField<__FieldTraits> Result(NoInitialization{});
|
||||
__FieldTraits::Add(Result._Val, _Val, Other._Val);
|
||||
return Result;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits>& operator+=(const GaloisField<__FieldTraits>& Other) noexcept {
|
||||
__FieldTraits::AddAssign(_Val, Other._Val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits> operator-(const GaloisField<__FieldTraits>& Other) const noexcept {
|
||||
GaloisField<__FieldTraits> Result(NoInitialization{});
|
||||
__FieldTraits::Substract(Result._Val, _Val, Other._Val);
|
||||
return Result;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits>& operator-=(const GaloisField<__FieldTraits>& Other) noexcept {
|
||||
__FieldTraits::SubstractAssign(_Val, Other._Val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits> operator*(const GaloisField<__FieldTraits>& Other) const noexcept {
|
||||
GaloisField<__FieldTraits> Result(NoInitialization{});
|
||||
__FieldTraits::Multiply(Result._Val, _Val, Other._Val);
|
||||
return Result;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits>& operator*=(const GaloisField<__FieldTraits>& Other) noexcept {
|
||||
__FieldTraits::MultiplyAssign(_Val, Other._Val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits> operator/(const GaloisField<__FieldTraits>& Other) const {
|
||||
GaloisField<__FieldTraits> Result(NoInitialization{});
|
||||
__FieldTraits::Divide(Result._Val, _Val, Other._Val);
|
||||
return Result;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits>& operator/=(const GaloisField<__FieldTraits>& Other) {
|
||||
__FieldTraits::DivideAssign(_Val, Other._Val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits>& operator++() noexcept { // prefix ++
|
||||
__FieldTraits::AddOneAssign(_Val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits> operator++(int) noexcept { // postfix ++
|
||||
GaloisField<__FieldTraits> Prev(*this);
|
||||
__FieldTraits::AddOneAssign(_Val);
|
||||
return Prev;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits>& operator--() noexcept { // prefix --
|
||||
__FieldTraits::SubstractOneAssign(_Val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits> operator--(int) noexcept { // postfix --
|
||||
GaloisField<__FieldTraits> Prev(*this);
|
||||
__FieldTraits::SubstractOneAssign(_Val);
|
||||
return Prev;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits>& Inverse() {
|
||||
__FieldTraits::InverseAssign(_Val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits> InverseValue() const {
|
||||
GaloisField<__FieldTraits> Result(NoInitialization{});
|
||||
__FieldTraits::Inverse(Result, _Val);
|
||||
return Result;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits>& AddOne() noexcept {
|
||||
__FieldTraits::AddOneAssign(_Val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits> AddOneValue() const noexcept {
|
||||
GaloisField<__FieldTraits> Result(NoInitialization{});
|
||||
__FieldTraits::AddOne(Result._Val, _Val);
|
||||
return Result;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits>& SubstractOne() noexcept {
|
||||
__FieldTraits::SubstractOneAssign(_Val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits> SubstractOneValue() const noexcept {
|
||||
GaloisField<__FieldTraits> Result(NoInitialization{});
|
||||
__FieldTraits::SubstractOne(Result._Val, _Val);
|
||||
return Result;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits>& Square() noexcept {
|
||||
__FieldTraits::SquareAssign(_Val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits> SquareValue() const noexcept {
|
||||
GaloisField<__FieldTraits> Result(NoInitialization{});
|
||||
__FieldTraits::Square(Result._Val, _Val);
|
||||
return Result;
|
||||
}
|
||||
|
||||
template<typename __Dummy = std::enable_if<BitSizeValue <= sizeof(uintptr_t) * 8>::type>
|
||||
uintptr_t Dump() const noexcept {
|
||||
return __FieldTraits::Dump(_Val);
|
||||
}
|
||||
|
||||
size_t Dump(void* lpBuffer, size_t cbBuffer) const {
|
||||
return __FieldTraits::Dump(_Val, lpBuffer, cbBuffer);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Dump() const noexcept {
|
||||
return __FieldTraits::Dump(_Val);
|
||||
}
|
||||
|
||||
template<typename __Dummy = std::enable_if<BitSizeValue <= sizeof(uintptr_t) * 8>::type>
|
||||
GaloisField<__FieldTraits>& Load(uintptr_t SerializedValue) {
|
||||
__FieldTraits::Load(_Val, SerializedValue);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits>& Load(const void* lpBuffer, size_t cbBuffer) {
|
||||
__FieldTraits::Load(_Val, lpBuffer, cbBuffer);
|
||||
return *this;
|
||||
}
|
||||
|
||||
GaloisField<__FieldTraits>& Load(const std::vector<uint8_t>& Buffer) {
|
||||
__FieldTraits::Load(_Val, Buffer);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
62
Hasher.hpp
Normal file
62
Hasher.hpp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#pragma once
|
||||
#include <utility>
|
||||
|
||||
template<typename __HashTraits>
|
||||
class Hasher {
|
||||
public:
|
||||
static constexpr size_t BlockSizeValue = __HashTraits::BlockSize;
|
||||
static constexpr size_t DigestSizeValue = __HashTraits::DigestSize;
|
||||
using DigestType = typename __HashTraits::DigestType;
|
||||
private:
|
||||
using ContextType = typename __HashTraits::ContextType;
|
||||
ContextType _Ctx;
|
||||
public:
|
||||
|
||||
Hasher(__HashTraits) :
|
||||
_Ctx(__HashTraits::ContextCreate()) {}
|
||||
|
||||
template<typename... __Ts>
|
||||
Hasher(__HashTraits, __Ts&&... Args) :
|
||||
_Ctx(__HashTraits::ContextCreate(std::forward<__Ts>(Args)...)) {}
|
||||
|
||||
Hasher(const Hasher<__HashTraits>& Other) :
|
||||
_Ctx(__HashTraits::ContextCopy(Other._Ctx)) {}
|
||||
|
||||
Hasher(Hasher<__HashTraits>&& Other) noexcept :
|
||||
_Ctx(std::move(Other._Ctx)) {}
|
||||
|
||||
Hasher<__HashTraits>& operator=(const Hasher<__HashTraits>& Other) {
|
||||
ContextType t = __HashTraits::ContextCopy(Other._Ctx);
|
||||
__HashTraits::ContextDestroy(_Ctx);
|
||||
_Ctx = std::move(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Hasher<__HashTraits>& operator=(Hasher<__HashTraits>&& Other) noexcept {
|
||||
_Ctx = std::move(Other._Ctx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr size_t BlockSize() const noexcept {
|
||||
return BlockSizeValue;
|
||||
}
|
||||
|
||||
constexpr size_t DigestSize() const noexcept {
|
||||
return DigestSizeValue;
|
||||
}
|
||||
|
||||
void Update(const void* lpBuffer, size_t cbBuffer) noexcept {
|
||||
__HashTraits::ContextUpdate(_Ctx, lpBuffer, cbBuffer);
|
||||
}
|
||||
|
||||
DigestType Evaluate() const noexcept {
|
||||
DigestType Digest;
|
||||
__HashTraits::ContextEvaluate(_Ctx, Digest);
|
||||
return Digest;
|
||||
}
|
||||
|
||||
~Hasher() {
|
||||
__HashTraits::ContextDestroy(_Ctx);
|
||||
}
|
||||
};
|
||||
|
||||
198
HasherCrc32Traits.hpp
Normal file
198
HasherCrc32Traits.hpp
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
#pragma once
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
template<uint32_t __Polynomial>
|
||||
struct HasherCrc32Traits {
|
||||
static constexpr size_t BlockSize = 0;
|
||||
static constexpr size_t DigestSize = 32 / 8;
|
||||
|
||||
using DigestType = uint32_t;
|
||||
using LookupTableType = uint32_t[256];
|
||||
|
||||
struct ContextType {
|
||||
uint32_t Value;
|
||||
|
||||
ContextType() noexcept :
|
||||
Value(0) {}
|
||||
|
||||
ContextType(uint32_t InitialValue) noexcept :
|
||||
Value(InitialValue) {}
|
||||
|
||||
ContextType(const ContextType& Other) noexcept = default;
|
||||
|
||||
ContextType(ContextType&& Other) noexcept : Value(Other.Value) {
|
||||
Other.Value = 0;
|
||||
}
|
||||
|
||||
ContextType& operator=(const ContextType& Other) noexcept = default;
|
||||
|
||||
ContextType& operator=(ContextType&& Other) noexcept {
|
||||
Value = Other.Value;
|
||||
Other.Value = 0;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
static const LookupTableType& InitializeLookupTable() noexcept {
|
||||
static LookupTableType LookupTable = {};
|
||||
|
||||
if (LookupTable[1] == 0) {
|
||||
for (unsigned i = 0; i < 256; ++i) {
|
||||
uint32_t result = i;
|
||||
for (unsigned j = 0; j < 8; ++j) {
|
||||
if (result % 2) {
|
||||
result /= 2;
|
||||
result ^= __Polynomial;
|
||||
} else {
|
||||
result /= 2;
|
||||
}
|
||||
}
|
||||
LookupTable[i] = result;
|
||||
}
|
||||
}
|
||||
|
||||
return LookupTable;
|
||||
}
|
||||
|
||||
static inline const LookupTableType& LookupTable = InitializeLookupTable();
|
||||
|
||||
static inline ContextType ContextCreate() noexcept {
|
||||
ContextType Ctx;
|
||||
return Ctx;
|
||||
}
|
||||
|
||||
static inline ContextType ContextCreate(const void* lpBuffer, size_t cbBuffer) noexcept {
|
||||
ContextType Ctx;
|
||||
ContextUpdate(Ctx, lpBuffer, cbBuffer);
|
||||
return Ctx;
|
||||
}
|
||||
|
||||
static inline ContextType ContextCreate(uint32_t InitialValue) noexcept {
|
||||
ContextType Ctx(InitialValue);
|
||||
return Ctx;
|
||||
}
|
||||
|
||||
static inline ContextType ContextCreate(uint32_t InitialValue, const void* lpBuffer, size_t cbBuffer) noexcept {
|
||||
ContextType Ctx;
|
||||
ContextUpdate(Ctx, lpBuffer, cbBuffer);
|
||||
return Ctx;
|
||||
}
|
||||
|
||||
static inline ContextType ContextCopy(const ContextType& Ctx) noexcept {
|
||||
return Ctx;
|
||||
}
|
||||
|
||||
static inline void ContextUpdate(ContextType& Ctx, const void* lpBuffer, size_t cbBuffer) noexcept {
|
||||
auto pbBuffer = reinterpret_cast<const uint8_t*>(lpBuffer);
|
||||
Ctx.Value = ~Ctx.Value;
|
||||
for (size_t i = 0; i < cbBuffer; ++i) {
|
||||
Ctx.Value = (Ctx.Value >> 8) ^ LookupTable[static_cast<uint8_t>(Ctx.Value) ^ pbBuffer[i]];
|
||||
}
|
||||
Ctx.Value = ~Ctx.Value;
|
||||
}
|
||||
|
||||
static inline void ContextEvaluate(const ContextType& Ctx, DigestType& Digest) noexcept {
|
||||
Digest = Ctx.Value;
|
||||
}
|
||||
|
||||
static inline void ContextDestroy(ContextType& Ctx) noexcept {
|
||||
Ctx.Value = 0;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#pragma comment(lib, "ntdll")
|
||||
|
||||
// available on WindowsXP and above
|
||||
NTSYSAPI
|
||||
DWORD
|
||||
NTAPI
|
||||
RtlComputeCrc32(
|
||||
_In_ DWORD InitialCrc,
|
||||
_In_reads_bytes_(Size) const void* Buffer,
|
||||
_In_ size_t Size
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
template<>
|
||||
struct HasherCrc32Traits<0xEDB88320> {
|
||||
static constexpr size_t BlockSize = 0;
|
||||
static constexpr size_t DigestSize = 32 / 8;
|
||||
|
||||
using DigestType = uint32_t;
|
||||
|
||||
struct ContextType {
|
||||
uint32_t Value;
|
||||
|
||||
ContextType() noexcept :
|
||||
Value(0) {}
|
||||
|
||||
ContextType(uint32_t InitialValue) noexcept :
|
||||
Value(InitialValue) {}
|
||||
|
||||
ContextType(const ContextType& Other) noexcept = default;
|
||||
|
||||
ContextType(ContextType&& Other) noexcept : Value(Other.Value) {
|
||||
Other.Value = 0;
|
||||
}
|
||||
|
||||
ContextType& operator=(const ContextType& Other) noexcept = default;
|
||||
|
||||
ContextType& operator=(ContextType&& Other) noexcept {
|
||||
Value = Other.Value;
|
||||
Other.Value = 0;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
static inline ContextType ContextCreate() noexcept {
|
||||
ContextType Ctx;
|
||||
return Ctx;
|
||||
}
|
||||
|
||||
static inline ContextType ContextCreate(const void* lpBuffer, size_t cbBuffer) noexcept {
|
||||
ContextType Ctx;
|
||||
ContextUpdate(Ctx, lpBuffer, cbBuffer);
|
||||
return Ctx;
|
||||
}
|
||||
|
||||
static inline ContextType ContextCreate(uint32_t InitialValue) noexcept {
|
||||
ContextType Ctx(InitialValue);
|
||||
return Ctx;
|
||||
}
|
||||
|
||||
static inline ContextType ContextCreate(uint32_t InitialValue, const void* lpBuffer, size_t cbBuffer) noexcept {
|
||||
ContextType Ctx;
|
||||
ContextUpdate(Ctx, lpBuffer, cbBuffer);
|
||||
return Ctx;
|
||||
}
|
||||
|
||||
static inline ContextType ContextCopy(const ContextType& Ctx) noexcept {
|
||||
return Ctx;
|
||||
}
|
||||
|
||||
static inline void ContextUpdate(ContextType& Ctx, const void* lpBuffer, size_t cbBuffer) noexcept {
|
||||
Ctx.Value = RtlComputeCrc32(Ctx.Value, lpBuffer, cbBuffer);
|
||||
}
|
||||
|
||||
static inline void ContextEvaluate(const ContextType& Ctx, DigestType& Digest) noexcept {
|
||||
Digest = Ctx.Value;
|
||||
}
|
||||
|
||||
static inline void ContextDestroy(ContextType& Ctx) noexcept {
|
||||
Ctx.Value = 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #ifdef _MSC_VER
|
||||
|
||||
153
HasherSha1Traits.hpp
Normal file
153
HasherSha1Traits.hpp
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
#include <system_error>
|
||||
|
||||
struct HasherSha1Traits {
|
||||
public:
|
||||
static constexpr size_t BlockSize = 512 / 8;
|
||||
static constexpr size_t DigestSize = 160 / 8;
|
||||
|
||||
struct DigestType {
|
||||
BYTE Bytes[DigestSize];
|
||||
};
|
||||
|
||||
struct ContextType {
|
||||
HCRYPTHASH hHash;
|
||||
|
||||
ContextType() noexcept :
|
||||
hHash(NULL) {}
|
||||
|
||||
ContextType(HCRYPTHASH HashHandle) noexcept :
|
||||
hHash(HashHandle) {}
|
||||
|
||||
ContextType(const ContextType& Other) noexcept = default;
|
||||
|
||||
ContextType(ContextType&& Other) noexcept : hHash(Other.hHash) {
|
||||
Other.hHash = NULL;
|
||||
}
|
||||
|
||||
ContextType& operator=(const ContextType& Other) noexcept = default;
|
||||
|
||||
ContextType& operator=(ContextType&& Other) noexcept {
|
||||
hHash = Other.hHash;
|
||||
Other.hHash = NULL;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
static inline struct ContextProvider {
|
||||
HCRYPTPROV Handle;
|
||||
|
||||
~ContextProvider() {
|
||||
if (Handle) {
|
||||
CryptReleaseContext(Handle, 0);
|
||||
Handle = NULL;
|
||||
}
|
||||
}
|
||||
} CryptProvider;
|
||||
|
||||
public:
|
||||
static inline ContextType ContextCreate() {
|
||||
ContextType Ctx;
|
||||
|
||||
if (CryptProvider.Handle == NULL) {
|
||||
if (!CryptAcquireContext(&CryptProvider.Handle, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) {
|
||||
auto err = GetLastError();
|
||||
if (err == NTE_BAD_KEYSET) {
|
||||
if (!CryptAcquireContext(&CryptProvider.Handle, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_NEWKEYSET)) {
|
||||
err = GetLastError();
|
||||
throw std::system_error(err, std::system_category());
|
||||
}
|
||||
} else {
|
||||
throw std::system_error(err, std::system_category());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!CryptCreateHash(CryptProvider.Handle, CALG_SHA1, NULL, 0, &Ctx.hHash)) {
|
||||
auto err = GetLastError();
|
||||
throw std::system_error(err, std::system_category());
|
||||
}
|
||||
|
||||
return Ctx;
|
||||
}
|
||||
|
||||
static inline ContextType ContextCreate(const void* lpBuffer, size_t cbBuffer) {
|
||||
ContextType Ctx;
|
||||
|
||||
if (CryptProvider.Handle == NULL) {
|
||||
if (!CryptAcquireContext(&CryptProvider.Handle, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) {
|
||||
auto err = GetLastError();
|
||||
if (err == NTE_BAD_KEYSET) {
|
||||
if (!CryptAcquireContext(&CryptProvider.Handle, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_NEWKEYSET)) {
|
||||
err = GetLastError();
|
||||
throw std::system_error(err, std::system_category());
|
||||
}
|
||||
} else {
|
||||
throw std::system_error(err, std::system_category());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!CryptCreateHash(CryptProvider.Handle, CALG_SHA1, NULL, 0, &Ctx.hHash)) {
|
||||
auto err = GetLastError();
|
||||
throw std::system_error(err, std::system_category());
|
||||
}
|
||||
|
||||
ContextUpdate(Ctx, lpBuffer, cbBuffer);
|
||||
|
||||
return Ctx;
|
||||
}
|
||||
|
||||
static inline ContextType ContextCopy(const ContextType& Ctx) {
|
||||
ContextType NewCtx;
|
||||
if (!CryptDuplicateHash(Ctx.hHash, NULL, 0, &NewCtx.hHash)) {
|
||||
auto err = GetLastError();
|
||||
throw std::system_error(err, std::system_category());
|
||||
}
|
||||
return NewCtx;
|
||||
}
|
||||
|
||||
static inline void ContextUpdate(ContextType& Ctx, const void* lpBuffer, size_t cbBuffer) {
|
||||
if constexpr (sizeof(size_t) <= sizeof(DWORD)) {
|
||||
if (!CryptHashData(Ctx.hHash, reinterpret_cast<const BYTE*>(lpBuffer), static_cast<DWORD>(cbBuffer), 0)) {
|
||||
auto err = GetLastError();
|
||||
throw std::system_error(err, std::system_category());
|
||||
}
|
||||
} else {
|
||||
size_t BytesRead = 0;
|
||||
DWORD BytesToRead = cbBuffer - BytesRead > MAXDWORD ? MAXDWORD : static_cast<DWORD>(cbBuffer - BytesRead);
|
||||
|
||||
do {
|
||||
if (!CryptHashData(Ctx.hHash, reinterpret_cast<const BYTE*>(lpBuffer) + BytesRead, BytesToRead, 0)) {
|
||||
auto err = GetLastError();
|
||||
throw std::system_error(err, std::system_category());
|
||||
}
|
||||
BytesRead += BytesToRead;
|
||||
BytesToRead = cbBuffer - BytesRead > MAXDWORD ? MAXDWORD : static_cast<DWORD>(cbBuffer - BytesRead);
|
||||
} while (BytesToRead);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ContextEvaluate(const ContextType& Ctx, DigestType& Digest) {
|
||||
DWORD SizeOfDigest = sizeof(Digest.Bytes);
|
||||
if (!CryptGetHashParam(Ctx.hHash, HP_HASHVAL, Digest.Bytes, &SizeOfDigest, 0)) {
|
||||
auto err = GetLastError();
|
||||
throw std::system_error(err, std::system_category());
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ContextDestroy(ContextType& Ctx) noexcept {
|
||||
if (Ctx.hHash) {
|
||||
CryptDestroyHash(Ctx.hHash);
|
||||
Ctx.hHash = NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
321
README.HOW_DOES_IT_WORK.md
Normal file
321
README.HOW_DOES_IT_WORK.md
Normal file
|
|
@ -0,0 +1,321 @@
|
|||
[GF2-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20%5Ctextrm%7BGF%7D%282%29
|
||||
[GF2p15-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20%5Ctextrm%7BGF%7D%282%5E%7B15%7D%29
|
||||
[GF2p15p17-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20%5Ctextrm%7BGF%7D%28%282%5E%7B15%7D%29%5E%7B17%7D%29
|
||||
[A-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20A
|
||||
[B-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20B
|
||||
[D-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20D
|
||||
[G-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20G
|
||||
[M-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20M
|
||||
[P-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20P
|
||||
[h-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20h
|
||||
[k-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20k
|
||||
[l-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20l
|
||||
[n-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20n
|
||||
[r-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20r
|
||||
[s-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20s
|
||||
[T-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20T
|
||||
[UU-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20U
|
||||
[LL-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20L
|
||||
[Rnd-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20Rnd
|
||||
[Temp-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20Temp
|
||||
[UID-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20UID
|
||||
[Data-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20Data
|
||||
[Data0-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20Data%5E0
|
||||
[Data1-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20Data%5E1
|
||||
[Data2-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20Data%5E2
|
||||
[Data3-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20Data%5E3
|
||||
|
||||
# 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
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?P%28%5Calpha%29%3D%5Calpha%5E%7B15%7D+%5Calpha+1")
|
||||
</p>
|
||||
|
||||
where each coefficients is in ![GF2-inlined]. If we use
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?B_1%3D%5C%7B1%2C%5Calpha%2C%5Calpha%5E2%2C%5Cldots%2C%5Calpha%5E%7B14%7D%5C%7D")
|
||||
</p>
|
||||
|
||||
as the standard basis of the ground field, an element ![A-inlined] in ![GF2p15-inlined] can be denoted as
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?A%3D%5Csum_%7Bi%3D0%7D%5E%7B14%7Da_i%5Calpha%5Ei%20%5Cquad%20%5Cquad%20%5Cquad%20a_i%5Cin%5Ctextrm%7BGF%7D%282%29")
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
The irreducible polynomial of composite field ![GF2p15p17-inlined] is
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?Q%28%5Cbeta%29%3D%5Cbeta%5E%7B17%7D+%5Cbeta%5E3+1")
|
||||
</p>
|
||||
|
||||
where each coefficients is in ![GF2p15-inlined]. If we use
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?B_2%3D%5C%7B1%2C%5Cbeta%2C%5Cbeta%5E2%2C%5Cldots%2C%5Cbeta%5E%7B16%7D%5C%7D")
|
||||
</p>
|
||||
|
||||
as the standard basis of the composite field, an element ![B-inlined] in ![GF2p15p17-inlined] can be denoted as
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?B%3D%5Csum_%7Bj%3D0%7D%5E%7B16%7D%28%5Csum_%7Bi%3D0%7D%5E%7B14%7Da_%7Bj%2Ci%7D%5Calpha%5Ei%29%5Cbeta%5Ej%3D%5Csum_%7Bj%3D0%7D%5E%7B16%7D%5Csum_%7Bi%3D0%7D%5E%7B14%7Da_%7Bj%2Ci%7D%5Calpha%5Ei%5Cbeta%5Ej%20%5Cquad%20%5Cquad%20%5Cquad%20a_%7Bj%2Ci%7D%5Cin%5Ctextrm%7BGF%7D%282%29")
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
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
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?B%3D%5Csum_%7Bj%3D0%7D%5E%7B16%7D%5Csum_%7Bi%3D0%7D%5E%7B14%7Da_%7Bj%2Ci%7D%5Calpha%5Ei%5Cbeta%5Ej%20%5Cleftrightarrow%20D%3D%5Csum_%7Bj%3D0%7D%5E%7B16%7D%5Csum_%7Bi%3D0%7D%5E%7B14%7Da_%7Bj%2Ci%7D%5Ccdot%202%5E%7B15j+i%7D")
|
||||
</p>
|
||||
|
||||
## 2. Elliptic curve over ![GF2p15p17-inlined]
|
||||
|
||||
The equation of the elliptic curve that WinRAR uses is
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?y%5E2+xy%3Dx%5E3+161%20%5Cquad%20%5Cquad%20%5Cquad%20161%5Cin%5Ctextrm%7BGF%7D%28%282%5E%7B15%7D%29%5E%7B17%7D%29")
|
||||
</p>
|
||||
|
||||
The base point ![G-inlined] is
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?%5Cbegin%7Baligned%7D%20G%26%3D%28G_x%2CG_y%29%20%5C%5C%20G_x%26%3D%5Ctextrm%7B0x56fdcbc6a27acee0cc2996e0096ae74feb1acf220a2341b898b549440297b8cc%7D%20%5Cquad%20G_x%5Cin%5Ctextrm%7BGF%7D%28%282%5E%7B15%7D%29%5E%7B17%7D%29%5C%5C%20G_y%26%3D%5Ctextrm%7B0x20da32e8afc90b7cf0e76bde44496b4d0794054e6ea60f388682463132f931a7%7D%20%5Cquad%20G_y%5Cin%5Ctextrm%7BGF%7D%28%282%5E%7B15%7D%29%5E%7B17%7D%29%20%5Cend%7Baligned%7D")
|
||||
</p>
|
||||
|
||||
whose order ![n-inlined] is
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?n%3D%5Ctextrm%7B0x1026dd85081b82314691ced9bbec30547840e4bf72d8b5e0d258442bbcd31%7D%20%5Cquad%20n%5Cin%5Cnolinebreak%5Cmathbb%7BZ%7D")
|
||||
</p>
|
||||
|
||||
## 3. Message hash algorithm
|
||||
|
||||
We use
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?M%3Dm_0m_1%20%5Cldots%20m_%7Bl-1%7D%20%5Cquad%20%5Cquad%20m_i%5Cin%5B0%2C%20256%29")
|
||||
</p>
|
||||
|
||||
to denote a message whose length is ![l-inlined]. So the SHA1 value of ![M-inlined] should be
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?%5Ctextrm%7BSHA%7D_1%28M%29%3DS_0%7C%7CS_1%7C%7CS_2%7C%7CS_3%7C%7CS_4%20%5Cquad%20%5Cquad%20S_i%5Cin%5B0%2C%202%5E%7B32%7D%29")
|
||||
</p>
|
||||
|
||||
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.
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?h%3D%28%5Csum_%7Bi%3D0%7D%5E%7B4%7DS_i%20%5Ccdot%202%5E%7B32i%7D%29+%5Ctextrm%7B0x1bd10xb4e33c7c0ffd8d43%7D%20%5Ccdot%202%5E%7B32*5%7D")
|
||||
</p>
|
||||
|
||||
## 4. ECC digital signature algorithm
|
||||
|
||||
We use ![k-inlined] to denote private key, ![P-inlined] to denote public key. So there must be
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?P%3Dk%20%5Ccdot%20G")
|
||||
</p>
|
||||
|
||||
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]
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?r%3D%28%28Rnd%20%5Ccdot%20G%29_x+h%29%5C%20%5C%20Mod%5C%20%5C%20n">
|
||||
</p>
|
||||
|
||||
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]
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?s%3D%28Rnd-kr%29%5C%20%5C%20Mod%5C%20%5C%20n">
|
||||
</p>
|
||||
|
||||
If , go back to step 1.
|
||||
|
||||
4. Output .
|
||||
|
||||
## 5. WinRAR private key generation algorithm
|
||||
|
||||
We use
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?T%3Dt_0t_1%20%5Cldots%20t_%7Bl-1%7D%20%5Cquad%20%5Cquad%20t_i%5Cin%5B0%2C256%29">
|
||||
</p>
|
||||
|
||||
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
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?g_j%3D%5Csum_%7Bi%3D0%7D%5E%7B3%7Dg_%7Bj%2Ci%7D%20%5Ccdot%202%5E%7B8i%7D%20%5Cquad%20%5Cquad%20g_%7Bj%2Ci%7D%5Cin%5B0%2C256%29">
|
||||
</p>
|
||||
|
||||
2. Let .
|
||||
|
||||
3. If , we calculate SHA1 value of ![T-inlined]. Then assign SHA1 state value  to :
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?%5Cbegin%7Baligned%7D%20%5Ctextrm%7BSHA%7D_1%28T%29%26%3DS_0%7C%7CS_1%7C%7CS_2%7C%7CS_3%7C%7CS_4%20%5C%5C%20g_1%26%3DS_0%20%5C%5C%20g_2%26%3DS_1%20%5C%5C%20g_3%26%3DS_2%20%5C%5C%20g_4%26%3DS_3%20%5C%5C%20g_5%26%3DS_4%20%5C%5C%20%5Cend%7Baligned%7D">
|
||||
</p>
|
||||
|
||||
Otherwise, when , we let
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?%5Cbegin%7Baligned%7D%20g_1%26%3D%5Ctextrm%7B0xeb3eb781%7D%20%5C%5C%20g_2%26%3D%5Ctextrm%7B0x50265329%7D%20%5C%5C%20g_3%26%3D%5Ctextrm%7B0xdc5ef4a3%7D%20%5C%5C%20g_4%26%3D%5Ctextrm%7B0x6847b9d5%7D%20%5C%5C%20g_5%26%3D%5Ctextrm%7B0xcde43b4c%7D%20%5C%5C%20%5Cend%7Baligned%7D">
|
||||
</p>
|
||||
|
||||
4. Regard  as counter, add itself by 1.
|
||||
|
||||
Calculate SHA1:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?%5Ctextrm%7BSHA%7D_1%28g_%7B0%2C0%7D%7C%7Cg_%7B0%2C1%7D%7C%7Cg_%7B0%2C2%7D%7C%7Cg_%7B0%2C3%7D%7C%7Cg_%7B1%2C0%7D%7C%7Cg_%7B1%2C1%7D%7C%7C%5Cldots%7C%7Cg_%7B5%2C0%7D%7C%7Cg_%7B5%2C1%7D%7C%7Cg_%7B5%2C2%7D%7C%7Cg_%7B5%2C3%7D%29%3DS_0%7C%7CS_1%7C%7CS_2%7C%7CS_3%7C%7CS_4">
|
||||
</p>
|
||||
|
||||
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
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?k%3D%5Csum_%7Bi%3D1%7D%5E%7B15%7Dk_i%20%5Ccdot%202%5E%7B16i%7D">
|
||||
</p>
|
||||
|
||||
## 6. The private key and public key of WinRAR
|
||||
|
||||
Private key ![k-inlined] is
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?k%3D%5Ctextrm%7B0x59fe6abcca90bdb95f0105271fa85fb9f11f467450c1ae9044b7fd61d65e%7D%20%5Cquad%20%5Cquad%20k%5Cin%5Cnolinebreak%5Cmathbb%7BZ%7D">
|
||||
</p>
|
||||
|
||||
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
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?%5Cbegin%7Baligned%7D%20P%26%3D%28P_x%2CP_y%29%20%5C%5C%20P_x%26%3D%5Ctextrm%7B0x3861220ed9b36c9753df09a159dfb148135d495db3af8373425ee9a28884ba1a%7D%20%5Cquad%20P_x%5Cin%5Ctextrm%7BGF%7D%28%282%5E%7B15%7D%29%5E%7B17%7D%29%20%5C%5C%20P_y%26%3D%5Ctextrm%7B0x12b64e62db43a56114554b0cbd573379338cea9124c8443c4f50e6c8b013ec20%7D%20%5Cquad%20P_y%5Cin%5Ctextrm%7BGF%7D%28%282%5E%7B15%7D%29%5E%7B17%7D%29%20%5Cend%7Baligned%7D">
|
||||
</p>
|
||||
|
||||
## 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
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?U%3Du_0u_1%20%5Cldots%20u_%7Bl-1%7D">
|
||||
</p>
|
||||
|
||||
2. License type, an ANSI-encoded string, without null-terminator. Denoted as
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?L%3Dl_0l_1%20%5Cldots%20l_%7Bl-1%7D">
|
||||
</p>
|
||||
|
||||
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
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?Data%5E3%3D%5Ctexttt%7B%2260%22%7D%7C%7CTemp_0%7C%7CTemp_1%7C%7C%5Cldots%7C%7CTemp_%7B47%7D">
|
||||
</p>
|
||||
|
||||
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
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?UID%3DTemp_%7B48%7D%7C%7CTemp_%7B49%7D%7C%7C%5Cldots%7C%7CTemp_%7B63%7D%7C%7CData%5E0_0%7C%7CData%5E0_1%7C%7CData%5E0_2%7C%7CData%5E0_3">
|
||||
</p>
|
||||
|
||||
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
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?Data%5E1%3D%5Ctexttt%7B%2260%22%7D%7C%7CSZ%5E%7Bs_L%7D%7C%7CSZ%5E%7Br_L%7D">
|
||||
</p>
|
||||
|
||||
8. Let ![Temp-inlined] be
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?Temp%3DU%7C%7CData%5E0">
|
||||
</p>
|
||||
|
||||
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
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?Data%5E2%3D%5Ctexttt%7B%2260%22%7D%7C%7CSZ%5E%7Bs_%7BTemp%7D%7D%7C%7CSZ%5E%7Br_%7BTemp%7D%7D">
|
||||
</p>
|
||||
|
||||
11. Calculate CRC32 value of
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?L%7C%7CU%7C%7CData%5E0%7C%7CData%5E1%7C%7CData%5E2%7C%7CData%5E3">
|
||||
</p>
|
||||
|
||||
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
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?%5Cinline%20Data%3DData%5E0%7C%7CData%5E1%7C%7CData%5E2%7C%7CData%5E3%7C%7CSZ%5E%7Bchecksum%7D">
|
||||
</p>
|
||||
|
||||
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:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?%5Ctexttt%7B%22UID%3D%22%7D%7C%7CUID">
|
||||
</p>
|
||||
|
||||
* Output ![Data-inlined], with 54 characters a line.
|
||||
|
||||
320
README.HOW_DOES_IT_WORK.zh-CN.md
Normal file
320
README.HOW_DOES_IT_WORK.zh-CN.md
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
[GF2-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20%5Ctextrm%7BGF%7D%282%29
|
||||
[GF2p15-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20%5Ctextrm%7BGF%7D%282%5E%7B15%7D%29
|
||||
[GF2p15p17-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20%5Ctextrm%7BGF%7D%28%282%5E%7B15%7D%29%5E%7B17%7D%29
|
||||
[A-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20A
|
||||
[B-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20B
|
||||
[D-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20D
|
||||
[G-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20G
|
||||
[M-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20M
|
||||
[P-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20P
|
||||
[h-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20h
|
||||
[k-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20k
|
||||
[l-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20l
|
||||
[n-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20n
|
||||
[r-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20r
|
||||
[s-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20s
|
||||
[T-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20T
|
||||
[UU-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20U
|
||||
[LL-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20L
|
||||
[Rnd-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20Rnd
|
||||
[Temp-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20Temp
|
||||
[UID-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20UID
|
||||
[Data-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20Data
|
||||
[Data0-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20Data%5E0
|
||||
[Data1-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20Data%5E1
|
||||
[Data2-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20Data%5E2
|
||||
[Data3-inlined]: http://latex.codecogs.com/svg.latex?%5Cinline%20Data%5E3
|
||||
|
||||
# "rarreg.key"是如何生成的?
|
||||
|
||||
WinRAR使用了基于ECC的签名算法来生成 `rarreg.key` 文件,其使用的签名算法是中国SM2数字签名算法的变体。与各种标准ECDSA不同的是,WinRAR使用的椭圆曲线是一个基于复合域 ![GF2p15p17-inlined] 上的曲线。
|
||||
|
||||
## 1. 复合域 ![GF2p15p17-inlined]
|
||||
|
||||
基域 ![GF2p15-inlined] 采用标准基(多项式基)来表达,采用的不可约多项式为:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?P%28%5Calpha%29%3D%5Calpha%5E%7B15%7D+%5Calpha+1")
|
||||
</p>
|
||||
|
||||
各项系数全部位于 ![GF2-inlined]。设基域的标准基为:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?B_1%3D%5C%7B1%2C%5Calpha%2C%5Calpha%5E2%2C%5Cldots%2C%5Calpha%5E%7B14%7D%5C%7D")
|
||||
</p>
|
||||
|
||||
则位于基域 ![GF2p15-inlined] 上的元素 ![A-inlined] 可以用如下方式表达:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?A%3D%5Csum_%7Bi%3D0%7D%5E%7B14%7Da_i%5Calpha%5Ei%20%5Cquad%20%5Cquad%20%5Cquad%20a_i%5Cin%5Ctextrm%7BGF%7D%282%29")
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
复合域 ![GF2p15p17-inlined] 的不可约多项式为:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?Q%28%5Cbeta%29%3D%5Cbeta%5E%7B17%7D+%5Cbeta%5E3+1")
|
||||
</p>
|
||||
|
||||
各项系数全部位于 ![GF2p15-inlined]。设复合域的标准基为:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?B_2%3D%5C%7B1%2C%5Cbeta%2C%5Cbeta%5E2%2C%5Cldots%2C%5Cbeta%5E%7B16%7D%5C%7D")
|
||||
</p>
|
||||
|
||||
则位于复合域 ![GF2p15p17-inlined] 上的元素 ![B-inlined] 可以用如下方式表达:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?B%3D%5Csum_%7Bj%3D0%7D%5E%7B16%7D%28%5Csum_%7Bi%3D0%7D%5E%7B14%7Da_%7Bj%2Ci%7D%5Calpha%5Ei%29%5Cbeta%5Ej%3D%5Csum_%7Bj%3D0%7D%5E%7B16%7D%5Csum_%7Bi%3D0%7D%5E%7B14%7Da_%7Bj%2Ci%7D%5Calpha%5Ei%5Cbeta%5Ej%20%5Cquad%20%5Cquad%20%5Cquad%20a_%7Bj%2Ci%7D%5Cin%5Ctextrm%7BGF%7D%282%29")
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
为了方便表述我们用255比特的大数 ![D-inlined] 来表示位于复合域 ![GF2p15p17-inlined] 上的元素 ![B-inlined]。它们的对应关系为:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?B%3D%5Csum_%7Bj%3D0%7D%5E%7B16%7D%5Csum_%7Bi%3D0%7D%5E%7B14%7Da_%7Bj%2Ci%7D%5Calpha%5Ei%5Cbeta%5Ej%20%5Cleftrightarrow%20D%3D%5Csum_%7Bj%3D0%7D%5E%7B16%7D%5Csum_%7Bi%3D0%7D%5E%7B14%7Da_%7Bj%2Ci%7D%5Ccdot%202%5E%7B15j+i%7D")
|
||||
</p>
|
||||
|
||||
## 2. 复合域 ![GF2p15p17-inlined] 上的椭圆曲线
|
||||
|
||||
曲线方程为:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?y%5E2+xy%3Dx%5E3+161%20%5Cquad%20%5Cquad%20%5Cquad%20161%5Cin%5Ctextrm%7BGF%7D%28%282%5E%7B15%7D%29%5E%7B17%7D%29")
|
||||
</p>
|
||||
|
||||
基点 ![G-inlined] 为:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?%5Cbegin%7Baligned%7D%20G%26%3D%28G_x%2CG_y%29%20%5C%5C%20G_x%26%3D%5Ctextrm%7B0x56fdcbc6a27acee0cc2996e0096ae74feb1acf220a2341b898b549440297b8cc%7D%20%5Cquad%20G_x%5Cin%5Ctextrm%7BGF%7D%28%282%5E%7B15%7D%29%5E%7B17%7D%29%5C%5C%20G_y%26%3D%5Ctextrm%7B0x20da32e8afc90b7cf0e76bde44496b4d0794054e6ea60f388682463132f931a7%7D%20%5Cquad%20G_y%5Cin%5Ctextrm%7BGF%7D%28%282%5E%7B15%7D%29%5E%7B17%7D%29%20%5Cend%7Baligned%7D")
|
||||
</p>
|
||||
|
||||
基点 ![G-inlined] 的阶 ![n-inlined] 为:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?n%3D%5Ctextrm%7B0x1026dd85081b82314691ced9bbec30547840e4bf72d8b5e0d258442bbcd31%7D%20%5Cquad%20n%5Cin%5Cnolinebreak%5Cmathbb%7BZ%7D")
|
||||
</p>
|
||||
|
||||
## 3. 消息哈希算法
|
||||
|
||||
设长度为 ![l-inlined] 的消息为:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?M%3Dm_0m_1%20%5Cldots%20m_%7Bl-1%7D%20%5Cquad%20%5Cquad%20m_i%5Cin%5B0%2C%20256%29")
|
||||
</p>
|
||||
|
||||
则消息 ![M-inlined] 的SHA1值为:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?%5Ctextrm%7BSHA%7D_1%28M%29%3DS_0%7C%7CS_1%7C%7CS_2%7C%7CS_3%7C%7CS_4%20%5Cquad%20%5Cquad%20S_i%5Cin%5B0%2C%202%5E%7B32%7D%29")
|
||||
</p>
|
||||
|
||||
其中  为SHA1算法输出时的5个状态值;将这5个状态值按照大端字节序依次输出,即为的SHA1哈希值 。
|
||||
|
||||
WinRAR在做完SHA1计算后,采用大数 ![h-inlined] 作为ECC签名时消息的哈希:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?h%3D%28%5Csum_%7Bi%3D0%7D%5E%7B4%7DS_i%20%5Ccdot%202%5E%7B32i%7D%29+%5Ctextrm%7B0x1bd10xb4e33c7c0ffd8d43%7D%20%5Ccdot%202%5E%7B32*5%7D")
|
||||
</p>
|
||||
|
||||
|
||||
## 4. ECC签名算法
|
||||
|
||||
设私钥为 ![k-inlined],公钥为 ![P-inlined],即:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?P%3Dk%20%5Ccdot%20G")
|
||||
</p>
|
||||
|
||||
消息哈希为 ![h-inlined],则签名  为:
|
||||
|
||||
1. 生成随机数 ![Rnd-inlined],满足 。
|
||||
|
||||
2. 计算 ![r-inlined]
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?r%3D%28%28Rnd%20%5Ccdot%20G%29_x+h%29%5C%20%5C%20Mod%5C%20%5C%20n">
|
||||
</p>
|
||||
|
||||
其中  表示取  的X坐标,同时将X坐标从 ![GF2p15p17-inlined] 转换为大数。
|
||||
|
||||
若  或者  则回到步骤1。
|
||||
|
||||
3. 计算 ![s-inlined]
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?s%3D%28Rnd-kr%29%5C%20%5C%20Mod%5C%20%5C%20n">
|
||||
</p>
|
||||
|
||||
若  则回到步骤1。
|
||||
|
||||
4. 输出 。
|
||||
|
||||
## 5. WinRAR的私钥生成算法
|
||||
|
||||
该算法会利用长度为 ![l-inlined] 的数据
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?T%3Dt_0t_1%20%5Cldots%20t_%7Bl-1%7D%20%5Cquad%20%5Cquad%20t_i%5Cin%5B0%2C256%29">
|
||||
</p>
|
||||
|
||||
来生成私钥 ![k-inlined]。
|
||||
|
||||
1. 设6个32位整数为 ,则有
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?g_j%3D%5Csum_%7Bi%3D0%7D%5E%7B3%7Dg_%7Bj%2Ci%7D%20%5Ccdot%202%5E%7B8i%7D%20%5Cquad%20%5Cquad%20g_%7Bj%2Ci%7D%5Cin%5B0%2C256%29">
|
||||
</p>
|
||||
|
||||
2. 令 。
|
||||
|
||||
3. 如果  则计算 ![T-inlined] 的SHA1值,并将状态值  赋值给 :
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?%5Cbegin%7Baligned%7D%20%5Ctextrm%7BSHA%7D_1%28T%29%26%3DS_0%7C%7CS_1%7C%7CS_2%7C%7CS_3%7C%7CS_4%20%5C%5C%20g_1%26%3DS_0%20%5C%5C%20g_2%26%3DS_1%20%5C%5C%20g_3%26%3DS_2%20%5C%5C%20g_4%26%3DS_3%20%5C%5C%20g_5%26%3DS_4%20%5C%5C%20%5Cend%7Baligned%7D">
|
||||
</p>
|
||||
|
||||
否则,即  时,令:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?%5Cbegin%7Baligned%7D%20g_1%26%3D%5Ctextrm%7B0xeb3eb781%7D%20%5C%5C%20g_2%26%3D%5Ctextrm%7B0x50265329%7D%20%5C%5C%20g_3%26%3D%5Ctextrm%7B0xdc5ef4a3%7D%20%5C%5C%20g_4%26%3D%5Ctextrm%7B0x6847b9d5%7D%20%5C%5C%20g_5%26%3D%5Ctextrm%7B0xcde43b4c%7D%20%5C%5C%20%5Cend%7Baligned%7D">
|
||||
</p>
|
||||
|
||||
4. 把  作为计数器,自增1。
|
||||
|
||||
计算SHA1值:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?%5Ctextrm%7BSHA%7D_1%28g_%7B0%2C0%7D%7C%7Cg_%7B0%2C1%7D%7C%7Cg_%7B0%2C2%7D%7C%7Cg_%7B0%2C3%7D%7C%7Cg_%7B1%2C0%7D%7C%7Cg_%7B1%2C1%7D%7C%7C%5Cldots%7C%7Cg_%7B5%2C0%7D%7C%7Cg_%7B5%2C1%7D%7C%7Cg_%7B5%2C2%7D%7C%7Cg_%7B5%2C3%7D%29%3DS_0%7C%7CS_1%7C%7CS_2%7C%7CS_3%7C%7CS_4">
|
||||
</p>
|
||||
|
||||
取  的低16位并记为 。
|
||||
|
||||
5. 步骤4再重复14次。
|
||||
|
||||
6. 重复执行完后会得到 ,则输出私钥
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?k%3D%5Csum_%7Bi%3D1%7D%5E%7B15%7Dk_i%20%5Ccdot%202%5E%7B16i%7D">
|
||||
</p>
|
||||
|
||||
## 6. WinRAR的公钥和私钥
|
||||
|
||||
WinRAR的私钥 ![k-inlined] 为:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?k%3D%5Ctextrm%7B0x59fe6abcca90bdb95f0105271fa85fb9f11f467450c1ae9044b7fd61d65e%7D%20%5Cquad%20%5Cquad%20k%5Cin%5Cnolinebreak%5Cmathbb%7BZ%7D">
|
||||
</p>
|
||||
|
||||
该私钥是通过算法5生成的,其中数据 ![T-inlined] 的长度为0。
|
||||
|
||||
公钥 ![P-inlined] 为:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?%5Cbegin%7Baligned%7D%20P%26%3D%28P_x%2CP_y%29%20%5C%5C%20P_x%26%3D%5Ctextrm%7B0x3861220ed9b36c9753df09a159dfb148135d495db3af8373425ee9a28884ba1a%7D%20%5Cquad%20P_x%5Cin%5Ctextrm%7BGF%7D%28%282%5E%7B15%7D%29%5E%7B17%7D%29%20%5C%5C%20P_y%26%3D%5Ctextrm%7B0x12b64e62db43a56114554b0cbd573379338cea9124c8443c4f50e6c8b013ec20%7D%20%5Cquad%20P_y%5Cin%5Ctextrm%7BGF%7D%28%282%5E%7B15%7D%29%5E%7B17%7D%29%20%5Cend%7Baligned%7D">
|
||||
</p>
|
||||
|
||||
## 7. 授权文件"rarreg.key"的生成
|
||||
|
||||
授权文件的生成需要两个参数:
|
||||
|
||||
1. 用户名的ANSI字符串,不包括null-terminator;记为
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?U%3Du_0u_1%20%5Cldots%20u_%7Bl-1%7D">
|
||||
</p>
|
||||
|
||||
2. 授权类型的ANSI字符串,不包括null-terminator;记为
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?L%3Dl_0l_1%20%5Cldots%20l_%7Bl-1%7D">
|
||||
</p>
|
||||
|
||||
`rarreg.key` 的生成算法如下:
|
||||
|
||||
1. 使用用户名 ![UU-inlined] 通过算法5计算出私钥  以及公钥 ,并将公钥  按照SM2压缩公钥格式以Hex字符串(ASCII编码)的形式输出。得到的Hex字符串记为临时值 ![Temp-inlined]。
|
||||
|
||||
![Temp-inlined] 的长度应该为64;若长度不足,则在前面补字符`'0'`,直到长度为64。
|
||||
|
||||
2. 令字符串 ![Data3-inlined]为
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?Data%5E3%3D%5Ctexttt%7B%2260%22%7D%7C%7CTemp_0%7C%7CTemp_1%7C%7C%5Cldots%7C%7CTemp_%7B47%7D">
|
||||
</p>
|
||||
|
||||
3. 使用 ![Data3-inlined] 通过算法5计算出私钥  以及公钥 ,并将公钥  按照SM2压缩公钥格式以Hex字符串(ASCII编码)的形式输出。得到的Hex字符串记为 ![Data0-inlined]。
|
||||
|
||||
![Data0-inlined] 的长度应该为64;若长度不足,则在前面补字符`'0'`,直到长度为64。
|
||||
|
||||
4. 令字符串 ![UID-inlined]为
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?UID%3DTemp_%7B48%7D%7C%7CTemp_%7B49%7D%7C%7C%5Cldots%7C%7CTemp_%7B63%7D%7C%7CData%5E0_0%7C%7CData%5E0_1%7C%7CData%5E0_2%7C%7CData%5E0_3">
|
||||
</p>
|
||||
|
||||
5. 对授权类型 ![LL-inlined] 使用算法4得到签名 ,其中私钥见第6节。
|
||||
|
||||
要求  和  的长度都不得超过240比特,否则重复该步骤。
|
||||
|
||||
6. 将  和  以16进制形式输出(无`"0x"`前缀),分别记为  和 。
|
||||
|
||||
若长度不满60,则在前面补字符`'0'`,直到长度为60。
|
||||
|
||||
7. 令字符串 ![Data1-inlined]为
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?Data%5E1%3D%5Ctexttt%7B%2260%22%7D%7C%7CSZ%5E%7Bs_L%7D%7C%7CSZ%5E%7Br_L%7D">
|
||||
</p>
|
||||
|
||||
8. 令字符串 ![Temp-inlined]为
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?Temp%3DU%7C%7CData%5E0">
|
||||
</p>
|
||||
|
||||
对 ![Temp-inlined] 使用算法4得到签名 ,其中私钥见第6节。
|
||||
|
||||
要求  和  的长度都不得超过240比特,否则重复该步骤。
|
||||
|
||||
9. 将  和  以16进制形式输出(无`"0x"`前缀),分别记为  和 。
|
||||
|
||||
若长度不满60,则在前面补字符`'0'`,直到长度为60。
|
||||
|
||||
10. 令字符串 ![Data2-inlined]为
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?Data%5E2%3D%5Ctexttt%7B%2260%22%7D%7C%7CSZ%5E%7Bs_%7BTemp%7D%7D%7C%7CSZ%5E%7Br_%7BTemp%7D%7D">
|
||||
</p>
|
||||
|
||||
11. 对
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?L%7C%7CU%7C%7CData%5E0%7C%7CData%5E1%7C%7CData%5E2%7C%7CData%5E3">
|
||||
</p>
|
||||
|
||||
计算CRC32值,最终校验和为CRC32值的反。将校验和以10进制形式输出,若长度不满10,则在前面补字符`'0'`,直到长度为10,记为 。
|
||||
|
||||
12. 令字符串 ![Data-inlined]为
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?%5Cinline%20Data%3DData%5E0%7C%7CData%5E1%7C%7CData%5E2%7C%7CData%5E3%7C%7CSZ%5E%7Bchecksum%7D">
|
||||
</p>
|
||||
|
||||
13. 格式化输出。
|
||||
|
||||
* 固定文件头`"RAR registration data"`,占一行。
|
||||
|
||||
* 用户名,占一行。
|
||||
|
||||
* 授权类型,占一行。
|
||||
|
||||
* UID,占一行:
|
||||
|
||||
<p align="center">
|
||||
<img src="http://latex.codecogs.com/svg.latex?%5Ctexttt%7B%22UID%3D%22%7D%7C%7CUID">
|
||||
</p>
|
||||
|
||||
* 将 ![Data-inlined] 按照每行54个字符输出。
|
||||
|
||||
87
README.md
Normal file
87
README.md
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# WinRAR-Keygen
|
||||
|
||||
[中文版 README](README.zh-CN.md)
|
||||
|
||||
<img src="icon1.png" alt="icon1" style="zoom:50%;" />
|
||||
|
||||
## 1. What is WinRAR?
|
||||
|
||||
WinRAR is a trialware file archiver utility for Windows, developed by Eugene Roshal of win.rar GmbH.
|
||||
|
||||
It can create and view archives in RAR or ZIP file formats and unpack numerous archive file formats.
|
||||
|
||||
WinRAR is not a free software. If you want to use it, you should pay to [__RARLAB__](https://rarlab.com/) and then you will get a license file named `rarreg.key`.
|
||||
|
||||
This repository will tell you how WinRAR license file `"rarreg.key"` is generated.
|
||||
|
||||
## 2. How is "rarreg.key" generated?
|
||||
|
||||
See [here](README.HOW_DOES_IT_WORK.md).
|
||||
|
||||
## 3. How to build?
|
||||
|
||||
### 3.1 Prerequisites
|
||||
|
||||
1. Please make sure that you have __Visual Studio 2019__ or the higher. Because this is a VS2019 project.
|
||||
|
||||
2. Please make sure you have installed `vcpkg` and the following libraries:
|
||||
|
||||
* `mpir:x86-windows-static`
|
||||
* `mpir:x64-windows-static`
|
||||
|
||||
is installed.
|
||||
|
||||
You can install them by:
|
||||
|
||||
```console
|
||||
$ vcpkg install mpir:x86-windows-static
|
||||
$ vcpkg install mpir:x64-windows-static
|
||||
```
|
||||
|
||||
3. Your `vcpkg` has been integrated into your __Visual Studio__, which means you have run
|
||||
|
||||
```console
|
||||
$ vcpkg integrate install
|
||||
```
|
||||
|
||||
successfully.
|
||||
|
||||
### 3.2 Build
|
||||
|
||||
1. Open this project in __Visual Studio__.
|
||||
|
||||
2. Select `Release` configuration.
|
||||
|
||||
3. Select __Build > Build Solution__.
|
||||
|
||||
You will see executable files in `bin/` directory.
|
||||
|
||||
## 4. How to Use?
|
||||
|
||||
```
|
||||
Usage:
|
||||
winrar-keygen.exe <your name> <license type>
|
||||
|
||||
Example:
|
||||
|
||||
winrar-keygen.exe "Rebecca Morrison" "Single PC usage license"
|
||||
or:
|
||||
winrar-keygen.exe "Rebecca Morrison" "Single PC usage license" > rarreg.key
|
||||
```
|
||||
|
||||
Now you can see the newly generated file. Save the generated information as `rarreg.key`.
|
||||
|
||||
```console
|
||||
$ winrar-keygen.exe "DoubleLabyrinth" "Single PC usage license"
|
||||
RAR registration data
|
||||
DoubleLabyrinth
|
||||
Single PC usage license
|
||||
UID=d2fb7cb15c078a3def58
|
||||
6412212250ef58bef21cdcb49ca34b7040112cae5a512f1adad1a8
|
||||
f6d2ee8c382fe64f8e3d6035c6ab9048e2c5c62f0238f183d28519
|
||||
aa87488bf38f5b634cf28190bdf438ac593b1857cdb55a7fcb0eb0
|
||||
c3e4c2736090b3dfa45384e08e9de05c5860d3051942adf2db9d96
|
||||
e2ec37f1cfae00b3e2455093b90e4e352f016f6b9853c735d45fb4
|
||||
01f9cbb91d3f3ac5664511229f8c9b0a9e1d61a2e087b481607e91
|
||||
bfc8a83414f6807d31a5f8c587513aa54f9b1249ad804214409316
|
||||
```
|
||||
81
README.zh-CN.md
Normal file
81
README.zh-CN.md
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
# WinRAR-Keygen
|
||||
|
||||
[README for English](README.md)
|
||||
|
||||
<img src="icon1.png" alt="icon1" style="zoom:50%;" />
|
||||
|
||||
## 1. WinRAR是什么?
|
||||
|
||||
WinRAR是一款用于管理压缩包文件的共享软件。其算法由作者尤金·罗谢尔研发,享有原创专利。
|
||||
|
||||
它可以用来创建或浏览RAR、ZIP等众多格式的压缩包。
|
||||
|
||||
WinRAR不是免费的软件。如果你想使用它,你应当向 [__RARLAB__](https://rarlab.com/) 付费,然后获得一个授权文件 `rarreg.key`。
|
||||
|
||||
这份repo将会告诉你 `rarreg.key` 是如何生成的。
|
||||
|
||||
## 2. "rarreg.key"是如何生成的?
|
||||
|
||||
见 [这里](README.HOW_DOES_IT_WORK.zh-CN.md)。
|
||||
|
||||
## 3. 如何编译?
|
||||
|
||||
### 3.1 前提条件
|
||||
|
||||
1. 请确保你有 __Visual Studio 2019__ 或其更高版本。因为这是一个VS2019项目。
|
||||
|
||||
2. 请确保你安装了 `vcpkg` 以及下面几个库:
|
||||
|
||||
* `mpir:x86-windows-static`
|
||||
* `mpir:x64-windows-static`
|
||||
|
||||
你可以通过下的命令来安装:
|
||||
|
||||
```console
|
||||
$ vcpkg install mpir:x86-windows-static
|
||||
$ vcpkg install mpir:x64-windows-static
|
||||
```
|
||||
|
||||
3. 你的 `vcpkg` 与 __Visual Studio__ 整合了,即你曾成功运行了下面这条命令:
|
||||
|
||||
```console
|
||||
$ vcpkg integrate install
|
||||
```
|
||||
|
||||
### 3.2 编译
|
||||
|
||||
1. 在 __Visual Studio__ 中打开这个项目。
|
||||
|
||||
2. 选择 `Release` 配置。
|
||||
|
||||
3. 选择 __生成 > 生成解决方案__。
|
||||
|
||||
## 4. 如何使用?
|
||||
|
||||
```
|
||||
Usage:
|
||||
winrar-keygen.exe <your name> <license type>
|
||||
|
||||
Example:
|
||||
|
||||
winrar-keygen.exe "Rebecca Morrison" "Single PC usage license"
|
||||
or:
|
||||
winrar-keygen.exe "Rebecca Morrison" "Single PC usage license" > rarreg.key
|
||||
```
|
||||
|
||||
现在你可以看到新生成的文件,将生成的信息保存为 `rarreg.key ` 即可:
|
||||
|
||||
```console
|
||||
$ winrar-keygen.exe "DoubleLabyrinth" "Single PC usage license"
|
||||
RAR registration data
|
||||
DoubleLabyrinth
|
||||
Single PC usage license
|
||||
UID=d2fb7cb15c078a3def58
|
||||
6412212250ef58bef21cdcb49ca34b7040112cae5a512f1adad1a8
|
||||
f6d2ee8c382fe64f8e3d6035c6ab9048e2c5c62f0238f183d28519
|
||||
aa87488bf38f5b634cf28190bdf438ac593b1857cdb55a7fcb0eb0
|
||||
c3e4c2736090b3dfa45384e08e9de05c5860d3051942adf2db9d96
|
||||
e2ec37f1cfae00b3e2455093b90e4e352f016f6b9853c735d45fb4
|
||||
01f9cbb91d3f3ac5664511229f8c9b0a9e1d61a2e087b481607e91
|
||||
bfc8a83414f6807d31a5f8c587513aa54f9b1249ad804214409316
|
||||
```
|
||||
486
WinRarConfig.hpp
Normal file
486
WinRarConfig.hpp
Normal file
|
|
@ -0,0 +1,486 @@
|
|||
#pragma once
|
||||
#include "GaloisField.hpp"
|
||||
#include "EllipticCurveGF2m.hpp"
|
||||
#include "BigInteger.hpp"
|
||||
|
||||
struct WinRarConfig {
|
||||
public:
|
||||
// Irreducible polynomial of ground field = x^15 + x + 1
|
||||
// Irreducible polynomial of extension field = y^17 + y^3 + 1;
|
||||
struct GF2p15p17Traits {
|
||||
struct ElementType {
|
||||
uint16_t Items[17];
|
||||
};
|
||||
|
||||
static constexpr size_t BitSizeValue = 15 * 17;
|
||||
static constexpr size_t DumpSizeValue = (BitSizeValue + 7) / 8;
|
||||
|
||||
using GF2p15LogExpTableType = uint16_t[0x8000];
|
||||
|
||||
static const GF2p15LogExpTableType& InitializeGF2p15Table(bool ReturnLogTable) noexcept {
|
||||
static GF2p15LogExpTableType LogTable;
|
||||
static GF2p15LogExpTableType ExpTable;
|
||||
constexpr size_t Order = 0x7fff;
|
||||
|
||||
if (ExpTable[Order] == 0) {
|
||||
|
||||
ExpTable[0] = 1;
|
||||
for (size_t i = 1; i < Order; ++i) {
|
||||
uint32_t temp = ExpTable[i - 1] * 2;
|
||||
if (temp & 0x8000) {
|
||||
temp ^= 0x8003;
|
||||
}
|
||||
ExpTable[i] = temp;
|
||||
}
|
||||
|
||||
// mark as initialized
|
||||
ExpTable[Order] = ~ExpTable[Order];
|
||||
|
||||
for (size_t i = 0; i < Order; ++i) {
|
||||
// #if defined(_MSC_VER)
|
||||
// __assume(ExpTable[i] <= Order);
|
||||
// #endif
|
||||
LogTable[ExpTable[i]] = static_cast<uint16_t>(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (ReturnLogTable) {
|
||||
return LogTable;
|
||||
} else {
|
||||
return ExpTable;
|
||||
}
|
||||
}
|
||||
|
||||
static inline const GF2p15LogExpTableType& GF2p15LogTable = InitializeGF2p15Table(true);
|
||||
static inline const GF2p15LogExpTableType& GF2p15ExpTable = InitializeGF2p15Table(false);
|
||||
static inline const ElementType ZeroValue = {};
|
||||
static inline const ElementType OneValue = { 1 };
|
||||
|
||||
static void Verify(const ElementType& Val) {
|
||||
for (size_t i = 0; i < 17; ++i) {
|
||||
if (Val.Items[i] >= 0x8000) {
|
||||
throw std::invalid_argument("Val is not in GF((2 ^ 15) ^ 17).");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static size_t Dump(const ElementType& Val, void* lpBuffer, size_t cbBuffer) {
|
||||
if (cbBuffer < DumpSizeValue) {
|
||||
throw std::length_error("Insufficient buffer.");
|
||||
} else {
|
||||
uint8_t* pbWritePtr = reinterpret_cast<uint8_t*>(lpBuffer);
|
||||
unsigned left_bits = 8;
|
||||
|
||||
for (size_t i = 0; i < 17; ++i) {
|
||||
uint8_t low8 = static_cast<uint8_t>(Val.Items[i]);
|
||||
uint8_t high7 = static_cast<uint8_t>(Val.Items[i] >> 8);
|
||||
|
||||
if (left_bits == 8) {
|
||||
*pbWritePtr = low8;
|
||||
++pbWritePtr;
|
||||
} else {
|
||||
*pbWritePtr |= low8 << (8 - left_bits);
|
||||
++pbWritePtr;
|
||||
*pbWritePtr = low8 >> left_bits;
|
||||
}
|
||||
|
||||
if (left_bits == 8) {
|
||||
*pbWritePtr = high7;
|
||||
left_bits = 1;
|
||||
} else if (left_bits == 7) {
|
||||
*pbWritePtr |= high7 << 1;
|
||||
++pbWritePtr;
|
||||
left_bits = 8;
|
||||
} else {
|
||||
*pbWritePtr |= high7 << (8 - left_bits);
|
||||
++pbWritePtr;
|
||||
*pbWritePtr = high7 >> left_bits;
|
||||
left_bits = 8 - (7 - left_bits);
|
||||
}
|
||||
}
|
||||
|
||||
return DumpSizeValue;
|
||||
}
|
||||
}
|
||||
|
||||
static std::vector<uint8_t> Dump(const ElementType& Val) noexcept {
|
||||
std::vector<uint8_t> bytes(DumpSizeValue);
|
||||
Dump(Val, bytes.data(), bytes.size());
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static void Load(ElementType& Val, const void* lpBuffer, size_t cbBuffer) {
|
||||
if (cbBuffer != DumpSizeValue) {
|
||||
throw std::length_error("The length of buffer is not correct.");
|
||||
} else {
|
||||
const uint8_t* pbBuffer = reinterpret_cast<const uint8_t*>(lpBuffer);
|
||||
|
||||
if (pbBuffer[DumpSizeValue - 1] & 0x80) {
|
||||
throw std::invalid_argument("Not in GF((2 ^ 15) ^ 17).");
|
||||
}
|
||||
|
||||
uint16_t* pbWritePtr = Val.Items;
|
||||
unsigned left_bits = 15;
|
||||
|
||||
for (size_t i = 0; i < DumpSizeValue; ++i) {
|
||||
uint16_t v;
|
||||
if (left_bits == 15) {
|
||||
v = pbBuffer[i];
|
||||
left_bits = 15 - 8;
|
||||
} else if (left_bits > 8) {
|
||||
v |= pbBuffer[i] << (15 - left_bits);
|
||||
left_bits -= 8;
|
||||
} else {
|
||||
v |= (pbBuffer[i] << (15 - left_bits)) & 0x7fff;
|
||||
*pbWritePtr = v;
|
||||
++pbWritePtr;
|
||||
v = pbBuffer[i] >> left_bits;
|
||||
left_bits = 15 - (8 - left_bits);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Load(ElementType& Val, const std::vector<uint8_t>& Buffer) {
|
||||
Load(Val, Buffer.data(), Buffer.size());
|
||||
}
|
||||
|
||||
static inline void Swap(ElementType& A, ElementType& B) noexcept {
|
||||
for (size_t i = 0; i < 17; ++i) {
|
||||
std::swap(A.Items[i], B.Items[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetZero(ElementType& Val) noexcept {
|
||||
memset(Val.Items, 0, sizeof(Val.Items));
|
||||
}
|
||||
|
||||
static inline void SetOne(ElementType& Val) noexcept {
|
||||
Val.Items[0] = 1;
|
||||
memset(Val.Items + 1, 0, sizeof(Val.Items) - sizeof(Val.Items[0]));
|
||||
}
|
||||
|
||||
static inline bool IsEqual(const ElementType& A, const ElementType& B) noexcept {
|
||||
return memcmp(A.Items, B.Items, sizeof(ElementType::Items)) == 0;
|
||||
}
|
||||
|
||||
static inline bool IsZero(const ElementType& Val) noexcept {
|
||||
return memcmp(Val.Items, ZeroValue.Items, sizeof(ElementType::Items)) == 0;
|
||||
}
|
||||
|
||||
static inline bool IsOne(const ElementType& Val) noexcept {
|
||||
return memcmp(Val.Items, OneValue.Items, sizeof(ElementType::Items)) == 0;
|
||||
}
|
||||
|
||||
// Result = A + B
|
||||
static inline void Add(ElementType& Result, const ElementType& A, const ElementType& B) noexcept {
|
||||
for (size_t i = 0; i < 17; ++i) {
|
||||
Result.Items[i] = A.Items[i] ^ B.Items[i];
|
||||
}
|
||||
}
|
||||
|
||||
// A += B
|
||||
static inline void AddAssign(ElementType& A, const ElementType& B) noexcept {
|
||||
for (size_t i = 0; i < 17; ++i) {
|
||||
A.Items[i] ^= B.Items[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Result = A + 1
|
||||
static inline void AddOne(ElementType& Result, const ElementType& A) noexcept {
|
||||
Result.Items[0] = A.Items[0] ^ 0x0001;
|
||||
memcpy(Result.Items + 1, A.Items + 1, sizeof(ElementType::Items) - sizeof(uint16_t));
|
||||
}
|
||||
|
||||
// A += 1
|
||||
static inline void AddOneAssign(ElementType& A) noexcept {
|
||||
A.Items[0] ^= 0x0001;
|
||||
}
|
||||
|
||||
// Result = A - B
|
||||
static inline void Substract(ElementType& Result, const ElementType& A, const ElementType& B) noexcept {
|
||||
for (size_t i = 0; i < 17; ++i) {
|
||||
Result.Items[i] = A.Items[i] ^ B.Items[i];
|
||||
}
|
||||
}
|
||||
|
||||
// A -= B
|
||||
static inline void SubstractAssign(ElementType& A, const ElementType& B) noexcept {
|
||||
for (size_t i = 0; i < 17; ++i) {
|
||||
A.Items[i] ^= B.Items[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Result = A - 1
|
||||
static inline void SubstractOne(ElementType& Result, const ElementType& A) noexcept {
|
||||
Result.Items[0] = A.Items[0] ^ 0x0001;
|
||||
memcpy(Result.Items + 1, A.Items + 1, sizeof(ElementType::Items) - sizeof(uint16_t));
|
||||
}
|
||||
|
||||
// A -= 1
|
||||
static inline void SubstractOneAssign(ElementType& A) noexcept {
|
||||
A.Items[0] ^= 0x0001;
|
||||
}
|
||||
|
||||
// Result = A * B
|
||||
// Require: len(Result) == M + N - 1
|
||||
static inline void FullMultiplySchoolBook(size_t M, size_t N, uint16_t Result[], const uint16_t A[], const uint16_t B[]) noexcept {
|
||||
memset(Result, 0, (M + N - 1) * sizeof(uint16_t));
|
||||
|
||||
for (size_t i = 0; i < M; ++i) {
|
||||
if (A[i]) {
|
||||
for (size_t j = 0; j < N; ++j) {
|
||||
if (B[j]) {
|
||||
auto g = GF2p15LogTable[A[i]] + GF2p15LogTable[B[j]];
|
||||
|
||||
if (g >= 0x7fff) {
|
||||
g -= 0x7fff;
|
||||
}
|
||||
|
||||
Result[i + j] ^= GF2p15ExpTable[g];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ModularReduction(size_t N, uint16_t A[]) noexcept {
|
||||
// Irreducible polynomial of extension field = y^17 + y^3 + 1;
|
||||
for (size_t i = N - 1; i > 16; --i) {
|
||||
if (A[i] != 0) {
|
||||
A[i - 17 + 0] ^= A[i];
|
||||
A[i - 17 + 3] ^= A[i];
|
||||
A[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Result = A * B mod (x^15 + x + 1, y^17 + y^3 + 1)
|
||||
static inline void Multiply(ElementType& Result, const ElementType& A, const ElementType& B) noexcept {
|
||||
uint16_t temp[16 + 16 + 1];
|
||||
FullMultiplySchoolBook(17, 17, temp, A.Items, B.Items);
|
||||
ModularReduction(16 + 16 + 1, temp);
|
||||
memcpy(Result.Items, temp, sizeof(ElementType::Items));
|
||||
}
|
||||
|
||||
static inline void MultiplyAssign(ElementType& A, const ElementType& B) noexcept {
|
||||
Multiply(A, A, B);
|
||||
}
|
||||
|
||||
static inline void Divide(ElementType& Result, const ElementType& A, const ElementType& B) {
|
||||
ElementType InverseOfB;
|
||||
Inverse(InverseOfB, B);
|
||||
Multiply(Result, A, InverseOfB);
|
||||
}
|
||||
|
||||
static inline void DivideAssign(ElementType& A, const ElementType& B) {
|
||||
ElementType InverseOfB;
|
||||
Inverse(InverseOfB, B);
|
||||
MultiplyAssign(A, InverseOfB);
|
||||
}
|
||||
|
||||
static inline void Inverse(ElementType& Result, const ElementType& A) {
|
||||
// lpA += (Alpha * x ^ j) * B
|
||||
auto AddScale = [](uint16_t A[], size_t& degA, uint16_t Alpha, size_t j, const uint16_t B[], size_t degB) {
|
||||
auto logAlpha = GF2p15LogTable[Alpha];
|
||||
auto Aj = A + j;
|
||||
|
||||
for (size_t i = 0; i <= degB; ++i) {
|
||||
if (B[i]) {
|
||||
auto g = logAlpha + GF2p15LogTable[B[i]];
|
||||
|
||||
if (g >= 0x7fff) {
|
||||
g -= 0x7fff;
|
||||
}
|
||||
|
||||
Aj[i] ^= GF2p15ExpTable[g];
|
||||
if (Aj[i] && i + j > degA) {
|
||||
degA = i + j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (A[degA] == 0) {
|
||||
--degA;
|
||||
}
|
||||
};
|
||||
|
||||
size_t degB;
|
||||
size_t degC;
|
||||
size_t degF;
|
||||
size_t degG;
|
||||
uint16_t B[2 * 17];
|
||||
uint16_t C[2 * 17];
|
||||
uint16_t F[2 * 17];
|
||||
uint16_t G[2 * 17];
|
||||
|
||||
// Initialize B
|
||||
degB = 0;
|
||||
B[0] = 1;
|
||||
memset(B + 1, 0, sizeof(B) - sizeof(uint16_t));
|
||||
|
||||
// Initialize C
|
||||
degC = 0;
|
||||
memset(C, 0, sizeof(C));
|
||||
|
||||
// Initialize F
|
||||
bool isZero = true;
|
||||
for (unsigned i = 0; i < 17; ++i) {
|
||||
if (A.Items[i] != 0) {
|
||||
isZero = false;
|
||||
}
|
||||
|
||||
F[i] = A.Items[i];
|
||||
|
||||
if (F[i]) {
|
||||
degF = i;
|
||||
}
|
||||
}
|
||||
memset(F + 17, 0, 17 * sizeof(uint16_t));
|
||||
|
||||
if (isZero) {
|
||||
throw std::domain_error("Zero doesn't have inverse.");
|
||||
}
|
||||
|
||||
// initialize G = x^17 + x^3 + 1;
|
||||
degG = 17;
|
||||
memset(G, 0, sizeof(G));
|
||||
G[0] = 1;
|
||||
G[3] = 1;
|
||||
G[17] = 1;
|
||||
|
||||
for (uint16_t *lpF = F, *lpG = G, *lpB = B, *lpC = C;;) {
|
||||
if (degF == 0) {
|
||||
for (size_t i = 0; i <= degB; ++i) {
|
||||
if (lpB[i]) {
|
||||
auto g = GF2p15LogTable[lpB[i]] - GF2p15LogTable[lpF[0]];
|
||||
|
||||
if (g < 0) {
|
||||
g += 0x7fff;
|
||||
}
|
||||
|
||||
Result.Items[i] = GF2p15ExpTable[g];
|
||||
} else {
|
||||
Result.Items[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = degB + 1; i < 17; ++i) {
|
||||
Result.Items[i] = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (degF < degG) {
|
||||
std::swap(lpF, lpG);
|
||||
std::swap(degF, degG);
|
||||
std::swap(lpB, lpC);
|
||||
std::swap(degB, degC);
|
||||
}
|
||||
|
||||
auto j = degF - degG;
|
||||
|
||||
auto g = GF2p15LogTable[lpF[degF]] - GF2p15LogTable[lpG[degG]];
|
||||
if (g < 0) {
|
||||
g += 0x7fff;
|
||||
}
|
||||
auto Alpha = GF2p15ExpTable[g];
|
||||
|
||||
AddScale(lpF, degF, Alpha, j, lpG, degG);
|
||||
AddScale(lpB, degB, Alpha, j, lpC, degC);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void InverseAssign(ElementType& Result) {
|
||||
Inverse(Result, Result);
|
||||
}
|
||||
|
||||
static inline void Square(ElementType& Result, const ElementType& A) noexcept {
|
||||
uint16_t temp[16 + 16 + 1];
|
||||
|
||||
for (size_t i = 0; i < 17; ++i) {
|
||||
if (A.Items[i]) {
|
||||
auto g = GF2p15LogTable[A.Items[i]] * 2;
|
||||
|
||||
if (g >= 0x7fff) {
|
||||
g -= 0x7fff;
|
||||
}
|
||||
|
||||
temp[2 * i] = GF2p15ExpTable[g];
|
||||
} else {
|
||||
temp[2 * i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < 16 + 16 + 1; i += 2) {
|
||||
temp[i] = 0;
|
||||
}
|
||||
|
||||
ModularReduction(16 + 16 + 1, temp);
|
||||
|
||||
memcpy(Result.Items, temp, sizeof(ElementType::Items));
|
||||
}
|
||||
|
||||
static inline void SquareAssign(ElementType& A) noexcept {
|
||||
Square(A, A);
|
||||
}
|
||||
};
|
||||
|
||||
static inline const EllipticCurveGF2m<GaloisField<GF2p15p17Traits>> Curve{
|
||||
{ GaloisFieldInitByZero{} }, // A
|
||||
{ GaloisFieldInitByElement{}, { 161 } } // B
|
||||
};
|
||||
|
||||
static inline const EllipticCurveGF2m<GaloisField<GF2p15p17Traits>>::Point G = Curve.GetPoint(
|
||||
{
|
||||
GaloisFieldInitByElement{},
|
||||
{
|
||||
0x38CC, 0x052F, 0x2510, 0x45AA,
|
||||
0x1B89, 0x4468, 0x4882, 0x0D67,
|
||||
0x4FEB, 0x55CE, 0x0025, 0x4CB7,
|
||||
0x0CC2, 0x59DC, 0x289E, 0x65E3,
|
||||
0x56FD
|
||||
}
|
||||
},
|
||||
{
|
||||
GaloisFieldInitByElement{},
|
||||
{
|
||||
0x31A7, 0x65F2, 0x18C4, 0x3412,
|
||||
0x7388, 0x54C1, 0x539B, 0x4A02,
|
||||
0x4D07, 0x12D6, 0x7911, 0x3B5E,
|
||||
0x4F0E, 0x216F, 0x2BF2, 0x1974,
|
||||
0x20DA
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
static inline const BigInteger Order = "0x1026dd85081b82314691ced9bbec30547840e4bf72d8b5e0d258442bbcd31";
|
||||
|
||||
// Generated by `WinRarKeygen<WinRarConfig>::GeneratePrivateKey(nullptr, 0);`
|
||||
static inline const BigInteger PrivateKey = "0x59fe6abcca90bdb95f0105271fa85fb9f11f467450c1ae9044b7fd61d65e";
|
||||
|
||||
static inline const EllipticCurveGF2m<GaloisField<GF2p15p17Traits>>::Point PublicKey = Curve.GetPoint(
|
||||
{
|
||||
GaloisFieldInitByElement{},
|
||||
{
|
||||
0x3A1A, 0x1109, 0x268A, 0x12F7,
|
||||
0x3734, 0x75F0, 0x576C, 0x2EA4,
|
||||
0x4813, 0x3F62, 0x0567, 0x784D,
|
||||
0x753D, 0x6D92, 0x366C, 0x1107,
|
||||
0x3861
|
||||
}
|
||||
},
|
||||
{
|
||||
GaloisFieldInitByElement{},
|
||||
{
|
||||
0x6C20, 0x6027, 0x1B22, 0x7A87,
|
||||
0x43C4, 0x1908, 0x2449, 0x4675,
|
||||
0x7933, 0x2E66, 0x32F5, 0x2A58,
|
||||
0x1145, 0x74AC, 0x36D0, 0x2731,
|
||||
0x12B6
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
233
WinRarKeygen.hpp
Normal file
233
WinRarKeygen.hpp
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
#pragma once
|
||||
#include "BigInteger.hpp"
|
||||
#include "Hasher.hpp"
|
||||
#include "HasherSha1Traits.hpp"
|
||||
#include "HasherCrc32Traits.hpp"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
template<typename __ConfigType>
|
||||
class WinRarKeygen {
|
||||
public:
|
||||
|
||||
struct RegisterInfo {
|
||||
std::string UserName;
|
||||
std::string LicenseType;
|
||||
std::string UID;
|
||||
std::string Items[4];
|
||||
uint32_t Checksum;
|
||||
std::string HexData;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
struct ECCSignature {
|
||||
BigInteger r;
|
||||
BigInteger s;
|
||||
};
|
||||
|
||||
static BigInteger GeneratePrivateKey(const void* lpSeed, size_t cbSeed) {
|
||||
uint32_t Generator[6];
|
||||
uint16_t RawPrivateKey[15] = {};
|
||||
|
||||
if (cbSeed) {
|
||||
Hasher Sha1(HasherSha1Traits{}, lpSeed, cbSeed);
|
||||
HasherSha1Traits::DigestType Sha1Digest;
|
||||
|
||||
Sha1Digest = Sha1.Evaluate();
|
||||
|
||||
for (unsigned i = 0; i < 5; ++i) {
|
||||
Generator[i + 1] = _byteswap_ulong(reinterpret_cast<uint32_t*>(Sha1Digest.Bytes)[i]);
|
||||
}
|
||||
} else {
|
||||
Generator[1] = 0xeb3eb781;
|
||||
Generator[2] = 0x50265329;
|
||||
Generator[3] = 0xdc5ef4a3;
|
||||
Generator[4] = 0x6847b9d5;
|
||||
Generator[5] = 0xcde43b4c;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < 15; ++i) {
|
||||
Hasher Sha1(HasherSha1Traits{});
|
||||
HasherSha1Traits::DigestType Sha1Digest;
|
||||
|
||||
Generator[0] = i + 1;
|
||||
Sha1.Update(Generator, sizeof(Generator));
|
||||
Sha1Digest = Sha1.Evaluate();
|
||||
|
||||
RawPrivateKey[i] = static_cast<uint16_t>(
|
||||
_byteswap_ulong(reinterpret_cast<uint32_t*>(Sha1Digest.Bytes)[0])
|
||||
);
|
||||
}
|
||||
|
||||
// `Order` has 241 bits, while `RawPrivateKey` has (15 * 16 = 240) bits at most
|
||||
// So `RawPrivateKey` must be less than `Order` which means `RawPrivateKey` must be valid private key.
|
||||
return BigInteger(false, RawPrivateKey, sizeof(RawPrivateKey), true);
|
||||
}
|
||||
|
||||
static auto GeneratePublicKey(const BigInteger& PrivateKey) {
|
||||
return __ConfigType::G * PrivateKey;
|
||||
}
|
||||
|
||||
static std::string GeneratePublicKeySM2CompressedFormat(const char* lpszMessage) {
|
||||
auto PrivateKey = GeneratePrivateKey(lpszMessage, strlen(lpszMessage));
|
||||
auto PublicKey = GeneratePublicKey(PrivateKey);
|
||||
auto PublicKeyCompressed = PublicKey.DumpCompressed();
|
||||
auto PublicKeyXInteger = BigInteger(false, PublicKeyCompressed.data() + 1, PublicKeyCompressed.size() - 1, false); // 255 bits at most
|
||||
|
||||
PublicKeyXInteger *= 2; // 256 bits at most
|
||||
if (PublicKeyCompressed[0] == 0x03) { // when LSB(PublicKeyY / PublicKeyX) == 1
|
||||
PublicKeyXInteger.SetBit(0);
|
||||
}
|
||||
|
||||
auto PublicKeyCompressedSM2Format = PublicKeyXInteger.ToString(16, true);
|
||||
if (PublicKeyCompressedSM2Format.length() < 32 * 2) {
|
||||
PublicKeyCompressedSM2Format.insert(PublicKeyCompressedSM2Format.begin(), 32 * 2 - PublicKeyCompressedSM2Format.size(), '0');
|
||||
}
|
||||
|
||||
return PublicKeyCompressedSM2Format;
|
||||
}
|
||||
|
||||
static BigInteger GenerateRandomInteger() {
|
||||
uint16_t RawRandomInteger[15];
|
||||
|
||||
srand(static_cast<unsigned int>(time(nullptr)));
|
||||
for (size_t i = 0; i < 15; ++i) {
|
||||
RawRandomInteger[i] = static_cast<uint16_t>(rand());
|
||||
}
|
||||
|
||||
return BigInteger(false, RawRandomInteger, sizeof(RawRandomInteger), true);
|
||||
}
|
||||
|
||||
static BigInteger GenerateHashInteger(const void* lpMessage, size_t cbMessage) {
|
||||
uint32_t RawHash[10];
|
||||
Hasher Sha1(HasherSha1Traits{}, lpMessage, cbMessage);
|
||||
HasherSha1Traits::DigestType Sha1Digest = Sha1.Evaluate();
|
||||
|
||||
for (size_t i = 0; i < 5; ++i) {
|
||||
RawHash[i] = _byteswap_ulong(reinterpret_cast<uint32_t*>(Sha1Digest.Bytes)[i]);
|
||||
}
|
||||
|
||||
// SHA1("") with all-zeroed initial value
|
||||
RawHash[5] = 0x0ffd8d43;
|
||||
RawHash[6] = 0xb4e33c7c;
|
||||
RawHash[7] = 0x53461bd1;
|
||||
RawHash[8] = 0x0f27a546;
|
||||
RawHash[9] = 0x1050d90d;
|
||||
|
||||
return BigInteger(false, RawHash, 15 * sizeof(uint16_t), true); // take first 240 bits
|
||||
}
|
||||
|
||||
static ECCSignature Sign(const void* lpData, size_t cbData) {
|
||||
ECCSignature Signature;
|
||||
BigInteger Hash = GenerateHashInteger(lpData, cbData);
|
||||
|
||||
while (true) {
|
||||
BigInteger Random = GenerateRandomInteger();
|
||||
|
||||
//
|
||||
// Calculate Signature.r
|
||||
//
|
||||
Signature.r.Load(false, (__ConfigType::G * Random).GetX().Dump(), true);
|
||||
Signature.r += Hash;
|
||||
Signature.r %= __ConfigType::Order;
|
||||
if (Signature.r.IsZero() || Signature.r + Random == __ConfigType::Order) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate Signature.s
|
||||
//
|
||||
Signature.s = Random - __ConfigType::PrivateKey * Signature.r;
|
||||
Signature.s %= __ConfigType::Order;
|
||||
if (Signature.s.IsZero()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return Signature;
|
||||
}
|
||||
|
||||
static void CalculateChecksum(RegisterInfo& Info) {
|
||||
Hasher Crc32(HasherCrc32Traits<0xEDB88320>{});
|
||||
Crc32.Update(Info.LicenseType.c_str(), Info.LicenseType.length());
|
||||
Crc32.Update(Info.UserName.c_str(), Info.UserName.length());
|
||||
Crc32.Update(Info.Items[0].c_str(), Info.Items[0].length());
|
||||
Crc32.Update(Info.Items[1].c_str(), Info.Items[1].length());
|
||||
Crc32.Update(Info.Items[2].c_str(), Info.Items[2].length());
|
||||
Crc32.Update(Info.Items[3].c_str(), Info.Items[3].length());
|
||||
Info.Checksum = ~Crc32.Evaluate();
|
||||
}
|
||||
public:
|
||||
|
||||
template<typename... ArgTypes>
|
||||
static inline std::string HelperStringFormat(const char* lpszFormat, ArgTypes&& ... Args) {
|
||||
std::string s(snprintf(nullptr, 0, lpszFormat, std::forward<ArgTypes>(Args)...) + 1, '\x00');
|
||||
|
||||
snprintf(s.data(), s.size(), lpszFormat, std::forward<ArgTypes>(Args)...);
|
||||
while (s.back() == '\x00') {
|
||||
s.pop_back();
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static RegisterInfo GenerateRegisterInfo(const char* lpszUserName, const char* lpszLicenseType) {
|
||||
RegisterInfo RegInfo;
|
||||
std::string temp;
|
||||
|
||||
RegInfo.UserName = lpszUserName;
|
||||
RegInfo.LicenseType = lpszLicenseType;
|
||||
|
||||
temp = GeneratePublicKeySM2CompressedFormat(lpszUserName);
|
||||
RegInfo.Items[3] = HelperStringFormat("60%.48s", temp.c_str());
|
||||
RegInfo.Items[0] = GeneratePublicKeySM2CompressedFormat(RegInfo.Items[3].c_str());
|
||||
RegInfo.UID = HelperStringFormat("%.16s%.4s", temp.c_str() + 48, RegInfo.Items[0].c_str());
|
||||
|
||||
while (true) {
|
||||
auto LicenseTypeSignature = Sign(RegInfo.LicenseType.c_str(), RegInfo.LicenseType.length());
|
||||
auto LicenseTypeSignatureR = LicenseTypeSignature.r.ToString(16, true);
|
||||
auto LicenseTypeSignatureS = LicenseTypeSignature.s.ToString(16, true);
|
||||
if (LicenseTypeSignatureR.length() <= 60 && LicenseTypeSignatureS.length() <= 60) {
|
||||
RegInfo.Items[1] = HelperStringFormat("60%060s%060s", LicenseTypeSignatureS.c_str(), LicenseTypeSignatureR.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
temp = RegInfo.UserName + RegInfo.Items[0];
|
||||
while (true) {
|
||||
auto UserNameSignature = Sign(temp.c_str(), temp.length());
|
||||
auto UserNameSignatureR = UserNameSignature.r.ToString(16, true);
|
||||
auto UserNameSignatureS = UserNameSignature.s.ToString(16, true);
|
||||
if (UserNameSignatureR.length() <= 60 || UserNameSignatureS.length() <= 60) {
|
||||
RegInfo.Items[2] = HelperStringFormat("60%060s%060s", UserNameSignatureS.c_str(), UserNameSignatureR.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CalculateChecksum(RegInfo);
|
||||
|
||||
RegInfo.HexData = HelperStringFormat(
|
||||
"%zd%zd%zd%zd%s%s%s%s%010lu",
|
||||
RegInfo.Items[0].length(),
|
||||
RegInfo.Items[1].length(),
|
||||
RegInfo.Items[2].length(),
|
||||
RegInfo.Items[3].length(),
|
||||
RegInfo.Items[0].c_str(),
|
||||
RegInfo.Items[1].c_str(),
|
||||
RegInfo.Items[2].c_str(),
|
||||
RegInfo.Items[3].c_str(),
|
||||
RegInfo.Checksum
|
||||
);
|
||||
if (RegInfo.HexData.length() % 54 != 0) {
|
||||
throw std::runtime_error("InternalError: The length of register data is not correct.");
|
||||
}
|
||||
|
||||
return RegInfo;
|
||||
}
|
||||
};
|
||||
74
_tmain.cpp
Normal file
74
_tmain.cpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#include <tchar.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include <locale.h>
|
||||
#include "WinRarConfig.hpp"
|
||||
#include "WinRarKeygen.hpp"
|
||||
#include <system_error>
|
||||
|
||||
void Help() {
|
||||
_putts(TEXT("Usage:"));
|
||||
_putts(TEXT(" winrar-keygen.exe <your name> <license type>"));
|
||||
_putts(TEXT(""));
|
||||
_putts(TEXT("Example:"));
|
||||
_putts(TEXT(""));
|
||||
_putts(TEXT(" winrar-keygen.exe \"Rebecca Morrison\" \"Single PC usage license\""));
|
||||
_putts(TEXT(" or:"));
|
||||
_putts(TEXT(" winrar-keygen.exe \"Rebecca Morrison\" \"Single PC usage license\" > rarreg.key\n"));
|
||||
}
|
||||
|
||||
void PrintRegisterInfo(const WinRarKeygen<WinRarConfig>::RegisterInfo& Info) {
|
||||
_tprintf_s(TEXT("%hs\n"), "RAR registration data");
|
||||
_tprintf_s(TEXT("%hs\n"), Info.UserName.c_str());
|
||||
_tprintf_s(TEXT("%hs\n"), Info.LicenseType.c_str());
|
||||
_tprintf_s(TEXT("UID=%hs\n"), Info.UID.c_str());
|
||||
for (size_t i = 0; i < Info.HexData.length(); i += 54) {
|
||||
_tprintf_s(TEXT("%.54hs\n"), Info.HexData.c_str() + i);
|
||||
}
|
||||
}
|
||||
|
||||
std::string ToACP(PCWSTR lpszUnicodeString) {
|
||||
int len;
|
||||
|
||||
len = WideCharToMultiByte(CP_ACP, 0, lpszUnicodeString, -1, NULL, 0, NULL, NULL);
|
||||
if (len == 0) {
|
||||
auto err = GetLastError();
|
||||
throw std::system_error(err, std::system_category());
|
||||
}
|
||||
|
||||
std::string Result(len, '\x00');
|
||||
|
||||
len = WideCharToMultiByte(CP_ACP, 0, lpszUnicodeString, -1, Result.data(), static_cast<int>(Result.length()), NULL, NULL);
|
||||
if (len == 0) {
|
||||
auto err = GetLastError();
|
||||
throw std::system_error(err, std::system_category());
|
||||
}
|
||||
|
||||
while (Result.back() == '\x00') {
|
||||
Result.pop_back();
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
int _tmain(int argc, PTSTR argv[]) {
|
||||
setlocale(LC_ALL, "");
|
||||
if (argc == 3) {
|
||||
try {
|
||||
PrintRegisterInfo(
|
||||
#if defined(_UNICODE) || defined(UNICODE)
|
||||
WinRarKeygen<WinRarConfig>::GenerateRegisterInfo(ToACP(argv[1]).c_str(), ToACP(argv[2]).c_str())
|
||||
#else
|
||||
WinRarKeygen<WinRarConfig>::GenerateRegisterInfo(argv[1], argv[2])
|
||||
#endif
|
||||
);
|
||||
} catch (std::exception& e) {
|
||||
_tprintf_s(TEXT("%hs\n"), e.what());
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
Help();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIN
bin/x64-Release/winrar-keygen.exe
Normal file
BIN
bin/x64-Release/winrar-keygen.exe
Normal file
Binary file not shown.
BIN
bin/x64-Release/winrar-keygen.iobj
Normal file
BIN
bin/x64-Release/winrar-keygen.iobj
Normal file
Binary file not shown.
BIN
bin/x64-Release/winrar-keygen.ipdb
Normal file
BIN
bin/x64-Release/winrar-keygen.ipdb
Normal file
Binary file not shown.
BIN
bin/x64-Release/winrar-keygen.pdb
Normal file
BIN
bin/x64-Release/winrar-keygen.pdb
Normal file
Binary file not shown.
BIN
icon1.ico
Normal file
BIN
icon1.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 264 KiB |
BIN
icon1.png
Normal file
BIN
icon1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
obj/x64-Debug/vc142.idb
Normal file
BIN
obj/x64-Debug/vc142.idb
Normal file
Binary file not shown.
BIN
obj/x64-Debug/vc142.pdb
Normal file
BIN
obj/x64-Debug/vc142.pdb
Normal file
Binary file not shown.
0
obj/x64-Debug/winrar-keygen.Build.CppClean.log
Normal file
0
obj/x64-Debug/winrar-keygen.Build.CppClean.log
Normal file
2
obj/x64-Debug/winrar-keygen.log
Normal file
2
obj/x64-Debug/winrar-keygen.log
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
_tmain.cpp
|
||||
D:\Users\haoning\Documents\Visual Studio 2019\winrar-keygen\BigInteger.hpp(4,10): fatal error C1083: 无法打开包括文件: “gmp.h”: No such file or directory
|
||||
1
obj/x64-Debug/winrar-keygen.tlog/CL.command.1.tlog
Normal file
1
obj/x64-Debug/winrar-keygen.tlog/CL.command.1.tlog
Normal file
|
|
@ -0,0 +1 @@
|
|||
|
||||
0
obj/x64-Debug/winrar-keygen.tlog/unsuccessfulbuild
Normal file
0
obj/x64-Debug/winrar-keygen.tlog/unsuccessfulbuild
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.27.29110:TargetPlatformVersion=10.0.18362.0:
|
||||
Debug|x64|D:\Users\haoning\Documents\Visual Studio 2019\winrar-keygen\|
|
||||
0
obj/x64-Debug/winrar-keygen.vcxproj.FileListAbsolute.txt
Normal file
0
obj/x64-Debug/winrar-keygen.vcxproj.FileListAbsolute.txt
Normal file
BIN
obj/x64-Release/_tmain.obj
Normal file
BIN
obj/x64-Release/_tmain.obj
Normal file
Binary file not shown.
BIN
obj/x64-Release/vc142.pdb
Normal file
BIN
obj/x64-Release/vc142.pdb
Normal file
Binary file not shown.
1
obj/x64-Release/vcpkg.applocal.log
Normal file
1
obj/x64-Release/vcpkg.applocal.log
Normal file
|
|
@ -0,0 +1 @@
|
|||
|
||||
18
obj/x64-Release/winrar-keygen.Build.CppClean.log
Normal file
18
obj/x64-Release/winrar-keygen.Build.CppClean.log
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\obj\x64-release\vc142.pdb
|
||||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\obj\x64-release\_tmain.obj
|
||||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\bin\x64-release\winrar-keygen.exe
|
||||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\bin\x64-release\winrar-keygen.pdb
|
||||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\obj\x64-release\winrar-keygen.res
|
||||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\bin\x64-release\winrar-keygen.ipdb
|
||||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\bin\x64-release\winrar-keygen.iobj
|
||||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\obj\x64-release\vcpkg.applocal.log
|
||||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\obj\x64-release\winrar-keygen.tlog\cl.command.1.tlog
|
||||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\obj\x64-release\winrar-keygen.tlog\cl.read.1.tlog
|
||||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\obj\x64-release\winrar-keygen.tlog\cl.write.1.tlog
|
||||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\obj\x64-release\winrar-keygen.tlog\link.command.1.tlog
|
||||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\obj\x64-release\winrar-keygen.tlog\link.read.1.tlog
|
||||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\obj\x64-release\winrar-keygen.tlog\link.write.1.tlog
|
||||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\obj\x64-release\winrar-keygen.tlog\rc.command.1.tlog
|
||||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\obj\x64-release\winrar-keygen.tlog\rc.read.1.tlog
|
||||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\obj\x64-release\winrar-keygen.tlog\rc.write.1.tlog
|
||||
d:\users\haoning\documents\visual studio 2019\winrar-keygen\obj\x64-release\winrar-keygen.tlog\winrar-keygen.write.1u.tlog
|
||||
7
obj/x64-Release/winrar-keygen.exe.recipe
Normal file
7
obj/x64-Release/winrar-keygen.exe.recipe
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project>
|
||||
<ProjectOutputs>D:\Users\haoning\Documents\Visual Studio 2019\winrar-keygen\bin\x64-Release\winrar-keygen.exe</ProjectOutputs>
|
||||
<ContentFiles></ContentFiles>
|
||||
<SatelliteDlls></SatelliteDlls>
|
||||
<NonRecipeFileRefs></NonRecipeFileRefs>
|
||||
</Project>
|
||||
6
obj/x64-Release/winrar-keygen.log
Normal file
6
obj/x64-Release/winrar-keygen.log
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
_tmain.cpp
|
||||
正在生成代码
|
||||
Previous IPDB not found, fall back to full compilation.
|
||||
All 409 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
|
||||
已完成代码的生成
|
||||
winrar-keygen.vcxproj -> D:\Users\haoning\Documents\Visual Studio 2019\winrar-keygen\bin\x64-Release\winrar-keygen.exe
|
||||
BIN
obj/x64-Release/winrar-keygen.res
Normal file
BIN
obj/x64-Release/winrar-keygen.res
Normal file
Binary file not shown.
BIN
obj/x64-Release/winrar-keygen.tlog/CL.command.1.tlog
Normal file
BIN
obj/x64-Release/winrar-keygen.tlog/CL.command.1.tlog
Normal file
Binary file not shown.
BIN
obj/x64-Release/winrar-keygen.tlog/CL.read.1.tlog
Normal file
BIN
obj/x64-Release/winrar-keygen.tlog/CL.read.1.tlog
Normal file
Binary file not shown.
BIN
obj/x64-Release/winrar-keygen.tlog/CL.write.1.tlog
Normal file
BIN
obj/x64-Release/winrar-keygen.tlog/CL.write.1.tlog
Normal file
Binary file not shown.
BIN
obj/x64-Release/winrar-keygen.tlog/link.command.1.tlog
Normal file
BIN
obj/x64-Release/winrar-keygen.tlog/link.command.1.tlog
Normal file
Binary file not shown.
BIN
obj/x64-Release/winrar-keygen.tlog/link.read.1.tlog
Normal file
BIN
obj/x64-Release/winrar-keygen.tlog/link.read.1.tlog
Normal file
Binary file not shown.
BIN
obj/x64-Release/winrar-keygen.tlog/link.write.1.tlog
Normal file
BIN
obj/x64-Release/winrar-keygen.tlog/link.write.1.tlog
Normal file
Binary file not shown.
BIN
obj/x64-Release/winrar-keygen.tlog/rc.command.1.tlog
Normal file
BIN
obj/x64-Release/winrar-keygen.tlog/rc.command.1.tlog
Normal file
Binary file not shown.
BIN
obj/x64-Release/winrar-keygen.tlog/rc.read.1.tlog
Normal file
BIN
obj/x64-Release/winrar-keygen.tlog/rc.read.1.tlog
Normal file
Binary file not shown.
BIN
obj/x64-Release/winrar-keygen.tlog/rc.write.1.tlog
Normal file
BIN
obj/x64-Release/winrar-keygen.tlog/rc.write.1.tlog
Normal file
Binary file not shown.
|
|
@ -0,0 +1,2 @@
|
|||
PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.27.29110:TargetPlatformVersion=10.0.18362.0:
|
||||
Release|x64|D:\Users\haoning\Documents\Visual Studio 2019\winrar-keygen\|
|
||||
BIN
obj/x64-Release/winrar-keygen.tlog/winrar-keygen.write.1u.tlog
Normal file
BIN
obj/x64-Release/winrar-keygen.tlog/winrar-keygen.write.1u.tlog
Normal file
Binary file not shown.
16
resource.h
Normal file
16
resource.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ 生成的包含文件。
|
||||
// 供 winrar-keygen.rc 使用
|
||||
//
|
||||
#define IDI_ICON1 101
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
BIN
winrar-keygen.aps
Normal file
BIN
winrar-keygen.aps
Normal file
Binary file not shown.
110
winrar-keygen.rc
Normal file
110
winrar-keygen.rc
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "winres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// 中文(简体,中国) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
|
||||
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
|
||||
#pragma code_page(936)
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_ICON1 ICON "icon1.ico"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,0
|
||||
PRODUCTVERSION 1,0,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "GmbH"
|
||||
VALUE "FileDescription", "GmbH Keygen Tool"
|
||||
VALUE "FileVersion", "1.0.0.0"
|
||||
VALUE "InternalName", "winrar-keygen.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2020"
|
||||
VALUE "OriginalFilename", "winrar-k.exe"
|
||||
VALUE "ProductName", "WinRAR Keygen"
|
||||
VALUE "ProductVersion", "1.0.0.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // 中文(简体,中国) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
31
winrar-keygen.sln
Normal file
31
winrar-keygen.sln
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29009.5
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winrar-keygen", "winrar-keygen.vcxproj", "{2443AA55-9534-4451-9BCC-48AC0982A0CC}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Debug|x64.Build.0 = Debug|x64
|
||||
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Debug|x86.Build.0 = Debug|Win32
|
||||
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Release|x64.ActiveCfg = Release|x64
|
||||
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Release|x64.Build.0 = Release|x64
|
||||
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Release|x86.ActiveCfg = Release|Win32
|
||||
{2443AA55-9534-4451-9BCC-48AC0982A0CC}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {382D4DCF-4617-437C-B855-01180D3AF852}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
190
winrar-keygen.vcxproj
Normal file
190
winrar-keygen.vcxproj
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{2443AA55-9534-4451-9BCC-48AC0982A0CC}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>winrarkeygen</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet>
|
||||
<VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)obj\$(Platform)-$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)obj\$(Platform)-$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)obj\$(Platform)-$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)obj\$(Platform)-$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="_tmain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="BigInteger.hpp" />
|
||||
<ClInclude Include="Hasher.hpp" />
|
||||
<ClInclude Include="EllipticCurveGF2m.hpp" />
|
||||
<ClInclude Include="GaloisField.hpp" />
|
||||
<ClInclude Include="HasherSha1Traits.hpp" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="WinRarKeygen.hpp" />
|
||||
<ClInclude Include="HasherCrc32Traits.hpp" />
|
||||
<ClInclude Include="WinRarConfig.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="winrar-keygen.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="icon1.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
61
winrar-keygen.vcxproj.filters
Normal file
61
winrar-keygen.vcxproj.filters
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="_tmain.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GaloisField.hpp">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="EllipticCurveGF2m.hpp">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Hasher.hpp">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HasherCrc32Traits.hpp">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HasherSha1Traits.hpp">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BigInteger.hpp">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="WinRarKeygen.hpp">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="WinRarConfig.hpp">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="winrar-keygen.rc">
|
||||
<Filter>资源文件</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="icon1.ico">
|
||||
<Filter>资源文件</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
6
winrar-keygen.vcxproj.user
Normal file
6
winrar-keygen.vcxproj.user
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ShowAllFiles>true</ShowAllFiles>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
Loading…
Reference in a new issue