Skip to content

Commit

Permalink
some final touches, also fixed shiftEncrypt in LNL.h
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeoborotov committed Dec 18, 2022
1 parent 28ca57f commit c11bdf4
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 19 deletions.
10 changes: 3 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# About LNL
## About LNL

**LNL** (short for **long number library**) is a single-file open source C++ library for arithmetics with arbitrary length numbers. It is designed to be simple and easy to use, taking into account possible applications in cryptography and information security. Current version of LNL only supports arbitrary length integers.

**WARNING:** The library is still under development, so be careful!

## Contents

- [How to install](#how-to-install)
Expand Down Expand Up @@ -41,12 +39,12 @@ The whole library is located in the `LNL.h` header. You can find it in the `incl
## How to use

### General info
This library introduces a new namespace `LNL` (short for long number library). Inside this namespace there is a `LNL::LongInt` class (arbitrary length integer class) and some functions for mathematical operations.
This library introduces a new namespace `LNL` (short for **long number library**). Inside this namespace there is a `LNL::LongInt` class (arbitrary length integer class) and some functions for mathematical operations.

### Creating an instance
It is possible to create a `LNL::LongInt` instance in different ways: with a `short`, `int`, `long`, `long long` or with unsigned equivalents of these types. It is also possible to create an instance with a `std::string`. If you do not pass a value to the constructor then an instance is initialized with 0 by default.

If you try to initialize with a `std::string` which contains non-digit characters (except front "-") then an instance will be initialized with 0 and an error message will be printed.
If you try to initialize with a `std::string` which contains non-digit characters (except front `-`) then an instance will be initialized with 0 and an error message will be printed.

Here are some examples:
```c++
Expand Down Expand Up @@ -135,8 +133,6 @@ Using `LNL::div(x,y)` is faster than operators `/` and `%` if you know you need
### Random numbers
The `LNL::Random()` function is defined for the LongInt class. It generates a random number of indeterminate size and type LongInt.
There are multiple ways to generate random numbers in LNL:
+ `LNL::random()` generates a random number of random size (returns `LNL::LongInt`).
Expand Down
5 changes: 2 additions & 3 deletions include/LNL-unit-tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -572,11 +572,10 @@ void Test::test_shiftEncryption() {
for (long long i = 1; i <= tests; i++) {
LongInt initial = random();
LongInt msg = initial;
long long key = std::rand() % 10;

long long key = std::rand();
shiftEncrypt(msg, key);
shiftDecrypt(msg, key);
verify("shiftEncryption #" + i, initial, msg);
verify("shiftEncryption", initial, msg);
}
}

Expand Down
30 changes: 22 additions & 8 deletions include/LNL.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,10 @@ class LongInt {
bool isMillerRabinPrime() const; // Miller-Rabin primality test
factor_t factor() const; // Returns 2 factors of number
friend LongInt randomPrime(long long size); // Generates random prime for encryption algorithms
friend LongInt modPowTwo(const LongInt& li, const long long pow, const LongInt& modular);
friend LongInt modPow(const LongInt& li, LongInt pow, const LongInt& modular);
friend void shiftEncrypt(LongInt& li, long long key);
friend void shiftDecrypt(LongInt& li, long long key);
friend LongInt modPowTwo(const LongInt& li, const long long pow, const LongInt& modular); // Modular exponentiation by 2 to some power
friend LongInt modPow(const LongInt& li, LongInt pow, const LongInt& modular); // Modular exponentiation
friend void shiftEncrypt(LongInt& li, long long key); // Caesar's cipher encryption
friend void shiftDecrypt(LongInt& li, long long key); // Caesar's cipher decryption
};

std::vector<int> LongInt::primes;
Expand Down Expand Up @@ -1167,6 +1167,7 @@ LongInt random() {
return randomNumber;
}

// Generates random LongInt in some range
LongInt random(const LongInt& left, const LongInt& right) {
std::random_device rd;
std::mt19937 gen(rd());
Expand Down Expand Up @@ -1206,6 +1207,7 @@ LongInt random(const LongInt& left, const LongInt& right) {
}
}

// Generates random LongInt number with specified size
LongInt random(const long long size) {
std::random_device rd;
std::mt19937 gen(rd());
Expand All @@ -1225,6 +1227,7 @@ LongInt random(const long long size) {
return result;
}

// Miller-Rabin primality test
bool LongInt::isMillerRabinPrime() const {
fillPrimes();

Expand Down Expand Up @@ -1289,6 +1292,7 @@ bool LongInt::isMillerRabinPrime() const {
return true;
}

// Returns 2 factors of number
factor_t LongInt::factor() const {
fillPrimes();

Expand Down Expand Up @@ -1323,9 +1327,7 @@ factor_t LongInt::factor() const {
return {1, *this};
}

/**
*
*/
// Generates random prime for encryption algorithms
LongInt randomPrime(long long size) {
// generate random number with size
LongInt li = random(size);
Expand All @@ -1348,6 +1350,7 @@ LongInt randomPrime(long long size) {
return li;
}

// Modular exponentiation by 2 to some power
LongInt modPowTwo(const LongInt& li, const long long pow, const LongInt& modular) {
LongInt result = li % modular;

Expand All @@ -1358,6 +1361,7 @@ LongInt modPowTwo(const LongInt& li, const long long pow, const LongInt& modular
return result;
}

// Modular exponentiation
LongInt modPow(const LongInt& li, LongInt pow, const LongInt& modular) {
if (li == 0 || modular == 0) {
return 0;
Expand All @@ -1380,15 +1384,25 @@ LongInt modPow(const LongInt& li, LongInt pow, const LongInt& modular) {
return result;
}

// Caesar's cipher encryption
void shiftEncrypt(LongInt& li, long long key) {
key %= 10;
for (long long i = 0; i < li.size(); i++) {
li._digits[i] = (li._digits[i] + key) % 10;
if (li._digits[i] < 0) {
li._digits[i] += 10;
}
}
}

// Caesar's cipher decryption
void shiftDecrypt(LongInt& li, long long key) {
key %= 10;
for (long long i = 0; i < li.size(); i++) {
li._digits[i] = (li._digits[i] - key + 10) % 10;
li._digits[i] = (li._digits[i] - key) % 10;
if (li._digits[i] < 0) {
li._digits[i] += 10;
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion source/benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

int main(int argc, char *argv[]) {
auto begin = std::chrono::steady_clock::now();
LNL::pow(LNL::LongInt(2), LNL::LongInt(5000));
LNL::pow(LNL::LongInt(2), LNL::LongInt(1000));
auto end = std::chrono::steady_clock::now();
auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin);
std::cout << elapsedTime.count();
Expand Down

0 comments on commit c11bdf4

Please sign in to comment.