dsa算法(17)

本文深入探讨了Lengauer-Tarjan算法中支配树的构建过程,特别是第四步的具体实现细节,包括如何定义每个节点的直接支配者,并通过实例展示了算法的工作流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.3.2.2.3.Lengauer-Tarjan算法第四步

在第四步,240行的DT.Vertex[i]得到的是序号为i的节点。如果DT.IDoms中的节点与Semi所指的节点不一致(即直接支配者节点与半支配者节点不一致),把DT.IDoms调整为DT.IDoms[DT.IDoms[W]]。因为推论1中,当sdom(w) != sdom(v)时,Idom(w) = Idom(v),第三步并没有计算该部分,这由第四步来完成,并且239行的循环从靠近树根处开始,以确保DT.IDoms[DT.IDoms[W]]一定有意义。

 

Calculate(续)

 

238      // Step #4:Explicitly define the immediate dominator of ea ch vertex

239      for (unsignedi = 2; i <= N; ++i) {

240        typenameGraphT::NodeType* W = DT.Vertex[i];

241        typenameGraphT::NodeType*& WIDom = DT.IDoms[W];

242        if (WIDom != DT.Vertex[DT.Info[W].Semi])

243          WIDom = DT.IDoms[WIDom];

244      }

245   

246      if (DT.Roots.empty()) return;

247   

248      // Add a node forthe root.  This node might be the actualroot, if there is

249      // one exit block,or it may be the virtual exit (denoted by (BasicBlock *)0)

250      // which postdominates all real exits ifthere are multiple exit blocks, or

251      // an infiniteloop.

252      typenameGraphT::NodeType* Root = !MultipleRoots ? DT.Roots[0] : 0;

253   

254      DT.DomTreeNodes[Root] = DT.RootNode =

255                            new DomTreeNodeBase<typenameGraphT::NodeType>(Root, 0);

256   

257      // Loop over all ofthe reachable blocks in the function...

258      for (unsignedi = 2; i <= N; ++i) {

259        typenameGraphT::NodeType* W = DT.Vertex[i];

260   

261        DomTreeNodeBase<typenameGraphT::NodeType> *BBNode = DT.DomTreeNodes[W];

262        if (BBNode) continue// Haven'tcalculated this node yet?

263   

264        typenameGraphT::NodeType* ImmDom = DT.getIDom(W);

265   

266        assert(ImmDom|| DT.DomTreeNodes[NULL]);

267   

268        // Get orcalculate the node for the immediate dominator

269        DomTreeNodeBase<typenameGraphT::NodeType> *IDomNode =

270                                                        DT.getNodeForBlock(ImmDom);

271   

272        // Add a new treenode for this BasicBlock, and link it as a child of

273        // IDomNode

274        DomTreeNodeBase<typenameGraphT::NodeType> *C =

275                        newDomTreeNodeBase<typenameGraphT::NodeType>(W, IDomNode);

276        DT.DomTreeNodes[W] = IDomNode->addChild(C);

277      }

278   

279      // Free temporarymemory used to construct idom's

280      DT.IDoms.clear();

281      DT.Info.clear();

282      std::vector<typenameGraphT::NodeType*>().swap(DT.Vertex);

283   

284      DT.updateDFSNumbers();

285    }

 

余下的代码则是构建一棵支配树(dominator tree)。我们例子的支配树如下图所示。


284行的updateDFSNumbers函数以深度优先序遍历配置树,对DomTreeNodeBase中的DFSNumIn及DFSNumOut域赋值。

 

