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

Merkle 树的认证路径

本文章翻译自David Ireland首次发表于Authentication Path for a Merkle Tree的原创文章, 强烈推荐有一定英文基础的小伙伴阅读原文。本页探讨如何计算和验证 Merkle 树的认证路径authentication path。二叉树中的路径这是一棵有 8 个节点的树在每个层级上节点从左到右编号为0 , 1 , … 0,1,\ldots0,1,…。洋红色标出的数值是该索引的二进制表示。叶子节点值Y 0 , … , Y 7 Y_0, \ldots, Y_7Y0​,…,Y7​是私钥secret keys。高度为 0 的节点被称为公钥public keys。公钥由H ( Y i ) H(Y_i)H(Yi​)计算得出其中H ( ) H()H()为某个哈希函数。路径上节点On-path nodes对于示例私钥Y 6 Y_6Y6​我们有i d x 6 idx6idx6。使用a aa位二进制数表示该索引6 110 b 6 110\text{b}6110b。我们可以利用这些二进制位从根节点出发绘制一条到达索引为 6 的叶子节点的路径。从根节点开始对于二进制表示中的每一位如果该位为 0 则向左下移动如果该位为 1 则向右下移动。按这些二进制数行进路径为0 1 → 1 1 → 11 0 → 110 0 \color{blue}{1} \rightarrow \color{magenta}{1} \color{blue}{1} \rightarrow \color{magenta}{11} \color{blue}{0} \rightarrow \color{magenta}{110}01→11→110→110。这样我们就到达了n o d e ( 0 , 6 ) node(0,6)node(0,6)如下图蓝线所示。路径上的这些节点蓝色标记称为路径上节点on-path nodes。计算认证路径认证路径节点authentication path nodes是路径上节点的兄弟节点。如果路径上节点的索引为i d x idxidx则认证路径节点的索引为i d x ⊕ 1 idx \oplus 1idx⊕1其中⊕ \oplus⊕是按位 XOR 操作。在 Python 中为idx ^ 1。操作n ⊕ 1 n \oplus 1n⊕1在n nn为偶数时等于n 1 n1n1在n nn为奇数时等于n − 1 n-1n−1即翻转最低有效位。这正是计算兄弟节点索引所需的方法。要查找索引为i d x idxidx的节点的父节点计算⌊ i d x / 2 ⌋ \lfloor idx/2 \rfloor⌊idx/2⌋。在 Python 中为idx // 2或idx 1。如果树的高度为a aa则认证路径恰好有a aa个值每个高度0 ≤ h a 0 \le h \lt a0≤ha各有一个。要计算高度大于零的认证节点值需要递归计算其子节点的值。注意这需要计算树中除路径上节点之外的所有节点的值。要查找上一层级中认证节点的索引计算⌊ i d x / 2 ⌋ ⊕ 1 \lfloor idx/2 \rfloor \oplus 1⌊idx/2⌋⊕1。在 Python 中a3# Number of levelsidx6# leaf indexauthpath[0]*a authpath[0]idx^1foriinrange(1,a):idxidx//2authpath[i]idx^1print(authpath)# [7, 2, 0]Merkle 树示例这是 Merkle 树的一个简单示例。为使树的表示更易于管理我们对哈希函数进行了简化使其仅输出 4 字节的摘要值见下文。这显然不安全但能使结果显示不那么冗长同时仍然展示出核心概念。在此示例中我们有 8 个私钥值Y 0 , … , Y 7 Y_0,\ldots,Y_7Y0​,…,Y7​每个 4 字节长以十六进制表示。这些私钥通过哈希函数make_sk基于秘密种子和密钥在树中的位置计算得到。我们使用符号( h , i ) (h, i)(h,i)表示高度为h hh、索引为i ii的节点从左到右编号从 0 开始。高度为 0 的叶子节点包含每个密钥的 4 字节哈希值( 0 , i ) H ( Y i ) (0,i)H(Y_i)(0,i)H(Yi​)。这些即为公钥。每个内部节点包含其左右子节点值的哈希值H ( l e f t ∣ ∣ r i g h t ) H(\mathtt{left} || \mathtt{right})H(left∣∣right)。Y 6 Y_6Y6​的认证路径为( 0 , 7 ) → ( 1 , 2 ) → ( 2 , 0 ) (0,7) \rightarrow (1,2) \rightarrow (2,0)(0,7)→(1,2)→(2,0)。在本例中叶子节点Y 6 20149512 Y_6\texttt{20149512}Y6​20149512认证路径值为( 0 , 7 ) 8fc53ad8 (0,7) \texttt{8fc53ad8}(0,7)8fc53ad8( 1 , 2 ) 7890c8b6 (1,2) \texttt{7890c8b6}(1,2)7890c8b6( 2 , 0 ) 076f83f6 (2,0) \texttt{076f83f6}(2,0)076f83f6有了这些值验证者可以重新计算根节点的值并将其与已发布的根值进行比较。计算根节点使用上述符号表示根节点为n o d e ( a , 0 ) node(a, 0)node(a,0)。该值作为 Merkle 签名的一部分存储用于验证已揭示私钥的认证路径。要计算根节点我们始终需要计算树中的每一个节点。有不同方法可以实现这一点。可以使用 TreeHash 算法 计算node(a, 0)。或者更简单的方法是先计算树底部的2 a 2^a2a个节点然后对每一层进行逐对哈希直到只剩一个元素。示例 Merkle 树的计算我们特殊定义的弱哈希函数H HH在 Python 中的实现如下。注意哈希摘要是对十六进制字符串解码后的二进制值进行计算然后截断得到的。importhashlibdefH(val:str)-str:Weak hash function returning hex-encoded 4-byte hash.returnhashlib.sha256(bytes.fromhex(val)).hexdigest()[:8]伪代码中的一些示例计算。Revealed secret key, Y_620149512 authpath[8fc53ad8, 7890c8b6, 076f83f6] node(0,6)H(Y_6)H(20149512)ef137f8f node(0,7)authpath[0]8fc53ad8 node(1,3)H(ef137f8f8fc53ad8)e090b2ce node(1,2)authpath[1]7890c8b6 node(2,1)H(7890c8b6e090b2ce)009a4350 node(2,0)authpath[2]076f83f6 rootnode(3,0)H(076f83f6009a4350)03583268Python 代码我们的简单函数make_sk用于派生私钥值defmake_sk(sk_seed,height,index):Generate a private key value given a secret key and address. :param str sk_seed: Secret key seed (hex string). :param int height: Height value to encode into address. :param int index: Index value to encode into address. :return: Derived private key value (4-byte hash as hex string). :rtype: str adrs{:04x}.format(height){:04x}.format(index)DPRINT(adrs,adrs,bytes.fromhex(adrs))returnH(seedadrs)# Generate all keys at leaf level 0sk_seed900150983cd24fb0# The first 8 bytes of MD5(abc)keys[make_sk(sk_seed,0,i)foriinrange(8)]print(keys ,keys)# [827efcd2, 29bb074b, a92eb2d2, e411ba45, f7d5e02e, a1644275, 20149512, 286c0ebd]使用hash_pairwise生成完整树生成整棵树的一种直接方法是取一个包含2 n 2n2n个节点的数组将值逐对哈希生成包含n nn个节点的新数组。重复此过程直到只剩下一个节点——即根节点。defhash_pairwise(hashes):Hash 2n hex values pairwise. :param list hashes: Array of 2*n hex strings to be hashed pairwise. :return: Array of n hex-encoded hash strings H(node_{2i} || node_{2i1}) for 0 i n. :rtype: list nlen(hashes)//2out[forxinrange(n)]foriinrange(n):hH(hashes[2*i]hashes[2*i1])out[i]hreturnout# Hash the keys to leaf nodeshashes[H(k)forkinkeys]print(leaf nodes,hashes)# Compute the Merkle tree nodeswhile(len(hashes)1):hasheshash_pairwise(hashes)print(hashes)roothashes[0]print(fRoot node is{root})assert(root03583268)输出keys [827efcd2, 29bb074b, a92eb2d2, e411ba45, f7d5e02e, a1644275, 20149512, 286c0ebd] size8 leaf nodes [33d97727, cbe3b654, db516084, c700ae29, 59bb626f, 804c9bdb, ef137f8f, 8fc53ad8] [9aed1e96, 2da82279, 7890c8b6, e090b2ce] [076f83f6, 009a4350] [03583268] Root node is 03583268使用 TreeHash 算法生成认证路径以下 Python 代码演示了使用我们简单哈希函数的 TreeHash 算法。gen_auth_path为给定叶子节点生成认证路径利用与 1 异或技巧向上查找兄弟节点。compute_node递归计算树中某个节点的值及其所有后代。defcompute_node(sk_seed,i,z):Compute a node in the Merkle tree. :param str sk_seed: Secret key seed (hex string). :param int i: Index of the node. :param int z: Height of the node. :return: Hash value of the node. :rtype: str nodeNoneifz0:skmake_sk(sk_seed,0,i)nodeH(sk)DPRINT(fnode: i {i}sk{sk}node{node})else:lnodecompute_node(sk_seed,2*i,z-1)rnodecompute_node(sk_seed,2*i1,z-1)nodeH(lnodernode)DPRINT(fnode: ({z},{i}){lnode}||{rnode}{node})returnnodedefgen_auth_path(sk_seed,a,idx):Generate authentication path (AUTH) for a leaf. :param str sk_seed: Secret key seed (hex string). :param int a: Height of the AUTH path. :param int idx: Leaf index for which to generate the AUTH. :return: List of node hashes (hex strings) forming the AUTH path. :rtype: list auth[None]*aforjinrange(a):sidx//(1j)^1DPRINT(fj{j}s{s})auth[j]compute_node(sk_seed,s,j)DPRINT(fauth[{j}]{auth[j]})returnauth a3idx6print(fleaf_index{idx})print(fsk[{idx}]{keys[idx]})authgen_auth_path(sk_seed,a,idx)print(auth ,auth)# auth [8fc53ad8, 7890c8b6, 076f83f6]# Compute root nodeDPRINT(Computing root...)rootcompute_node(sk_seed,0,a)print(froot{root})assert(root03583268)输出leaf_index6 sk[6]20149512 auth [8fc53ad8, 7890c8b6, 076f83f6] root03583268另外我们也可以使用hash_pairwise函数在已知全部 8 个公钥值的情况下计算认证路径# Hash the keys to leaf nodeshashes[H(k)forkinkeys]print(public keys ,hashes)# Compute AUTHPATH given public keys in hashesa3idx6print(fleaf_index{idx})print(fsk[{idx}]{keys[idx]})authpath[forxinrange(a)]iidx^1j0authpath[j]hashes[i]forjinrange(1,a):hasheshash_pairwise(hashes)i(i//2)^1authpath[j]hashes[i]print(authpath ,authpath)# authpath [8fc53ad8, 7890c8b6, 076f83f6]输出public keys [33d97727, cbe3b654, db516084, c700ae29, 59bb626f, 804c9bdb, ef137f8f, 8fc53ad8] leaf_index6 sk[6]20149512 authpath [8fc53ad8, 7890c8b6, 076f83f6]验证认证路径以下展示如何验证上述硬编码的认证路径已知可信的根节点值和已揭示的私钥。# Required root value in Merkle treeroot03583268# Authentication pathauthpath[8fc53ad8,7890c8b6,076f83f6,]print(authpath,[xforxinauthpath])# Known key valuesk20149512# Y_6print(fsk{sk})# Compute leaf value above skidx6ht0nodeH(sk)# leaf node (public key)print(fpk{node})forapinauthpath:print(f(ht,idx){ht},{idx})# Get last bit of child idxlastbitidx1# Move up to next levelidx1ht1print(fchild node{node})print(fauthpath{ap})# Last bit of child determines left/right order of authpathif(lastbit):print(fm1,m2{ap}{node})nodeH(apnode)else:print(fm1,m2{node}{ap})nodeH(nodeap)print(fnode{node})print(fRequired root{root})assert(rootnode)输出authpath [8fc53ad8, 7890c8b6, 076f83f6] sk20149512 pkef137f8f (ht,idx)0,6 child nodeef137f8f authpath8fc53ad8 m1,m2ef137f8f 8fc53ad8 nodee090b2ce (ht,idx)1,3 child nodee090b2ce authpath7890c8b6 m1,m27890c8b6 e090b2ce node009a4350 (ht,idx)2,1 child node009a4350 authpath076f83f6 m1,m2076f83f6 009a4350 node03583268 Required root03583268

