密码学常用基本数据类型和运算在不同语言当中的体现

admin 2023年2月18日09:37:59评论29 views字数 3393阅读11分18秒阅读模式

密码学常用基本数据类型和运算在不同语言当中的体现

密码学常用基本数据类型和运算在不同语言当中的体现

在密码学当中,我们核心需要处理的东西其实就是数据,对于数据我们一般需要考虑的可能是2个问题,一方面这个数据如何存储,另一个是这些数据如何处理或者说可以做什么运算。本文呢,就来聊一聊在密码学当中常见的数据存储或者运算方案在不同语言当中的体现,当然这一篇文章纯属我个人的理解,如果理解有偏差也欢迎读者和我交流。

数据类型

在编程语言的学习过程当中,我们常见的基本类型有不少,比如数值类型,布尔类型,字符串类型等等,但是对于实际在内存当中的存储,最小单位实际上还是字节。在任何的存储方式当中,具体存储的内容是什么含义是根据当前程序解析的,和具体保存在存储器当中的比特流其实是没有关系的,我们来看一个简单的例子。

密码学常用基本数据类型和运算在不同语言当中的体现
同样的内存数据的不同呈现形式

从上面这张图我们便可以看出,我们保存在内存当中的数据和具体呈现形式实际上是无关的,而对于密码学来说,我们实际上并不关心数据的具体体现形式,而是关心的是实际保存在存储器当中的数据,因此我们不需要关心这么多类型,个人理解我们关注下面三个类型就足够了。

  • UINT8
  • UINT32
  • UINT64

第一个是存储的最小的存储单元,所有数据实际上都可以看成UINT8的数组,但是我们在计算过程当中,经常会用到32位或者64位的寄存器,如果全都表示为UINT8实际上会比较麻烦,比如说MD5当中的状态数组就是4个UINT32的类型,而对于SHA3/512来说,他的状态数组当中使用的则为UINT64,其他数据处理形式,都可以看做上面这三种,因为128位的寄存器用的还是少,也没有太多的算法直接用到了这个寄存器,因此U128这个就不放进来了,而且支持U128的编程语言也不多。

不同编程语言的表示

我们聊完了具体密码学当中常用的数据类型,因为密码学算法实际上和编程语言无关的,我们可以用我们喜欢的任意语言来实现密码学的算法,然后我们来看下上面说的三个类型在不同的编程语言当中具体体现形式,个人理解可以分成三类。

  • 全类型: 本身编程语言当中支持这三种类型,常见的语言有C、C++、Go、Rust等。
  • 半全类型: 本身语言是不支持无符号数字的,或者仅有他们当中的部分,常见的语言有Java、JavaScript等。
  • 其他: 这个我能想到的语言只有Python,因为Python当中的数字类型本身是一个大数对象,而不是像我们上面说的直接在内存当中表示的数值,因此这个不方便把他们归结到上面这两种,其实这个就是一个都没有的类型,这个处理是方便了大数的运算,我们不需要考虑溢出的情况,但是在某些我们需要特定大小的类型下就会显得些许繁琐,需要自己做个小的转换。

接下来,我们就根据上面这三类来分别讨论他们的使用情况,因为这三类里面的语言,对于处理是一致的,因此我这里分了三类。

全类型

对于全类型来说,这个是最好处理的,因为不需要处理,我们本身就可以正常使用了。

半全类型

对于半全类型来说,基本都会给我们提供一个无符号右移的函数>>>,这样我们就可以来按照无符号数组来处理这个东西了。

其他

这个其他实际上只有Python,因为Python的运算不会溢出,而且也没提供无符号右移的相关函数,因此我们这里需要做一些特殊的处理,这里先补充一个无符号右移的方案,因为我们这里是有三种类型的,分别给出一下对应的无符号右移的代码吧。

import ctypes


def unsigned_right_shift_uint8(x, y):
    x, y = ctypes.c_uint8(x).value, y & 0xFF
    return ctypes.c_uint8(x >> y).value


def unsigned_right_shift_uint32(x, y):
    x, y = ctypes.c_uint32(x).value, y & 0xFFFFFFFF
    return ctypes.c_uint32(x >> y).value


