diff --git a/cryptographic_estimators/IFEstimator/IFAlgorithms/__init__.py b/cryptographic_estimators/IFEstimator/IFAlgorithms/__init__.py
new file mode 100644
index 00000000..ce27cff9
--- /dev/null
+++ b/cryptographic_estimators/IFEstimator/IFAlgorithms/__init__.py
@@ -0,0 +1 @@
+from .gnfs import GNFS
\ No newline at end of file
diff --git a/cryptographic_estimators/IFEstimator/IFAlgorithms/gnfs.py b/cryptographic_estimators/IFEstimator/IFAlgorithms/gnfs.py
new file mode 100644
index 00000000..577205ab
--- /dev/null
+++ b/cryptographic_estimators/IFEstimator/IFAlgorithms/gnfs.py
@@ -0,0 +1,92 @@
+# ****************************************************************************
+# Copyright 2023 Technology Innovation Institute
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+# ****************************************************************************
+
+
+from ..if_algorithm import IFAlgorithm
+from ..if_problem import IFProblem
+from ..if_constants import *
+from ..if_helper import *
+from math import exp, log
+
+
+class GNFS(IFAlgorithm):
+ """
+ Construct an instance of IFAlgorithm1 estimator
+ The estimates as per Sec. 5.5.4
+ https://eprint.iacr.org/2017/1087.pdf
+
+ INPUT:
+
+ - ``problem`` -- an instance of the IFProblem class
+ """
+
+ def __init__(self, problem: IFProblem, **kwargs):
+ self._name = "GNFS"
+ super(GNFS, self).__init__(problem, **kwargs)
+
+ def _compute_time_complexity(self, parameters: dict, correctingfactor = True):
+ """
+ Return the time complexity of the algorithm for a given set of parameters
+
+ The correcting factor is per https://people.rennes.inria.fr/Aurore.Guillevic/talks/2024-07-Douala/24-07-Douala-RSA.pdf
+
+ INPUT:
+
+ - ``parameters`` -- dictionary including the parameters
+
+ """
+ n = self.problem.parameters["n"]
+ n = n/lge # n is given log2-based, convert to ln-base
+
+ k = (64 / 9) ** (1 / 3)
+
+ T = k*(n**(1 / 3))*((log(n))**(1 - 1/3))*lge
+ #T = Lfunction(1/3, k, log(n)) * lge
+
+ if correctingfactor:
+ T = T - correcting_factor
+
+ return T
+
+ def _compute_memory_complexity(self, parameters: dict):
+ """
+ Return the memory complexity of the algorithm for a given set of parameters
+
+ INPUT:
+
+ - ``parameters`` -- dictionary including the parameters
+
+ """
+ n = self.problem.parameters["n"]
+ n = n/lge
+
+ k = 2/(3 ** (2/3))
+
+ #b1 = b2
+ b1 = exp(k * (log(n) ** (1 / 3)) * (log(log(n)) ** (1-1/3)))
+
+ #B'_1 / B'_2 ( B'_1 * log(B_1) + B'_2)
+
+ b1_prime = pifunction(b1) + 1
+ b2_prime = pifunction(b1) + log(n)
+
+ T = (b1_prime / b2_prime) * (b1_prime * log(b1) + b2_prime) * lge
+
+ if correcting_factor:
+ T = T - correcting_factor
+
+ return T
\ No newline at end of file
diff --git a/cryptographic_estimators/IFEstimator/__init__.py b/cryptographic_estimators/IFEstimator/__init__.py
new file mode 100644
index 00000000..f5b4f2d2
--- /dev/null
+++ b/cryptographic_estimators/IFEstimator/__init__.py
@@ -0,0 +1,4 @@
+from .if_algorithm import IFAlgorithm
+from .if_estimator import IFEstimator
+from .if_problem import IFProblem
+from .IFAlgorithms import *
\ No newline at end of file
diff --git a/cryptographic_estimators/IFEstimator/if_algorithm.py b/cryptographic_estimators/IFEstimator/if_algorithm.py
new file mode 100644
index 00000000..69b057cf
--- /dev/null
+++ b/cryptographic_estimators/IFEstimator/if_algorithm.py
@@ -0,0 +1,34 @@
+# ****************************************************************************
+# Copyright 2023 Technology Innovation Institute
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+# ****************************************************************************
+
+
+from ..base_algorithm import BaseAlgorithm
+from .if_problem import IFProblem
+
+
+class IFAlgorithm(BaseAlgorithm):
+ def __init__(self, problem: IFProblem, **kwargs):
+ """
+ Base class for IF algorithms complexity estimator
+
+ INPUT:
+
+ - ``problem`` -- IFProblem object including all necessary parameters
+
+ """
+ super(IFAlgorithm, self).__init__(problem, **kwargs)
+ self._name = "sample_name"
\ No newline at end of file
diff --git a/cryptographic_estimators/IFEstimator/if_constants.py b/cryptographic_estimators/IFEstimator/if_constants.py
new file mode 100644
index 00000000..748d9d42
--- /dev/null
+++ b/cryptographic_estimators/IFEstimator/if_constants.py
@@ -0,0 +1,19 @@
+# ****************************************************************************
+# Copyright 2023 Technology Innovation Institute
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+# ****************************************************************************
+
+correcting_factor = 11.91 # as per https://people.rennes.inria.fr/Aurore.Guillevic/talks/2024-07-Douala/24-07-Douala-RSA.pdf
+lge = 1.44269504088896
\ No newline at end of file
diff --git a/cryptographic_estimators/IFEstimator/if_estimator.py b/cryptographic_estimators/IFEstimator/if_estimator.py
new file mode 100644
index 00000000..63444517
--- /dev/null
+++ b/cryptographic_estimators/IFEstimator/if_estimator.py
@@ -0,0 +1,59 @@
+# ****************************************************************************
+# Copyright 2023 Technology Innovation Institute
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+# ****************************************************************************
+
+
+from .if_algorithm import IFAlgorithm
+from .if_problem import IFProblem
+from ..base_estimator import BaseEstimator
+from math import inf
+
+
+class IFEstimator(BaseEstimator):
+ """
+ Construct an instance of IFEstimator
+
+ INPUT:
+
+ - ``excluded_algorithm`` -- A list/tuple of excluded algorithms (default: None)
+
+ """
+ excluded_algorithms_by_default = []
+
+ def __init__(self, n:int, memory_bound=inf, **kwargs): # Fill with parameters
+ super(IFEstimator, self).__init__(
+ IFAlgorithm,
+ IFProblem(n, memory_bound=memory_bound, **kwargs),
+ **kwargs
+ )
+
+ def table(self, show_quantum_complexity=0, show_tilde_o_time=0,
+ show_all_parameters=0, precision=1, truncate=0):
+ """
+ Print table describing the complexity of each algorithm and its optimal parameters
+
+ INPUT:
+
+ - ``show_quantum_complexity`` -- show quantum time complexity (default: False)
+ - ``show_tilde_o_time`` -- show Ō time complexity (default: False)
+ - ``show_all_parameters`` -- show all optimization parameters (default: False)
+ - ``precision`` -- number of decimal digits output (default: 1)
+ - ``truncate`` -- truncate rather than round the output (default: False)
+ """
+ super(IFEstimator, self).table(show_quantum_complexity=show_quantum_complexity,
+ show_tilde_o_time=show_tilde_o_time,
+ show_all_parameters=show_all_parameters,
+ precision=precision, truncate=truncate)
diff --git a/cryptographic_estimators/IFEstimator/if_helper.py b/cryptographic_estimators/IFEstimator/if_helper.py
new file mode 100644
index 00000000..56782d1d
--- /dev/null
+++ b/cryptographic_estimators/IFEstimator/if_helper.py
@@ -0,0 +1,31 @@
+# ****************************************************************************
+# Copyright 2023 Technology Innovation Institute
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+# ****************************************************************************
+from math import log
+
+def Lfunction(alpha, beta, logN):
+ """
+ implements the exponent of the L-function
+ L[alpha, beta] = exp((beta+o(1))*logN**alpha * log(logN)**(1-alpha) )
+ """
+ assert alpha >= 0
+ assert beta >= 0
+ assert alpha <= 1
+ assert beta <= 1
+ return beta*(logN**alpha)*(log(logN))**(1-alpha)
+
+def pifunction(x):
+ return x/log(x)
\ No newline at end of file
diff --git a/cryptographic_estimators/IFEstimator/if_problem.py b/cryptographic_estimators/IFEstimator/if_problem.py
new file mode 100644
index 00000000..b9127b8c
--- /dev/null
+++ b/cryptographic_estimators/IFEstimator/if_problem.py
@@ -0,0 +1,72 @@
+# ****************************************************************************
+# Copyright 2023 Technology Innovation Institute
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+# ****************************************************************************
+
+
+from ..base_problem import BaseProblem
+
+
+class IFProblem(BaseProblem):
+ """
+ Construct an instance of IFProblem. Contains the parameters to optimize
+ over.
+
+ INPUT:
+ - Fill with parameters
+
+ """
+
+ def __init__(self, n:int , **kwargs): # Fill with parameters
+ super().__init__(**kwargs)
+ self.parameters["n"] = n
+
+ def to_bitcomplexity_time(self, basic_operations: float):
+ """
+ Return the bit-complexity corresponding to a certain amount of basic_operations
+
+ INPUT:
+
+ - ``basic_operations`` -- Number of basic operations (logarithmic)
+
+ """
+ return basic_operations
+
+ def to_bitcomplexity_memory(self, elements_to_store: float):
+ """
+ Return the memory bit-complexity associated to a given number of elements to store
+
+ INPUT:
+
+ - ``elements_to_store`` -- number of memory operations (logarithmic)
+
+ """
+ return elements_to_store
+
+ def expected_number_solutions(self):
+ """
+ Return the logarithm of the expected number of existing solutions to the problem
+
+ """
+ pass
+
+ def get_parameters(self):
+ """
+ Return the optimizations parameters
+ """
+ return list(self.parameters.values())
+
+ def __repr__(self):
+ return "IFProblem"
diff --git a/tests/test_if.py b/tests/test_if.py
new file mode 100644
index 00000000..89757a79
--- /dev/null
+++ b/tests/test_if.py
@@ -0,0 +1,3 @@
+from cryptographic_estimators.IFEstimator import *
+A = IFEstimator(n=795)
+A.table()
\ No newline at end of file