相关文章:

Merkle 树的认证路径

本文章翻译自David Ireland首次发表于Authentication Path for a Merkle Tree的原创文章, 强烈推荐有一定英文基础的小伙伴阅读原文。 本页探讨如何计算和验证 Merkle 树的认证路径(authentication path)。 二叉树中的路径 这是一棵有 8 个节点的树&a…...

计算 FORS 签名

本文章翻译自David Ireland首次发表于Computing the FORS signature的原创文章, 强烈推荐有一定英文基础的小伙伴阅读原文。 让我们回顾一下 FORS 签名的相关知识。 FORS 是一种*有限次签名 (Few Time Signature, FTS)*方案,其中我们有大量可能的私钥,…...

手把手教你玩转Codesys定时器:TON、TOF、TP、RTC功能块实战配置

手把手教你玩转Codesys定时器:TON、TOF、TP、RTC功能块实战配置 在工业自动化领域,精确的时间控制往往是实现复杂逻辑的关键。想象一下,一条自动化生产线需要精确控制每个工位的停留时间,或者一个包装设备需要准确计算产品间隔——…...

从GEE下载TFRecord分片文件到本地训练?这份TensorFlow数据管道构建指南请收好

从GEE到本地训练:TensorFlow高效处理TFRecord分片文件全指南 当你在Google Earth Engine(GEE)上完成遥感影像分析后,将数据导出为TFRecord格式是进行本地模型训练的关键第一步。但面对那些以-00000到-0000N命名的分片文件&#xf…...

