/* * RELIC is an Efficient LIbrary for Cryptography * Copyright (c) 2009 RELIC Authors * * This file is part of RELIC. RELIC is legal property of its developers, * whose names are not listed here. Please refer to the COPYRIGHT file * for contact information. * * RELIC is free software; you can redistribute it and/or modify it under the * terms of the version 2.1 (or later) of the GNU Lesser General Public License * as published by the Free Software Foundation; or version 2.0 of the Apache * License as published by the Apache Software Foundation. See the LICENSE files * for more details. * * RELIC 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 LICENSE files for more details. * * You should have received a copy of the GNU Lesser General Public or the * Apache License along with RELIC. If not, see * or . */ /** * @file * * Interface of the low-level multiple precision integer arithmetic module. * * All functions assume that the destination has enough capacity to store * the result of the computation. * * @ingroup bn */ #ifndef RLC_BN_LOW_H #define RLC_BN_LOW_H /*============================================================================*/ /* Constant definitions */ /*============================================================================*/ #ifdef ASM #include "relic_conf.h" #if (BN_PRECI % WSIZE) > 0 #define RLC_BN_DIGS (BN_PRECI/WSIZE + 1) #else #define RLC_BN_DIGS (BN_PRECI/WSIZE) #endif #if BN_MAGNI == DOUBLE #define RLC_BN_SIZE (2 * RLC_BN_DIGS + 2) #elif BN_MAGNI == CARRY #define RLC_BN_SIZE ((RLC_BN_DIGS + 1) #elif BN_MAGNI == SINGLE #define RLC_BN_SIZE (RLC_BN_DIGS) #endif #else #include "relic_types.h" /*============================================================================*/ /* Function prototypes */ /*============================================================================*/ /** * Adds a digit to a digit vector. Computes c = a + digit. * * @param[out] c - the result. * @param[in] a - the first digit vector to add. * @param[in] digit - the digit to add. * @param[in] size - the number of digits in the first operand. * @return the carry of the last digit addition. */ dig_t bn_add1_low(dig_t *c, const dig_t *a, const dig_t digit, const int size); /** * Adds two digit vectors of the same size. Computes c = a + b. * * @param[out] c - the result. * @param[in] a - the first digit vector to add. * @param[in] b - the second digit vector to add. * @param[in] size - the number of digits to add. * @return the carry of the last digit addition. */ dig_t bn_addn_low(dig_t *c, const dig_t *a, const dig_t *b, int size); /** * Subtracts a digit from a digit vector. Computes c = a - digit. * * @param[out] c - the result. * @param[in] a - the digit vector. * @param[in] digit - the digit to subtract. * @param[in] size - the number of digits in a. * @return the carry of the last digit subtraction. */ dig_t bn_sub1_low(dig_t *c, const dig_t *a, dig_t digit, int size); /** * Subtracts a digit vector from another digit vector. Computes c = a - b. * * @param[out] c - the result. * @param[in] a - the digit vector. * @param[in] b - the digit vector to subtract. * @param[in] size - the number of digits to subtract. * @return the carry of the last digit subtraction. */ dig_t bn_subn_low(dig_t *c, const dig_t *a, const dig_t *b, int size); /** * Compares two digits. * * @param[in] a - the first digit to compare. * @param[in] b - the second digit to compare. * @return BN_LT if a < b, BN_EQ if a == b and BN_GT if a > b. */ int bn_cmp1_low(dig_t a, dig_t b); /** * Compares two digit vectors of the same size. * * @param[in] a - the first digit vector to compare. * @param[in] b - the second digit vector to compare. * @param[in] size - the number of digits to compare. * @return BN_LT if a < b, BN_EQ if a == b and BN_GT if a > b. */ int bn_cmpn_low(const dig_t *a, const dig_t *b, int size); /** * Shifts a digit vector to the left by 1 bit. Computes c = a << 1. * * @param[out] c - the result * @param[in] a - the digit vector to shift. * @param[in] size - the number of digits to shift. * @return the carry of the last digit shift. */ dig_t bn_lsh1_low(dig_t *c, const dig_t *a, int size); /** * Shifts a digit vector to the left by an amount smaller than a digit. Computes * c = a << bits. * * @param[out] c - the result * @param[in] a - the digit vector to shift. * @param[in] size - the number of digits to shift. * @param[in] bits - the shift amount. * @return the carry of the last digit shift. */ dig_t bn_lshb_low(dig_t *c, const dig_t *a, int size, int bits); /** * Shifts a digit vector to the right by 1 bit. Computes c = a >> 1. * * @param[out] c - the result * @param[in] a - the digit vector to shift. * @param[in] size - the number of digits to shift. * @return the carry of the last digit shift. */ dig_t bn_rsh1_low(dig_t *c, const dig_t *a, int size); /** * Shifts a digit vector to the right by an amount smaller than a digit. * Computes c = a >> bits. * * @param[out] c - the result * @param[in] a - the digit vector to shift. * @param[in] size - the number of digits to shift. * @param[in] bits - the shift amount. * @return the carry of the last digit shift. */ dig_t bn_rshb_low(dig_t *c, const dig_t *a, int size, int bits); /** * Multiplies a digit vector by a digit and adds this result to another digit * vector. Computes c = c + a * digit. * * @param[out] c - the result. * @param[in] a - the digit vector to multiply. * @param[in] digit - the digit to multiply. * @param[in] size - the number of digits to multiply. * @return the carry of the last addition. */ dig_t bn_mula_low(dig_t *c, const dig_t *a, dig_t digit, int size); /** * Multiplies a digit vector by a digit and stores this result in another digit * vector. Computes c = a * digit. * * @param[out] c - the result. * @param[in] a - the first digit vector to multiply. * @param[in] digit - the digit to multiply. * @param[in] size - the number of digits to multiply. * @return the most significant digit. */ dig_t bn_mul1_low(dig_t *c, const dig_t *a, dig_t digit, int size); /** * Multiplies two digit vectors of the same size. Computes c = a * b. * * @param[out] c - the result. * @param[in] a - the first digit vector to multiply. * @param[in] b - the second digit vector to multiply. * @param[in] size - the number of digits to multiply. */ void bn_muln_low(dig_t *c, const dig_t *a, const dig_t *b, int size); /** * Multiplies two digit vectors of different sizes, with sa > sb. Computes * c = a * b. This function outputs as result only the digits between low and * high, inclusive, with high > sa and low < sb. * * @param[out] c - the result. * @param[in] a - the first digit vector to multiply. * @param[in] b - the second digit vector to multiply. * @param[in] sa - the number of digits in the first operand. * @param[in] sb - the number of digits in the second operand. * @param[in] low - the first digit to compute. * @param[in] high - the last digit to compute. */ void bn_muld_low(dig_t *c, const dig_t *a, int sa, const dig_t *b, int sb, int low, int high); /** * Squares a digit vector and adds this result to another digit vector. * Computes c = c + a * a. * * @param[out] c - the result. * @param[in] a - the digit vector to square. * @param[in] size - the number of digits to square. * @return the carry of the last addition. */ dig_t bn_sqra_low(dig_t *c, const dig_t *a, int size); /** * Squares a digit vector. Computes c = a * a. * * @param[out] c - the result. * @param[in] a - the digit vector to square. * @param[in] size - the number of digits to square. */ void bn_sqrn_low(dig_t *c, const dig_t *a, int size); /** * Divides a digit vector by another digit vector. Computes c = floor(a / b) and * d = a mod b. The dividend and divisor may be destroyed inside the function. * * @param[out] c - the quotient. * @param[out] d - the remainder. * @param[in,out] a - the dividend. * @param[in] sa - the size of the dividend. * @param[in,out] b - the divisor. * @param[in] sb - the size of the divisor. */ void bn_divn_low(dig_t *c, dig_t *d, dig_t *a, int sa, dig_t *b, int sb); /** * Divides a digit vector by a digit. Computes c = floor(a / digit) and * d = a mod digit. * * @param[out] c - the quotient. * @param[out] d - the remainder. * @param[in] a - the dividend. * @param[in] size - the size of the dividend. * @param[in] digit - the divisor. */ void bn_div1_low(dig_t *c, dig_t *d, const dig_t *a, int size, dig_t digit); /** * Reduces a digit vector modulo m by Montgomery's algorithm. * * @param[out] c - the result. * @param[in] a - the digit vector to reduce. * @param[in] sa - the number of digits to reduce * @param[in] m - the modulus. * @param[in] sm - the size of the modulus. * @param[in] u - the reciprocal of the modulus. */ void bn_modn_low(dig_t *c, const dig_t *a, int sa, const dig_t *m, int sm, dig_t u); #endif /* !ASM */ #endif /* !RLC_BN_LOW_H */