当前位置: 首页 > news >正文

chacha20 算法流程

chacha20算法请参看 RFC:7539。下面是我的理解,欢迎指正。

chacha20算法的基本思想:加密时,将明文数据与用户之间约定的某些数据进行异或操作,得到密文数据;由异或操作的特点可知,在解密时,只需要将密文数据与用户之间约定的那些数据再次进行异或操作,就得到了明文数据。

用相同值异或两次就能恢复出原来的值,所以加密和解密都严格采用同一个程序。

从原理上来说,chacha20的加解密过程还是非常简单的。这里面的难点在于理解 chacha20中那些用来与明文数据进行异或的数据是如何生成的,这就是 chacha20算法的核心所在。

大体的流程是这样的:首先,用户之间会约定一些初始的元数据,简单起见,称之为 KEYS_INIT,则 KEYS_INIT需要经过某种运算,得到另外一个 KEYS_1,然后用 KEYS_1与明文数据的第 1个分组进行异或,以得到密文数据的第 1个分组,接下来,KEYS_INIT再经过某种运算,得到另外一个 KEYS_2,然后用 KEYS_2与明文数据的第 2个分组进行异或,以得到密文数据的第 2个分组,以此类推,直到处理完所有的明文分组。从这里可以看到,与每个明文分组进行异或的数据(KEY_n)是不相同的,且与分组所对应的顺序有关。

下面讲解一下如何由 KEY_INIT得到 KEY_1, KEY_2, ..., KEY_n

首先需要明确的是,在 chacha20算法中,KEY_INITKEY_n的长度是相同的,都是 64个字节。因此,明文分组的长度也是 64字节,即 164字节整数。
其中,KEY_INIT4部分组成:
KEY_INIT[0]~ KEY_INIT[15]16字节的常量(constant);
KEY_INIT[16]~ KEY_INIT[47]32字节的 key;
KEY_INIT[48]~ KEY_INIT[51]4字节的 block counter;
KEY_INIT[52]~ KEY_INIT[63]12字节的 nonce

按顺序将上述 164字节整数排列成 4x4的矩阵,记为矩阵 M,它的内容示意如下:

cccccccc  cccccccc  cccccccc  cccccccc
kkkkkkkk  kkkkkkkk  kkkkkkkk  kkkkkkk
kkkkkkkk  kkkkkkkk  kkkkkkkk  kkkkkkk
bbbbbbbb  nnnnnnnn  nnnnnnnn  nnnnnnnn

其中,
c表示 constant4bit;
k表示 key4bit;
b表示 block counter4bit;
n表示 nonce4bit

上面之所以把 64字节的 KEY_INIT排列成矩阵的形式,是因为后续的计算都是在这个矩阵上展开的,写成矩阵形式后,能很清楚看到每次参与计算的元素的相对位置。

基于上述的 4x4矩阵,chacha20里面的运算包含两种形式:列运算对角线运算。先暂时不说列运算对角线运算的具体含义,先讲讲计算中涉及的 "轮"的概念,简单讲,"轮"是若干个运算步骤的组合,chacha20中的 20就是指进行 20轮运算。在 chacha20中, 1"轮"还可以进一步划分为 4"四分之一轮",也就是说,chacha20包含 80四分之一轮组成的运算。

终于讲到四分之一轮的概念了,先给出四分之一轮的定义,如下所示:

a += b; d ^= a; d <<<= 16;
c += d; b ^= c; b <<<= 12;
a += b; d ^= a; d <<<= 8;
c += d; b ^= c; b <<<= 7;

从上述定义可以看到,四分之一轮的定义很简单,只有 4个变量参与运算,共计 12个基本操作,涉及 3种普通运算:加法、异或、循环移位。值得注意的是,这 4个变量都是 4字节整数,加法运算是模 2^32的。

现在可以猜到,在每个四分之一轮中,a, b, c, d44字节整数均来自于矩阵 M,现在来讲讲列运算对角线运算的含义。先用 4字节整数出现的顺序来重新表示矩阵 M,记为矩阵 T

0    1    2    3 
4    5    6    7
8    9    10   11
12   13   14   15

有了上述索引表示,则所谓的列运算就是:在四分之一轮中,a, b, c, d44字节整数在矩阵 M中的索引为矩阵 T的某个列向量
具体来说就是,
对于第 1四分之一轮而言,a, b, c, d在矩阵 M中的索引为 0, 4, 8, 12
对于第 2四分之一轮而言,a, b, c, d在矩阵 M中的索引为 1, 5, 9, 13
对于第 3四分之一轮而言,a, b, c, d在矩阵 M中的索引为 2, 6, 10, 14,
对于第 4四分之一轮而言,a, b, c, d在矩阵 M中的索引为 3, 7, 11, 15

同理,所谓的对角线运算就是:在四分之一轮中,a, b, c, d44字节整数在矩阵 M中的索引为矩阵 T对角线元素
具体来说就是,
对于第 1四分之一轮而言,a, b, c, d在矩阵 M中的索引为 0, 5, 10, 15
对于第 2四分之一轮而言,a, b, c, d在矩阵 M中的索引为 1, 6, 11, 12
对于第 3四分之一轮而言,a, b, c, d在矩阵 M中的索引为 2, 7, 8, 13,
对于第 4四分之一轮而言,a, b, c, d在矩阵 M中的索引为 3, 4, 9, 14

有了上述背景知识,现在就可以对 chacha20中的 20轮运算有一个整体的认识:在 chacha20中,先执行 4四分之一轮列运算,再执行 4四分之一轮对角线运算,然后将这两轮运算重复10遍,这样一共就是 20轮运算,在执行完 20轮运算后,得到一个新的矩阵,记为矩阵 S,然后还需要将原矩阵 M与刚刚得到的矩阵 S对应位置元素相加,以便得到最终的矩阵,记为矩阵 W,最后以小端序将矩阵 W164字节整数整理为一个 64字节的数据块(也即上述中的 KEY_n),并与 64字节的明文分组相异或,得到对应的密文分组。

综上所述,在 chacha20中,明文数据会被划分为若干个 64字节的分组,然后通过 chacha20算法计算出对应的 KEY_n(也即是上述中的矩阵 W),并让明文分组与 KEY_n相异或,得到对应的密文分组。其中最重要的一点是,在每处理完一个分组后,矩阵 M中的 block counter部分需要自增 1,其他三个部分( constant, keynonce)保持不变,这样就确保了对于不同的明文分组,对应的 KEY_n是不同的。若最后一个明文分组不足 64字节,则只异或 KEY_n中对应的字节。因此,即使明文分组不足 64字节,也不影响计算,但对应的 KEY_n的所有字节(矩阵 W的所有元素)需要被全部计算出来。

忘了说了,KEY_INIT中的前 16字节 constant是个字符串,它的内容是:"expand 32-byte k",数一下应该是 16字节。

下面给出 chacha20算法的 C语言实现,摘自 OpenSSL项目的 crypto/chacha/chacha_enc.c文件,可以在 githubgitee上再看看这段代码:
https://github.com/openssl/openssl/blob/master/crypto/chacha/chacha_enc.c
https://gitee.com/mirrors/openssl/blob/master/crypto/chacha/chacha_enc.c