def unsigned_right_shift_uint64(x, y):
    x, y = ctypes.c_uint64(x).value, y & 0xFFFFFFFF_FFFFFFFF
    return ctypes.c_uint64(x >> y).value


if __name__ == '__main__':
    print(hex(unsigned_right_shift_uint8(-10)))
    print(hex(unsigned_right_shift_uint32(-10)))
    print(hex(unsigned_right_shift_uint64(-10)))

对于左移,Python实际上也需要处理下,因为Python的左移是没有溢出的,这里同样直接给出代码了。

def left_shift_uint8(x, y):
    return (x << y) & 0xFF


def left_shift_uint32(x, y):
    return (x << y) & 0xFFFFFFFF


def left_shift_uint64(x, y):
    return (x << y) & 0xFFFFFFFF_FFFFFFFF


if __name__ == '__main__':
    print(hex(left_shift_uint8(-11)))
    print(hex(left_shift_uint32(-11)))
    print(hex(left_shift_uint64(-11)))

这样机制,其实在Python当中的处理过程是繁琐的,相比于其他带有这些类型的语言,需要做一些额外的操作。

运算

上面我们聊完了密码学当中的数据类型,然后呢,有了数据,那我们就要考虑针对于这些数据的具体的运算,常见的运算符如下。

  • +: "广义"加法运算
  • *: "广义"乘法运算
  • &: 与运算
  • |: 或运算
  • ^: 异或运算
  • %: 取余运算
  • <<: 无符号左移
  • >>: 无符号右移
  • <<<: 循环左移
  • >>>: 循环右移

这里说一下,我上面列出来的这些运算,和具体的编程语言是无关的,当然也不是所有编程语言都给提供了这些运算符的,这里针对运算符来说,我来稍微解释一下,因为这个是我自己的理解出来的,如有雷同,纯属巧合,这里只写出了加法和乘法运算,因为在密码学当中,我们处理的所有数据实际上都在域或者环上,针对不同的域或者环来说,他们的加法和乘法运算不一定相同,这里不是我们说的实数意义上的加法运算,而是在特定的代数系统下的加法和乘法运算,这块如果不理解,可以忽略上面这一段文字,只要理解这是一种特殊定义的加法和乘法运算就可以了(如果有兴趣的读者可以学习一下有关抽象代数当中的相关内容,或者看一下我写的有关有限域的那一篇文章,这里不展开来讲了,因为展开来讲,东西就太多了)。剩余的那些是为了处理位运算,这里所有的位运算都是基于上面说的那三种数据类型来的,也就是均不予考虑符号。

总结

本文呢,我们主要是讨论了一下在密码学当中的常用数据类型(我自己定义的),以及他们之间的运算律,通过这些,我们实际上可以用上面的东西来描述具体的密码学算法的,如果大家去看密码学的相关论文或者rfc的话,在前面绝大多数文章都会标明他们用的数据类型和运算,这个实际上也没啥通用的定义,只要在前面说明白就好了,我是没找到有啥规定的地方,我发现的使用形式就好几种了,包括不同的符号表示。最后呢,来个投票吧,大佬们最常用的编程语言是什么,后面文章我考虑下优先使用投票数目比较多的语言,其他语言就不要提了,比如易语言之类的,因为我不会。这里最多选择三个,多选的无效蛤,最终解释权归本人所有。

参考资料

  • [数学基础-有限域](https://mp.weixin.qq.com/s/r_QOcDFqXW3biIpS0rjAJg[1])

Reference

[1]

https://mp.weixin.qq.com/s/r_QOcDFqXW3biIpS0rjAJg: https://mp.weixin.qq.com/s/r_QOcDFqXW3biIpS0rjAJg


原文始发于微信公众号(Coder小Q):密码学常用基本数据类型和运算在不同语言当中的体现

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年2月18日09:37:59
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   密码学常用基本数据类型和运算在不同语言当中的体现https://cn-sec.com/archives/1559424.html

发表评论

匿名网友 填写信息