区块链 区块链技术 比特币公众号手机端

QARMA可调分组密码(TBC)

liumuhui 4小时前 阅读数 1 #区块链

QARMA 可调分组密码(TBC)

是时候构建在设计上就安全的系统了,而不是依靠零散的安全补丁拼凑而成。因此,我们经常加密静态数据(例如使用 AES),也经常加密空中传输的数据(例如使用 TLS),但为什么不对进程内的数据进行加密呢?那么,来认识一下 QARMA(Qualcomm ARM Authenticator)分组密码吧,它擅长在内存中加密,这样入侵者就无法窥探运行中的内存并发现机密。

QARMA [1] 是一个轻量级可调分组密码家族,可用于内存加密、为硬件辅助的软件漏洞利用防护(如内存分析)生成极短标签,以及创建带密钥的哈希函数。它基于 PRINCE [2] 和 MANTIS [3] 密码,但增加了一个 tweak 输入。

QARMA 支持 64 位和 128 位的分组大小,其中分组与 tweak 等长,而密钥长度是分组的两倍。它通常是一种低延迟密码。我们也可以实现 QARMA-128,它具有 128 位分组大小和 256 位加密密钥。目标架构是 ARMv8,其主要用途是内存加密。在本例中,我们将实现 QARMA-64,它具有 64 位分组大小和 128 位密钥。

对于可调分组密码(TBC),我们使用密钥对明文或密文进行运算,但还需要一个公开的 tweak 值。通过密钥和 tweak 值,我们为每个分组生成所需的密码置换。这通常用于磁盘和内存加密,我们可以为每个分组设置不同的 tweak,例如针对给定的分组号递增公开 tweak。

代码

代码概要参见此处:

import sys

tweak = 0x477D469DEC0B8762
block_tweak = (tweak + i) & 0xFFFFFFFFFFFFFFFF

def string_to_blocks(message):
    """
    将 UTF-8 字符串转换为 64 位分组。
    使用 PKCS#7 风格的填充,使其为 8 字节的倍数。
    """
    data = message.encode("utf-8")
    # QARMA-64 分组大小为 8 字节
    padding = 8 - (len(data) % 8)
    data += bytes([padding]) * padding
    blocks = []
    for i in range(0, len(data), 8):
        block = int.from_bytes(data[i:i+8], byteorder="big")
        blocks.append(block)
    return blocks

def blocks_to_string(blocks):
    """
    将解密后的 64 位分组转换回 UTF-8 字符串。
    """
    data = b""
    for block in blocks:
        data += block.to_bytes(8, byteorder="big")
    # 移除填充
    padding = data[-1]
    if padding < 1 or padding > 8:
        raise ValueError("Invalid padding")
    data = data[:-padding]
    return data.decode("utf-8")

def encrypt_string(message, tweak, key, rounds=7):
    blocks = string_to_blocks(message)
    ciphertext = []
    for block in blocks:
        c = qarma64(
            block,
            tweak,
            key,
            encrypt=True,
            rounds=rounds
        )
        ciphertext.append(c)
    return ciphertext

def decrypt_string(ciphertext, tweak, key, rounds=7):
    plaintext = []
    for block in ciphertext:
        p = qarma64(
            block,
            tweak,
            key,
            encrypt=False,
            rounds=rounds
        )
        plaintext.append(p)
    return blocks_to_string(plaintext)

c = qarma64(
    block,
    block_tweak,
    key,
    encrypt=True,
    rounds=rounds
)
## ---------------------------------------------------------
## 主程序
## ---------------------------------------------------------
if __name__ == "__main__":

    # 示例 QARMA 参数

    w0 = 0x84BE85CE9804E94B
    k0 = 0xEC2802D4E0A488E9
    key = (w0 << 64) | k0
    rounds = 7
    # 获取明文
    if len(sys.argv) > 1:
        message = " ".join(sys.argv[1:])
    else:
        message = input("Enter plaintext: ")
    print()
    print("QARMA-64")
    print("=" * 60)
    print(f"Plaintext : {message}")
    print(f"Tweak     : {tweak:016X}")
    print(f"Key       : {key:032X}")
    print(f"Rounds    : {rounds}")

    # 加密
    ciphertext = encrypt_string(message,tweak,key,rounds)
    print()
    print("Ciphertext blocks:")
    for i, block in enumerate(ciphertext):
        print(f"  Block {i:2}: {block:016X}")
    # 将密文合并为一个十六进制字符串
    ciphertext_hex = "".join(f"{block:016X}" for block in ciphertext)
    print()
    print(f"Ciphertext: {ciphertext_hex}")

    # 解密
    recovered = decrypt_string(ciphertext,tweak,key,rounds)
    print(f"\nRecovered : {recovered}")

QARMA-64 的示例运行参见此处:

QARMA-64
============================================================
Plaintext : Testing
Tweak     : 477D469DEC0B8762
Key       : 84BE85CE9804E94BEC2802D4E0A488E9
Rounds    : 7

Ciphertext blocks:
  Block 0: 111C289ECADCF576

Ciphertext: 111C289ECADCF576
Recovered : Testing

需要注意的是,这里使用的是 64 位分组大小,共七轮。如果输入超过八个字节,我们会使用第二个分组:

QARMA-64
============================================================
Plaintext : Testing 123
Tweak     : 477D469DEC0B8762
Key       : 84BE85CE9804E94BEC2802D4E0A488E9
Rounds    : 7

Ciphertext blocks:
  Block 0: F2CE19C095D6312E
  Block 1: C4F47955E7BC11F0

Ciphertext: F2CE19C095D6312EC4F47955E7BC11F0
Recovered : Testing 123

通常,我们会力求为每个分组创建一个 tweak。

记住我,以便更快登录

你可以在这里尝试:

https://asecuritysite.com/light/quarma

参考文献

[1] Avanzi, R. (2017). The QARMA block cipher family. almost MDS matrices over rings with zero divisors, nearly symmetric even-mansour constructions with non-involutory central rounds, and search heuristics for low-latency s-boxes. IACR Transactions on Symmetric Cryptology, 4–44.

[2] Borghoff, J., Canteaut, A., Güneysu, T., Kavun, E. B., Knezevic, M., Knudsen, L. R., … & Yalçın, T. (2012, December). PRINCE–a low-latency block cipher for pervasive computing applications. In International conference on the theory and application of cryptology and information security (pp. 208–225). Berlin, Heidelberg: Springer Berlin Heidelberg.

[3] Beierle, C., Jean, J., Kölbl, S., Leander, G., Moradi, A., Peyrin, T., … & Sim, S. M. (2016, July). The SKINNY family of block ciphers and its low-latency variant MANTIS. In Annual international cryptology conference (pp. 123–153). Berlin, Heidelberg: Springer Berlin Heidelberg.

  • 原文链接: medium.com/asecuritysite...
  • 鸿途知科网 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
版权声明

本文仅代表作者观点,不代表区块链技术网立场。
本文系作者授权本站发表,未经许可,不得转载。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门