typedef unsigned int u32;
typedef unsigned char u8;
typedef union {u32 u[16];u8 c[64];
} chacha_buf;# define ROTATE(v, n) (((v) << (n)) | ((v) >> (32 - (n))))# define U32TO8_LITTLE(p, v) do { \(p)[0] = (u8)(v >>  0); \(p)[1] = (u8)(v >>  8); \(p)[2] = (u8)(v >> 16); \(p)[3] = (u8)(v >> 24); \} while(0)/* QUARTERROUND updates a, b, c, d with a ChaCha "quarter" round. */
# define QUARTERROUND(a,b,c,d) ( \x[a] += x[b], x[d] = ROTATE((x[d] ^ x[a]),16), \x[c] += x[d], x[b] = ROTATE((x[b] ^ x[c]),12), \x[a] += x[b], x[d] = ROTATE((x[d] ^ x[a]), 8), \x[c] += x[d], x[b] = ROTATE((x[b] ^ x[c]), 7)  )/* chacha_core performs 20 rounds of ChaCha on the input words in* |input| and writes the 64 output bytes to |output|. */
static void chacha20_core(chacha_buf *output, const u32 input[16])
{u32 x[16];int i;DECLARE_IS_ENDIAN;memcpy(x, input, sizeof(x));for (i = 20; i > 0; i -= 2) {QUARTERROUND(0, 4, 8, 12);QUARTERROUND(1, 5, 9, 13);QUARTERROUND(2, 6, 10, 14);QUARTERROUND(3, 7, 11, 15);QUARTERROUND(0, 5, 10, 15);QUARTERROUND(1, 6, 11, 12);QUARTERROUND(2, 7, 8, 13);QUARTERROUND(3, 4, 9, 14);}if (IS_LITTLE_ENDIAN) {for (i = 0; i < 16; ++i)output->u[i] = x[i] + input[i];} else {for (i = 0; i < 16; ++i)U32TO8_LITTLE(output->c + 4 * i, (x[i] + input[i]));}
}void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp,size_t len, const unsigned int key[8],const unsigned int counter[4])
{u32 input[16];chacha_buf buf;size_t todo, i;/* sigma constant "expand 32-byte k" in little-endian encoding */input[0] = ((u32)ossl_toascii('e')) | ((u32)ossl_toascii('x') << 8)| ((u32)ossl_toascii('p') << 16)| ((u32)ossl_toascii('a') << 24);input[1] = ((u32)ossl_toascii('n')) | ((u32)ossl_toascii('d') << 8)| ((u32)ossl_toascii(' ') << 16)| ((u32)ossl_toascii('3') << 24);input[2] = ((u32)ossl_toascii('2')) | ((u32)ossl_toascii('-') << 8)| ((u32)ossl_toascii('b') << 16)| ((u32)ossl_toascii('y') << 24);input[3] = ((u32)ossl_toascii('t')) | ((u32)ossl_toascii('e') << 8)| ((u32)ossl_toascii(' ') << 16)| ((u32)ossl_toascii('k') << 24);input[4] = key[0];input[5] = key[1];input[6] = key[2];input[7] = key[3];input[8] = key[4];input[9] = key[5];input[10] = key[6];input[11] = key[7];input[12] = counter[0];input[13] = counter[1];input[14] = counter[2];input[15] = counter[3];while (len > 0) {todo = sizeof(buf);if (len < todo)todo = len;chacha20_core(&buf, input);for (i = 0; i < todo; i++)out[i] = inp[i] ^ buf.c[i];out += todo;inp += todo;len -= todo;/** Advance 32-bit counter. Note that as subroutine is so to* say nonce-agnostic, this limited counter width doesn't* prevent caller from implementing wider counter. It would* simply take two calls split on counter overflow...*/input[12]++;}
}

参考资料:

chacha20算法的RFC: https://www.rfc-editor.org/rfc/rfc7539

相关文章:

chacha20 算法流程

chacha20算法请参看 RFC:7539。下面是我的理解&#xff0c;欢迎指正。 chacha20算法的基本思想&#xff1a;加密时&#xff0c;将明文数据与用户之间约定的某些数据进行异或操作&#xff0c;得到密文数据&#xff1b;由异或操作的特点可知&#xff0c;在解密时&#xff0c;只需…...

准备篇(三)Python 爬虫第三方库

第三方库无法将 "pip" 识别ModuleNotFoundError: No module named pip install 安装路径相关问题requests 库和 BeautifulSoup 库requests 库BeautifulSoup 库第三方库 Python 的 标准库 中提供了许多有用的模块和功能,如字符串处理、网络通信、多线程等,但它们并…...

从零开始的PICO开发教程(4)-- VR世界 射线传送、旋转和移动

从零开始的PICO开发教程&#xff08;4&#xff09;-- VR世界 射线传送、旋转和移动 文章目录 从零开始的PICO开发教程&#xff08;4&#xff09;-- VR世界 射线传送、旋转和移动一、前言1、大纲 二、VR射线移动功能实现与解析1、区域传送&#xff08;1&#xff09;新建 XR Orig…...

防止攥改之水印功能组件

防止攥改之水印功能组件 效果图逻辑代码 效果图 逻辑代码 <template><div class"containerBox" ref"parentRef" style"height: 300px;background-color: red;"><slot></slot></div> </template><script…...

