/**
\file powmod.cpp
\author daniel.demmler@ec-spride.de
\copyright ABY - A Framework for Efficient Mixed-protocol Secure Two-party Computation
Copyright (C) 2019 ENCRYPTO Group, TU Darmstadt
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ABY 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see .
\brief PowMod Implementation
*/
#include "powmod.h"
#include
#define POWMOD_DEBUG 0
#if POWMOD_DEBUG
#include
#endif
mpz_t* m_table_g;
mpz_t* m_table_h;
mpz_t* m_prod;
mpz_t m_mod;
size_t m_numberOfElements_g, m_numberOfElements_h;
void fbpowmod_init_g(const mpz_t base, const mpz_t mod, size_t bitsize) {
m_numberOfElements_g = bitsize;
mpz_init(m_mod);
mpz_set(m_mod, mod);
m_table_g = (mpz_t*) malloc(sizeof(mpz_t) * bitsize);
for (size_t i = 0; i < bitsize; i++) {
mpz_init(m_table_g[i]);
}
mpz_set(m_table_g[0], base);
for (size_t u = 1; u < bitsize; u++) {
mpz_mul(m_table_g[u], m_table_g[u - 1], m_table_g[u - 1]);
mpz_mod(m_table_g[u], m_table_g[u], mod);
}
}
void fbpowmod_init_h(const mpz_t base, const mpz_t mod, size_t bitsize) {
m_numberOfElements_h = bitsize;
mpz_init(m_mod);
mpz_set(m_mod, mod);
m_table_h = (mpz_t*) malloc(sizeof(mpz_t) * bitsize);
for (size_t i = 0; i < bitsize; i++) {
mpz_init(m_table_h[i]);
}
mpz_set(m_table_h[0], base);
for (size_t u = 1; u < bitsize; u++) {
mpz_mul(m_table_h[u], m_table_h[u - 1], m_table_h[u - 1]);
mpz_mod(m_table_h[u], m_table_h[u], mod);
}
}
void fbpowmod_g(mpz_t result, const mpz_t exp) {
auto top = mpz_sizeinbase(exp, 2);
if (top <= m_numberOfElements_g) {
mpz_set_ui(result, 1);
for (size_t u = 0; u < top; u++) {
if (mpz_tstbit(exp, u)) {
mpz_mul(result, result, m_table_g[u]);
mpz_mod(result, result, m_mod);
}
}
} else {
printf("(g) Exponent too big for pre-computed fixed-base powmod! %zu %zu\n", top, m_numberOfElements_g);
}
}
void fbpowmod_h(mpz_t result, const mpz_t exp) {
auto top = mpz_sizeinbase(exp, 2);
if (top <= m_numberOfElements_h) {
mpz_set_ui(result, 1);
for (size_t u = 0; u < top; u++) {
if (mpz_tstbit(exp, u)) {
mpz_mul(result, result, m_table_h[u]);
mpz_mod(result, result, m_mod);
}
}
} else {
printf("Exponent too big for pre-computed fixed-base powmod! %zu %zu\n", top, m_numberOfElements_h);
}
}
void dbpowmod(mpz_t ret, const mpz_t b1, const mpz_t e1, const mpz_t b2, const mpz_t e2, const mpz_t mod) {
unsigned char index;
mpz_t prod[3];
auto size = (mpz_cmp(e1, e2) > 0) ? mpz_sizeinbase(e1, 2) : mpz_sizeinbase(e2, 2);
#if POWMOD_DEBUG
printf("size: %zu\n", size);
#endif
mpz_init_set(prod[0], b1);
mpz_init_set(prod[1], b2);
mpz_init(prod[2]);
mpz_mul(prod[2], b1, b2);
mpz_mod(prod[2], prod[2], mod);
mpz_set_ui(ret, 1);
for (ssize_t i = size - 1; i >= 0; i--) {
index = (mpz_tstbit(e2, i) << 1) + mpz_tstbit(e1, i);
#if POWMOD_DEBUG
gmp_printf("%d | %Zd", index, ret);
#endif
mpz_mul(ret, ret, ret);
mpz_mod(ret, ret, mod);
#if POWMOD_DEBUG
gmp_printf(" - sq:%Zd", ret);
#endif
if (index) {
mpz_mul(ret, prod[index - 1], ret);
mpz_mod(ret, ret, mod);
}
#if POWMOD_DEBUG
gmp_printf(" - end:%Zd\n", ret);
#endif
}
mpz_clears(prod[0], prod[1], prod[2], NULL);
}
void fbdbpowmod_init(const mpz_t b1, const mpz_t b2, const mpz_t mod, size_t) {
mpz_init(m_mod);
mpz_set(m_mod, mod);
m_prod = (mpz_t*) malloc(sizeof(mpz_t) * 3);
mpz_init_set(m_prod[0], b1);
mpz_init_set(m_prod[1], b2);
mpz_init(m_prod[2]);
mpz_mul(m_prod[2], b1, b2);
mpz_mod(m_prod[2], m_prod[2], mod);
}
void fbdbpowmod(mpz_t ret, const mpz_t e1, const mpz_t e2) {
unsigned char index;
auto size = (mpz_cmp(e1, e2) > 0) ? mpz_sizeinbase(e1, 2) : mpz_sizeinbase(e2, 2);
mpz_set_ui(ret, 1);
for (ssize_t i = size - 1; i >= 0; i--) {
index = (mpz_tstbit(e2, i) << 1) + mpz_tstbit(e1, i);
mpz_mul(ret, ret, ret);
mpz_mod(ret, ret, m_mod);
if (index) {
mpz_mul(ret, m_prod[index - 1], ret);
mpz_mod(ret, ret, m_mod);
}
}
}