/** \file utils.cpp \author \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 utils */ #include "utils.h" #include #include #include #include #include //TODO: this is bad, fix occurrences of ceil_log2 and replace by ceil_log2_min1 where log(1) = 1 is necessary. For all else use ceil_log2_real uint32_t ceil_log2(int bits) { if (bits == 1) return 1; int targetlevel = 0, bitstemp = bits; while (bitstemp >>= 1) ++targetlevel; return targetlevel + ((1 << targetlevel) < bits); } uint32_t ceil_log2_min1(int bits) { if (bits <= 1) return 1; int targetlevel = 0, bitstemp = bits; while (bitstemp >>= 1) ++targetlevel; return targetlevel + ((1 << targetlevel) < bits); } uint32_t ceil_log2_real(int bits) { if (bits == 1) return 0; int targetlevel = 0, bitstemp = bits; while (bitstemp >>= 1) ++targetlevel; return targetlevel + ((1 << targetlevel) < bits); } uint32_t floor_log2(int bits) { if (bits == 1) return 1; int targetlevel = 0; while (bits >>= 1) ++targetlevel; return targetlevel; } /** * returns a 4-byte value from dev/random */ uint32_t aby_rand() { int frandom = open("/dev/random", O_RDONLY); if (frandom < 0) { std::cerr << "Error in opening /dev/random: utils.h:aby_rand()" << std::endl; exit(1); } else { char data[4]; size_t len = 0; while (len < sizeof data) { ssize_t result = read(frandom, data + len, (sizeof data) - len); if (result < 0) { std::cerr << "Error in generating random number: utils.h:aby_rand()" << std::endl; exit(1); } len += result; } close(frandom); return *((uint32_t*) data); } return 0; } /** * returns a random mpz_t with bitlen len generated from dev/urandom */ void aby_prng(mpz_t rnd, mp_bitcnt_t bitlen) { size_t byte_count = ceil_divide(bitlen, 8); char * data; int furandom = open("/dev/urandom", O_RDONLY); if (furandom < 0) { std::cerr << "Error in opening /dev/urandom: utils.cpp:aby_prng()" << std::endl; exit(1); } else { data = (char*) malloc(sizeof(*data) * byte_count); size_t len = 0; while (len < byte_count) { ssize_t result = read(furandom, data + len, byte_count - len); if (result < 0) { std::cerr << "Error in generating random number: utils.cpp:aby_prng()" << std::endl; exit(1); } len += result; } close(furandom); } mpz_import(rnd, byte_count, 1, sizeof(*data), 0, 0, data); //set MSBs to zero, if we are not working on full bytes if (bitlen % 8) { for (uint8_t i = 0; i < 8 - bitlen % 8; ++i) { mpz_clrbit(rnd, byte_count * 8 - i - 1); } } free(data); }