iOS 17 适配 Xcode 15 问题

在适配 iOS 17 xcode 15时遇到的问题&#xff0c;记录一下。 1、 Could not build module ‘WebKit’ type argument nw_proxy_config_t (aka struct nw_proxy_config *) is neither an Objective-C object nor a block type解决方案&#xff1a; 选中不能编译的库的xcodep…...

Element Plus 快速开始

1.完整引入&#xff08;全局引入&#xff09; // main.ts import { createApp } from vue import ElementPlus from element-plus import element-plus/dist/index.css import App from ./App.vueconst app createApp(App)app.use(ElementPlus) app.mount(#app) npm install e…...

华为云云耀云服务器L实例评测|StackEdit中文版在线Markdown笔记工具

华为云云耀云服务器L实例评测&#xff5c;StackEdit中文版在线Markdown笔记工具 一、云耀云服务器L实例介绍1.1 云服务器介绍1.2 应用场景1.3 支持镜像 二、云耀云服务器L实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 StackEdit 中文版3.1 StackEdit 介绍3.2 环…...

MyEclipse报错javax/persistence/EntityManagerFactory

MyEclipse报错&#xff1a; Build path is incomplete. Cannot find class file for javax/persistence/EntityManagerFactory 解决方案&#xff1a; 引入依赖 <dependency><groupId>javax.persistence</groupId> <artifactId>persistence-api</a…...

【MySQL进阶】SQL性能分析

一、SQL性能分析 1.SQL执行频率 MySQL 客户端连接成功后&#xff0c;通过 show [session|global] status 命令可以提供服务器状态信 息。通过如下指令&#xff0c;可以查看当前数据库的 INSERT 、 UPDATE 、 DELETE 、 SELECT 的访问频次&#xff1a; -- session 是查看当…...

在SpringBoot项目中整合SpringSession,基于Redis实现对Session的管理和事件监听

1、SpringSession简介 SpringSession是基于Spring框架的Session管理解决方案。它基于标准的Servlet容器API&#xff0c;提供了Session的分布式管理解决方案&#xff0c;支持把Session存储在多种场景下&#xff0c;比如内存、MongoDB、Redis等&#xff0c;并且能够快速集成到Spr…...

浅析vue中computed,method,watch,watchEffect的区别

方法methods只要调用每次都会执行watch(惰性)只有依赖项更新才会执行回调函数&#xff0c;且组件初次渲染不会执行watchEffect:自动追踪依赖变化&#xff0c;只要依赖更新即执行回调函数&#xff0c;且组件初次渲染即执行回调函数computed(惰性): 返回一个只读的ref,具有缓存功…...

activiti7的数据表和字段的解释

activiti7的数据表和字段的解释 activiti7版本有25张表&#xff0c;而activiti6有28张表&#xff0c;activiti5有27张表&#xff0c;绝大部分的表和字段的含义都是一样的&#xff0c;所以本次整理的activiti7数据表和字段的解释&#xff0c;也同样适用于activiti6和5。 1、总览…...

Java手写Trie树和Trie树应用拓展案例

Java手写Trie树和Trie树应用拓展案例 1. 算法思维导图 以下是使用mermaid代码表示的Trie树的实现原理&#xff1a; #mermaid-svg-5twy24X7Wqbhyulb {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-5twy24X7Wqbhyul…...

alova.js快速入门教程

官网地址&#xff1a;Alova.JS - Lightweight request strategy library | Alova.JS 目录 一、alova 是什么&#xff1f; 二、 快速入门 1、安装依赖 &#xff08;1&#xff09;使用npm方式安装 &#xff08;2&#xff09;使用yarn方式安装 2、在静态 html 中使用 一、al…...

获取IP地址-根据IP获取位置信息

获取外网IP地址&#xff0c;并得到该地址所在位置&#xff1b; 如&#xff1a;101.249.255.255 对应&#xff1a;西藏自治区-拉萨市-堆龙德庆区 string ipAddress GetIPAddress(); string location GetIPLocation(ipAddress); /// <summary>/// 获取IP地址/// </s…...

