Blame crypto/bn/README.pod

Packit c4476c
=pod
Packit c4476c
Packit c4476c
=head1 NAME
Packit c4476c
Packit c4476c
bn_mul_words, bn_mul_add_words, bn_sqr_words, bn_div_words,
Packit c4476c
bn_add_words, bn_sub_words, bn_mul_comba4, bn_mul_comba8,
Packit c4476c
bn_sqr_comba4, bn_sqr_comba8, bn_cmp_words, bn_mul_normal,
Packit c4476c
bn_mul_low_normal, bn_mul_recursive, bn_mul_part_recursive,
Packit c4476c
bn_mul_low_recursive, bn_sqr_normal, bn_sqr_recursive,
Packit c4476c
bn_expand, bn_wexpand, bn_expand2, bn_fix_top, bn_check_top,
Packit c4476c
bn_print, bn_dump, bn_set_max, bn_set_high, bn_set_low - BIGNUM
Packit c4476c
library internal functions
Packit c4476c
Packit c4476c
=head1 SYNOPSIS
Packit c4476c
Packit c4476c
 #include <openssl/bn.h>
Packit c4476c
Packit c4476c
 BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);
Packit c4476c
 BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num,
Packit c4476c
   BN_ULONG w);
Packit c4476c
 void     bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num);
Packit c4476c
 BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
Packit c4476c
 BN_ULONG bn_add_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,
Packit c4476c
   int num);
Packit c4476c
 BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,
Packit c4476c
   int num);
Packit c4476c
Packit c4476c
 void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
Packit c4476c
 void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
Packit c4476c
 void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a);
Packit c4476c
 void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a);
Packit c4476c
Packit c4476c
 int bn_cmp_words(BN_ULONG *a, BN_ULONG *b, int n);
Packit c4476c
Packit c4476c
 void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b,
Packit c4476c
   int nb);
Packit c4476c
 void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n);
Packit c4476c
 void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
Packit c4476c
   int dna, int dnb, BN_ULONG *tmp);
Packit c4476c
 void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b,
Packit c4476c
   int n, int tna, int tnb, BN_ULONG *tmp);
Packit c4476c
 void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b,
Packit c4476c
   int n2, BN_ULONG *tmp);
Packit c4476c
Packit c4476c
 void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp);
Packit c4476c
 void bn_sqr_recursive(BN_ULONG *r, BN_ULONG *a, int n2, BN_ULONG *tmp);
Packit c4476c
Packit c4476c
 void mul(BN_ULONG r, BN_ULONG a, BN_ULONG w, BN_ULONG c);
Packit c4476c
 void mul_add(BN_ULONG r, BN_ULONG a, BN_ULONG w, BN_ULONG c);
Packit c4476c
 void sqr(BN_ULONG r0, BN_ULONG r1, BN_ULONG a);
Packit c4476c
Packit c4476c
 BIGNUM *bn_expand(BIGNUM *a, int bits);
Packit c4476c
 BIGNUM *bn_wexpand(BIGNUM *a, int n);
Packit c4476c
 BIGNUM *bn_expand2(BIGNUM *a, int n);
Packit c4476c
 void bn_fix_top(BIGNUM *a);
Packit c4476c
Packit c4476c
 void bn_check_top(BIGNUM *a);
Packit c4476c
 void bn_print(BIGNUM *a);
Packit c4476c
 void bn_dump(BN_ULONG *d, int n);
Packit c4476c
 void bn_set_max(BIGNUM *a);
Packit c4476c
 void bn_set_high(BIGNUM *r, BIGNUM *a, int n);
Packit c4476c
 void bn_set_low(BIGNUM *r, BIGNUM *a, int n);
Packit c4476c
Packit c4476c
=head1 DESCRIPTION
Packit c4476c
Packit c4476c
This page documents the internal functions used by the OpenSSL
Packit c4476c
B<BIGNUM> implementation. They are described here to facilitate
Packit c4476c
debugging and extending the library. They are I<not> to be used by
Packit c4476c
applications.
Packit c4476c
Packit c4476c
=head2 The BIGNUM structure
Packit c4476c
Packit c4476c
 typedef struct bignum_st BIGNUM;
Packit c4476c
Packit c4476c
 struct bignum_st
Packit c4476c
        {
Packit c4476c
        BN_ULONG *d;    /* Pointer to an array of 'BN_BITS2' bit chunks. */
Packit c4476c
        int top;        /* Index of last used d +1. */
Packit c4476c
        /* The next are internal book keeping for bn_expand. */
Packit c4476c
        int dmax;       /* Size of the d array. */
Packit c4476c
        int neg;        /* one if the number is negative */
Packit c4476c
        int flags;
Packit c4476c
        };
