nsa的simon和speck分组密码的实现

simonspeckciphers的Python项目详细描述


python 3.x/2.x中的simon&speck块密码

Simon and Speck块密码的纯python实现。这些是由{a2}设计的小型密码,用于受限硬件和软件环境,如微控制器或小型asic/fpgas。

警告以下实现仅用于参考/研究/娱乐,不应被视为100%没有错误或副频道攻击。不鼓励在生产环境中使用。

安装

simon/speck套件可以通过pipPyPi安装:

pip install simonspeckciphers

如果pip不可用,则下载或克隆此项目并从以下目录运行:

python setup.py install

其中python是最受欢迎的python interperator

您可以使用:

python setup.py test# or
py.test -xvvv

基本用法

西蒙和斯派克工作原理相同。一旦代码复制到您的项目中,就可以导入密码:

>>> from speck import SpeckCipher
>>> from simon import SimonCipher

一旦导入,就可以创建存储密码状态的密码对象。初始化密码对象所需的唯一参数是加密密钥。

>>> my_speck= SpeckCipher(0x123456789ABCDEF00FEDCBA987654321)
>>> my_simon= SimonCipher(0xABBAABBAABBAABBAABBAABBAABBAABBA)

一旦初始化,密码就可以使用encrypt()decrypt()方法加密或解密提供的明文或密文值。只要对象存在,对象将继续处理加密/解密请求。

>>> my_plaintext= 0xCCCCAAAA55553333
>>> speck_ciphertext= my_speck.encrypt(my_plaintext)
>>> speck_plaintext= my_speck.decrypt(speck_ciphertext)
>>> simon_ciphertext= my_simon.encrypt(0xFFFF0000EEEE1111)
>>> simon_plaintext= my_simon.decrypt(simon_ciphertext)

可以通过key属性读取或更新加密密钥

>>> hex(my_speck.key)'0x123456789abcdef00fedcba987654321'

块和键大小

规范中描述的所有有效键和块大小都支持作为可选参数。以位为单位的有效块和密钥大小为:

block sizekey sizes
3264
4872,96
6496,128
9696,144
128128,192,256

如果在初始化时未提供,则两个密码将默认为128位加密密钥和块大小。如果未使用默认值,建议明确指定密钥大小和块。

>>> tiny_cipher= SpeckCipher(0x123456789ABCDEF0, key_size=64, block_size=32)
>>> big_cipher= SimonCipher(0x111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000, key_size=256, block_size=128)
>>> trunc_cipher= SimonCipher(0x111122223333444455556666777788889999, key_size=96, block_size=48)
>>> hex(trunc_cipher.key)'0x444455556666777788889999'

所有输入值(键、明文、ivs等)将被截断或用零填充到块和键大小指定的位大小。当前的键和块大小可以通过key_sizeblock_size属性来访问

块模式

为了方便起见,两个密码都支持分组密码操作的most common modes

  • 电子码本ECB(speck/simon的默认模式)
  • 计数器CTR
  • 密码块链CBC
  • 传播密码块链PCBC
  • 密码反馈CFB
  • 输出反馈OFB

这些可以在初始化时使用mode可选参数启用,也可以在创建后通过mode属性启用。 除了ecb,这些模式还需要额外的初始化向量(iv)和可能的计数器。可以在创建密码时使用initcounter可选参数设置这些值。 密码在加密和解密操作之间自动更新或增加内部的iv和计数器值。操作之间不需要手动更新它们。

>>> ofb_cipher= SpeckCipher(1234, mode='OFB', init=0x999999)
>>> ctr_cipher= SimonCipher(0x525354, mode='CTR', init=0xCABCABCAB, counter=1)
>>> ctr_cipher.counter
1
>>> ofb_cipher.update_iv()10066329

在密码对象生命周期中,也可以使用update_iv()方法随时更改或读取iv。如果提供了新的iv,此方法将返回当前的iv,否则,它将返回刚刚更新的iv。可通过counter属性读取和更改密码内部计数器值。

数据类型

目前,speck和simon密码都希望输入int密钥、ivs、计数器、明文和密文。提供的任何值如果与键、明文等的位大小不匹配,则将被截断或用0填充msb,直至达到正确的大小。如果应用程序需要字符串或bytearray,则可以轻松地将输入和输出值转换为int或从int转换为int。

>>> key_bytes= bytes([0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00])# For Python 3.x Only
>>> key_int= int.from_bytes(key_bytes, byteorder='big', signed='False')# Python 2.x/3.x
>>> import binascii
>>> key_int= int(binascii.hexlify(key_bytes),16)
>>> hex(key_int)'0x112233445566778899aabbccddeeff00'
>>> msg='ATTACK AT DAWN!!'
>>> msg_int= sum([ord(c) << (8 * x)for x, c in enumerate(reversed(msg))])
>>> hex(msg_int)'0x41545441434b204154204441574e2121'
>>> new_cipher= SimonCipher(key_int, key_size=128, block_size=128)
>>> my_secret= new_cipher(msg_int)
>>> my_secret_bytes= bytearray.fromhex('{:032x}'.format(my_secret))
>>> my_secret_bytes
bytearray(b'HD\xbb\xe4\xa1\xed\x95\xd8>\x1bx<HOL[')

测试和示例

tests.py中提供了一个健壮的pytest套件。在这里,所有的官方测试向量和随机值都被执行呃。测试异常以及分组密码模式。有关如何使用每个模式的干净示例,请参阅这些测试。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java数据库返回请求检索所有记录时重复的相同记录   java swing组件使用什么来显示带有说明的照片   java每次打开一个shell   如何在Java中计算HashMap内存使用率?   java使用onClick-in按钮创建视图   java Spring MVC拦截器是否只拦截特定的映射?   使用Java中的规则将文件从一个目录复制到另一个目录   java无法在64位linux上使用9g保留堆   java如何在“@context HttpServletRequest”中插入头?   在java中处理HTTP MIME REST消息   java如何使用flyway创建数据库?   java Elasticsearch 5.5.0 maven依赖性问题   将java对象写入的文件。csv   Java捕获多个异常并识别发生的异常   C++与java的主要区别   服务中的java Void方法在集成测试中不是模拟