密码学C/C++语言实现学习笔记——基本运算函数
基础数据结构:
typedef unsigned short clint;
typedef unsigned long clintd;
书中所使用环境unsigned short是16位(2个字节)的,unsigned long是32位(4个字节)的。满足非形式化公式表示的大小关系USHORTXUSHORT<=ULONG
 
#define CLINTMAXDIGIT   256U     CLINTMAXDIGIT指定程序能处理的最大位数(0x10000进制的)。
#define CLINTMAXSHORT   (CLINTMAXDIGIT + 1)  CLINTMAXSHORT指定数值存储器的大小
typedef clint CLINT[CLINTMAXSHORT];                         CLINTMAXSHORTCLINTMAXDIGIT + 1
typedef clint CLINTD[1 + (CLINTMAXDIGIT << 1)];       1 + (CLINTMAXDIGIT << 1) = CLINTMAXDIGIT * 2 + 1
typedef clint CLINTQ[1 + (CLINTMAXDIGIT << 2)];       1 + (CLINTMAXDIGIT << 2)CLINTMAXDIGIT * 4 + 1
typedef clint *CLINTPTR;    
CLINT、CLINTDCLINTQ是定义无符号短整型数组的数据类型,区别是所定义的数组大小不同。CLINTPTR是定义指向无符号短整型变量的指针类型。
声明大数的方式:
CLINT n_l;
作为表示长度的附加元素被存储在数组的第一个元素中,数值表示的数字随着存储器地址或数组索引的增加而增加。由于unsigned short是32位的,将32位存储单元存储为大数的一位,即为0x10000进制
访问大数的位数: *n_l 即是取数组的第一个元素,存放的是大数的位数
/* CLINT-Constant Values */ CLINT类型常数值 
clint nul_l[] = { 0, 0, 0, 0, 0 };
clint one_l[] = { 1, 1, 0, 0, 0 };
clint two_l[] = { 1, 2, 0, 0, 0 };

 

基本运算:

没有溢出检测功能和前导零检测功能的函数

void add (CLINT a_l, CLINT b_l, CLINT s_l)
void sub (CLINT a_l, CLINT b_l, CLINT d_l )

void mult (CLINT, CLINT, CLINT)

 

void sqr (CLINT, CLINT, CLINT) 

 

void umul (CLINT, CLINT, CLINT)

 

 

 

 

 

 

#pragma warning(disable:4996)

 

参数中有USHORT类型的数据的函数

 

 

int uadd_l(CLINT a_l, USHORT b, CLINT s_l)
int usub_l(CLINT a_l, USHORT b, CLINT d_l)
int umul_l(CLINT aa_l, USHORT b, CLINT pp_l)

int udiv_l(CLINT dv_l, USHORT uds, CLINT q_l, CLINT r_l)

 

           模运算

 

int umadd_l(CLINT a_l, USHORT b, CLINT s_l, CLINT m_l)
int umsub_l(CLINT a_l, USHORT b, CLINT d_l, CLINT m_l)
int ummul_l(CLINT a_l, USHORT b, CLINT c_l, CLINT m_l)

 

USHORT umod_l(CLINT dv_l, USHORT uds)

            模幂运算

 

 

int umexp_l(CLINT bas_l, USHORT e, CLINT rem_l, CLINT m_l)

 

 

 

运算

 

int inc_l(CLINT a_l)
int dec_l(CLINT a_l)
int add_l(CLINT a_l, CLINT b_l, CLINT s_l)
int sub_l(CLINT aa_l, CLINT bb_l, CLINT d_l)
int mul_l(CLINT f1_l, CLINT f2_l, CLINT pp_l)
int sqr_l(CLINT f_l, CLINT pp_l)
int div_l(CLINT, CLINT, CLINT, CLINT)

 

 

 

模运算

int mod_l(CLINT dv_l, CLINT ds_l, CLINT r_l)
int mod2_l(CLINT d_l, ULONG k, CLINT r_l)
int mequ_l(CLINT a_l, CLINT b_l, CLINT m_l)
int madd_l(CLINT aa_l, CLINT bb_l, CLINT c_l, CLINT m_l)
int msub_l(CLINT aa_l, CLINT bb_l, CLINT c_l, CLINT m_l)
int mmul_l(CLINT aa_l, CLINT bb_l, CLINT c_l, CLINT m_l)
int msqr_l(CLINT aa_l, CLINT c_l, CLINT m_l)

 

 

 

 

 