如何免费解锁百度网盘SVIP高速下载:macOS用户终极指南

如何免费解锁百度网盘SVIP高速下载:macOS用户终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘Mac版的龟速下载而烦恼…...

慧知开源虚拟电厂(VPP)核心平台PRD需求文档(大白话与专业结合版)- 慧知开源充电桩平台

虚拟电厂(VPP)核心平台PRD需求文档 1. 文档概述一句话大白话:虚拟电厂(VPP)就是“没有烟囱、没有发电机的电厂”,靠一套软件平台,把一堆分散的光伏、储能、充电桩、工厂可调节负荷“拼成一个大电…...

贵阳本地GEO首选贵阳伍子柒网络,懂贵阳市场,适配本地企业推广需求

在贵阳做GEO推广,为什么越来越多本地企业选择贵阳伍子柒网络?答案很简单:懂贵阳市场、适配本地需求,靠谱、省心、有效果!当前贵阳GEO市场鱼龙混杂,很多服务商要么是异地团队,不懂贵阳本地市场特…...

AHK2_Lib:让AutoHotkey V2从脚本工具蜕变为专业开发平台

AHK2_Lib:让AutoHotkey V2从脚本工具蜕变为专业开发平台 【免费下载链接】ahk2_lib 项目地址: https://gitcode.com/gh_mirrors/ah/ahk2_lib 在Windows自动化领域,AutoHotkey一直以其简洁高效的脚本能力著称。然而,当您需要构建复杂的…...

