• 基于JPBC的无证书聚合签名方案实现


    基于JPBC的无证书聚合签名方案实现

    摘要

    一开始签名方案是基于PKI的,无证书签名起源于 基于身份密码体制, 2009 年第一篇无证书签名方案1被提出,随后出现了一些列方案2,3;包括无配对的无证书聚合签名方案4,更多内容参考文献5.

    暂时没有看见无证书聚合签名方案实现相关的代码,本文基于JPBC库实现,使用方法可以参考B站视频。也可以使用C++和PBC库实现。

    方案概述

    本文方案是基于论文3描述的。

    Setup
    给定安全参数 κ ∈ Z \kappa \in Z κZ,KGC选择两个循环群 G 1 G_1 G1 G 2 G_2 G2,其阶均为素数 q q q G 1 G_1 G1 的生成元 P P P,计算可接受的配对 e : G 1 × G 1 → G 2 e:G_1×G_1→G_2 e:G1×G1G2 。 KGC 随机选择主密钥 s ∈ Z q ∗ s\in Z_q^\ast sZq ,设置 P p u b = s P P_{pub}=sP Ppub=sP ,选择加密哈希函数 H 1 : { 0 , 1 } ∗ → G 1 H_1:\{0,1\}^\ast→G_1 H1:{0,1}G1 , H 2 : { 0 , 1 } ∗ → G 1 H_2:\{0,1\}^\ast→G_1 H2:{0,1}G1, H 3 : { 0 , 1 } ∗ → Z q ∗ H_3:\{0,1\}^\ast→Z_q^\ast H3:{0,1}Zq. 系统参数为 { q , G 1 , G 2 , e , P , P p u b , H 1 , H 2 , H 3 } \{q,G_1,G_2,e,P,P_{pub},H_1,H_2,H_3 \} {q,G1,G2,e,P,Ppub,H1,H2,H3}, 主密钥是s。

    PartialKeyGen:
    给定用户身份 I D i ∈ { 0 , 1 } ∗ ID_i\in \{0,1\}^\ast IDi{0,1},KGC首先计算 Q I D i = H 1 ( I D i ) Q_{ID_i }=H_1 (ID_i) QIDi=H1(IDi)。 然后,它设置该用户的部分密钥 p s k I D i = s Q ( I D i ) psk_{ID_i }=sQ_(ID_i ) pskIDi=sQ(IDi)并将其通过安全通道传输给对应用户。 用户可以通过检查是否正确来检查其正确性 e ( p s k I D i , P ) = e ( Q I D i , P p u b ) e(psk_{ID_i },P)=e(Q_{ID_i },P_{pub}) e(pskIDi,P)=e(QIDi,Ppub)

    UserKeyGen:
    用户 I D i ID_i IDi随机选择值 x I D i ∈ Z q ∗ x_{ID_i }\in Z_q^\ast xIDiZq作为他的用户私钥 u s k I D i usk_{ID_i } uskIDi,并且计算用户公钥 u p k I D i = x I D i P upk_{ID_i}=x_{ID_i } P upkIDi=xIDiP

    Sign:
    对于消息 m i ∈ 0 , 1 ∗ m_i∈{0,1}^\ast mi0,1,选择状态信息 ∆ ∆ (选择公开参数作为状态信息),具有 I D i ID_i IDi身份的签名者执行以下步骤:

    1. 选择随机数 r i ∈ Z q ∗ r_i∈Z_q^\ast riZq并且计算 U i = r i P ∈ G 1 U_i=r_i P∈G_1 Ui=riPG1.
    2. 计算 Q = H 2 ( ∆ ) , h i = H 3 ( m i , I D i , u p k I D i , U i ) Q=H_2(∆),h_i=H_3(m_i,ID_i,upk_{ID_i},U_i) Q=H2(),hi=H3(mi,IDi,upkIDi,Ui)
    3. 计算 V i = p s k I D i + r i ⋅ Q + h i ⋅ x i ⋅ P p u b V_i=psk_{ID_i }+r_i⋅Q+h_i⋅x_i⋅P_{pub} Vi=pskIDi+riQ+hixiPpub.

    输出 ( U i , V i ) (U_i,V_i ) (Ui,Vi)作为 m i m_i mi的签名。

    Verify
    给定一个消息 m i m_i mi签名 ( U i , V i ) (U_i,V_i ) (Ui,Vi),其对应的身份为 I D i ID_i IDi和公钥 u p k I D i upk_{ID_i} upkIDi,计算 Q ( I D i ) = H 1 ( I D i ) , Q = H 2 ( ∆ ) Q_(ID_i )=H_1 (ID_i ),Q=H_2 (∆) Q(IDi)=H1(IDi),Q=H2() ,
    h i = H 3 ( m i , I D i , u p k I D i , U i ) h_i=H_3 (m_i,ID_i,upk_{ID_i },U_i ) hi=H3(mi,IDi,upkIDi,Ui)
    如果等式 e ( V i , P ) = e ( h i ⋅ u p k I D i + Q I D i , P p u b ) e ( U i , Q ) e(V_i,P)=e(h_i⋅upk_{ID_i }+Q_{ID_i },P_{pub} )e(U_i,Q) e(Vi,P)=e(hiupkIDi+QIDi,Ppub)e(Ui,Q) 成立,接收签名;否则拒绝。

    Aggregate
    任何人都可以充当聚合签名生成器, 对于n个用户的聚合集 { U 1 , … , U n } \{U_1,…,U_n\} {U1,,Un}其对应身份为 { I D 1 , … , I D n } \{ID_1,…,ID_n \} {ID1,,IDn}以及对应公钥 { u p k 1 , … , u p k n } \{upk_1,…,upk_n\} {upk1,,upkn},对应消息签名对为 { ( m 1 , σ 1 = ( U 1 , V 1 ) ) , … , ( m n , σ n = ( U n , V n ) ) } \{(m_1,σ_1=(U_1,V_1 )),…,(m_n,σ_n=(U_n,V_n))\} {(m1,σ1=(U1,V1)),,(mn,σn=(Un,Vn))},
    聚合签名计算: V = ∑ i = 1 n V i V=∑_{i=1}^n V_i V=i=1nVi, 将 σ = ( U 1 , … , U n , V ) σ=(U_1,…,U_n,V) σ=(U1,,Un,V)作为聚合签名。

    Aggregate-Verify
    验证聚合签名 σ = ( U 1 , … , U n , V ) σ=(U_1,…,U_n,V) σ=(U1,,Un,V)由n个用户 { U 1 , … , U n } \{U_1,…,U_n\} {U1,,Un}身份为 { I D 1 , … , I D n } \{ID_1,…,ID_n\} {ID1,,IDn}和对应的公钥 { u p k 1 , … , u p k n } \{upk_1,…,upk_n\} {upk1,,upkn};关于消息 { m 1 , … , m n } \{m_1,…,m_n \} {m1,,mn} 验证者执行以下操作:
    计算 Q I D i = H 1 ( I D i ) , Q = H 2 ( ∆ ) , h i = H 3 ( m i , I D i , u p k I D i , U i ) , i = 1 , … , n Q_{ID_i }=H_1 (ID_i ),Q=H_2 (∆),h_i=H_3 (m_i,ID_i,upk_{ID_i },U_i ),i=1,…,n QIDi=H1(IDi),Q=H2(),hi=H3(mi,IDi,upkIDi,Ui),i=1,,n.
    验证: e ( V , P ) = e ( ∑ i = 1 n [ h i ⋅ u p k I D i + Q I D i ] , P p u b ) e ( ∑ i = 1 n U i , Q ) e(V,P)=e(∑_{i=1}^n [h_i⋅upk_{ID_i}+Q_{ID_i} ] ,P_{pub} )e(∑_{i=1}^n U_i ,Q) e(V,P)=e(i=1n[hiupkIDi+QIDi],Ppub)e(i=1nUi,Q).如果满足则通过;否则验证失败。

    代码实现

    整体思路, 将相关密钥信息作为文件保存(序列化后可以通过网络传输),根据方案不同的功能设计不同的函数。

    关于文件a_181_603.properties的内容

    type=a
    q=98826429041171753291515535532523512299028170537954154869719707264887274916552228805607584116490046284509883309001532457986879277885241872021906840932513241346999389365188296460009947
    h=32243626948934860887488490158437299489453513352745889246437755713701521031193083418924110592954582395114812811896992400310730276
    r=3064991081731777546575510593831386635550174528483098623
    exp2=181
    exp1=127
    sign1=-1
    sign0=-1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    代码

    import it.unisa.dia.gas.jpbc.Element;
    import it.unisa.dia.gas.jpbc.Pairing;
    import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.*;
    
    public class CLAS {
    
        //生成公私钥对,并保存到文件中
        public static void Setup(String pairingParametersFileName, String pubParamFileName, String KGC_SK_FileName) {
            Pairing bp = PairingFactory.getPairing(pairingParametersFileName);
            //G1的生成元P
            Element P = bp.getG1().newRandomElement().getImmutable();
            //计算主私钥和公钥
            Element s = bp.getZr().newRandomElement().getImmutable();
            Element P_Pub = P.mulZn(s);
    
            Properties pubParamProp = new Properties();
    
            //后面对写的元素统一采用如下方法:首先将元素转为字节数组,然后进行Base64编码为可读字符串
            pubParamProp.setProperty("P", Base64.getEncoder().encodeToString(P.toBytes()));
            pubParamProp.setProperty("P_Pub", Base64.getEncoder().encodeToString(P_Pub.toBytes()));
    
            storePropToFile(pubParamProp, pubParamFileName);
    
            Properties param_s = new Properties();//私钥不存入公开参数中,由KGC自己保存
            param_s.setProperty("s", Base64.getEncoder().encodeToString(s.toBytes()));
            storePropToFile(param_s, KGC_SK_FileName);
        }
    
        //根据用户id生成私钥
        public static void PartialPrivateKeyGen(String pairingParametersFileName, String id, String KGC_SK_FileName) throws NoSuchAlgorithmException {
            Pairing bp = PairingFactory.getPairing(pairingParametersFileName);
            //使用HASH 将 id 转为QID
            byte[] idHash = HASH(id);
            Element QID = bp.getG1().newElementFromHash(idHash, 0, idHash.length).getImmutable();
    
            //从文件中读取 主私钥
            Properties mskProp = loadPropFromFile(KGC_SK_FileName);
            String sString = mskProp.getProperty("s");
            Element s = bp.getZr().newElementFromBytes(Base64.getDecoder().decode(sString)).getImmutable();  //Base64编码后对应的恢复元素的方法
    
            //计算用户私钥, 这里应该将私钥安全的传输给用户
            //方便模拟,统一存入一个文件中
            Element psk_ID = QID.powZn(s).getImmutable();
            Properties pskProp = new Properties();
            pskProp.setProperty("psk", Base64.getEncoder().encodeToString(psk_ID.toBytes()));
            storePropToFile(pskProp, id + ".properties");
        }
    
        //生成用户私钥
        public static void UserKeyGen(String pairingParametersFileName, String pubParamFileName, String id) {
            Pairing bp = PairingFactory.getPairing(pairingParametersFileName);
            //从文件中读取公钥
            Properties pkProp = loadPropFromFile(pubParamFileName);
            String PString = pkProp.getProperty("P");
    
            Element P = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(PString)).getImmutable();
            //生成随机数x,作为用户的私钥
            Element x = bp.getZr().newRandomElement().getImmutable();
            //计算用户公钥
            Element upk = P.mulZn(x);
    
            Properties userProp = new Properties();
            userProp.setProperty("usk", Base64.getEncoder().encodeToString(x.toBytes()));
            userProp.setProperty("upk", Base64.getEncoder().encodeToString(upk.toBytes()));
            storePropToFile(userProp, id + ".properties");
        }
    
        //签名
        public static Element[] Sign(String pairingParametersFileName, String pubParamFileName, String id, byte[] message) throws NoSuchAlgorithmException {
            Pairing bp = PairingFactory.getPairing(pairingParametersFileName);
            //获取公开参数
            Properties pubProp = loadPropFromFile(pubParamFileName);
            Element P = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(pubProp.getProperty("P"))).getImmutable();
            Element P_Pub = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(pubProp.getProperty("P_Pub"))).getImmutable();
    
            //获取用户自己的信息
            Properties userProp = loadPropFromFile(id + ".properties");
            Element upk = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(userProp.getProperty("upk"))).getImmutable();
            Element x = bp.getZr().newElementFromBytes(Base64.getDecoder().decode(userProp.getProperty("usk"))).getImmutable();
            Element psk = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(userProp.getProperty("psk"))).getImmutable();
    
            //选择随机数
            Element r = bp.getZr().newRandomElement();
            Element U = P.mulZn(r).getImmutable();
    
            //获取状态信息,将公开参数作为状态信息
            String p = pubProp.getProperty("P");
            String pPub = pubProp.getProperty("P_Pub");
            byte[] hash = HASH(p + pPub);
            Element Q = hashToG(bp, hash);
    
            // 计算m, id, upk,U组合的hash值
            byte[] res = hashCombination(message, id.getBytes(), upk.toBytes(), U.toBytes());
            Element h = hashToZ(bp, res);
    
    
            Element V = P_Pub.mulZn(x).mulZn(h).add(Q.mulZn(r)).add(psk).getImmutable();
    
            Element[] sigma = new Element[2];
            sigma[0] = U;
            sigma[1] = V;
            return sigma;
    
        }
    
        //验证
        public static boolean Verify(String pairingParametersFileName, String pubParamFileName, String id, byte[] message, Element[] sigma) throws NoSuchAlgorithmException {
            Pairing bp = PairingFactory.getPairing(pairingParametersFileName);
    
            //使用sha1 将 id 转为QID
            byte[] idHash = HASH(id);
            Element QID = bp.getG1().newElementFromHash(idHash, 0, idHash.length).getImmutable();
    
            //获取公开参数
            Properties pubProp = loadPropFromFile(pubParamFileName);
            Element P = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(pubProp.getProperty("P"))).getImmutable();
            Element P_Pub = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(pubProp.getProperty("P_Pub"))).getImmutable();
    
            //获取状态信息,将公开参数作为状态信息
            String p = pubProp.getProperty("P");
            String pPub = pubProp.getProperty("P_Pub");
            byte[] hash = HASH(p + pPub);
            Element Q = hashToG(bp, hash);
    
            //获取用户的公钥,
            Properties userProp = loadPropFromFile(id + ".properties");
            Element upk = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(userProp.getProperty("upk"))).getImmutable();
    
            // 计算m, id, upk,U组合的hash值
            byte[] res = hashCombination(message, id.getBytes(), upk.toBytes(), sigma[0].toBytes());
    
            Element h = hashToZ(bp, res);
    
            Element left = bp.pairing(sigma[1], P);
            Element right = bp.pairing(QID.add(upk.mulZn(h)), P_Pub).mul(bp.pairing(sigma[0], Q));
            return left.isEqual(right);
        }
    
        //聚合签名, U_1,U_2,...,U_n,V
        public static Element[] Aggregate(List<Element[]> sigmaList) {
            Element[] res = new Element[sigmaList.size() + 1];
            Element[] init = sigmaList.get(0);
            res[0] = init[0];
            Element V = init[1];
            for (int i = 1; i < sigmaList.size(); i++) {
                res[i] = sigmaList.get(i)[0];
                V = V.add(sigmaList.get(1)[1]);
            }
            res[sigmaList.size()] = V;
            return res;
        }
    
        // 聚合签名验证
        public static boolean AggregateVerify(String pairingParametersFileName, String pubParamFileName, String[] idx, byte[][] message, Element[] sigma) throws NoSuchAlgorithmException {
            Pairing bp = PairingFactory.getPairing(pairingParametersFileName);
    
            Element[] QIDX = new Element[idx.length];
            for (int i = 0; i < idx.length; i++) {
                byte[] idHash = HASH(idx[i]);
                Element QID = bp.getG1().newElementFromHash(idHash, 0, idHash.length).getImmutable();
                QIDX[i] = QID;
            }
    
            //获取公开参数信息
            Properties pubProp = loadPropFromFile(pubParamFileName);
            Element P = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(pubProp.getProperty("P"))).getImmutable();
            Element P_Pub = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(pubProp.getProperty("P_Pub"))).getImmutable();
            String p = pubProp.getProperty("P");
            String pPub = pubProp.getProperty("P_Pub");
            byte[] hash = HASH(p + pPub);
            Element Q = hashToG(bp, hash);
    
    
            Element[] PKX = new Element[idx.length];
            for (int i = 0; i < idx.length; i++) {
                Properties userProp = loadPropFromFile(idx[i] + ".properties");
                Element upk = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(userProp.getProperty("upk"))).getImmutable();
                PKX[i] = upk;
            }
    
            Element[] hx = new Element[idx.length];
            for (int i = 0; i < idx.length; i++) {
                byte[] res = hashCombination(message[i], idx[i].getBytes(), PKX[i].toBytes(), sigma[i].toBytes());
                Element h = hashToZ(bp, res);
                hx[i] = h;
            }
            Element left = bp.pairing(sigma[idx.length], P);
            Element U = sigma[0];
            for (int i = 1; i < idx.length; i++) {
                U = U.add(sigma[i]);
            }
            Element part = QIDX[0].add(PKX[0].mulZn(hx[0]));
            for (int i = 1; i < idx.length; i++) {
                part = part.add(QIDX[i].add(PKX[i].mulZn(hx[i])));
            }
            Element right = bp.pairing(part, P_Pub).mul(bp.pairing(U, Q));
            return left.isEqual(right);
        }
    
        //一种可行的组合方法
        public static byte[] hashCombination(byte[] message, byte[] id, byte[] upk, byte[] U) throws NoSuchAlgorithmException {
            int m_len = message.length, id_len = id.length, upk_len = upk.length, u_len = U.length;
            int total_len = m_len + id_len + upk_len + u_len;
            byte[] res = new byte[total_len];
            for (int i = 0; i < m_len; i++) {
                res[i] = message[i];
            }
            for (int i = 0; i < id_len; i++) {
                res[i + m_len] = id[i];
            }
            for (int i = 0; i < upk_len; i++) {
                res[i + m_len + id_len] = upk[i];
            }
            for (int i = 0; i < u_len; i++) {
                res[i + m_len + id_len + upk_len] = U[i];
            }
            MessageDigest instance = MessageDigest.getInstance("SHA-256");
            instance.update(res);
            return instance.digest();
        }
    
        public static void storePropToFile(Properties prop, String fileName) {
            try (FileOutputStream out = new FileOutputStream(fileName, true)) {
                prop.store(out, null);
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println(fileName + " save failed!");
                System.exit(-1);
            }
        }
    
        public static Properties loadPropFromFile(String fileName) {
            Properties prop = new Properties();
            try (FileInputStream in = new FileInputStream(fileName)) {
                prop.load(in);
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println(fileName + " load failed!");
                System.exit(-1);
            }
            return prop;
        }
    
        public static byte[] HASH(String content) throws NoSuchAlgorithmException {
            MessageDigest instance = MessageDigest.getInstance("SHA-1");
            instance.update(content.getBytes());
            return instance.digest();
        }
    
        public static Element hashToG(Pairing pb, byte[] code) {
            return pb.getG1().newElementFromHash(code, 0, code.length).getImmutable();
        }
    
        public static Element hashToZ(Pairing pb, byte[] code) {
            return pb.getZr().newElementFromHash(code, 0, code.length).getImmutable();
        }
    
        public static void main(String[] args) throws Exception {
            String pairingParametersFileName = "a_181_603.properties";
            String idAlice = "alice@example.com";
            String idBob = "bob@example.com";
            String pubParamFileName = "data/pub.properties";
            String KGCFileName = "data/kgc.properties";
            Setup(pairingParametersFileName, pubParamFileName, KGCFileName);
            PartialPrivateKeyGen(pairingParametersFileName, idAlice, KGCFileName);
            PartialPrivateKeyGen(pairingParametersFileName, idBob, KGCFileName);
            UserKeyGen(pairingParametersFileName, pubParamFileName, idAlice);
            UserKeyGen(pairingParametersFileName, pubParamFileName, idBob);
    
            String message_a = "Alice,This is a message from Alice!";
            String message_b = "Bob,This is a message from Bob!";
    
    
            Element[] sigma1 = Sign(pairingParametersFileName, pubParamFileName, idAlice, message_a.getBytes());
            Element[] sigma2 = Sign(pairingParametersFileName, pubParamFileName, idBob, message_b.getBytes());
            boolean result = Verify(pairingParametersFileName, pubParamFileName, idAlice, message_a.getBytes(), sigma1);
            System.out.println("Alice 验证签名通过? " + result);
            result = Verify(pairingParametersFileName, pubParamFileName, idBob, message_b.getBytes(), sigma2);
            System.out.println("Bob 验证签名通过? " + result);
    
            List<Element[]> sigmaList = new ArrayList<>();
            sigmaList.add(sigma1);
            sigmaList.add(sigma2);
            Element[] SIGMA = Aggregate(sigmaList);
            String[] idx = {idAlice, idBob};
            byte[][] message = {message_a.getBytes(), message_b.getBytes()};
    //        message[0][1] = 1;//假如消息被篡改
            result = AggregateVerify(pairingParametersFileName, pubParamFileName, idx, message, SIGMA);
            System.out.println("聚合签名验证通过? " + result);
    
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301

    参考文献

    1. A new certificateless aggregate signature scheme

    2. Cryptanalysis and improvement of a certificateless aggregate signature scheme

    3. A certificateless aggregate signature scheme for healthcare wireless sensor network

    4. Efficient certificateless aggregate signcryption scheme without bilinear pairings

    5. Security issues in IoT applications using certificateless aggregate signcryption schemes: An overview

  • 相关阅读:
    库存管理“智慧官”上线!北京电信基于飞桨打造主动型库存决策分析系统
    为什么IN操作符一般比OR操作符清单执行更快
    [面试直通版]操作系统之锁、同步与通信(上)
    【Matlab】智能优化算法_麻雀搜索算法SSA
    Python教程:with语句的用法
    领导:谁再用redis过期监听实现关闭订单,立马滚蛋!
    【Kotlin学习路线】讲解
    小程序真机调试提示系统错误
    win10下wsl2使用记录(系统迁移到D盘、配置国内源、安装conda环境、配置pip源、安装pytorch-gpu环境、安装paddle-gpu环境)
    mongo实际业务场景实战
  • 原文地址:https://blog.csdn.net/u013671216/article/details/134542079