位运算与逻辑函数

 

int cmp_l(CLINT a_l, CLINT b_l)
int equ_l(CLINT a_l, CLINT b_l)
int shl_l(CLINT a_l)
int shr_l(CLINT a_l)

 

int shift_l(CLINT n_l, long int noofbits)

 

 

void xor_l(CLINT a_l, CLINT b_l, CLINT c_l)
void or_l(CLINT a_l, CLINT b_l, CLINT c_l)
void and_l(CLINT a_l, CLINT b_l, CLINT c_l)

int setbit_l(CLINT a_l, unsigned int pos)

int testbit_l(CLINT a_l, unsigned int pos)
int clearbit_l(CLINT a_l, unsigned int pos)

 

 

工具类函数

 

 

unsigned int ld_l(CLINT n_l)
int vcheck_l(CLINT n_l)
void u2clint_l(CLINT num_l, USHORT u)
void ul2clint_l(CLINT num_l, ULONG ul)
char * xclint2str_l(CLINT n_l, USHORT base, int showbase)
int str2clint_l(CLINT n_l, char *str, USHORT base)
UCHAR *clint2byte_l(CLINT n_l, int *len)
int byte2clint_l(CLINT n_l, UCHAR *bytestr, int len)
char *fhexstr_l(CLINT n_l)
char *fdecstr_l(CLINT n_l)
char *foctstr_l(CLINT n_l)
char *fbinstr_l(CLINT n_l)
clint * setmax_l(CLINT a_l)
void cpy_l(CLINT dest_l, CLINT src_l)
void fswap_l(CLINT a_l, CLINT b_l)

 

 

 

 

 

 

#ifdef LINT_ASM

#ifndef FLINT_ASM

#define FLINT_ASM
#endif
#endif
如果定义了LINT_ASM,就必须定义FLINT_ASM
#ifdef LINT_ANSI
#ifndef FLINT_ANSI 
#define FLINT_ANSI #endif
#endif
如果定义LINT_ANSI,就必须定义FLINT_ANSI

 

 

 

#ifndef __FLINT_API
#ifdef FLINT_USEDLL
#define __FLINT_API                   __cdecl
#else
#define __FLINT_API                   /**/
#endif /* FLINT_USEDLL */
#endif /* !defined __FLINT_API */

如果没有定义__FLINT_API,但定义可FLINT_USEDLL,就定义__FLINT_API为__cdecl,否则定义为/**/。

 

#if !defined __FLINT_API_A       没有定义__FLINT_API_A
#if defined __GNUC__ && !defined __cdecl    若定义了__GNUC__ 且没有定义__cdecl
#define __FLINT_API_A                 /**/             则定义__FLINT_API_A为/**/
#else
#define __FLINT_API_A                 __cdecl        否则定义__FLINT_API_A为__cdecl
#endif /* !defined __GNUC__ */
#endif /* !defined __FLINT_API_A */

https://www.cnblogs.com/Cccarl/p/7215515.html?utm_source=itdadao&utm_medium=referral

 

__cdecl 是C Declaration的缩写(declaration,声明),表示C语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈。被调用函数不会要求调用者传递多少参数,调用者传递过多或者过少的参数,甚至完全不同的参数都不会产生编译阶段的错误。

VS 2017添加asm文件到工程中

 

 

/* If the FLINT/C-Package is used under MS Visual C/C++ as DLL,               */
/* all modules accessing data nul_l, one_l, two_l or smallprimes from outside */
/* the DLL must be compiled with -D__FLINT_API_DATA=__declspec(dllimport)     */
#ifndef __FLINT_API_DATA
#if (defined _MSC_VER && _MSC_VER >= 11) && defined FLINT_USEDLL
#define __FLINT_API_DATA              __declspec(dllimport)
#else
#define __FLINT_API_DATA              /**/
#endif /* MSC_VER && FLINT_USEDLL */
#endif /* !defined __FLINT_API_DATA */
 

 

 

 

 

 

#define CLINTMAXLONG    ((CLINTMAXDIGIT >> 1) + 1)
#define CLINTMAXBYTE    (CLINTMAXSHORT << 1)
#define CLINTMAXBIT     (CLINTMAXDIGIT << 4)
(以上代码位于flint.h文件中。)

 

 

 

 

 

动态寄存器

 

