math.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* Copyright (c) 1999 by Sun Microsystems, Inc.
* All rights reserved.
*/
/*
* Cylink Corporation � 1998
*
* This software is licensed by Cylink to the Internet Software Consortium to
* promote implementation of royalty free public key cryptography within IETF
* standards. Cylink wishes to expressly thank the contributions of Dr.
* Martin Hellman, Whitfield Diffie, Ralph Merkle and Stanford University for
* their contributions to Internet Security. In accordance with the terms of
* this license, ISC is authorized to distribute and sublicense this software
* for the practice of IETF standards.
*
* The software includes BigNum, written by Colin Plumb and licensed by Philip
* R. Zimmermann for royalty free use and distribution with Cylink's
* software. Use of BigNum as a stand alone product or component is
* specifically prohibited.
*
* Disclaimer of All Warranties. THIS SOFTWARE IS BEING PROVIDED "AS IS",
* WITHOUT ANY EXPRESSED OR IMPLIED WARRANTY OF ANY KIND WHATSOEVER. IN
* PARTICULAR, WITHOUT LIMITATION ON THE GENERALITY OF THE FOREGOING, CYLINK
* MAKES NO REPRESENTATION OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*
* Cylink or its representatives shall not be liable for tort, indirect,
* special or consequential damages such as loss of profits or loss of
* goodwill from the use or inability to use the software for any purpose or
* for any reason whatsoever.
*
* EXPORT LAW: Export of the Foundations Suite may be subject to compliance
* with the rules and regulations promulgated from time to time by the Bureau
* of Export Administration, United States Department of Commerce, which
* restrict the export and re-export of certain products and technical data.
* If the export of the Foundations Suite is controlled under such rules and
* regulations, then the Foundations Suite shall not be exported or
* re-exported, directly or indirectly, (a) without all export or re-export
* licenses and governmental approvals required by any applicable laws, or (b)
* in violation of any applicable prohibition against the export or re-export
* of any part of the Foundations Suite. All export licenses for software
* containing the Foundations Suite are the sole responsibility of the licensee.
*/
/****************************************************************************
* FILENAME: math.c PRODUCT NAME: CRYPTOGRAPHIC TOOLKIT
*
* FILE STATUS:
*
* DESCRIPTION: Math Routines for the ToolKit
*
* PUBLIC FUNCTIONS:
*
* int Sum_big (ord *X,
* ord *Y,
* ord *Z,
* u_int16_t len_X )
*
* int Sub_big (ord *X,
* ord *Y,
* ord *Z,
* u_int16_t len_X )
*
* void Mul_big( ord *X, ord *Y,ord *XY,
* u_int16_t lx, u_int16_t ly)
*
*
* PRIVATE FUNCTIONS:
*
* REVISION HISTORY:
*
* 14 Oct 94 GKL Initial release
* 26 Oct 94 GKL (alignment for big endian support )
*
****************************************************************************/
#pragma ident "%Z%%M% %I% %E% SMI"
/****************************************************************************
* INCLUDE FILES
****************************************************************************/
/* bn files */
#include "port_before.h"
#include "bn.h"
/* system files */
#ifdef VXD
#include <vtoolsc.h>
#else
#include <stdlib.h>
#include <string.h>
#endif
/* program files */
#include "cylink.h"
#include "ctk_endian.h"
#include "toolkit.h"
#include "port_after.h"
/****************************************************************************
* NAME: void BigNumInit( void )
*
*
* DESCRIPTION: Initialize BigNum
*
* INPUTS:
* PARAMETERS:
* OUTPUT:
* PARAMETERS:
*
* RETURN:
*
*
* REVISION HISTORY:
*
* 29 Sep 96 Initial release
*
****************************************************************************/
void BigNumInit()
{
static int bignuminit = 0;
if(!bignuminit){
bnInit();
bignuminit = 1;
}
}
/****************************************************************************
* NAME: int Sum_big (ord *X,
* ord *Y,
* ord *Z,
* u_int16_t len_X )
*
* DESCRIPTION: Compute addition.
*
* INPUTS:
* PARAMETERS:
* ord *X Pointer to first array
* ord *Y Pointer to second array
* int len_X Number of longs in X_l
* OUTPUT:
* PARAMETERS:
* ord *Z Pointer to result arrray
*
* RETURN:
* Carry bit
*
* REVISION HISTORY:
*
* 24 Sep 94 KPZ Initial release
* 14 Oct 94 GKL Second version (big endian support)
*
****************************************************************************/
ord *Y,
ord *Z,
{
BigNumInit();
/*bnInit();
bnBegin(&src2);
bnBegin(&temp_bn);
*/
/*bn package increments the size of dest by 1 if the carry bit is 1*/
return 1;
else
return 0;
}
{
/*ord *temp;*/
BigNumInit();
#if 0
bnInit();
#endif
/*memcpy(temp,X,len_X*sizeof(ord));*/
/*memcpy(Z,temp_bn.ptr,len_X*sizeof(ord));*/
/*bn package increments the size of dest by 1 if the carry bit is 1*/
/*free(temp);*/
return 1;
else
return 0;
}
/****************************************************************************
* NAME: int Sum_Q(ord *X,
* u_int16_t src,
* u_int16_t len_X )
* DESCRIPTION: Compute addition X += src.
*
* INPUTS:
* PARAMETERS:
* ord *X Pointer to first array
* u_int16_t src Second operand must be <65535
* int len_X Number of ords in X_l
* OUTPUT:
* PARAMETERS:
* ord *X Pointer to result arrray
*
* RETURN:
* SUCCESS or -1
*
* REVISION HISTORY:
*
* 21 Sep 96 AAB Initial release
****************************************************************************/
{
BigNumInit();
/*bnInit();*/
return status;
}
/****************************************************************************
* NAME: int Sub_big (ord *X,
* ord *Y,
* ord *Z,
* u_int16_t len_X )
*
*
* DESCRIPTION: Compute subtraction.
*
* INPUTS:
* PARAMETERS:
* ord *X Pointer to first array
* ord *Y Pointer to second array
* u_int16_t len_X Number of longs in X_l
* OUTPUT:
* PARAMETERS:
* ord *Z Pointer to result arrray
*
* RETURN:
* Carry bit
*
* REVISION HISTORY:
*
* 24 Sep 94 KPZ Initial release
* 14 Oct 94 GKL Second version (big endian support)
*
****************************************************************************/
ord *Y,
ord *Z,
{
/* carry is not returned in bn version */
int status;
BigNumInit();
/*bnInit();
bnBegin(&dest);
bnBegin(&src);
*/
return status;
}
#if 0
/****************************************************************************
* NAME: void Mul_big( ord *X, ord *Y, ord *XY,
* u_int16_t lx, u_int16_t ly)
*
*
*
* DESCRIPTION: Compute a product.
*
* INPUTS:
* PARAMETERS:
* ord *X Pointer to first long array
* ord *Y Pointer to second long array
* u_int16_t lx Leftmost non zero element of first array
* u_int16_t ly Leftmost non zero element of second array
* OUTPUT:
* PARAMETERS:
* ord *XY Pointer to result
*
* RETURN:
*
*
* REVISION HISTORY:
*
* 24 Sep 94 KPZ Initial release
* 14 Oct 94 GKL Second version (big endian support)
* 08 Sep 95 AAB Comment out calloc and discard the elements_in_X,
* elements_in_Y
****************************************************************************/
{
BigNumInit();
/*bnInit();*/
/*
bnBegin(&src1);
bnBegin(&src2);
*/
/* Call bn routine */
}
#endif
/****************************************************************************
* NAME: void Mul_big_1( ord X, ord *Y, ord *XY,
* u_int16_t lx, u_int16_t ly )
*
*
*
* DESCRIPTION: Compute a product.
*
* INPUTS:
* PARAMETERS:
* ord X Number
* ord *Y Pointer to long array
* u_int16_t ly Leftmost non zero element of second array
* OUTPUT:
* PARAMETERS:
* ord *XY Pointer to result
*
* RETURN:
*
*
* REVISION HISTORY:
*
* 08 Oct 95 AAB Initial relaese
*
****************************************************************************/
{
BigNumInit();
/*bnInit();
bnBegin(&dest);
bnBegin(&src);
*/
}
/****************************************************************************
* NAME: int Mul( u_int16_t X_bytes,
* ord *X,
* u_int16_t Y_bytes,
* ord *Y,
* u_int16_t P_bytes,
* ord *P,
* ord *Z )
*
* DESCRIPTION: Compute a modulo product
*
* INPUTS:
* PARAMETERS:
* ord *X Pointer to first operand
* u_int16_t X_bytes Number of bytes in X
* ord *Y Pointer to second operand
* u_int16_t Y_bytes Number of bytes in Y
* ord *P Pointer to modulo
* u_int16_t P_bytes Number of bytes in P
*
* OUTPUT:
* PARAMETERS:
* ord *Z Pointer to result
*
* RETURN:
* SUCCESS No errors
* ERR_INPUT_LEN Invalid length for input data (zero bytes)
*
* REVISION HISTORY:
*
* 24 Sep 94 KPZ Initial release
* 14 Oct 94 GKL Second version (big endian support)
*
****************************************************************************/
ord *X,
ord *Y,
ord *P,
ord *Z )
{
BigNumInit();
/*bnInit();
bnBegin(&dest);
bnBegin(&src1);
bnBegin(&src2);
bnBegin(&mod);
*/
{
return status;
}
{
return status;
}
if( !XY )
{
return ERR_ALLOC;
}
return status;
}
/****************************************************************************
* NAME: int Square( u_int16_t X_bytes,
* ord *X,
* u_int16_t P_bytes,
* ord *P,
* ord *Z )
*
* DESCRIPTION: Compute a modulo square
*
* INPUTS:
* PARAMETERS:
* ord *X Pointer to array to be squared
* u_int16_t X_bytes Number of bytes in X
* ord *P Pointer to modulo
* u_int16_t P_bytes Number of bytes in P
*
* OUTPUT:
* PARAMETERS:
* ord *Z Pointer to result
*
* RETURN:
* SUCCESS No errors
* ERR_INPUT_LEN Invalid length for input data (zero bytes)
*
* REVISION HISTORY:
*
* 1 Sep 95 AAB Initial release
****************************************************************************/
ord *X,
ord *P,
ord *Z )
{
BigNumInit();
/*bnInit();
bnBegin(&dest);
bnBegin(&src);
bnBegin(&mod);
*/
{
return status;
}
{
return status;
}
if( !XY )
{
return ERR_ALLOC;
}
return status;
}
/****************************************************************************
* NAME: int PartReduct( u_int16_t X_bytes,
* ord *X,
* u_int16_t P_bytes,
* ord *P,
* ord *Z )
*
* DESCRIPTION: Compute a modulo
*
* INPUTS:
* PARAMETERS:
* ord *X Pointer to array
* u_int16_t X_bytes Number of bytes in X
* ord *P Pointer to modulo
* u_int16_t P_bytes Number of bytes in P
*
* OUTPUT:
* PARAMETERS:
* ord *Z Pointer to result
*
* RETURN:
* SUCCESS No errors
* ERR_INPUT_LEN Invalid length for input data (zero bytes)
* REVISION HISTORY:
*
* 24 Sep 94 KPZ Initial release
* 14 Oct 94 GKL Second version (big endian support)
*
****************************************************************************/
ord *X,
ord *P,
ord *Z )
{
BigNumInit();
/*bnInit();
bnBegin(&dest);
bnBegin(&src);
bnBegin(&d);
src.ptr = X;
*/
d.ptr = P;
return status;
}
/****************************************************************************
* NAME: int Expo( u_int16_t X_bytes,
* ord *X,
* u_int16_t Y_bytes,
* ord *Y,
* u_int16_t P_bytes,
* ord *P,
* ord *Z,
* YIELD_context *yield_cont )
*
* DESCRIPTION: Compute a modulo exponent
*
* INPUTS:
* PARAMETERS:
* ord *X Pointer to base array
* u_int16_t X_bytes Number of bytes in base
* ord *Y Pointer to exponent array
* u_int16_t Y_bytes Number of bytes in exponent
* ord *P Pointer to modulo
* u_int16_t P_bytes Number of bytes in P
* YIELD_context *yield_cont Pointer to yield_cont structure (NULL if not used)
*
* OUTPUT:
* PARAMETERS:
* ord *Z Pointer to result
*
* RETURN:
* SUCCESS No errors
* ERR_INPUT_LEN Invalid length for input data(zero bytes)
*
* REVISION HISTORY:
*
* 24 Sep 94 KPZ Initial release
* 14 Oct 94 GKL Second version (big endian support)
* 08 Dec 94 GKL Added YIELD_context
* 01 Sep 95 Fast exponentation algorithm
****************************************************************************/
ord *Z )
{
BigNumInit();
#if 0
/*bnInit();*/
bnBegin(&n);
#endif
n.ptr = X;
/* Call bn routine */
return status;
}
/****************************************************************************
* NAME: int DoubleExpo( u_int16_t X1_bytes,
* ord *X1,
* u_int16_t Y1_bytes,
* ord *Y1,
* u_int16_t X2_bytes,
* ord *X2,
* u_int16_t Y2_bytes,
* ord *Y2,
* u_int16_t P_bytes,
* ord *P,
* ord *Z)
*
* DESCRIPTION: Compute a modulo exponent
*
* INPUTS:
* PARAMETERS:
* ord *X1 Pointer to first base array
* u_int16_t X1_bytes Number of bytes in first base
* ord *Y1 Pointer to first exponent array
* u_int16_t Y1_bytes Number of bytes in first exponent
* ord *X2 Pointer to second base array
* u_int16_t X2_bytes Number of bytes in second base
* ord *Y2 Pointer to second exponent array
* u_int16_t Y2_bytes Number of bytes in second exponent ord *P Pointer to modulo
* ord *P Pointer to modulo
* u_int16_t P_bytes Number of bytes in
*
* OUTPUT:
* PARAMETERS:
* ord *Z Pointer to result
*
* RETURN:
* SUCCESS No errors
* ERR_INPUT_LEN Invalid length for input data(zero bytes)
*
* REVISION HISTORY:
*
* 21 Aug 96 AAB Initial release
****************************************************************************/
ord *Z)
{
BigNumInit();
return status;
}
/****************************************************************************
* NAME: int Inverse( u_int16_t X_bytes,
* ord *X,
* u_int16_t P_bytes,
* ord *P,
* ord *Z )
*
*
*
*
* DESCRIPTION: Compute a modulo inverse element
*
* INPUTS:
* PARAMETERS:
* ord *X Pointer to array
* u_int16_t X_bytes Number of bytes in array
* ord *P Pointer to modulo
* u_int16_t P_bytes Number of bytes in P
*
* OUTPUT:
* PARAMETERS:
* ord *Z Pointer to result
*
* RETURN:
* SUCCESS No errors
* ERR_INPUT_LEN Invalid length for input data(zero bytes)
* ERR_INPUT_VALUE Invalid input value
*
* REVISION HISTORY:
*
* 24 Sep 94 KPZ Initial release
* 14 Oct 94 GKL Second version (big endian support)
* 08 Nov 94 GKL Added input parameters check
* 01 Sep 95 Improve fuction
****************************************************************************/
ord *X,
ord *P,
ord *Z )
{
BigNumInit();
/*bnInit();
bnBegin(&dest);
bnBegin(&src);
bnBegin(&mod);
*/
return status;
}
/****************************************************************************
* NAME: void Add( ord *X,
* ord *Y,
* u_int16_t P_len,
* ord *P,
* ord *Z )
*
* DESCRIPTION: Compute modulo addition
*
* INPUTS:
* PARAMETERS:
* ord *X Pointer to first operand
* ord *Y Pointer to second operand
* u_int16_t P_len Length of modulo
* ord *P Pointer to modulo
* OUTPUT:
* ord *Z Pointer to result
* RETURN:
*
* REVISION HISTORY:
*
* 24 sep 94 KPZ Initial release
* 10 Oct 94 KPZ Fixed bugs
* 14 Oct 94 GKL Second version (big endian support)
*
****************************************************************************/
/*
int Add( ord *X,
ord *Y,
u_int16_t P_len,
ord *P,
ord *Z )
{
int status = SUCCESS;
ord *temp;
struct BigNum dest, src, mod;
bnInit();
bnBegin(&dest);
bnBegin(&src);
bnBegin(&mod);
temp = (ord*)malloc(P_len + sizeof(ord));
memcpy(temp, X, P_len);
dest.ptr = temp;
src.ptr = Y;
mod.ptr = P;
status = bnAdd(&dest,&src);
status = bnMod(&dest,&dest,&mod);
memcpy(Z,temp,P_len);
free(temp);
return status;
}
*/
ord *Y,
ord *P)
{
/* ord *temp;*/
BigNumInit();
/*bnInit();
bnBegin(&dest);
bnBegin(&src);
bnBegin(&mod);
*/
/*
temp = (ord*)malloc(P_len + sizeof(ord));
memcpy(temp, X, P_len);
*/
/*dest.ptr = temp;*/
/*
memcpy(Z,temp,P_len);
free(temp);
*/
return status;
}
/****************************************************************************
* NAME: int SteinGCD( ord *m,
* ord *b
* u_int16_t len )
*
* DESCRIPTION: Compute great common divisor
*
* INPUTS:
* PARAMETERS:
* ord *m Pointer to first number
* ord *b Pointer to second number
* u_int16_t len Number of elements in number
* OUTPUT:
*
* RETURN:
* TRUE if gcd != 1
* FALSE if gcd == 1
* REVISION HISTORY:
*
*
* 24 Sep 94 KPZ Initial release
* 14 Oct 94 GKL Second version (big endian support)
* 01 Sep 95 AAB Speed up
*
****************************************************************************/
/* test if GCD equal 1 */
ord *n,
{
int status;
BigNumInit();
/*bnInit();
bnBegin(&dest);
bnBegin(&a);
bnBegin(&b);
*/
a.ptr = m;
b.ptr = n;
status = 0;
else
status = 1;
return status;
}
/****************************************************************************
* NAME: int DivRem( u_int16_t X_bytes,
* ord *X,
* u_int16_t P_bytes,
* ord *P,
* ord *Z,
* ord *D)
*
* DESCRIPTION: Compute a modulo and quotient
*
* INPUTS:
* PARAMETERS:
* ord *X Pointer to array
* u_int16_t X_bytes Number of bytes in X
* ord *P Pointer to modulo
* u_int16_t P_bytes Number of bytes in P
*
* OUTPUT:
* PARAMETERS:
* ord *Z Pointer to result
* ord *D Pointer to quotient
* RETURN:
* SUCCESS No errors
* ERR_INPUT_LEN Invalid length for input data (zero bytes)
* REVISION HISTORY:
*
* 24 Sep 94 KPZ Initial release
* 10 Oct 94 KPZ Fixed bugs
* 14 Oct 94 GKL Second version (big endian support)
*
****************************************************************************/
ord *X,
ord *P,
ord *Z,
ord *D)
{
struct BigNum q, r, /*n,*/ d;
BigNumInit();
/*bnInit();
bnBegin(&q);
bnBegin(&r);
bnBegin(&n);
bnBegin(&d);
n.ptr = X;
*/
d.ptr = P;
q.ptr = D;
return status;
}