【C语言逻辑题】谋杀案凶手是谁?——经典矛盾推理题详解

一、题目背景日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。以下为4个嫌疑犯的供词:A说:不是我。B说:是C。C说:是D。D说:C在胡说。已知3个人说了真话,1个人说的是假话…...

AI代码安全执行:E2B沙箱技术原理与实战指南

1. 项目概述:当AI需要“动手”时,我们如何安全地执行它生成的代码? 在AI应用开发,尤其是大语言模型(LLM)驱动的智能体(Agent)领域,一个核心且棘手的问题是:如…...

ESP32-C3硬件I2C不够用?手把手教你用SlowSoftWire库扩展软件I2C(以VL53L0X为例)

ESP32-C3硬件I2C资源扩展实战:用SlowSoftWire实现多总线并行控制 当你在ESP32-C3上同时连接多个I2C设备时,很快就会发现这个芯片的硬件限制——它仅提供一组硬件I2C接口。这就像在高峰期的单车道公路上试图同时通行多辆卡车,必然导致交通堵塞…...

助睿实验作业1-订单利润分流数据加工

一、实验背景1.1 实验目的本次实验旨在掌握零代码数据集成平台的核心操作与 ETL 基础方法,具体包括:• 熟悉数据转换任务的创建、组件添加与任务执行的完整流程;• 掌握数据读取、多表关联、字段筛选、条件分流与文件输出等常用功能的配置&am…...

