Page 100 - 《软件学报》2025年第10期
P. 100

张川 等: 抗量子的高效区块链认证存储方案                                                           4497


                 的认证过程如下所示.
                                                 ′                               dforc_sig  提供的签名, 输入为
                       proo f_ver(SIG dforc ,PK.seed,ADRS,md ,dforc pk ) → (True/False): 算法用于验证由
                                                                            ′                     md  计算
                                                                                                    ′
                 SIG dforc 、公钥种子   PK.seed、私钥种子   SK.seed、地址   ADRS  和消息摘要  md . 首先, 算法通过消息摘要
                                                                               F
                 出与消息对应的叶子节点索引, 并找到签名中的私钥                 SIG dforc .getsk(i). 接着, 通过   (详见第  2.2  节) 生成节点, 并根
                                                                                                   dforc .
                                                                                                       ′
                 据   SIG dforc .getAUTH(i)  提供的认证路径, 从叶子节点向上依次计算每层的节点, 直至生成树的根节点, 即                    pk
                 最终, 将计算得到的     dforc ′   与公钥  d forc pk  进行比对, 如果两者匹配则返回  True, 否则返回  False, 表示签名无效. 该
                                    pk
                 过程在算法    8  中给出, 其中   SIG dforc .getsk(i) 和  SIG dforc .getAUTH (i), 前者返回存储在签名中的第   个私钥, 后者返回
                                                                                          i
                                                   H  的说明见第    2.2      ADRS  的操作参考文献     [30].
                 存储在签名中的第      i 个认证路径, 其中    Th k  和            节, 有关
                 算法  8.  proof_verify.
                 输入:  SIG dforc ,PK.seed,ADRS,md ,dforc pk ;
                                         ′
                 输出: True/False.
                 1. for  i = 0 to  k −1 do
                           ⌊      ⌋  ⌊           ⌋
                 2.    idx[i] = i×log(t) to (i+1)×log(t)−1  bits of  md ;
                                                          ′
                 3.    dforc sk = SIG dforc .getsk(i);
                 4.     ADRS.setTreeHeight(0);
                 5.    ADRS.setTreeidx(i×t +idx[i]);
                 6.    node[0] = F(PK.seed,ADRS,dforc sk );
                 7.    auth[i] = SIG dforc .getAUTH(i);
                 8.   ADRS.setTreeIdx(i×t +idx[i]);
                 9.  for   j = 0 to  a−1 do
                 10.     ADRS.setTreeHeight( j+1);
                 11.   if  idx[ j]%2 == 0 then
                 12.      ADRS.setTreeIdx(ADRS.getTreeIdx()/2);
                 13.      node[1] = H(PK.seed,ADRS,(node[0]||auth[0]));
                 14.   else
                 15.      ADRS.setTreeIdx((ADRS.getTreeIdx()−1)/2);
                 16.      node[1] = H(PK.seed,ADRS,(auth[ j]||node[0]));
                 17.   endif

                 18.    node[0] = node[1];
                 19.  endfor
                 20.   root[i] = node[0];
                 21. endfor
                 22.  dforc.setType(DFORC_roots);
                 23.  dforc.setKeyPairAddr(ADRS.getKeyPairAddr());
                       ′
                 24.  dforc = Th k (PK.seed,dforc pk ,ADRS,root[0]||...||root[k −1]);
                       pk
                 25. if  dforc == dforc pk  then
                         ′
                         pk
                 26.   return True;
                 27. else
                 28.   return False;
                 29. endif
   95   96   97   98   99   100   101   102   103   104   105