I’m trying to implement a wrapper for running a fermat-factorization test on a public key. I’ve generated the shared library successfully using SWIG:
fermat.h
:
#ifndef FERMAT_H
#define FERMAT_H
#include <iostream>
#include <stdio.h>
#include <gmpxx.h>
class Fermat
{
private:
mpz_class key;
mpz_class ceil_sqrt(const mpz_class&);
public:
Fermat(mpz_class);
std::string test();
};
#endif
fermat.cpp
:
#include "fermat.h"
#include <iostream>
#include <sstream>
#include <gmpxx.h>
Fermat::Fermat(mpz_class n)
{
key = n;
}
std::string Fermat::test()
{
// Test logic. Not important
}
mpz_class Fermat::ceil_sqrt(const mpz_class& n)
{
// A helper function
}
I compiled this with the below Makefile and .i
file required by SWIG.
Makefile
:
all:
swig -c++ -python -v -I/usr/include/ fermat.i
python setup.py build_ext --inplace
g++ -O3 -fPIC -c -lgmp -lgmpxx fermat.cpp
g++ -O3 -fPIC -c -lgmp -lgmpxx -I/usr/include/python3.10 fermat_wrap.cxx
g++ -shared fermat.o fermat_wrap.o -lgmp -lgmpxx -o _fermat.so
fermat.i
:
%module fermat
%{
#define SWIG_FERMAT_WITH_INIT
#include "fermat.h"
%}
%include "std_string.i"
%include "fermat.h"
Now, I can include this SWIG module in my main.py
code that calls this test method. I pass the public key’s e value as a decimal number to the constructor.
import fermat as f
key_decimal = 98372489374731875343284493738234 # arbitrarily long decimal number
test_fermat = f.Fermat(key_decimal)
print(test_fermat.test())
In summary: I’m trying to pass an integer in Python to a function that accepts mpz_class
type arguments. As far as I know, there’s no native way to convert an int to mpz_class
, so this renders my SWIG module useless, unless I find a way to have the constructor accept that large integer in Python.
Running the above Python code would result in TypeError: in method 'new_Fermat', argument 1 of type 'mpz_class'
I’ve read about typemaps in SWIG, which might come in handy, but I’m not sure if they would solve my problem. I thought I’d ask for reassurance here first.