Vim集成LLM智能代理:打造沉浸式AI编程助手

1. 项目概述:当Vim遇上LLM,一个开发者的效率革命 如果你和我一样,是一个常年泡在终端和Vim里的开发者,那么你一定经历过这样的时刻:面对一段复杂的正则表达式,或者一个不熟悉的API调用,你不得不…...

AVRCP 1.6的隐藏技能:手把手教你实现蓝牙音乐封面传输(基于BIP/OBEX)

AVRCP 1.6的隐藏技能:手把手教你实现蓝牙音乐封面传输(基于BIP/OBEX) 在蓝牙音频设备的使用体验中,音乐封面传输一直是个被低估的功能。想象一下,当你用高端蓝牙耳机听歌时,耳机上的小屏幕不仅能显示歌曲信…...

【LangChain】使用 LangChain 快速实现 RAG

写在前面公司内部的技术文档、产品手册、运营报告——这些资料积累多了,想让人工智能基于它们回答问题,直接丢给 ChatGPT 不现实。文档量一大,就超出了模型的上下文窗口。RAG(检索增强生成)技术解决的就是这个问题。RA…...

2026年Python+AI工具链环境搭建指南:从零到可用的完整配置

AI辅助创作 | 专栏《2026 AI编程效率革命》第02篇 前言 很多朋友问我:"你用AI写代码效率那么高,是不是有什么秘诀?"说实话,真正的秘诀不在模型本身,而在于环境配置。一个标准化的AI开发环境能让你少踩80%的…...

SAKE基准:音频语言模型听觉属性评估与编辑新方法

1. 项目背景与核心价值音频语言模型正在成为AI领域的新前沿,但如何系统评估和编辑这类模型的听觉属性知识,一直是行业痛点。SAKE基准的提出,相当于给这个领域装上了"调试器"——它首次构建了覆盖音高、音色、响度、节奏等核心听觉维…...

告别黑窗口:用MobaXterm+VSCode搞定服务器上Matplotlib/OpenCV的可视化调试

告别黑窗口:用MobaXtermVSCode搞定服务器上Matplotlib/OpenCV的可视化调试 远程服务器上的机器学习开发常常面临一个尴尬局面:代码能跑通,但图像输出却成了"黑箱操作"。想象一下,你正在调试一个复杂的计算机视觉模型&a…...

撕开AI落地的遮羞布:大模型到底跟什么在死磕?(附架构级深度剖析)

撕开AI落地的遮羞布:大模型到底跟什么在死磕?标题:撕开AI落地的遮羞布:大模型到底跟什么在死磕?(附架构级深度剖析)标签: 架构设计、大模型应用、AI工程化、组织变革、技术商业化 咱…...

基于CPU+GPU架构的雷达信号处理快速实现CUDA【附代码】

✨ 本团队擅长数据搜集与处理、建模仿真、程序设计、仿真代码、EI、SCI写作与指导,毕业论文、期刊论文经验交流。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,查看文章底部二维码(1)基于CUDA流与共享内存的脉压并行化:雷达…...

为什么.NET 8.0.3 SDK悄悄禁用了主构造函数的隐式字段捕获?微软内部邮件首次公开解读