通过如上图所示的数据结构,通过寄存器管理函数来对CLINT变量进行管理

 

 

 

对变量值进行清零

 

/******************************************************************************/
/*                                                                            */
/*  Function:  Purging of variables                                           */
/*             This function can be called for purging variables by           */
/*             overwriting with 0. This works even in cases where compiler    */
/*             optimization is used, which typically causes assignments to    */
/*             variables or calls to memset() for automatic CLINT variables   */
/*             at the end of of a function to be ignored.                     */
/*  Syntax:    static void purgevars_l (int noofvars, ...);                   */
/*  Input:     noofvars (Number of following pairs of arguments)              */
/*             ... (noofvars pairs of (sizeof (var), (type *)var))            */
/*  Output:    purged variable *var                                           */
/*  Returns:   -                                                              */
/*                                                                            */
/******************************************************************************/
static void purgevars_l(int noofvars, ...)
{
	va_list ap;
	size_t size;
	va_start(ap, noofvars);
	for (; noofvars > 0; --noofvars)
	{
		switch (size = va_arg(ap, size_t))
		{
		case 1:  *va_arg(ap, char *) = 0;
			break;
		case 2:  *va_arg(ap, short *) = 0;
			break;
		case 4:  *va_arg(ap, long *) = 0;
			break;
		default: Assert(size >= CLINTMAXBYTE);
			memset(va_arg(ap, char *), 0, size);
		}
	}
	va_end(ap);
}

/******************************************************************************/
/*                                                                            */
/*  Function:  Check whether variables are purged with 0                      */
/*  Syntax:    static int ispurged_l (int noofvars, ...);                     */
/*  Input:     noofvars (Number of followign pairs of arguments)              */
/*             ... (noofvars pairs of (sizeof (var), (typ *)var))             */
/*  Output:    -                                                              */
/*  Returns:   1 if the arguments are purged with 0                           */
/*             0 else                                                         */
/*                                                                            */
/******************************************************************************/
static int ispurged_l(int noofvars, ...)
{
	va_list ap;
	size_t size;
	char *cptr;
	va_start(ap, noofvars);
	for (; noofvars > 0; --noofvars)
	{
		size = va_arg(ap, size_t);
		cptr = va_arg(ap, char *);
		for (; size > 0; size--)
		{
			if (0 != *cptr++) return 0;
		}
	}
	va_end(ap);
	return 1;
}

 

VS2017中stdarg.h中的定义

#define va_start __crt_va_start
#define va_arg   __crt_va_arg
#define va_end   __crt_va_end
#define va_copy(destination, source) ((destination) = (source))

 

 

 

 

 

#define PURGEVARS_L(X) purgevars_l  X
#define ISPURGED_L(X) ispurged_l  X

 

 

/* Purging of variables */
 PURGEVARS_L((2, sizeof(q_l), q_l,sizeof(r_l), r_l));
第一个参数指明后续的参数对的数量,参数对为类型大小+变量
 ISPURGED_L((2, sizeof(q_l), q_l,sizeof(r_l), r_l));
 

 

参见征服C指针 可变长参数部分

#include <stdio.h>
#include <stdarg.h>
#include <assert.h>

void tiny_printf(char *format, ...)
{
  int i;
  va_list ap;
  
  va_start(ap, format);
  for (i = 0; format[i] != '\0'; i++) {
    switch (format[i]) {
      case 's':
        printf("%s ", va_arg(ap, char*));
        break;
      case 'd':
        printf("%d ", va_arg(ap, int));
        break;
      default:
        assert(0);
    }
  }
  va_end(ap);
  putchar('\n');
}

int main(void)
{
  tiny_printf("sdd", "result..", 3, 5);
  return 0;
}

声明va_list类型的变量ap。stdarg.h文件中定义了va_list类型,在作者环境中是这样定义的:

 

typedef char *va_list; 也就是说va_list被定义成指向char的指针

 

va_start(ap, format) 意味着使指针ap指向参数format的下一个位置,因此我们得到了可变长部分的第一个参数。

 

给宏va_arg()指定ap和参数类型,就可以顺序地取出可变长部分的参数

 

va_end()是个摆设,只不过因为在标准中指出对于具有va_start()的函数需要写va_end()

在作者环境中,宏va_end()定义为: #define   va_end(ap) 是个空定义。

 

 

源码网址:https://github.com/Apress/cryptography-in-c-cpp

 

 

 

 

 

 

 

 

 

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