I'm curious about how to encrypt R functions in a package so that once the package is built, the function can be called but the algorithm behind cannot be found. The algorithm is written in R.
Suppose we create a Function
in Rcpp and call it with an exported Rcpp function wrapper. The source code is a string to create an expression to be evaluated to be a Function
.
#include <Rcpp.h>
using namespace Rcpp;
ExpressionVector secret_expr("function(x) x + 1");
Function secret_fun = secret_expr.eval();
//' Secret function
//' @param x a numeric vector
//' @export
// [[Rcpp::export]]
SEXP SF(SEXP x)
{
return secret_fun(x);
}
Once the package that contains the C++ code above is built to a binary, it seems that we don't have a way to see the body of secret_fun
. However, the function body still can be revealed by calling strings package.so | grep function
in shell where package.so
is the binary of the built package.
This means that in order to hide the function body, we cannot write it directly in C++ code. I found https://stackoverflow.com/a/1360175/2906900 quite interesting so I test it with the example above:
#include "HideString.h"
#include <Rcpp.h>
using namespace Rcpp;
DEFINE_HIDDEN_STRING(Secret, 0x2f, ('f')('u')('n')('c')('t')('i')('o')('n')('(')('x')(')')('x')('+')('1'))
ExpressionVector secret_expr(GetSecret());
Function secret_fun = secret_expr.eval();
//' Secret function
//' @param x a numeric vector
//' @export
// [[Rcpp::export]]
SEXP SF(SEXP x)
{
return secret_fun(x);
}
This time I cannot find any meaningful functions via strings
and the function works exactly the same. Therefore, it seems quite possible to encrypt sensitive algorithms in this way. But I'm wondering is there an easy way to crack this?