I am using this function from the GMP arbitrary precision arithmetic library:
Function: void mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t a, const mpz_t b)
Set g to the greatest common divisor of a and b, and in addition set s and t to coefficients satisfying a*s + b*t = g. The value in g is always positive, even if one or both of a and b are negative (or zero if both inputs are zero). The values in s and t are chosen such that normally, abs(s) < abs(b) / (2 g) and abs(t) < abs(a) / (2 g), and these relations define s and t uniquely. There are a few exceptional cases:
If abs(a) = abs(b), then s = 0, t = sgn(b).
Otherwise, s = sgn(a) if b = 0 or abs(b) = 2 g, and t = sgn(b) if a = 0 or abs(a) = 2 g.
In all cases, s = 0 if and only if g = abs(b), i.e., if b divides a or a = b = 0.
If t is NULL then that value is not computed.
I do not need the values of 'g' or 't' and would not like to create variables for the sole purpose of passing to this function. What can I do to pass something like a placeholder to this specific function, and how can I do this in c++ in general?
You might overload the function.
void mpz_gcdext (mpz_t s, const mpz_t a, const mpz_t b)
{
mpz_t g, t;
// initialize g and t as needed
mpz_gcdext(g, s, t, a, b);
}
Does that help?
Related
Im trying to encrypt and decrypt various messages with RSA and while it is working flawlessly while d is positive, it obviously breaks when d is negative as d is supposed to be a natural number.
I am using the EXTENDED_EUCLID algorithm to find it and the code is as follows.
void EXTENDED_EUCLID(cpp_int a, cpp_int b, cpp_int&d, cpp_int&x, cpp_int&y) {
cpp_int n_d = d,
n_x = x,
n_y = y;
if(b == 0) {
d = a;
x = 1;
y = 0;
} else {
cpp_int n_a = a % b;
if (n_a < 0) n_a += b;
EXTENDED_EUCLID(b, n_a, n_d, n_x, n_y);
d = n_d;
x = n_y;
y = n_x - a / b * n_y;
}
}
The 2 lines of code before the recursive call EXTENDED_EUCLID(b, n_a, n_d, n_x, n_y); are from a solution I found on https://crypto.stackexchange.com/questions/10805/how-does-one-deal-with-a-negative-d-in-rsa. Obviously I am doing something wrong here, maybe they need to be positioned somewhere else?
The initial call of the EXTENDED_EUCLID is made with the following parameters EXTENDED_EUCLID(a, n, d, x, y); from a function named MODULAR_LINEAR_EQUATION_SOLVER. a in this case is e(public key if I'm not mistaken) and n or b in this case are φ(n).
Thank you for donating your time to this, hopefully not too silly question.
The solution was to move the 2 lines of code that are above the EXTENDED_EUCLID(b, n_a, n_d, n_x, n_y); recursive call to the function MODULAR_LINEAR_EQUATION_SOLVER, below the initial EXTENDED_EUCLID call. Many thanks to President James K. Polk.
In C++ interface of SuiteSparse, I can use
SuiteSparseQR_factorization <double> *QR;
QR = SuiteSparseQR_factorize(A) ;
to calculate QR decomposition of matrix A so that I can reuse QR for further calculation. But I wonder can I get the real Q,R directly from
this QR object?
SuiteSparse is awesome, but the interface can be confusing. Unfortunately, the methods that involve the SuiteSparseQR_factorization struct, which appear to be the most convenient, haven't worked so well for me in practice. For instance, using SuiteSparseQR_factorize and then SuiteSparseQR_qmult with a sparse matrix input argument actually converts it to a dense matrix first, which seems completely unnecessary!
Instead, use
template <typename Entry> SuiteSparse_long SuiteSparseQR
(
// inputs, not modified
int ordering, // all, except 3:given treated as 0:fixed
double tol, // only accept singletons above tol
SuiteSparse_long econ, // number of rows of C and R to return; a value
// less than the rank r of A is treated as r, and
// a value greater than m is treated as m.
int getCTX, // if 0: return Z = C of size econ-by-bncols
// if 1: return Z = C' of size bncols-by-econ
// if 2: return Z = X of size econ-by-bncols
cholmod_sparse *A, // m-by-n sparse matrix
// B is either sparse or dense. If Bsparse is non-NULL, B is sparse and
// Bdense is ignored. If Bsparse is NULL and Bdense is non-NULL, then B is
// dense. B is not present if both are NULL.
cholmod_sparse *Bsparse,
cholmod_dense *Bdense,
// output arrays, neither allocated nor defined on input.
// Z is the matrix C, C', or X
cholmod_sparse **Zsparse,
cholmod_dense **Zdense,
cholmod_sparse **R, // the R factor
SuiteSparse_long **E, // size n; fill-reducing ordering of A.
cholmod_sparse **H, // the Householder vectors (m-by-nh)
SuiteSparse_long **HPinv,// size m; row permutation for H
cholmod_dense **HTau, // size nh, Householder coefficients
// workspace and parameters
cholmod_common *cc
) ;
This method will perform the factorization and then, optionally, output (among other things) R, the matrix product Z = Q^T * B (or its transpose -- B^T * Q), or the solution of a linear system. To get Q, define B as the identity matrix. Here's an example to get Q and R.
cholmod_common Common, * cc;
cc = &Common;
cholmod_l_start(cc);
cholmod_sparse *A;//assume you have already defined this
int ordering = SPQR_ORDERING_BEST;
double tol = 0;
Long econ = A->nrow;
int getCTX = 1;// Z = (Q^T * B)^T = B^T * Q
cholmod_sparse *B = cholmod_l_speye(A->nrow, A->nrow, CHOLMOD_REAL, cc);//the identity matrix
cholmod_sparse *Q, *R;//output pointers to the Q and R sparse matrices
SuiteSparseQR<double>(ordering, tol, econ, getCTX, A, B, NULL, &Q, NULL, &R, NULL, NULL, NULL, NULL, cc);
If you want any of the other outputs to perform subsequent operations without the use of an explicitly formed Q and/or R, then you need to substitute the NULL's for additional pointers and then make calls to SuiteSparseQR_qmult.
I've implemented algorithms for finding an inverse of a polynomial as described at onboard security resourses, but these algorithms imply that GCD of poly that I want to invert and X^N - 1 is 1.
For proper NTRU implementation I need to randomly generate small polynomials and define if their inverse exist, for now I don't have such functionality.
In order to get it work i tried to implement Euclidean algorithm as described in documentation for NTRU Open Source project. But I found some things very inconsistent which bugs me off.
Division and Euclidean algorithms can be found on page 19 of named document.
So, in division algorithm the inputs are polynomials a and b. It is stated that polynomial b must be of degree N-1.
Pseudocode for division algorithm (taken from this answer):
a) Set r := a and q := 0
b) Set u := (b_N)^–1 mod p
c) While deg r >= N do
1) Set d := deg r(X)
2) Set v := u × r_d × X^(d–N)
3) Set r := r – v × b
4) Set q := q + v
d) Return q, r
In order to find GCD of two polynomials, one must call Euclidean algorithm with inputs a (some polynomial) and X^N-1. These inputs are then passed to division algorighm.
Question is: how can X^N - 1 be passed into division algorithm if it is clearly stated that second parameter should be poly with degree N-1 ?
Ignoring this issue, there's still things I do not understand:
what is N in division algorithm? Is it N from NTRU parameters or is it degree of polynomial b?
either way, how can condition c) ever be true? NTRU operates with polynomials of degree less than N
For the greater context, here is my C++ implementation of Euclidean and Division algorithms. Given the inputs a = {-1, 1, 1, 0, -1, 0, 1, 0, 0, 1, -1}, b = {-1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1}, p = 3 and N = 11 it enters endless loop inside division algorithm
using tPoly = std::deque<int>;
std::pair<tPoly, tPoly> divisionAlg(tPoly a, tPoly b, int p, int N)
{
tPoly r = a;
tPoly q{0};
int b_degree = degree(b);
int u = Helper::getInverseNumber(b[b_degree], p);
while (degree(r) >= N)
{
int d = degree(r);
tPoly v = genXDegreePoly(d-N); // X^(d-N)
v[d-N] = u*r[d]; // coefficient of v
r -= multiply(v, b, N);
q += v;
}
return {q, r};
}
struct sEucl
{
sEucl(int U=0, int V=0, int D=0)
: u{U}
, v{V}
, d{D}
{}
tPoly u;
tPoly v;
tPoly d;
};
sEucl euclidean(tPoly a, tPoly b, int p, int N)
{
sEucl res;
if ((degree(b) == 0) && (b[0] == 0))
{
res = sEucl(1, 0);
res.d = a;
Helper::printPoly(res.d);
return res;
}
tPoly u{1};
tPoly d = a;
tPoly v1{0};
tPoly v3 = b;
while ((0 != degree(v3)) && (0 != v3[0]))
{
std::pair<tPoly, tPoly> division = divisionAlg(d, v3, p, N);
tPoly q = division.first;
tPoly t3 = division.second;
tPoly t1 = u;
t1 -= PolyMath::multiply(q, v1, N);
u = v1;
d = v3;
v1 = t1;
v3 = t3;
}
d -= multiply(a, u, N);
tPoly v = divide(d, b).first;
res.u = u;
res.v = v;
res.d = d;
return res;
}
Additionally, polynomial operations used in this listing may be found at github page
I accidentally googled the answer. I don't really need to calculate GCD to pick a random invertable polynomial, I just need to choose the right amount of 1 and 0 (for binary) or -1, 0 and 1 (for ternary) for my random poly.
Please, consider this question solved.
I'm mapping a large number of floats to ints. All floats are in range [0;1] and the ints should be in range [0, M) where M = 1 << k, e.g. 256.
I care about even distribution, so I cannot use something like round (f * 255), which leaves the first and buckets with half the capacity.
So naively, one would do this:
int i = (int)(f * M);
Since this fails for f = 1.0 (leading to i = M instead of M - 1), we need to cover that separately:
int i = min (M - 1, (int)(f * M));
Instead I would like to simply do something like
int i = (int)(f * C);
where C is a float constant smaller than M that guarantees the strict inequality (int)(f * C) < M for all f in range [0;1].
Of course, we could simply set C = M - 0.001f and be done with it. But let's suppose we want to do it the right way. What exactly is C, if arbitrary integer widths rather than just 8 bit are involved? In other words:
Given an integer M > 0, what is the largest float C such that (int)C < M?
Given an integer M, what is the largest float C such that (int)C < M?
It will be std::nextafterf(M, 0).
A number of matrix expressions I have evaluate to a 1 by 1 matrix. I would like to do something like:
cv::Mat a = cv::Mat(n, m, CV_64F), b = ..., c = ...
double d = a.t() * b * c.inv(); // result happens to be 1 x 1 matrix
The way I found to do this is to write:
double d = ((cv::Mat)(a.t() * b * c.inv())).at<double>(0);
Which is a bit long and very confusing, especially if long expressions are involved.
Is there a better, clearer way to write this? can I somehow overload the operator double to apply only to 1x1 cv::MatExpr's?
Edit
A simple function to do this is of course possible, though ugly. Any more elegant solutions?
double toDouble(cv::MatExpr M) {
cv::Mat A = M;
if (A.rows != 1 || A.cols != 1) throw "Matrix is not 1 by 1!";
return A.at<double>(0);
}
What you could do is make use of the cv::Mat::dot function (documentation link), which takes two cv::Mat of same sizes and returns a double.
If the result of your operation is a 1x1 matrix, then you should be able to express it using cv::Mat::dot. For example, if a and b are nx1, the two following lines are equivalent:
double d = ((cv::Mat)(a.t() * b)).at<double>(0);
double d = a.dot(b);
One could also imagine more complex operations:
double d = (M.t()*U.inv()*a).dot(V.inv()*b);