int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
-int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b);
+int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
BN_CTX *ctx);
-int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b,BN_CTX *ctx);
+int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
int BN_sqr(BIGNUM *r, BIGNUM *a,BN_CTX *ctx);
BN_ULONG BN_mod_word(BIGNUM *a, BN_ULONG w);
BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
#include "bn_lcl.h"
/* r can == a or b */
-int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b)
+int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
{
- BIGNUM *tmp;
+ const BIGNUM *tmp;
bn_check_top(a);
bn_check_top(b);
Free(c);
}
+/* This is an internal function that should not be used in applications.
+ * It ensures that 'b' has enough room for a 'bits' bit number. It is
+ * mostly used by the various BIGNUM routines. If there is an error,
+ * NULL is returned. if not, 'b' is returned.
+ */
BIGNUM *bn_expand2(BIGNUM *b, int words)
{
BN_ULONG *A,*a;
return(ret);
}
-#define RECP_MUL_MOD
-
static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx, BN_CTX *ctx2,
BN_MONT_CTX *mont)
{
}
#if 0
-static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx)
+
+#define RECP_MUL_MOD
+
+static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx,
+ BN_CTX *unused, BN_MONT_CTX *unused2)
{
- int k,i,nb,ret= -1;
+ int k,i,ret= -1;
BIGNUM *d,*dd,*tmp;
- BIGNUM *d1,*d2,*x,*n1,*inv;
+ BIGNUM *d1,*d2,*x,*n1;
+ BN_RECP_CTX recp;
d1= &(ctx->bn[ctx->tos]);
d2= &(ctx->bn[ctx->tos+1]);
x= &(ctx->bn[ctx->tos+2]);
n1= &(ctx->bn[ctx->tos+3]);
- inv=&(ctx->bn[ctx->tos+4]);
- ctx->tos+=5;
+ ctx->tos+=4;
d=d1;
dd=d2;
/* i=BN_num_bits(n); */
#ifdef RECP_MUL_MOD
- nb=BN_reciprocal(inv,n,ctx); /**/
- if (nb == -1) goto err;
+ BN_RECP_CTX_init(&recp);
+ if (BN_RECP_CTX_set(&recp,n,ctx) <= 0) goto err;
#endif
for (i=k-1; i>=0; i--)
#ifndef RECP_MUL_MOD
if (!BN_mod_mul(dd,d,d,n,ctx)) goto err;
#else
- if (!BN_mod_mul_reciprocal(dd,d,d,n,inv,nb,ctx)) goto err;
+ if (!BN_mod_mul_reciprocal(dd,d,d,&recp,ctx)) goto err;
#endif
if ( BN_is_one(dd) &&
!BN_is_one(x) &&
#ifndef RECP_MUL_MOD
if (!BN_mod_mul(d,dd,a,n,ctx)) goto err;
#else
- if (!BN_mod_mul_reciprocal(d,dd,a,n,inv,nb,ctx)) goto err;
+ if (!BN_mod_mul_reciprocal(d,dd,a,&recp,ctx)) goto err;
#endif
}
else
else i=1;
ret=i;
err:
- ctx->tos-=5;
+ ctx->tos-=4;
+#ifdef RECP_MUL_MOD
+ BN_RECP_CTX_free(&recp);
+#endif
return(ret);
}
#endif
--- /dev/null
+=pod
+
+=head1 NAME
+
+BN_CTX_new, BN_CTX_init, BN_CTX_free - allocate and free BN_CTX structures
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ BN_CTX *BN_CTX_new(void);
+
+ void BN_CTX_init(BN_CTX *c);
+
+ void BN_CTX_free(BN_CTX *c);
+
+=head1 DESCRIPTION
+
+A B<BN_CTX> is a structure that holds temporary variables used by
+library functions. Thus, it can be avoided to create and destroy
+the temporary B<BIGNUM> objects whenever a library function is
+called.
+
+BN_CTX_new() allocated and initializes a B<BN_CTX>
+structure. BN_CTX_init() initializes an existing uninitialized
+B<BN_CTX>.
+
+BN_CTX_free() frees the components of the B<BN_CTX>, and if it was
+created by BN_CTX_new(), also the structure itself.
+
+=head1 RETURN VALUES
+
+BN_CTX_new() returns a pointer to the B<BN_CTX>. If the allocation fails,
+it returns B<NULL> and sets an error code that can be obtained by
+ERR_get_error(3).
+
+BN_CTX_init() and BN_CTX_free() have no return values.
+
+=head1 SEE ALSO
+
+bn(3), err(3), BN_add(3)
+
+=head1 HISTORY
+
+BN_CTX_new() and BN_CTX_free() are availabe in all versions on SSLeay
+and OpenSSL. BN_CTX_init() was added in SSLeay 0.9.1b.
+
+=cut
--- /dev/null
+=pod
+
+=head1 NAME
+
+BN_add, BN_sub, BN_mul, BN_div, BN_sqr, BN_mod, BN_mod_mul, BN_exp,
+BN_mod_exp, BN_gcd - Arithmetic operations on BIGNUMs
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+
+ int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+
+ int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+
+ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *a, const BIGNUM *d,
+ BN_CTX *ctx);
+
+ int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx);
+
+ int BN_mod(BIGNUM *rem, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+
+ int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m,
+ BN_CTX *ctx);
+
+ int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx);
+
+ int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+
+ int BN_gcd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+
+=head1 DESCRIPTION
+
+BN_add() adds B<a> and B<b> and places the result in B<r> (C<r=a+b>).
+B<r> may be the same B<BIGNUM> as B<a> or B<b>.
+
+BN_sub() substracts B<b> from B<a> and places the result in B<r> (C<r=a-b>).
+
+BN_mul() multiplies B<a> and B<b> and places the result in B<r> (C<r=a*b>).
+
+BN_div() divides B<a> by B<d> and places the result in B<dv> and the
+remainder in B<rem> (C<dv=a/d, rem=a%d>). Either of B<dv> and B<rem> may
+be NULL, in which case the respective value is not returned.
+
+BN_sqr() takes the square of B<a> and places the result in B<r>
+(C<r=a^2>). B<r> and B<a> may be the same B<BIGNUM>.
+This function is faster than BN_mul(r,a,a).
+
+BN_mod() find the remainder of B<a> divided by B<m> and places it in
+B<rem> (C<rem=a%m>).
+
+BN_mod_mul() multiplies B<a> by B<b> and finds the remainder when
+divided by B<m> (C<r=(a*b)%m>). B<r> may be the same B<BIGNUM> as B<a>
+or B<b>. For a more efficient algorithm, see
+L<BN_mod_mul_montgomery(3)>; for repeated computations using the same
+modulus, see L<BN_mod_mul_reciprocal(3)>.
+
+BN_exp() raises B<a> to the B<p>-th power and places the result in B<r>
+(C<r=a^p>). This function is faster than repeated applications of
+BN_mul().
+
+BN_mod_exp() computes B<a> to the B<p>-th power modulo B<m> (C<r=a^p %
+m>). This function uses less time and space than BN_exp().
+
+BN_gcd() computes the greatest common divisor of B<a> and B<b> and
+places the result in B<r>. B<r> may be the same B<BIGNUM> as B<a> or
+B<b>.
+
+For all functions, B<ctx> is a previously allocated B<BN_CTX> used for
+temporary variables; see L<BN_CTX_new(3)>.
+
+Unless noted otherwise, the result B<BIGNUM> must be different from
+the arguments.
+
+=head1 RETURN VALUES
+
+For all functions, 1 is returned for success, 0 on error. The return
+value should always be checked (e.g., C<if (!BN_add(r,a,b)) goto err;>).
+The error codes can be obtained by ERR_get_error(3).
+
+=head1 SEE ALSO
+
+bn(3), err(3), BN_CTX_new(3), BN_add_word(3), BN_set_bit(3)
+
+=head1 HISTORY
+
+BN_add(), BN_sub(), BN_div(), BN_sqr(), BN_mod(), BN_mod_mul(),
+BN_mod_exp() and BN_gcd() are available in all versions of SSLeay and
+OpenSSL. The B<ctx> argument to BN_mul() was added in SSLeay
+0.9.1b. BN_exp() appeared in SSLeay 0.9.0.
+
+=cut
--- /dev/null
+=pod
+
+=head1 NAME
+
+BN_add_word, BN_sub_word, BN_mul_word, BN_div_word, BN_mod_word - Arithmetic
+functions on BIGNUMs with integers
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ int BN_add_word(BIGNUM *a, BN_ULONG w);
+
+ int BN_sub_word(BIGNUM *a, BN_ULONG w);
+
+ int BN_mul_word(BIGNUM *a, BN_ULONG w);
+
+ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
+
+ BN_ULONG BN_mod_word(BIGNUM *a, BN_ULONG w);
+
+=head1 DESCRIPTION
+
+These functions perform arithmetic operations on BIGNUMs with unsigned
+integers. They are much more efficient than the normal BIGNUM
+arithmetic operations.
+
+BN_add_word() adds B<w> to B<a> (C<a+=w>).
+
+BN_sub_word() substracts B<w> from B<a> (C<a-=w>).
+
+BN_mul_word() multiplies B<a> and B<w> (C<a*=b>).
+
+BN_div_word() divides B<a> by B<w> (C<a/=w>) and returns the remainder.
+
+BN_mod_word() returns the remainder of B<a> divided by B<w> (C<a%m>).
+
+For BN_div_word() and BN_mod_word(), B<w> must not be 0.
+
+=head1 RETURN VALUES
+
+BN_add_word(), BN_sub_word() and BN_mul_word() return 1 for success, 0
+on error. The error codes can be obtained by ERR_get_error(3).
+
+BN_mod_word() and BN_div_word() return B<a>%B<w>.
+
+=head1 SEE ALSO
+
+bn(3), err(3), BN_add(3)
+
+=head1 HISTORY
+
+BN_add_word() and BN_mod_word() are available in all versions of
+SSLeay and OpenSSL. BN_div_word() was added in SSLeay 0.8, and
+BN_sub_word() and BN_mul_word() in SSLeay 0.9.0.
+
+=cut
--- /dev/null
+=pod
+
+=head1 NAME
+
+BN_bn2bin, BN_bin2bn, BN_bn2hex, BN_bn2dec, BN_hex2bn, BN_dec2bn,
+BN_print_fp, BN_print, BN_bn2mpi, BN_mpi2bn - Format conversions
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ int BN_bn2bin(const BIGNUM *a, unsigned char *to);
+ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
+
+ char *BN_bn2hex(const BIGNUM *a);
+ char *BN_bn2dec(const BIGNUM *a);
+ int BN_hex2bn(BIGNUM **a, const char *str);
+ int BN_dec2bn(BIGNUM **a, const char *str);
+
+ int BN_print_fp(FILE *fp, BIGNUM *a);
+ int BN_print(BIO *fp, const BIGNUM *a);
+
+ int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
+ BIGNUM *BN_mpi2bn(unsigned char *s, int len, BIGNUM *ret);
+
+=head1 DESCRIPTION
+
+BN_bn2bin() converts the absolute value of B<a> into big-endian form
+and stores it at B<to>. B<to> must point to BN_num_bytes(B<a>) bytes of
+memory.
+
+BN_bin2bn() converts the positive integer in big-endian form of length
+B<len> at B<s> into a B<BIGNUM> and places it in B<ret>. If B<ret> is
+NULL, a new B<BIGNUM> is created.
+
+BN_bn2hex() and BN_bn2dec() return printable strings containing the
+hexadecimal and decimal encoding of B<a> respectively. For negative
+numbers, the string is prefaced with a leading '-'. The string must be
+Free()d later.
+
+BN_hex2bn() converts the string B<str> containing a hexadecimal number
+to a B<BIGNUM> and stores it in **B<bn>. If *B<bn> is NULL, a new
+B<BIGNUM> is created. If B<bn> is NULL, it only computes the number's
+length in hexadecimal digits. If the string starts with '-', the
+number is negative. BN_dec2bn() is the same using the decimal system.
+
+BN_print_fp() and BN_print() write the hexadecimal encoding of B<a>,
+with a leading '-' for negative numbers, to the B<FILE> or B<BIO>
+B<fp>.
+
+BN_bn2mpi() and BN_mpi2bn() convert B<BIGNUM>s from and to a format
+that consists of the number's length in bytes represented as a 3-byte
+big-endian number, and the number itself in big-endian format, where
+the most significant bit signals a negative number (the representation
+of numbers with the MSB set is prefixed with null byte).
+
+BN_bn2mpi() stores the representation of B<a> at B<to>, where B<to>
+must be large enough to hold the result. The size can be determined by
+calling BN_bn2mpi(B<a>, NULL).
+
+BN_mpi2bn() converts the B<len> bytes long representation at B<s> to
+a B<BIGNUM> and stores it ar B<ret>, or in a newly allocated B<BIGNUM>
+if B<ret> is NULL.
+
+=head1 RETURN VALUES
+
+BN_bn2bin() returns the length of the big-endian number placed at B<to>.
+BN_bin2bn() returns the B<BIGNUM>, NULL on error.
+
+BN_bn2hex() and BN_bn2dec() return a null-terminated string, or NULL
+on error. BN_hex2bn() and BN_dec2bn() return the number's length in
+hexadecimal or decimal digits, and 0 on error.
+
+BN_print_fp() and BN_print() return 1 on success, 0 on write errors.
+
+BN_bn2mpi() returns the length of the representation. BN_mpi2bn()
+returns the B<BIGNUM>, and NULL on error.
+
+The error codes can be obtained by ERR_get_error(3).
+
+=head1 SEE ALSO
+
+bn(3), err(3), BN_zero(3), ASN1_INTEGER_to_BN(3), BN_num_bytes(3)
+
+=head1 HISTORY
+
+BN_bn2bin(), BN_bin2bn(), BN_print_fp() and BN_print() are available
+in all versions of SSLeay and OpenSSL.
+
+BN_bn2hex(), BN_bn2dec(), BN_hex2bn(), BN_dec2bn(), BN_bn2mpi() and
+BN_mpi2bn() were added in SSLeay 0.9.0.
+
+=cut
--- /dev/null
+=pod
+
+=head1 NAME
+
+BN_cmp, BN_ucmp, BN_is_zero, BN_is_one, BN_is_word, BN_is_odd - BIGNUM comparison and test functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ int BN_cmp(BIGNUM *a, BIGNUM *b);
+ int BN_ucmp(BIGNUM *a, BIGNUM *b);
+
+ int BN_is_zero(BIGNUM *a);
+ int BN_is_one(BIGNUM *a);
+ int BN_is_word(BIGNUM *a, BN_ULONG w);
+ int BN_is_odd(BIGNUM *a);
+
+=head1 DESCRIPTION
+
+BN_cmp() compares the numbers B<a> and B<b>. BN_ucmp() compares their
+absolute values.
+
+BN_is_zero(), BN_is_one() and BN_is_word() test if B<a> equals 0, 1,
+or B<w> respectively. BN_is_odd() tests if a is odd.
+
+BN_is_zero(), BN_is_one(), BN_is_word() and BN_is_odd() are macros.
+
+=head1 RETURN VALUES
+
+BN_cmp() returns -1 if B<a> E<lt> B<b>, 0 if B<a> == B<b> and 1 if
+B<a> E<gt> B<b>. BN_ucmp() is the same using the absolute values
+of B<a> and B<b>.
+
+BN_is_zero(), BN_is_one() BN_is_word() and BN_is_odd() return 1 if
+the condition is true, 0 otherwise.
+
+=head1 SEE ALSO
+
+bn(3)
+
+=head1 HISTORY
+
+BN_cmp(), BN_ucmp(), BN_is_zero(), BN_is_one() and BN_is_word() are
+available in all versions of SSLeay and OpenSSL.
+BN_is_odd() was added in SSLeay 0.8.
+
+=cut
--- /dev/null
+=pod
+
+=head1 NAME
+
+BN_copy, BN_dup - copy BIGNUMs
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ BIGNUM *BN_copy(BIGNUM *to, const BIGNUM *from);
+
+ BIGNUM *BN_dup(const BIGNUM *from);
+
+=head1 DESCRIPTION
+
+BN_copy() copies B<from> to B<to>. BN_dup() creates a new B<BIGNUM>
+containing the value B<from>.
+
+=head1 RETURN VALUES
+
+BN_copy() returns B<to> on success, NULL on error. BN_dup() returns
+the new B<BIGNUM>, and NULL on error. The error codes can be obtained
+by ERR_get_error(3).
+
+=head1 SEE ALSO
+
+bn(3), err(3)
+
+=head1 HISTORY
+
+BN_copy() and BN_dup() are available in all versions of SSLeay and OpenSSL.
+
+=cut
--- /dev/null
+=pod
+
+=head1 NAME
+
+BN_mod_inverse - Compute inverse modulo n
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ BIGNUM *BN_mod_inverse(BIGNUM *r, BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
+
+=head1 DESCRIPTION
+
+BN_mod_inverse() computes the inverse of B<a> modulo B<n>
+places the result in B<r> (C<(a*r)%n==1>). If B<r> is NULL,
+a new B<BIGNUM> is created.
+
+B<ctx> is a previously allocated B<BN_CTX> used for temporary
+variables. B<r> may be the same B<BIGNUM> as B<a> or B<n>.
+
+=head1 RETURN VALUES
+
+BN_mod_inverse() returns the B<BIGNUM> containing the inverse, and
+NULL on error. The error codes can be obtained by ERR_get_error(3).
+
+=head1 SEE ALSO
+
+bn(3), err(3), BN_add(3)
+
+=head1 HISTORY
+
+BN_mod_inverse() is available in all versions of SSLeay and OpenSSL.
+
+=cut
--- /dev/null
+=pod
+
+=head1 NAME
+
+BN_mod_mul_reciprocal, BN_RECP_CTX_new, BN_RECP_CTX_init,
+BN_RECP_CTX_free, BN_RECP_CTX_set - Modular multiplication using
+reciprocal
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ BN_RECP_CTX *BN_RECP_CTX_new(void);
+ void BN_RECP_CTX_init(BN_RECP_CTX *recp);
+ void BN_RECP_CTX_free(BN_RECP_CTX *recp);
+
+ int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *m, BN_CTX *ctx);
+
+ int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *a, BIGNUM *b,
+ BN_RECP_CTX *recp, BN_CTX *ctx);
+
+=head1 DESCRIPTION
+
+BN_mod_mul_reciprocal() can be used to perform an efficient
+BN_mod_mul(3) operation when the operation will be performed
+repeatedly with the same modulus. It computes B<r>=(B<a>*B<b>)%B<m>
+using B<recp>=1/B<m>, which is set as described below. B<ctx> is a
+previously allocated B<BN_CTX> used for temporary variables.
+
+BN_RECP_CTX_new() allocates and initializes a B<BN_RECP> structure.
+BN_RECP_CTX_init() initializes an existing uninitialized B<BN_RECP>.
+
+BN_RECP_CTX_free() frees the components of the B<BN_RECP>, and, if it
+was created by BN_RECP_CTX_new(), also the structure itself.
+
+BN_RECP_CTX_set() computes 1/B<m> and shifts it left by
+BN_num_bits(B<m>)+1 to make it an integer. The result and the
+number of bits it was shifted left are stored in B<recp>.
+
+The B<BN_RECP_CTX> structure is defined as follows:
+
+ typedef struct bn_recp_ctx_st
+ {
+ BIGNUM N; /* the divisor */
+ BIGNUM Nr; /* the reciprocal */
+ int num_bits;
+ int shift;
+ int flags;
+ } BN_RECP_CTX;
+
+It cannot be shared between threads.
+
+=head1 RETURN VALUES
+
+BN_RECP_CTX_new() returns the newly allocated B<BN_RECP_CTX>, and NULL
+on error.
+
+BN_RECP_CTX_init() and BN_RECP_CTX_free() have no return values.
+
+For the other functions, 1 is returned for success, 0 on error.
+The error codes can be obtained by ERR_get_error(3).
+
+=head1 SEE ALSO
+
+bn(3), err(3), BN_add(3), BN_CTX_new(3)
+
+=head1 HISTORY
+
+B<BN_RECP_CTX> was added in SSLeay 0.9.0. Before that, the function
+BN_reciprocal() was used instead, and the BN_mod_mul_reciprocal()
+arguments werde different.
+
+=cut
--- /dev/null
+=pod
+
+=head1 NAME
+
+BN_new, BN_init, BN_clear, BN_free, BN_clear_free - allocate and free BIGNUMs
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ BIGNUM *BN_new(void);
+
+ void BN_init(BIGNUM *);
+
+ void BN_clear(BIGNUM *a);
+
+ void BN_free(BIGNUM *a);
+
+ void BN_clear_free(BIGNUM *a);
+
+=head1 DESCRIPTION
+
+BN_new() allocated and initializes a B<BIGNUM> structure. BN_init()
+initializes an existing uninitialized B<BIGNUM>.
+
+BN_clear() is used to destroy sensitive data such as keys when they
+are no longer needed. It erases the memory used by B<a> and sets it
+to the value 0.
+
+BN_free() frees the components of the B<BIGNUM>, and if it was created
+by BN_new(), also the structure itself. BN_clear_free() additionally
+overwrites the data before the memory is returned to the system.
+
+=head1 RETURN VALUES
+
+BN_new() returns a pointer to the B<BIGNUM>. If the allocation fails,
+it returns B<NULL> and sets an error code that can be obtained
+by ERR_get_error(3).
+
+BN_init(), BN_clear(), BN_free() and BN_clear_free() have no return
+values.
+
+=head1 SEE ALSO
+
+bn(3), err(3)
+
+=head1 HISTORY
+
+BN_new(), BN_clear(), BN_free() and BN_clear_free() are availabe in
+all versions on SSLeay and OpenSSL. BN_init() was added in SSLeay
+0.9.1b.
+
+=cut
--- /dev/null
+=pod
+
+=head1 NAME
+
+BN_num_bits, BN_num_bytes, BN_num_bits_word - Get BIGNUM size
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ int BN_num_bytes(const BIGNUM *a);
+
+ int BN_num_bits(const BIGNUM *a);
+
+ int BN_num_bits_word(BN_ULONG w);
+
+=head1 DESCRIPTION
+
+These functions return the size of a B<BIGNUM> in bytes or bits,
+and the size of an unsigned integer in bits.
+
+BN_num_bytes() is a macro.
+
+=head1 RETURN VALUES
+
+The size.
+
+=head1 SEE ALSO
+
+bn(3)
+
+=head1 HISTORY
+
+BN_num_bytes(), BN_num_bits() and BN_num_bits_word() are available in
+all versions of SSLeay and OpenSSL.
+
+=cut
--- /dev/null
+=pod
+
+=head1 NAME
+
+BN_rand - Generate pseudo-random number
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
+
+=head1 DESCRIPTION
+
+BN_rand() generates a cryptographically strong pseudo-random number of
+B<bits> bits in length and stores it in B<rnd>. If B<top> is true, the
+two most significant bits of the number will be set to 1, so that the
+product of two such random numbers will always have 2*B<bits> length.
+If B<bottom> is true, the number will be odd.
+
+The PRNG must be seeded prior to calling BN_rand().
+
+=head1 RETURN VALUES
+
+BN_rand() returns 1 on success, 0 on error.
+The error codes can be obtained by ERR_get_error(3).
+
+=head1 SEE ALSO
+
+bn(3), err(3), rand(3), RAND_add(), RAND_bytes()
+
+=head1 HISTORY
+
+BN_rand() is available in all versions of SSLeay and OpenSSL.
+
+=cut
--- /dev/null
+=pod
+
+=head1 NAME
+
+BN_set_bit, BN_clear_bit, BN_is_bit_set, BN_mask_bits, BN_lshift,
+BN_lshift1, BN_rshift, BN_rshift1 - Bit operations on BIGNUMs
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ int BN_set_bit(BIGNUM *a, int n);
+ int BN_clear_bit(BIGNUM *a, int n);
+
+ int BN_is_bit_set(const BIGNUM *a, int n);
+
+ int BN_mask_bits(BIGNUM *a, int n);
+
+ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+ int BN_lshift1(BIGNUM *r, BIGNUM *a);
+
+ int BN_rshift(BIGNUM *r, BIGNUM *a, int n);
+ int BN_rshift1(BIGNUM *r, BIGNUM *a);
+
+=head1 DESCRIPTION
+
+BN_set_bit() sets bit B<n> in B<a> to 1 (C<a|=(1E<lt>E<lt>n)>). The
+number is expanded if necessary.
+
+BN_clear_bit() sets bit B<n> in B<a> to 0 (C<a&=~(1E<lt>E<lt>n)>). An
+error occurs it B<a> is shorter than B<n> bits.
+
+BN_is_bit_set() tests if bit B<n> in B<a> is set.
+
+BN_mask_bits() truncates B<a> to an B<n> bit number
+(C<q&=~((~0)E<gt>E<gt>n)>). An error occurs it B<a> already is
+shorter than B<n> bits.
+
+BN_lshift() shifts B<a> left by B<n> bits and places the result in
+B<r> (C<r=a*2^n>). BN_lshift1() shifts B<a> left by one and places
+the result in B<r> (C<r=2*a>).
+
+BN_rshift() shifts B<a> right by B<n> bits and places the result in
+B<r> (C<r=a/2^n>). BN_rshift1() shifts B<a> right by one and places
+the result in B<r> (C<r=a/2>).
+
+=head1 RETURN VALUES
+
+BN_is_bit_set() returns 1 if the bit is set, 0 otherwise.
+
+All other functions return 1 for success, 0 on error. The error codes
+can be obtained by ERR_get_error(3).
+
+=head1 SEE ALSO
+
+bn(3), BN_num_bytes(3), BN_add(3)
+
+=head1 HISTORY
+
+BN_set_bit(), BN_clear_bit(), BN_is_bit_set(), BN_mask_bits(),
+BN_lshift(), BN_lshift1(), BN_rshift(), and BN_rshift1() are available
+in all versions of SSLeay and OpenSSL.
+
+=cut
--- /dev/null
+=pod
+
+=head1 NAME
+
+BN_zero, BN_one, BN_set_word, BN_get_word - BIGNUM assignment operations
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ int BN_zero(BIGNUM *a);
+ int BN_one(BIGNUM *a);
+
+ BIGNUM *BN_value_one(void);
+
+ int BN_set_word(BIGNUM *a, unsigned long w);
+ unsigned long BN_get_word(BIGNUM *a);
+
+=head1 DESCRIPTION
+
+BN_zero(), BN_one() and BN_set_word() set B<a> to the values 0, 1 and
+B<w> respectively. BN_zero() and BN_one() are macros.
+
+BN_value_one() returns a B<BIGNUM> constant of value 1. This constant
+is useful for use in comparisons and assignment.
+
+BN_get_word() returns B<a>, if it can be represented as an unsigned
+long.
+
+=head1 RETURN VALUES
+
+BN_get_word() returns the value B<a>, and 0xffffffffL if B<a> cannot
+be represented as an unsigned long.
+
+BN_zero(), BN_one() and BN_set_word() return 1 on success, 0 otherwise.
+BN_value_one() returns the constant.
+
+=head1 BUGS
+
+Someone might change the constant.
+
+=head1 SEE ALSO
+
+bn(3), BN_bn2bin(3)
+
+=head1 HISTORY
+
+BN_zero(), BN_one() and BN_set_word() are available in all versions of
+SSLeay and OpenSSL. BN_value_one() and BN_get_word() were added in
+SSLeay 0.8.
+
+=cut
#include <openssl/bn.h>
- #define BN_prime_checks(b)
- #define BN_num_bytes(a)
- #define BN_is_word(a,w)
- #define BN_is_zero(a)
- #define BN_is_one(a)
- #define BN_is_odd(a)
- #define BN_one(a)
- #define BN_zero(a)
-
- #define bn_expand(n,b)
- #define bn_wexpand(n,b)
-
- #define bn_fix_top(a)
-
- BIGNUM *BN_value_one(void);
- char * BN_options(void);
- BN_CTX *BN_CTX_new(void);
- void BN_CTX_init(BN_CTX *c);
- void BN_CTX_free(BN_CTX *c);
- int BN_rand(BIGNUM *rnd, int bits, int top,int bottom);
- int BN_num_bits(const BIGNUM *a);
- int BN_num_bits_word(BN_ULONG);
BIGNUM *BN_new(void);
- void BN_init(BIGNUM *);
- void BN_clear_free(BIGNUM *a);
+ void BN_free(BIGNUM *a);
+ void BN_init(BIGNUM *);
+ void BN_clear(BIGNUM *a);
+ void BN_clear_free(BIGNUM *a);
+
+ BN_CTX *BN_CTX_new(void);
+ void BN_CTX_init(BN_CTX *c);
+ void BN_CTX_free(BN_CTX *c);
+
BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
- BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret);
- int BN_bn2bin(const BIGNUM *a, unsigned char *to);
- BIGNUM *BN_mpi2bn(unsigned char *s,int len,BIGNUM *ret);
- int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
- int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
- int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
- int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
- int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b);
- int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
- int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
- BN_CTX *ctx);
- int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b,BN_CTX *ctx);
- int BN_sqr(BIGNUM *r, BIGNUM *a,BN_CTX *ctx);
- BN_ULONG BN_mod_word(BIGNUM *a, BN_ULONG w);
- BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
- int BN_mul_word(BIGNUM *a, BN_ULONG w);
- int BN_add_word(BIGNUM *a, BN_ULONG w);
- int BN_sub_word(BIGNUM *a, BN_ULONG w);
- int BN_set_word(BIGNUM *a, BN_ULONG w);
- BN_ULONG BN_get_word(BIGNUM *a);
- int BN_cmp(const BIGNUM *a, const BIGNUM *b);
- void BN_free(BIGNUM *a);
- int BN_is_bit_set(const BIGNUM *a, int n);
- int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
- int BN_lshift1(BIGNUM *r, BIGNUM *a);
- int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p,BN_CTX *ctx);
- int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
- const BIGNUM *m,BN_CTX *ctx);
- int BN_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
- const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
- int BN_mod_exp2_mont(BIGNUM *r, BIGNUM *a1, BIGNUM *p1,BIGNUM *a2,
- BIGNUM *p2,BIGNUM *m,BN_CTX *ctx,BN_MONT_CTX *m_ctx);
- int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p,
- BIGNUM *m,BN_CTX *ctx);
- int BN_mask_bits(BIGNUM *a,int n);
- int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
- int BN_print_fp(FILE *fp, BIGNUM *a);
- int BN_print(BIO *fp, const BIGNUM *a);
- int BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx);
- int BN_rshift(BIGNUM *r, BIGNUM *a, int n);
- int BN_rshift1(BIGNUM *r, BIGNUM *a);
- void BN_clear(BIGNUM *a);
- BIGNUM *bn_expand2(BIGNUM *b, int bits);
BIGNUM *BN_dup(const BIGNUM *a);
- int BN_ucmp(const BIGNUM *a, const BIGNUM *b);
- int BN_set_bit(BIGNUM *a, int n);
- int BN_clear_bit(BIGNUM *a, int n);
- char * BN_bn2hex(const BIGNUM *a);
- char * BN_bn2dec(const BIGNUM *a);
- int BN_hex2bn(BIGNUM **a, const char *str);
- int BN_dec2bn(BIGNUM **a, const char *str);
- int BN_gcd(BIGNUM *r,BIGNUM *in_a,BIGNUM *in_b,BN_CTX *ctx);
- BIGNUM *BN_mod_inverse(BIGNUM *ret,BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+
+ int BN_num_bytes(const BIGNUM *a);
+ int BN_num_bits(const BIGNUM *a);
+ int BN_num_bits_word(BN_ULONG w);
+
+ int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b);
+ int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+ int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *a, const BIGNUM *d,
+ BN_CTX *ctx);
+ int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx);
+ int BN_mod(BIGNUM *rem, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+ int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m,
+ BN_CTX *ctx);
+ int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx);
+ int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+ int BN_gcd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx);
+
+ int BN_add_word(BIGNUM *a, BN_ULONG w);
+ int BN_sub_word(BIGNUM *a, BN_ULONG w);
+ int BN_mul_word(BIGNUM *a, BN_ULONG w);
+ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
+ BN_ULONG BN_mod_word(BIGNUM *a, BN_ULONG w);
+
+ int BN_cmp(BIGNUM *a, BIGNUM *b);
+ int BN_ucmp(BIGNUM *a, BIGNUM *b);
+ int BN_is_zero(BIGNUM *a);
+ int BN_is_one(BIGNUM *a);
+ int BN_is_word(BIGNUM *a, BN_ULONG w);
+ int BN_is_odd(BIGNUM *a);
+
+ int BN_zero(BIGNUM *a);
+ int BN_one(BIGNUM *a);
+ BIGNUM *BN_value_one(void);
+ int BN_set_word(BIGNUM *a, unsigned long w);
+ unsigned long BN_get_word(BIGNUM *a);
+
+ int BN_rand(BIGNUM *rnd, int bits, int top,int bottom);
+
BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,BIGNUM *add,
- BIGNUM *rem,void (*callback)(int,int,void *),void *cb_arg);
- int BN_is_prime(BIGNUM *p,int nchecks,void (*callback)(int,int,void *),
- BN_CTX *ctx,void *cb_arg);
- void ERR_load_BN_strings(void );
-
- BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);
- BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);
- void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num);
- BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
- BN_ULONG bn_add_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num);
- BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num);
-
- BN_MONT_CTX *BN_MONT_CTX_new(void );
+ BIGNUM *rem,void (*callback)(int,int,void *),void *cb_arg);
+ int BN_is_prime(BIGNUM *p,int nchecks,void (*callback)(int,int,void *),
+ BN_CTX *ctx,void *cb_arg);
+
+ int BN_set_bit(BIGNUM *a, int n);
+ int BN_clear_bit(BIGNUM *a, int n);
+ int BN_is_bit_set(const BIGNUM *a, int n);
+ int BN_mask_bits(BIGNUM *a, int n);
+ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+ int BN_lshift1(BIGNUM *r, BIGNUM *a);
+ int BN_rshift(BIGNUM *r, BIGNUM *a, int n);
+ int BN_rshift1(BIGNUM *r, BIGNUM *a);
+
+ int BN_bn2bin(const BIGNUM *a, unsigned char *to);
+ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
+ char *BN_bn2hex(const BIGNUM *a);
+ char *BN_bn2dec(const BIGNUM *a);
+ int BN_hex2bn(BIGNUM **a, const char *str);
+ int BN_dec2bn(BIGNUM **a, const char *str);
+ int BN_print_fp(FILE *fp, BIGNUM *a);
+ int BN_print(BIO *fp, const BIGNUM *a);
+ int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
+ BIGNUM *BN_mpi2bn(unsigned char *s, int len, BIGNUM *ret);
+
+ BIGNUM *BN_mod_inverse(BIGNUM *r, BIGNUM *a, const BIGNUM *n,
+ BN_CTX *ctx);
+
+ BN_RECP_CTX *BN_RECP_CTX_new(void);
+ void BN_RECP_CTX_init(BN_RECP_CTX *recp);
+ void BN_RECP_CTX_free(BN_RECP_CTX *recp);
+ int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *m, BN_CTX *ctx);
+ int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *a, BIGNUM *b,
+ BN_RECP_CTX *recp, BN_CTX *ctx);
+
+ BN_MONT_CTX *BN_MONT_CTX_new(void);
void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
- int BN_mod_mul_montgomery(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_MONT_CTX *mont,
- BN_CTX *ctx);
- int BN_from_montgomery(BIGNUM *r,BIGNUM *a,BN_MONT_CTX *mont,BN_CTX *ctx);
void BN_MONT_CTX_free(BN_MONT_CTX *mont);
- int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *modulus,BN_CTX *ctx);
- BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from);
-
- BN_BLINDING *BN_BLINDING_new(BIGNUM *A,BIGNUM *Ai,BIGNUM *mod);
- void BN_BLINDING_free(BN_BLINDING *b);
- int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
- int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *r, BN_CTX *ctx);
- int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
-
- void BN_set_params(int mul,int high,int low,int mont);
- int BN_get_params(int which);
-
- void BN_RECP_CTX_init(BN_RECP_CTX *recp);
- BN_RECP_CTX *BN_RECP_CTX_new(void);
- void BN_RECP_CTX_free(BN_RECP_CTX *recp);
- int BN_RECP_CTX_set(BN_RECP_CTX *recp,const BIGNUM *rdiv,BN_CTX *ctx);
- int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y,
- BN_RECP_CTX *recp,BN_CTX *ctx);
- int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
- const BIGNUM *m, BN_CTX *ctx);
- int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m,
- BN_RECP_CTX *recp, BN_CTX *ctx);
+ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *m, BN_CTX *ctx);
+ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from);
+ int BN_mod_mul_montgomery(BIGNUM *r, BIGNUM *a, BIGNUM *b,
+ BN_MONT_CTX *mont, BN_CTX *ctx);
+ int BN_from_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont,
+ BN_CTX *ctx);
+ int BN_to_montgomery(BIGNUM *r, BIGNUM *a, BN_MONT_CTX *mont,
+ BN_CTX *ctx);
+
=head1 DESCRIPTION
+This library performs arithmetic operations on integers of arbitrary
+size. It was written for use in public key cryptography, such as RSA
+and Diffie-Hellman.
+
+It uses dynamic memory allocation for storing its data structures.
+That means that there is no limit on the size of the numbers
+manipulated by these functions, but return values must always be
+checked in case a memory allocation error has occurred.
+
+The basic object in this library is a B<BIGNUM>. It is used to hold a
+single large integer. This type should be considered opaque and fields
+should not be modified or accessed directly.
+
+The creation of B<BIGNUM> objects is described in L<BN_new(3)>;
+L<BN_add(3)> describes most of the arithmetic operations.
+Comparision is described in L<BN_cmp(3)>; L<BN_zero(3)> describes
+certain assignments, L<BN_rand(3)> the generation of random numbers,
+L<BN_generate_prime(3)> deals with prime numbers and L<BN_set_bit(3)>
+with bit operations. The conversion of B<BIGNUM>s to external
+formats is described in L<BN_bn2bin(3)>.
+
+=head1 INTERNALS
+
+The following description is based on the SSLeay documentation:
+
+ typedef struct bignum_st
+ {
+ int top; /* Index of last used d. */
+ BN_ULONG *d; /* Pointer to an array of 'BITS2' bit chunks. */
+ int max; /* Size of the d array. */
+ int neg;
+ } BIGNUM;
+
+The big number is stored in B<d>, a malloc()ed array of B<BN_ULONG>s.
+A B<BN_ULONG> can be either 16, 32 or 64 bits in size, depending on
+the 'number of bits' specified in bn.h.
+
+B<max> is the size of the B<d> array that has been allocated. B<top>
+is the 'last' entry being used, so for a value of 4, bn.d[0]=4 and
+bn.top=1. B<neg> is 1 if the number is negative. When a BIGNUM is
+'0', the B<d> field can be NULL and B<top> == 0. Various routines in
+this library require the use of temporary B<BIGNUM> variables during
+their execution. Since dynamic memory allocation to create B<BIGNUM>s
+is rather expensive when used in conjunction with repeated subroutine
+calls, the B<BN_CTX> structure is used. This structure contains
+B<BN_CTX_NUM> B<BIGNUM>s. B<BN_CTX_NUM> is the maximum number of
+temporary B<BIGNUM>s any publicly exported function will use.
+
+ #define BN_CTX_NUM 12
+ typedef struct bignum_ctx
+ {
+ int tos; /* top of stack */
+ BIGNUM *bn[BN_CTX_NUM]; /* The variables */
+ } BN_CTX;
+
=head1 SEE ALSO
-err(3), rand(3)
+dh(3), err(3), rand(3), rsa(3), BN_new(3), BN_CTX_new(3), BN_copy(3),
+BN_num_bytes(3), BN_add(3), BN_add_word(3), BN_cmp(3), BN_zero(3),
+BN_rand(3), BN_generate_prime(3), BN_set_bit(3), BN_bn2bin(3),
+BN_mod_inverse(3), BN_mod_mul_reciprocal(3), BN_mod_mul_montgomery(3)
=cut
BIGNUM *g; // generator of Z_p (shared)
BIGNUM *priv_key; // private DH value x
BIGNUM *pub_key; // public DH value g^x
- // ...
+ // ...
};
DH