📄 flintpp.cpp
字号:
//*****************************************************************************/
// */
// Functions for arithmetic and number theory with large integers in C */
// Software supplement to the book "Cryptography in C and C++" */
// by Michael Welschenbach, published by Apress Berkeley CA, 2001 */
// */
// Module flintpp.cpp Revision: 27.01.2002 */
// */
// Copyright (C) 1998-2003 by Michael Welschenbach */
// Copyright (C) 1998-2003 by Springer-Verlag Berlin, Heidelberg */
// Copyright (C) 2001-2003 by Apress L.P., Berkeley, CA */
// Copyright (C) 2002-2003 by Wydawnictwa MIKOM, Poland */
// Copyright (C) 2002-2003 by PHEI, P.R.China */
// Copyright (C) 2002-2003 by InfoBook, Korea */
// Copyright (C) 2002-2003 by Triumph Publishing, Russia */
// */
// All Rights Reserved */
// */
// The software may be used for noncommercial purposes and may be altered, */
// as long as the following conditions are accepted without any */
// qualification: */
// */
// (1) All changes to the sources must be identified in such a way that the */
// changed software cannot be misinterpreted as the original software. */
// */
// (2) The statements of copyright may not removed or altered. */
// */
// (3) The following DISCLAIMER is accepted: */
// */
// DISCLAIMER: */
// */
// There is no warranty for the software contained on this CD-ROM, to the */
// extent permitted by applicable law. The copyright holders provide the */
// software `as is' without warranty of any kind, either expressed or */
// implied, including, but not limited to, the implied warranty of fitness */
// for a particular purpose. The entire risk as to the quality and */
// performance of the program is with you. */
// */
// In no event unless required by applicable law or agreed to in writing */
// will the copyright holders, or any of the individual authors named in */
// the source files, be liable to you for damages, including any general, */
// special, incidental or consequential damages arising out of any use of */
// the software or out of inability to use the software (including but not */
// limited to any financial losses, loss of data or data being rendered */
// inaccurate or losses sustained by you or by third parties as a result of */
// a failure of the software to operate with any other programs), even if */
// such holder or other party has been advised of the possibility of such */
// damages. */
// */
//*****************************************************************************/
//
// History
//
// 27.01.2002
// Added member and friend functions lint2clint for export to type CLINT
//
////////////////////////////////////////////////////////////////////////////////
#include "flintpp.h"
#if defined FLINTPP_ANSI
#define NOTHROW (nothrow)
#else
#define NOTHROW
#endif
#define NO_ASSERTS
#ifdef FLINT_DEBUG
#undef NO_ASSERTS
#define ASSERT_LOG_AND_QUIT
#include "_assert.h"
#endif
#ifdef NO_ASSERTS
#define Assert(a) (void)0
#endif
// Version control
//#define FLINTCPPVMAJ 2
//#define FLINTCPPVMIN 3
//#if ((FLINTCPPVMIN != FLINTCPPHVMIN) || (FLINTCPPVMAJ != FLINTCPPHVMAJ))
//#error Version error: FLINTPP.CPP not compatibel to FLINTPP.H
//#endif
//lint -wlib(0)
//lint -e537 (Don't complain about "repeated include files")
#include <stdlib.h>
#include <string.h>
//lint -wlib(4)
////////////////////////////////////////////////////////////////////////////////
// Constructors //
////////////////////////////////////////////////////////////////////////////////
// Constructor 1
// Default-constructor without assigment
LINT::LINT (void)
{
n_l = new NOTHROW CLINT;
if (NULL == n_l)
{
panic (E_LINT_NHP, "Default constructor", 0, __LINE__);
}
status = E_LINT_INV;
}
// Constructor 2
// LINT is constructed from character string
LINT::LINT (const char* const str, const int base)
{
int error;
n_l = new NOTHROW CLINT;
if (NULL == n_l)
{
panic (E_LINT_NHP, "constructor 2", 0, __LINE__);
}
error = str2clint_l (n_l , (char*)str, base);
switch (error)
{
case E_CLINT_OK:
status = E_LINT_OK;
break;
case E_CLINT_NPT:
status = E_LINT_INV;
panic (E_LINT_NPT, "constructor 2", 1, __LINE__);
break;
case E_CLINT_OFL:
status = E_LINT_OFL;
panic (E_LINT_OFL, "constructor 2", 1, __LINE__);
break;
case E_CLINT_BOR:
status = E_LINT_BOR;
panic (E_LINT_BOR, "constructor 2", 2, __LINE__);
break;
default:
status = E_LINT_INV;
panic (E_LINT_ERR, "constructor 2", error, __LINE__);
}
} //lint !e1541
// Constructor 3
// LINT is constructed from byte array with digits to base 2^8
// according to IEEE P1363, significance of bytes increasing from left to right
LINT::LINT (const UCHAR* const bytevector, const int length)
{
int error;
if (NULL == bytevector)
{
panic (E_LINT_INV, "constructor 3", 1, __LINE__);
}
n_l = new NOTHROW CLINT;
if (NULL == n_l)
{
panic (E_LINT_NHP, "constructor 3", 0, __LINE__);
}
error = byte2clint_l (n_l , (UCHAR*)bytevector, length);
switch (error)
{
case E_CLINT_OK:
status = E_LINT_OK;
break;
case E_CLINT_NPT:
status = E_LINT_INV;
panic (E_LINT_NPT, "constructor 3", 1, __LINE__);
break;
case E_CLINT_OFL:
status = E_LINT_OFL;
panic (E_LINT_OFL, "constructor 3", 1, __LINE__);
break;
default:
status = E_LINT_INV;
panic (E_LINT_ERR, "constructor 3", error, __LINE__);
}
} //lint !e1541
// Constructor 4
// LINT is constructed from ASCII-string with C syntax.
// Syntax:
// "0[x|X]{0123456789abcdefABCDEF}" : HEX number
// "0[b|B]{01}" : Binary number
// "{0123456789}" : Characters are interpreted as decimal digits
LINT::LINT (const char* const str)
{
int error;
n_l = new NOTHROW CLINT;
if (NULL == n_l)
{
panic (E_LINT_NHP, "constructor 5", 0, __LINE__);
}
//lint -e668 -e613 (str is not NULL)
if (strncmp (str, "0x", 2) == 0 || strncmp (str, "0X", 2) == 0)
{
error = str2clint_l (n_l, (char*)str+2, 16);
}
else
{
if (strncmp (str, "0b", 2) == 0 || strncmp (str, "0B", 2) == 0)
{
error = str2clint_l (n_l, (char*)str+2, 2);
}
else
{
error = str2clint_l (n_l, (char*)str, 10);
}
}
switch (error)
{
case E_CLINT_OK:
status = E_LINT_OK;
break;
case E_CLINT_NPT:
status = E_LINT_INV;
panic (E_LINT_NPT, "constructor 4", 1, __LINE__);
break;
case E_CLINT_OFL:
status = E_LINT_OFL;
panic (E_LINT_OFL, "constructor 4", 1, __LINE__);
break;
default:
status = E_LINT_INV;
panic (E_LINT_ERR, "constructor 4", error, __LINE__);
}
} //lint !e1541 +e668
// Constructor 5
// LINT is constructed from LINT
LINT::LINT (const LINT& ln)
{
if (ln.status == E_LINT_INV) panic (E_LINT_INV, "constructor 5", 1, __LINE__);
n_l = new NOTHROW CLINT;
if (NULL == n_l)
{
panic (E_LINT_NHP, "constructor 5", 0, __LINE__);
}
cpy_l (n_l, ln.n_l);
status = ln.status;
} //lint !e1541
// Constructor 6
// LINT is constructed from int (w/o sign extension)
LINT::LINT (const signed int i)
{
unsigned long ul;
n_l = new NOTHROW CLINT;
if (NULL == n_l)
{
panic (E_LINT_NHP, "constructor 8", 0, __LINE__);
}
status = E_LINT_OK;
ul = (unsigned)abs(i);
ul2clint_l (n_l, ul);
}
// Constructor 7
// LINT is constructed from long (w/o sign extension)
LINT::LINT (const signed long l)
{
unsigned long ul;
n_l = new NOTHROW CLINT;
if (NULL == n_l)
{
panic (E_LINT_NHP, "constructor 9", 0, __LINE__);
}
status = E_LINT_OK;
ul = (ULONG)abs(l);
ul2clint_l (n_l, ul);
}
// Constructor 8
// LINT is constructed from unsigned char
LINT::LINT (const unsigned char uc)
{
unsigned long ul;
n_l = new NOTHROW CLINT;
if (NULL == n_l)
{
panic (E_LINT_NHP, "constructor 10", 0, __LINE__);
}
status = E_LINT_OK;
ul = uc;
ul2clint_l (n_l, ul);
}
// Constructor 9
// LINT is constructed from unsigned short
LINT::LINT (const unsigned short us)
{
n_l = new NOTHROW CLINT;
if (NULL == n_l)
{
panic (E_LINT_NHP, "constructor 11", 0, __LINE__);
}
status = E_LINT_OK;
u2clint_l (n_l, us);
}
// Constructor 10
// LINT is constructed from unsigned int
LINT::LINT (const unsigned int ui)
{
unsigned long ul;
n_l = new NOTHROW CLINT;
if (NULL == n_l)
{
panic (E_LINT_NHP, "constructor 12", 0, __LINE__);
}
status = E_LINT_OK;
ul = ui;
ul2clint_l (n_l, ul);
}
// Constructor 11
// LINT is constructed from unsigned long
LINT::LINT (const unsigned long ul)
{
n_l = new NOTHROW CLINT;
if (NULL == n_l)
{
panic (E_LINT_NHP, "constructor 13", 0, __LINE__);
}
status = E_LINT_OK;
ul2clint_l (n_l, ul);
}
// Constructor 12
// LINT is constructed from type CLINT
LINT::LINT (const CLINT m_l)
{
if (vcheck_l ((clint*)(m_l)) < 0)
{
panic (E_LINT_INV, "constructor 14", 1, __LINE__);
}
n_l = new NOTHROW CLINT;
if (NULL == n_l)
{
panic (E_LINT_NHP, "constructor 14", 0, __LINE__);
}
cpy_l (n_l, (clint*)m_l); //lint !e613 (m_l is not NULL)
status = E_LINT_OK;
} //lint !e1541
////////////////////////////////////////////////////////////////////////////////
// Overloaded operators //
////////////////////////////////////////////////////////////////////////////////
// Assignment
const LINT& LINT::operator= (const LINT& ln)
{
if (ln.status == E_LINT_INV) panic (E_LINT_INV, "=", 1, __LINE__);
if (&ln != this) // Don't copy object to itself
{
cpy_l (n_l, ln.n_l);
status = ln.status;
}
return *this;
} /*lint !e1539*/
// Arithmetic
const LINT operator+ (const LINT& lm, const LINT& ln)
{
LINT sum;
int err;
if (lm.status == E_LINT_INV) LINT::panic (E_LINT_INV, "+", 1, __LINE__);
if (ln.status == E_LINT_INV) LINT::panic (E_LINT_INV, "+", 2, __LINE__);
err = add_l (ln.n_l, lm.n_l, sum.n_l);
switch (err)
{
case E_CLINT_OK:
sum.status = E_LINT_OK;
break;
case E_CLINT_OFL:
sum.status = E_LINT_OFL;
break;
default:
LINT::panic (E_LINT_ERR, "+", err, __LINE__);
}
return sum;
}
const LINT operator- (const LINT& lm, const LINT& ln)
{
LINT diff;
int err;
if (lm.status == E_LINT_INV) LINT::panic (E_LINT_INV, "-", 1, __LINE__);
if (ln.status == E_LINT_INV) LINT::panic (E_LINT_INV, "-", 2, __LINE__);
err = sub_l (lm.n_l, ln.n_l, diff.n_l);
switch (err)
{
case E_CLINT_OK:
diff.status = E_LINT_OK;
break;
case E_CLINT_UFL:
diff.status = E_LINT_UFL;
break;
default:
LINT::panic (E_LINT_ERR, "-", err, __LINE__);
}
return diff;
}
const LINT operator* (const LINT& lm, const LINT& ln)
{
LINT prd;
int err;
if (lm.status == E_LINT_INV) LINT::panic (E_LINT_INV, "*", 1, __LINE__);
if (ln.status == E_LINT_INV) LINT::panic (E_LINT_INV, "*", 2, __LINE__);
if (&lm == &ln) //lint !e506
err = sqr_l (lm.n_l, prd.n_l); // Use squaring function sqr_l for lm*lm
else
err = mul_l (lm.n_l, ln.n_l, prd.n_l);
switch (err)
{
case E_CLINT_OK:
prd.status = E_LINT_OK;
break;
case E_CLINT_OFL:
prd.status = E_LINT_OFL;
break;
default:
LINT::panic (E_LINT_ERR, "*", err, __LINE__);
}
return prd;
}
const LINT operator/ (const LINT& lm, const LINT& ln)
{
LINT quot;
CLINT junk_l;
int err;
if (lm.status == E_LINT_INV) LINT::panic (E_LINT_INV, "/", 1, __LINE__);
if (ln.status == E_LINT_INV) LINT::panic (E_LINT_INV, "/", 2, __LINE__);
err = div_l (lm.n_l, ln.n_l, quot.n_l, junk_l);
switch (err)
{
case E_CLINT_OK:
quot.status = E_LINT_OK;
break;
case E_CLINT_DBZ:
LINT::panic (E_LINT_DBZ, "/", 2, __LINE__);
break;
default:
LINT::panic (E_LINT_ERR, "/", err, __LINE__);
}
ZEROCLINT_L (junk_l);
return quot;
}
const LINT operator% (const LINT& lm, const LINT& ln)
{
LINT rem;
CLINT junk_l;
int err;
if (lm.status == E_LINT_INV) LINT::panic (E_LINT_INV, "%", 1, __LINE__);
if (ln.status == E_LINT_INV) LINT::panic (E_LINT_INV, "%", 2, __LINE__);
err = div_l (lm.n_l, ln.n_l, junk_l, rem.n_l);
switch (err)
{
case E_CLINT_OK:
rem.status = E_LINT_OK;
break;
case E_CLINT_DBZ:
LINT::panic (E_LINT_DBZ, "%", 2, __LINE__);
break;
default:
LINT::panic (E_LINT_ERR, "%", err, __LINE__);
}
ZEROCLINT_L (junk_l);
return rem;
}
const LINT& LINT::operator++ (void) // Prefix operation
{
int err;
if (status == E_LINT_INV) panic (E_LINT_INV, "++", 0, __LINE__);
err = inc_l (n_l);
switch (err)
{
case E_CLINT_OK:
status = E_LINT_OK;
break;
case E_CLINT_OFL:
status = E_LINT_OFL;
break;
default:
panic (E_LINT_ERR, "++", err, __LINE__);
}
return *this;
}
const LINT LINT::operator++ (int i) // Postfix operation
{
LINT tmp = *this;
int err;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -