研一
C语言 变长参数表
C语言中printf, scanf等函数都是可变长度函数,可变长度函数的实现实质上是C语言维护了一个未命名的参数表。该参数表由va_list类型获取,在可变长度函数中,需要先用
va_list ap;
类似的语句进行指针声明,然后使用:
va_start(ap, last_input_param);
语句对该指针初始化,指针应当指到已命名的最后一个参数上。接着便需要向ap指针传入相应未命名参数的类型以提供内存指针偏移量:
val1 = va_arg(ap, int);
val2 = va_arg(ap, char);
val3 = va_arg(ap, char *);
当到达参数尾的时候需要调用va_end函数来执行对ap的清理工作:
va_end(ap);
va_start函数可以执行多次以重复对传入的参数进行多次处理。
DES S盒研究
昨天仍对DES仍遗留了一些疑问,其中之一是在加密的过程中,数据经过S盒的代换之后是如何再次在解密的过程中恢复的。当S盒对数据进行了一次代换,生成了一个代换值,而相同的代换值在一个S表中存在4个(每一行都有一个),那么在解密的时候怎么知道这个值对应的是哪个地方生成的值呢?今天对这个问题进行了一些思考,最终仍无结论,但可以肯定的是S盒中的运算并不会使得数据的丢失。尽管6bits变成了4bits,但需要注意到在该轮运算的初始阶段数据即为4bits,增加的2bits不过是L的32bits在扩展阶段增加的,而每6bits的分组中增加的位置也是第一位和最后一位,而在进入S盒后被丢弃的两位也是首尾的bits,所以无论在加密还是解密阶段,都没有产生数据的损失,数据的还原是没有问题的。除此之外,从S盒传出的数据是该轮密钥和输入的L共同运算得到的结果,因此对于每6bits的分组,到底最终传出的是哪一行的值也是由数据和该轮密钥共同决定的。所以对于解密阶段轮密钥的使用应当是逆过来的,可以类比为ISO七层网络协议来想,数据从应用层传出后不断被下层封装处理,最终到达接收方后需要从底层逐层网上解封装。DES的每层轮函数都可以想成对数据进行一次封装,而解密方也需要对应依次将数据解封装,解封装的密钥则依次是加密密钥顺序反过来排列,即一个栈的数据结构。
具体该问题等明天看看论文再说,今天已经把DES的运算过程搞明白了。
SM2 相关ASN1 结构
SM2值得记住的OID由1.2.156.10197, 1.2.840.10045
《SM2密码算法加密签名消息语法规范》GM/T 0010 包括对象标识符,数据格式
《基于SM2密码算法的数字证书格式规范》 GM/T 0015
《SM2密码算法使用规范》 GM/T 0009 包含对密钥数据格式,加密数据格式,签名数据格式,密钥对保护数据格式,签名预处理,加密签名解密验签密钥协商的规范要求。