579      void updateDFSNumbers(){

580        unsigned DFSNum = 0;

581   

582        SmallVector<std::pair<DomTreeNodeBase<NodeT>*,

583                    typenameDomTreeNodeBase<NodeT>::iterator>, 32> WorkStack;

584   

585        DomTreeNodeBase<NodeT> *ThisRoot =getRootNode();

586   

587        if (!ThisRoot)

588          return;

589   

590        // Even in thecase of multiple exits that form the post dominator root

591        // nodes, do notiterate over all exits, but start from the virtual root

592        // node.Otherwise bbs, that are not post dominated by any exit but by the

593        // virtual rootnode, will never be assigned a DFS number.

594       WorkStack.push_back(std::make_pair(ThisRoot, ThisRoot->begin()));

595        ThisRoot->DFSNumIn = DFSNum++;

596   

597        while(!WorkStack.empty()) {

598          DomTreeNodeBase<NodeT> *Node =WorkStack.back().first;

599          typename DomTreeNodeBase<NodeT>::iteratorChildIt =

600            WorkStack.back().second;

601   

602          // If wevisited all of the children of this node, "recurse" back up the

603          // stacksetting the DFOutNum.

604          if (ChildIt == Node->end()) {

605            Node->DFSNumOut = DFSNum++;

606            WorkStack.pop_back();

607          } else {

608            // Otherwise,recursively visit this child.

609            DomTreeNodeBase<NodeT> *Child =*ChildIt;

610            ++WorkStack.back().second;

611   

612            WorkStack.push_back(std::make_pair(Child,Child->begin()));

613            Child->DFSNumIn = DFSNum++;

614          }

615        }

616   

617        SlowQueries = 0;

618        DFSInfoValid = true;

619      }

 

编号的结果如上图所示。注意DT是DominatorTree中的成员,因此这些内容可以带到下一个遍使用。


### DSA算法详解 #### 算法概述 DSA(Digital Signature Algorithm)是一种基于离散对数问题的数字签名算法。它主要用于生成和验证数字签名,广泛应用于信息安全领域中的身份验证和数据完整性保护[^1]。 #### 算法原理 DSA的核心思想是利用模幂运算以及离散对数问题来实现签名的安全性和不可伪造性。以下是其主要过程: 1. **参数生成** - 选择一个素数 \( p \),使得 \( p-1 \) 是另一个大素数 \( q \) 的倍数。 - 计算基元 \( g \),满足 \( g = h^{(p-1)/q} \mod p \),其中 \( h \) 是一个小于 \( p-1 \) 的随机数。 - 私钥 \( x \) 和公钥 \( y \) 的关系为:\( y = g^x \mod p \)。 2. **签名生成** 对消息 \( m \) 进行哈希处理得到摘要 \( H(m) \)。随后执行以下操作: - 随机选取临时私钥 \( k \),并计算 \( r = (g^k \mod p) \mod q \)。 - 使用 \( s = k^{-1}(H(m)+xr) \mod q \) 来生成签名部分 \( s \)。 - 最终签名为一对值 \( (r, s) \)[^2]。 3. **签名验证** 接收方收到消息及其签名后,按照如下步骤验证签名的有效性: - 计算 \( w = s^{-1} \mod q \)。 - 计算 \( u_1 = H(m)w \mod q \) 和 \( u_2 = rw \mod q \)。 - 计算 \( v = ((g^{u_1}y^{u_2})\mod p)\mod q \)。 - 如果 \( v = r \),则签名有效;否则无效。 #### 安全性分析 DSA的安全性依赖于以下几个方面: 1. **离散对数难题** 攻击者难以从已知的 \( y = g^x \mod p \) 中推导出私钥 \( x \)。这是DSA算法的主要安全保障之一。 2. **哈希函数的选择** 在实际应用中,通常使用SHA系列哈希函数(如SHA-256)代替早期不安全的MD5或SHA-1。这可以防止攻击者通过碰撞攻击伪造签名。 3. **随机数的重要性** 临时私钥 \( k \) 必须每次都是真正随机且保密的。如果重复使用相同的 \( k \),可能会泄露私钥信息。 尽管如此,在某些场景下,更现代的算法(如Ed25519)可能提供更高的性能和安全性[^3]。 --- ### 示例代码 以下是一个简单的Python示例,演示如何使用`cryptography`库生成和验证DSA签名。 ```python from cryptography.hazmat.primitives.asymmetric import dsa from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import utils # 参数生成 private_key = dsa.generate_private_key(key_size=2048) public_key = private_key.public_key() # 消息签名 message = b"Hello, this is a test message." hash_algorithm = hashes.SHA256() signature = private_key.sign(message, hash_algorithm) # 签名验证 try: public_key.verify(signature, message, hash_algorithm) print("Signature verified successfully.") except Exception as e: print(f"Verification failed: {e}") ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值