1*2175Sjp161948=pod 2*2175Sjp161948 3*2175Sjp161948=head1 NAME 4*2175Sjp161948 5*2175Sjp161948BN_mod_mul_reciprocal, BN_div_recp, BN_RECP_CTX_new, BN_RECP_CTX_init, 6*2175Sjp161948BN_RECP_CTX_free, BN_RECP_CTX_set - modular multiplication using 7*2175Sjp161948reciprocal 8*2175Sjp161948 9*2175Sjp161948=head1 SYNOPSIS 10*2175Sjp161948 11*2175Sjp161948 #include <openssl/bn.h> 12*2175Sjp161948 13*2175Sjp161948 BN_RECP_CTX *BN_RECP_CTX_new(void); 14*2175Sjp161948 void BN_RECP_CTX_init(BN_RECP_CTX *recp); 15*2175Sjp161948 void BN_RECP_CTX_free(BN_RECP_CTX *recp); 16*2175Sjp161948 17*2175Sjp161948 int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *m, BN_CTX *ctx); 18*2175Sjp161948 19*2175Sjp161948 int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *a, BN_RECP_CTX *recp, 20*2175Sjp161948 BN_CTX *ctx); 21*2175Sjp161948 22*2175Sjp161948 int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *a, BIGNUM *b, 23*2175Sjp161948 BN_RECP_CTX *recp, BN_CTX *ctx); 24*2175Sjp161948 25*2175Sjp161948=head1 DESCRIPTION 26*2175Sjp161948 27*2175Sjp161948BN_mod_mul_reciprocal() can be used to perform an efficient 28*2175Sjp161948L<BN_mod_mul(3)|BN_mod_mul(3)> operation when the operation will be performed 29*2175Sjp161948repeatedly with the same modulus. It computes B<r>=(B<a>*B<b>)%B<m> 30*2175Sjp161948using B<recp>=1/B<m>, which is set as described below. B<ctx> is a 31*2175Sjp161948previously allocated B<BN_CTX> used for temporary variables. 32*2175Sjp161948 33*2175Sjp161948BN_RECP_CTX_new() allocates and initializes a B<BN_RECP> structure. 34*2175Sjp161948BN_RECP_CTX_init() initializes an existing uninitialized B<BN_RECP>. 35*2175Sjp161948 36*2175Sjp161948BN_RECP_CTX_free() frees the components of the B<BN_RECP>, and, if it 37*2175Sjp161948was created by BN_RECP_CTX_new(), also the structure itself. 38*2175Sjp161948 39*2175Sjp161948BN_RECP_CTX_set() stores B<m> in B<recp> and sets it up for computing 40*2175Sjp1619481/B<m> and shifting it left by BN_num_bits(B<m>)+1 to make it an 41*2175Sjp161948integer. The result and the number of bits it was shifted left will 42*2175Sjp161948later be stored in B<recp>. 43*2175Sjp161948 44*2175Sjp161948BN_div_recp() divides B<a> by B<m> using B<recp>. It places the quotient 45*2175Sjp161948in B<dv> and the remainder in B<rem>. 46*2175Sjp161948 47*2175Sjp161948The B<BN_RECP_CTX> structure is defined as follows: 48*2175Sjp161948 49*2175Sjp161948 typedef struct bn_recp_ctx_st 50*2175Sjp161948 { 51*2175Sjp161948 BIGNUM N; /* the divisor */ 52*2175Sjp161948 BIGNUM Nr; /* the reciprocal */ 53*2175Sjp161948 int num_bits; 54*2175Sjp161948 int shift; 55*2175Sjp161948 int flags; 56*2175Sjp161948 } BN_RECP_CTX; 57*2175Sjp161948 58*2175Sjp161948It cannot be shared between threads. 59*2175Sjp161948 60*2175Sjp161948=head1 RETURN VALUES 61*2175Sjp161948 62*2175Sjp161948BN_RECP_CTX_new() returns the newly allocated B<BN_RECP_CTX>, and NULL 63*2175Sjp161948on error. 64*2175Sjp161948 65*2175Sjp161948BN_RECP_CTX_init() and BN_RECP_CTX_free() have no return values. 66*2175Sjp161948 67*2175Sjp161948For the other functions, 1 is returned for success, 0 on error. 68*2175Sjp161948The error codes can be obtained by L<ERR_get_error(3)|ERR_get_error(3)>. 69*2175Sjp161948 70*2175Sjp161948=head1 SEE ALSO 71*2175Sjp161948 72*2175Sjp161948L<bn(3)|bn(3)>, L<ERR_get_error(3)|ERR_get_error(3)>, L<BN_add(3)|BN_add(3)>, 73*2175Sjp161948L<BN_CTX_new(3)|BN_CTX_new(3)> 74*2175Sjp161948 75*2175Sjp161948=head1 HISTORY 76*2175Sjp161948 77*2175Sjp161948B<BN_RECP_CTX> was added in SSLeay 0.9.0. Before that, the function 78*2175Sjp161948BN_reciprocal() was used instead, and the BN_mod_mul_reciprocal() 79*2175Sjp161948arguments were different. 80*2175Sjp161948 81*2175Sjp161948=cut 82