Packit c4476c
Packit c4476c
Packit c4476c
The integer value is stored in B<d>, a malloc()ed array of words (B<BN_ULONG>),
Packit c4476c
least significant word first. A B<BN_ULONG> can be either 16, 32 or 64 bits
Packit c4476c
in size, depending on the 'number of bits' (B<BITS2>) specified in
Packit c4476c
C<openssl/bn.h>.
Packit c4476c
Packit c4476c
B<dmax> is the size of the B<d> array that has been allocated.  B<top>
Packit c4476c
is the number of words being used, so for a value of 4, bn.d[0]=4 and
Packit c4476c
bn.top=1.  B<neg> is 1 if the number is negative.  When a B<BIGNUM> is
Packit c4476c
B<0>, the B<d> field can be B<NULL> and B<top> == B<0>.
Packit c4476c
Packit c4476c
B<flags> is a bit field of flags which are defined in C<openssl/bn.h>. The
Packit c4476c
flags begin with B<BN_FLG_>. The macros BN_set_flags(b, n) and
Packit c4476c
BN_get_flags(b, n) exist to enable or fetch flag(s) B<n> from B<BIGNUM>
Packit c4476c
structure B.
Packit c4476c
Packit c4476c
Various routines in this library require the use of temporary
Packit c4476c
B<BIGNUM> variables during their execution.  Since dynamic memory
Packit c4476c
allocation to create B<BIGNUM>s is rather expensive when used in
Packit c4476c
conjunction with repeated subroutine calls, the B<BN_CTX> structure is
Packit c4476c
used.  This structure contains B<BN_CTX_NUM> B<BIGNUM>s, see
Packit c4476c
L<BN_CTX_start(3)>.
Packit c4476c
Packit c4476c
=head2 Low-level arithmetic operations
Packit c4476c
Packit c4476c
These functions are implemented in C and for several platforms in
Packit c4476c
assembly language:
Packit c4476c
Packit c4476c
bn_mul_words(B<rp>, B<ap>, B<num>, B<w>) operates on the B<num> word
Packit c4476c
arrays B<rp> and B<ap>.  It computes B<ap> * B<w>, places the result
Packit c4476c
in B<rp>, and returns the high word (carry).
Packit c4476c
Packit c4476c
bn_mul_add_words(B<rp>, B<ap>, B<num>, B<w>) operates on the B<num>
Packit c4476c
word arrays B<rp> and B<ap>.  It computes B<ap> * B<w> + B<rp>, places
Packit c4476c
the result in B<rp>, and returns the high word (carry).
Packit c4476c
Packit c4476c
bn_sqr_words(B<rp>, B<ap>, B<n>) operates on the B<num> word array
Packit c4476c
B<ap> and the 2*B<num> word array B<ap>.  It computes B<ap> * B<ap>
Packit c4476c
word-wise, and places the low and high bytes of the result in B<rp>.
Packit c4476c
Packit c4476c
bn_div_words(B<h>, B<l>, B<d>) divides the two word number (B<h>, B<l>)
Packit c4476c
by B<d> and returns the result.
Packit c4476c
Packit c4476c
bn_add_words(B<rp>, B<ap>, B<bp>, B<num>) operates on the B<num> word
Packit c4476c
arrays B<ap>, B<bp> and B<rp>.  It computes B<ap> + B<bp>, places the
Packit c4476c
result in B<rp>, and returns the high word (carry).
Packit c4476c
Packit c4476c
bn_sub_words(B<rp>, B<ap>, B<bp>, B<num>) operates on the B<num> word
Packit c4476c
arrays B<ap>, B<bp> and B<rp>.  It computes B<ap> - B<bp>, places the
Packit c4476c
result in B<rp>, and returns the carry (1 if B<bp> E<gt> B<ap>, 0
Packit c4476c
otherwise).
Packit c4476c
Packit c4476c
bn_mul_comba4(B<r>, B, B) operates on the 4 word arrays B and
Packit c4476c
B and the 8 word array B<r>.  It computes B*B and places the
Packit c4476c
result in B<r>.
Packit c4476c
Packit c4476c
bn_mul_comba8(B<r>, B, B) operates on the 8 word arrays B and
Packit c4476c
B and the 16 word array B<r>.  It computes B*B and places the
Packit c4476c
result in B<r>.
Packit c4476c
Packit c4476c
bn_sqr_comba4(B<r>, B, B) operates on the 4 word arrays B and
Packit c4476c
B and the 8 word array B<r>.
Packit c4476c
Packit c4476c
bn_sqr_comba8(B<r>, B, B) operates on the 8 word arrays B and
Packit c4476c
B and the 16 word array B<r>.
Packit c4476c
Packit c4476c
The following functions are implemented in C:
Packit c4476c
Packit c4476c
bn_cmp_words(B, B, B<n>) operates on the B<n> word arrays B
Packit c4476c
and B.  It returns 1, 0 and -1 if B is greater than, equal and
Packit c4476c
less than B.
Packit c4476c
Packit c4476c
bn_mul_normal(B<r>, B, B<na>, B, B<nb>) operates on the B<na>
Packit c4476c
word array B, the B<nb> word array B and the B<na>+B<nb> word
Packit c4476c
array B<r>.  It computes B*B and places the result in B<r>.
Packit c4476c
Packit c4476c
bn_mul_low_normal(B<r>, B, B, B<n>) operates on the B<n> word
Packit c4476c
arrays B<r>, B and B.  It computes the B<n> low words of
Packit c4476c
B*B and places the result in B<r>.
Packit c4476c
Packit c4476c
bn_mul_recursive(B<r>, B, B, B<n2>, B<dna>, B<dnb>, B<t>) operates
Packit c4476c
on the word arrays B and B of length B<n2>+B<dna> and B<n2>+B<dnb>
Packit c4476c
(B<dna> and B<dnb> are currently allowed to be 0 or negative) and the 2*B<n2>
Packit c4476c
word arrays B<r> and B<t>.  B<n2> must be a power of 2.  It computes
Packit c4476c
B*B and places the result in B<r>.
Packit c4476c
Packit c4476c
bn_mul_part_recursive(B<r>, B, B, B<n>, B<tna>, B<tnb>, B<tmp>)
Packit c4476c
operates on the word arrays B and B of length B<n>+B<tna> and
Packit c4476c
B<n>+B<tnb> and the 4*B<n> word arrays B<r> and B<tmp>.
Packit c4476c
Packit c4476c
bn_mul_low_recursive(B<r>, B, B, B<n2>, B<tmp>) operates on the
Packit c4476c
B<n2> word arrays B<r> and B<tmp> and the B<n2>/2 word arrays B
Packit c4476c
and B.
Packit c4476c
Packit c4476c
BN_mul() calls bn_mul_normal(), or an optimized implementation if the
Packit c4476c
factors have the same size: bn_mul_comba8() is used if they are 8
Packit c4476c
words long, bn_mul_recursive() if they are larger than
Packit c4476c
B<BN_MULL_SIZE_NORMAL> and the size is an exact multiple of the word
Packit c4476c
size, and bn_mul_part_recursive() for others that are larger than
Packit c4476c
B<BN_MULL_SIZE_NORMAL>.
Packit c4476c
Packit c4476c
bn_sqr_normal(B<r>, B, B<n>, B<tmp>) operates on the B<n> word array
Packit c4476c
B and the 2*B<n> word arrays B<tmp> and B<r>.
Packit c4476c
Packit c4476c
The implementations use the following macros which, depending on the
Packit c4476c
architecture, may use "long long" C operations or inline assembler.
Packit c4476c
They are defined in C<bn_local.h>.
Packit c4476c
Packit c4476c
mul(B<r>, B, B<w>, B<c>) computes B<w>*B+B<c> and places the
Packit c4476c
low word of the result in B<r> and the high word in B<c>.
Packit c4476c
Packit c4476c
mul_add(B<r>, B, B<w>, B<c>) computes B<w>*B+B<r>+B<c> and
Packit c4476c
places the low word of the result in B<r> and the high word in B<c>.
Packit c4476c
Packit c4476c
sqr(B<r0>, B<r1>, B) computes B*B and places the low word
Packit c4476c
of the result in B<r0> and the high word in B<r1>.
Packit c4476c
Packit c4476c
=head2 Size changes
Packit c4476c
Packit c4476c
bn_expand() ensures that B has enough space for a B<bits> bit
Packit c4476c
number.  bn_wexpand() ensures that B has enough space for an
Packit c4476c
B<n> word number.  If the number has to be expanded, both macros
Packit c4476c
call bn_expand2(), which allocates a new B<d> array and copies the
Packit c4476c
data.  They return B<NULL> on error, B otherwise.
Packit c4476c
Packit c4476c
The bn_fix_top() macro reduces B<a-E<gt>top> to point to the most
Packit c4476c
significant non-zero word plus one when B has shrunk.
Packit c4476c
Packit c4476c
=head2 Debugging
Packit c4476c
Packit c4476c
bn_check_top() verifies that C<((a)-E<gt>top E<gt>= 0 && (a)-E<gt>top
Packit c4476c
E<lt>= (a)-E<gt>dmax)>.  A violation will cause the program to abort.
Packit c4476c
Packit c4476c
bn_print() prints B to stderr. bn_dump() prints B<n> words at B<d>
Packit c4476c
(in reverse order, i.e. most significant word first) to stderr.
Packit c4476c
Packit c4476c
bn_set_max() makes B a static number with a B<dmax> of its current size.
Packit c4476c
This is used by bn_set_low() and bn_set_high() to make B<r> a read-only
Packit c4476c
B<BIGNUM> that contains the B<n> low or high words of B.
Packit c4476c
Packit c4476c
If B<BN_DEBUG> is not defined, bn_check_top(), bn_print(), bn_dump()
Packit c4476c
and bn_set_max() are defined as empty macros.
Packit c4476c
Packit c4476c
=head1 SEE ALSO
Packit c4476c
Packit c4476c
L<bn(3)>
Packit c4476c
Packit c4476c
=head1 COPYRIGHT
Packit c4476c
Packit c4476c
Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
Packit c4476c
Packit c4476c
Licensed under the OpenSSL license (the "License").  You may not use
Packit c4476c
this file except in compliance with the License.  You can obtain a copy
Packit c4476c
in the file LICENSE in the source distribution or at
Packit c4476c
L<https://www.openssl.org/source/license.html>.
Packit c4476c
Packit c4476c
=cut