更多请点击: https://intelliparadigm.com 第一章:C# 13 主构造函数增强实战教程 C# 13 引入了主构造函数(Primary Constructor)的显著增强,允许在类和结构体声明中直接定义参数并自动参与成员初始化,大幅…...

Perseus:面向移动游戏的零偏移原生脚本补丁架构设计

Perseus:面向移动游戏的零偏移原生脚本补丁架构设计 【免费下载链接】Perseus Azur Lane scripts patcher. 项目地址: https://gitcode.com/gh_mirrors/pers/Perseus 在移动游戏生态中,脚本补丁技术的核心挑战在于如何平衡兼容性、稳定性与维护成…...

10B参数多模态模型STEP3-VL的技术突破与应用实践

1. 项目背景与核心突破在计算机视觉与自然语言处理交叉领域,多模态模型通常需要庞大的参数量才能实现高质量的跨模态理解。我们团队开发的STEP3-VL-10B模型,首次在10B参数规模下实现了接近百亿参数模型的性能表现。这个突破性进展来自三个关键技术革新&a…...

从L1d缓存未命中率飙升190%说起:C++27原子变量布局对齐调优——Intel Ice Lake vs AMD Zen4实测对比(附objdump反汇编验证)

更多请点击: https://intelliparadigm.com 第一章:C27原子操作性能调优的底层动因与问题定位 现代多核处理器的缓存一致性协议(如 MESI、MOESI)与内存序模型的复杂交互,正成为 C27 原子操作性能瓶颈的核心根源。随着硬…...

别再搞混了!QT Creator新建QML项目时,选qmake和CMake对资源管理的影响

QML项目构建系统选择指南:qmake与CMake在资源管理中的关键差异 当你在Qt Creator中新建一个QML项目时,第一个重要决策就是选择构建系统——这个看似简单的选择会深刻影响整个项目的资源管理方式。本文将深入剖析qmake和CMake两种构建系统在QML项目中的表…...

性能暴涨47%?揭秘.NET 9容器运行时新特性,80%开发者尚未启用的GC优化开关

更多请点击: https://intelliparadigm.com 第一章:性能暴涨47%?揭秘.NET 9容器运行时新特性,80%开发者尚未启用的GC优化开关 .NET 9 首次为容器环境深度定制了垃圾回收(GC)策略,引入 DOTNET_G…...

告别信号干扰!用Xilinx FPGA的LVDS接口实现高速稳定传输(附DPA配置避坑)

告别信号干扰!用Xilinx FPGA的LVDS接口实现高速稳定传输(附DPA配置避坑) 在高速数字系统设计中,信号完整性问题往往成为工程师的噩梦。当数据速率突破Gbps门槛时,传统的单端信号传输方式已难以满足需求——时钟抖动、串…...

PHP低代码表单引擎国产化“黑盒”拆解:AST语法树重构、ZTS线程安全补丁、国密算法内核注入(仅限首批200家信创伙伴获取的架构白皮书)

更多请点击: https://kaifayun.com 第一章:PHP低代码表单引擎国产化战略定位与信创合规基线 在信创产业纵深推进的背景下,PHP低代码表单引擎不再仅是开发提效工具,而是承载操作系统适配、数据库自主可控、中间件兼容性验证及密码…...

Node.js爬虫框架NodeClaw:模块化设计与工程化实践指南

1. 项目概述与核心价值最近在折腾一些自动化工具时,发现了一个挺有意思的项目,叫NodeClaw。乍一看这个名字,可能会联想到“节点”和“抓取”,没错,它的核心功能就是围绕Node.js环境进行数据抓取和自动化操作。这个项目…...

5分钟上手PiliPlus:开源B站客户端的跨平台终极指南

5分钟上手PiliPlus:开源B站客户端的跨平台终极指南 【免费下载链接】PiliPlus PiliPlus 项目地址: https://gitcode.com/gh_mirrors/pi/PiliPlus 你是否厌倦了官方B站客户端的广告干扰和功能限制?想要一个纯净、高效、支持全平台的B站观影体验&am…...