Android13适配-Google官方照片视频选择器

官方照片选择器 图 1. 照片选择器提供了一个直观的界面&#xff0c;便于与您的应用分享照片。 照片选择器的界面可供浏览和搜索&#xff0c;并按日期降序向用户显示其媒体库中的文件。如隐私保护最佳实践 Codelab 中所示&#xff0c;照片选择器为用户提供了一种安全的内置授权…...

云计算的发展趋势和挑战

本文将探讨云计算的发展趋势和挑战&#xff0c;旨在帮助读者了解云计算的最新动态和未来发展方向。 随着信息技术的发展&#xff0c;云计算作为一种新兴的计算模式&#xff0c;已经得到了广泛的应用和认可。它通过将计算资源、存储资源和应用程序等服务通过互联网提供给用户&a…...

PyG-GAT-Cora(在Cora数据集上应用GAT做节点分类)

文章目录 model.pymain.py参数设置运行图 model.py import torch.nn as nn from torch_geometric.nn import GATConv import torch.nn.functional as F class gat_cls(nn.Module):def __init__(self,in_dim,hid_dim,out_dim,dropout_size0.5):super(gat_cls,self).__init__()s…...

java专项练习(验证码)

package 专题练习;import java.util.Random;public class Developing_CAPTCHA {public static void main(String[] args) {/* 需求:定义方法生成一个5位的验证码 验证码长度为5,前四位为大或小写字母,最后一位是数字*///方法: 如果我们要在一堆没有规律的数据中随机抽取,可以先…...

MS1861 视频处理与显示控制器 HDMI转MIPI LVDS转MIPI带旋转功能 图像带缩放,旋转,锐化

1. 基本介绍 MS1861 单颗芯片集成了 HDMI 、 LVDS 和数字视频信号输入&#xff1b;输出端可以驱动 MIPI(DSI-2) 、 LVDS 、 Mini-LVDS 以及 TTL 类型 TFT-LCD 液晶显示。可支持对输入视频信号进行滤波&#xff0c;图 像增强&#xff0c;锐化&#xff0c;对比度调节&am…...

广州华锐互动:利用VR复原文化遗址,沉浸式体验历史文物古迹的魅力

在过去的几十年里&#xff0c;科技发展飞速&#xff0c;为我们打开了无数新的视角和可能性。其中&#xff0c;虚拟现实&#xff08;Virtual Reality&#xff0c;简称VR&#xff09;技术的崭新应用&#xff0c;为我们提供了一种全新的、近乎身临其境的体验历史的方式。本文将重点…...

微信小程序——事件监听

微信小程序是一种轻量级的应用程序&#xff0c;它在移动设备上提供了丰富的用户体验。在开发微信小程序时&#xff0c;事件监听是一项重要的技术&#xff0c;它允许开发者捕捉和处理用户的各种操作。本文将介绍微信小程序事件监听的概念、用法和一些实用示例。 1. 什么是事件监…...

View绘制流程的源码所得

一些问题 子线程可以更新 UI 吗 答案是可以的&#xff0c;在特定的情况下可以 可以先在主线程中调用requestLayout() 方法&#xff0c;然后紧接着在子线程中更新UI&#xff08;原理&#xff1a;不要在子线程触发 checkThread() 方法&#xff0c;而checkThread() 方法的调用时…...

企业级数据仓库-理论知识

D3 AM 大数据中间件 Hive&#xff1a;将SQL转化成分布式Map/Reduce进行运算&#xff0c;也支持转换成Spark,需要单独安装Hive集群才能访问Spark,支持60%的SQL&#xff0c;延迟比较大。SparkSQL:属于Spark生态圈&#xff0c;Hive on Sqark。HBase: NoSQL,高并发读&#xff0c;适…...

解决flutter不识别yaml里面配置的git项目

解决办法找到相应的 git路径&#xff0c;然后手动 git pull 暂时先用这个笨方法&#xff0c;后面有更好的解决办法了再说 studio 自己拉取的项目里面没有ios 和lib包...

rust结构体

一、定义结构体类型 语法 struct Name_of_structure {field1: data_type,field2: data_type,field3: data_type, }注意&#xff1a; 不同于C&#xff0c;Rust的struct语句仅用来定义类型&#xff0c;不能定义实例。 结尾不需要;。 每个字段定义之后用 , 分隔。最后一个逗号可…...

Python - 小玩意 - 键盘记录器

pip install keyboardimport keyboard import timedef get_time():date_time time.strftime("%Y-%m-%d %H:%S", time.localtime())return date_timedef abc(x):if x.event_type down:print(f"{get_time()}你按下了{x.name}")with open(./键盘记录器.txt,…...

msvcp71.dll丢失的解决方法分享,全面分析msvcp71.dll丢失原因

msvcp71.dll 丢失的问题可能困扰着许多使用 Windows 操作系统的用户。msvcp71.dll 是微软 C运行时库中的一个动态链接库文件&#xff0c;负责提供一些基本的函数和类&#xff0c;例如字符串处理、数学运算、文件操作等。如果这个文件丢失或损坏了&#xff0c;那么在使用依赖于它…...

stm32----ADC模数转换

一、ADC介绍 ADC&#xff0c;即模数转换器&#xff0c;它可以将模拟信号转化为数字信号。在stm32种一般有3个ADC&#xff0c;每个ADC有18个通道。 12位ADC是一种逐次逼近型模拟数字转换器&#xff0c;它有多达18个通道&#xff0c;可测量16个外部和两个内部信号源。各个通道的A…...

Unity SteamVR 开发教程:用摇杆/触摸板控制人物持续移动(2.x 以上版本)

文章目录 &#x1f4d5;教程说明&#x1f4d5;场景搭建&#x1f4d5;创建移动的动作&#x1f4d5;移动脚本⭐移动⭐实时调整 CharacterController 的高度 &#x1f4d5;取消手部和 CharacterController 的碰撞 持续移动是 VR 开发中的一个常用功能。一般是用户推动手柄摇杆&…...

临沂网站优化哪家好/产品质量推广营销语

"whats" 是 "what is" 的缩写,表示"什么是"的意思,常用来询问对方关于某些事物的细节或信息。例如: "Whats your name?" (你叫什么名字?)...

余姚网站建设的公司/培训学校加盟费用

大家好&#xff0c;我是老赵一. 介绍FACE-UI 基于前后端分离Web端项目&#xff0c;主要实现了网页版的人脸登录&#xff0c;通过调取前端摄像头拍照&#xff0c;传入后台进行跟数据库人脸库的相似度比对。技术点&#xff1a;Springboot&#xff0c;Mysql&#xff0c;JWT&#x…...

贵阳专业做网站的公司有哪些/高级搜索引擎

第13周作业-多线程 1. 本周学习总结 以你喜欢的方式&#xff08;思维导图、OneNote或其他&#xff09;归纳总结多网络相关内容。 1.常用端口号&#xff1a;Web服务&#xff1a;80 FTP服务&#xff1a;21 Telnet服务&#xff1a;23 2.网络常用命令(cmd)&#xff1a;ipconfig …...

暴雪战网官方网站入口/网站快速优化排名推荐

Jquery on("click") 方法绑定事件后执行多次解决办法参考文章&#xff1a; &#xff08;1&#xff09;Jquery on("click") 方法绑定事件后执行多次解决办法 &#xff08;2&#xff09;https://www.cnblogs.com/yangsoon/p/6593021.html 备忘一下。...

网页框架设计/流程优化的七个步骤

在近日举行的JP摩根技术峰会上&#xff0c;AMD CEO苏姿丰确认&#xff0c;采用7nm工艺制程的AMD芯片将会在今年流片&#xff0c;而采用7nm工艺制程的AMD处理器和显卡最快能在2018年年底亮相。千万不要以为2018年年底展示7nm工艺制程成品没什么稀奇的&#xff0c;AMD的老冤家英特…...

百度制作网站推广/网络平台推广运营公司

今天踩了一堆的坑&#xff0c;记录一下。安装logstash的过程很不顺利https://www.elastic.co/downloads/logstash在releases版本中选择与ES相同版本下载$echo "export PATH\$PATH:/opt/app/logstash-6.3.1/bin" > /etc/profile.d/logstash.sh$cd logstash-6.3.1/a…...