首页 > 编程语言 >密码学C/C++语言实现学习笔记——基本运算函数

密码学C/C++语言实现学习笔记——基本运算函数

时间:2022-11-14 16:38:26浏览次数:65  
标签:__ va CLINT int 笔记 ap FLINT C++ 密码学


密码学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]; CLINTMAXSHORT = CLINTMAXDIGIT + 1

typedef clint CLINTD[1 + (CLINTMAXDIGIT << 1)]; 1 + (CLINTMAXDIGIT << 1) = CLINTMAXDIGIT * 2 + 1

typedef clint CLINTQ[1 + (CLINTMAXDIGIT << 2)]; 1 + (CLINTMAXDIGIT << 2) = CLINTMAXDIGIT

typedef clint *CLINTPTR;
CLINT、CLINTD、CLINTQ是定义无符号短整型数组的数据类型,区别是所定义的数组大小不同。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)

 

 

 

 

密码学C/C++语言实现学习笔记——基本运算函数_git

#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 */


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

VS 2017添加asm文件到工程中

 

密码学C/C++语言实现学习笔记——基本运算函数_密码学_02

 


/* 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文件中。)


 

 

 

 

 

动态寄存器

 

密码学C/C++语言实现学习笔记——基本运算函数_git_03

通过如上图所示的数据结构,通过寄存器管理函数来对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



 

 

 

 

标签:__,va,CLINT,int,笔记,ap,FLINT,C++,密码学
From: https://blog.51cto.com/feishujun/5849420

相关文章

  • synchronized学习笔记
    Synchronized1.synchronized的作用能够保证在同一时刻最多只有一个线程执行该段代码,以达到保证并发安全的效果。2.不使用并发会有什么后果?两个线程同时a++,最后结果......
  • 10、 ARM 内联汇编学习笔记
    基本思想:随手记录一下ARM的内联汇编的基础语法,以便更深入的学习NCNN源码~​​ARMGCCInlineAssemblerCookbook​​ 参考官网(1)、基本的汇编语法结构为asmvolatile(co......
  • Unity开发笔记-Timeline扩展笔记(1)
    ILayerable代码修改动画后推publicstaticvoidSetTimeClipExtrapolation(TimelineClipclip,TimelineClip.ClipExtrapolationextrapolation){vartype=clip.Get......
  • 『NLP学习笔记』如何理解attention中的Q,K,V
    如何理解attention中的Q,K,V?文章目录​​一.如何理解attention中的Q,K,V?​​​​1.1.定义三个线性变换矩阵​​​​1.2.定义QKV​​​​1.3.自注意力计算​​​​1.3.1......
  • C++软件编码规范推荐--程序的版式
    1.背景  版式虽然不会影响程序的功能,但会影响程序的可读性;追求清晰、直观;2.规范2.1空行  空行起分隔程序段落的作用。合理的空行使布局更清晰,也不会浪费内存; ......
  • C++11中enable_shared_from_this的用法解析
    转载:https://blog.csdn.net/breadheart/article/details/112451022什么是enable_shared_from_this?下面摘自cppreference中概述C++11开始支持enable_shared_from_......
  • C++中sort函数、1.4最长公共子串
    sort()即为用来排序的函数,它根据具体情况使用不同的排序方法,效率较高。sort在实现时避免了经典快速排序中可能出现的会导致实际复杂度退化到O(n2)的极端情况。使用sort()......
  • java基础笔记
    java的数据类型分为两大类  进制前缀二进制:0b八进制:0十六进制:0xJava会直接将它们转换为十进制输出 float、double并不能准确表示每一位小数,对于有的小数只能无......
  • 使用 C++ 部署深度学习模型快速上手方案
    本文将从获取一个训练好的 shufflenet_v2 模型出发,讲解如何使用MegEngineLite的C++接口将其部署到CPU(Linuxx86/AndroidArm)环境下运行。主要分为以下小节:导......
  • Navicat使用笔记08---利用Navicat进行数据迁移
    1.使用背景需要将一台服务器上mysql数据迁移到另一台服务器的mysql中2.单库迁移2.1在目标服务器中创建一个和源服务器数据库名称一样的数据库2.2创建任务开始迁移......