Ensure that you have the following installed on your system:
- CMake (version 3.0 or higher)
- GMP library (
libgmp
)
Follow these steps to build the project:
-
Clone the repository
git clone git@github.com:lollerfirst/libmg.git cd libmg
-
Create a build directory
mkdir build cd build
-
Run CMake
cmake ..
-
Build the project
make
After the build is complete, you will find the executables test_mg
and poc_fhe
in the build
directory. You can run them using:
./test_mg
./poc_fhe
You will also find the static library:
libmg.a
If you encounter the following error:
libgmp is not installed. Please install libgmp.
It means that the GMP library is not found on your system. Install it using your package manager. For example, on Debian-based systems:
sudo apt-get install libgmp-dev
On Red Hat-based systems:
sudo yum install gmp-devel
This library provides functionality for performing Montgomery reductions, which are useful in modular arithmetic operations, particularly in cryptographic applications.
Before using the Montgomery reduction functions, you must initialize the mg_t
structure. There are two initialization functions available:
-
Standard Initialization
mg_t mg; mpz_t n; mpz_init_set_str(n, "YOUR_MODULUS_HERE", 10); // Set your modulus here mg_init(&mg, n); mpz_clear(n);
-
Initialization with a Specific Value for
r
mg_t mg; mpz_t r, n; mpz_init_set_str(r, "YOUR_R_HERE", 10); // Set your r here mpz_init_set_str(n, "YOUR_MODULUS_HERE", 10); // Set your modulus here mg_init_r(&mg, r, n); mpz_clear(r); mpz_clear(n);
To work with numbers in Montgomery form, use the following functions:
-
Convert to Montgomery Form
mpz_t x; mpz_init_set_str(x, "YOUR_NUMBER_HERE", 10); // Set your number here mg_i2mg(&mg, x);
-
Convert from Montgomery Form
mg_mg2i(&mg, x);
To perform a Montgomery reduction on a number x
, use the mg_redc
function:
mg_redc(&mg, x);
To print the contents of the mg_t
structure for debugging purposes, use:
print_mg_struct(&mg);
Once you are done using the Montgomery reduction library, release the resources associated with the mg_t
structure:
mg_release(&mg);
Here is a complete example that demonstrates the initialization, conversion, reduction, and cleanup:
#include <gmp.h>
#include <stdio.h>
#include "libmg.h" // Include your header file
int main() {
mg_t mg;
mpz_t n, r, x, y;
// Initialize modulus and r
mpz_init_set_str(n, "YOUR_MODULUS_HERE", 10);
mpz_init_set_str(r, "YOUR_R_HERE", 10);
// Initialize the Montgomery structure
mg_init_r(&mg, r, n);
// Initialize and set x
mpz_init_set_str(x, "YOUR_NUMBER_HERE", 10);
mpz_init_set_str(y, "YOUR_NUMBER_HERE", 10);
// Convert x to Montgomery form
mg_i2mg(&mg, x);
mg_i2mg(&mg, y);
// Perform Montgomery reduction
mpz_mul(x, x, y);
mg_redc(&mg, x);
// Convert x out of Montgomery form
mg_mg2i(&mg, x);
// Print the result
gmp_printf("Result: %Zd\n", x);
// Release resources
mg_release(&mg);
// Clear mpz_t variables
mpz_clear(n);
mpz_clear(r);
mpz_clear(x);
mpz_clear(y);
return 0;
}
Replace YOUR_MODULUS_HERE
, YOUR_R_HERE
, and YOUR_NUMBER_HERE
with appropriate values for your application.
- Ensure that the modulus
n
is a prime number for the Montgomery reduction to work correctly. - The value of
r
should be a power of two that is greater thann
.
By following these instructions, you can effectively utilize the Montgomery reduction library in your applications.
Many algorithms in number theory, like prime testing or integer factorization, and in cryptography, like RSA, require lots of operations modulo a large number.
A multiplication like
The Montgomery (modular) multiplication is a method that allows computing such multiplications faster. Instead of dividing the product and subtracting
The representative
Inside the Montgomery space you can still perform most operations as usual. You can add two elements, subtract, check for equality, and compute the GCD.
However this is not the case for multiplication.
Since normal multiplication would give us:
Therefore we need the multiplication -inside the Montgomery space- defined as:
The multiplication of two numbers in the Montgomery space requires an efficient computation of
Because
Using this identity we can write
Where
Remember that if
That means we don't really need to calculate
Turns out we can use the Montgomery form not just for its intended use case, but also to obfuscate values we want to remain private such that they preserve their structure. This in turn allows for multiplying, adding ciphertexts and producing valid ciphertext.
We pick a private and a public modulus,
We can now encrypt our values by bringing them in Montgomery form under the private modulus
Which can be done by applying REDC
to the product
Now we can broadcast the encrypted values
Now it can send back the result to the host, which will be able to decrypt with:
and get back the multiplication of the two original values!
This scheme would have been possible without the Montgomery form
In fact, here is a link to a PoC i've written on the matter: link. But the Montgomery form makes it much more feasible to use because it reduces by a lot CPU cycles needed to carry out the computations on encrypted values, especially if said computations are many!