/** \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); } } }