Schnorr数字签名方案

Schnorr数字签名方案

Schnorr签名算法最初由德国密码学家claus schnorr于2008年提出,在密码学中,它是一种数字签名方案,以其简单著称

Schnorr数字签名方案也是基于离散对数的(基于离散对数的还有ElGamal数字签名方案、DSA数字签名方案)。Schnorr方案将生成签名所需的消息计算量最小化。生成签名的主要工作不依赖于消息,可以在处理器空闲时执行。

该方案的第一部分是生成私钥/公钥对,它由以下步骤组成:

  1. 选择素数p和q,使得q是p-1的素因子。即 p-1 ≡ 0 (mod q)
  2. 选择一整数a,使得a^q = 1 mod p , a,p和q组成全局公钥参数,在用户组内的每一个用户都可以取此值
  3. 选择随机整数s,0<s<q,作为用户的私钥
  4. 计算v=a^(-s) mod p ,作为用户的公钥

对于私钥为s,公钥为v的用户,可以通过以下步骤产生签名:

  1. 选择随机整数r,0<r<q,并且计算x=a^r mod p 
  2. 将x附在消息M的后面一起计算hash值e , e=H(M||x)
  3. 计算y=(r+se) mod q .签名由(e,y)对组成

任何其他用户能够通过以下步骤验证签名:

  1. 计算
  2. 验证是否

对于该验证过程有,

因此,有

 

 

 

 

 

 

 

 

 

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现Schnorr批量签名验证,你可以使用MIRACL密码库提供的函数和数据结构。下面是一个简单的步骤: 1. 首先,你需要定义一个MIRACL的ECn类对象,用于表示椭圆曲线上的点。 ``` ECn G; ``` 2. 然后,你需要初始化MIRACL密码库,并选择适当的椭圆曲线和哈希函数。在下面的示例中,我们使用的是secp256k1曲线和SHA-256哈希函数: ``` // 初始化MIRACL密码库 miracl *mip = mirsys(10000, 16); mip->IOBASE = 16; // 选择secp256k1曲线和SHA-256哈希函数 ecurve2_init(&MIRACL.ecp2, "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", "-3", "0x7", "0x4B", mip->TWIST, TRUE, MR_PROJECTIVE); irand(time(NULL)); mip->RPOINT = MILLER_RHO; mip->BLS_CURVE = FALSE; mip->QUIET = TRUE; mip->NTRY = 50; mip->ERNUM = 0; mip->TRACER = 0; mip->MONTY = FALSE; mip->EXACT = FALSE; mip->LOGFILE = NULL; mip->DEPTH = 0; mip->STAMP = 0; mip->base = 10; mip->IOBSIZ = 2048; mip->NIO = 0; mip->IOBUFF = NULL; mip->TWISTS = 0; mip->TWISTB = 0; mip->PSEUDO = 0; mip->PRIMES = NULL; mip->PR_INDEX = 0; mip->PR_MAX = 0; mip->EXPMETHOD = 2; mip->MONTY1 = FALSE; mip->QBITS = 0; mip->DIF_LEN = 0; mip->NTRYMILLER = 10; mip->SPR = FALSE; mip->MONTY3 = FALSE; mip->MONTY4 = FALSE; mip->MONTY5 = FALSE; mip->SPAIR = FALSE; mip->HWORD = FALSE; mip->ECC_STORE_CURVES = FALSE; mip->ECC_STORE_POINTS = FALSE; mip->ECC_STORE_MULTI_EXP = FALSE; mip->ECC_STORE_PRODUCTS = FALSE; mip->ECC_STORE_INNER_PRODUCTS = FALSE; mip->ECC_STORE_HASH = FALSE; mip->ECC2_STORE_CURVES = FALSE; mip->ECC2_STORE_POINTS = FALSE; mip->ECC2_STORE_MULTI_EXP = FALSE; mip->ECC2_STORE_PRODUCTS = FALSE; mip->ECC2_STORE_INNER_PRODUCTS = FALSE; mip->ECC2_STORE_HASH = FALSE; mip->VMONTY = FALSE; mip->LOOP_COUNT = 10; mip->QUIET_MODE = 0; mip->SP_NTRY = 10; mip->SPR_B = 0; mip->SPR_C = 0; mip->SPR_D = 0; mip->SPR_E = 0; mip->SPR_F = 0; mip->SPR_G = 0; mip->SPR_H = 0; mip->SPR_I = 0; mip->SPR_J = 0; mip->SPR_K = 0; mip->SPR_L = 0; mip->SPR_M = 0; mip->SPR_N = 0; mip->SPR_O = 0; mip->SPR_P = 0; mip->SPR_Q = 0; mip->SPR_R = 0; mip->SPR_S = 0; mip->IOBUFF = (char *)malloc(mip->IOBSIZ); memset(mip->IOBUFF, 0, mip->IOBSIZ); mip->IOBUFF[0] = 0; MIRACL.hash_func = SHA256; MIRACL.base = 10; MIRACL.nib = 4; MIRACL.ioalen = 12; MIRACL.ioalenw = 3; MIRACL.iowlen = 6; MIRACL.iowlenw = 2; MIRACL.docrc = FALSE; MIRACL.compress = TRUE; ecurve2_mult(secp256k1_Gx, secp256k1_Gy, G); ``` 3. 接下来,你需要定义一个Schnorr签名的数据结构,包括一个ECn类对象和一个Bn类对象。 ``` struct schnorr_sig_t { ECn A; Big s; }; ``` 4. 然后,你需要定义一个Schnorr签名的验证函数,该函数接受一个公钥和多个签名,并返回一个布尔值,指示这些签名是否都有效。 ``` bool schnorr_verify_batch(ECn *pub_key, schnorr_sig_t *sigs, int num_sigs) { // 初始化累加器 ECn acc; acc = 0; // 计算累加器 for (int i = 0; i < num_sigs; i++) { // 计算哈希值 Big e = hash_to_scalar(sigs[i].A, pub_key, sigs[i].s); // 计算累加器 acc += sigs[i].A + (*pub_key * e); } // 计算哈希值 Big e = hash_to_scalar(acc, pub_key); // 检查哈希值是否为0 if (e == 0) { return false; } // 检查签名是否有效 ECn R = G * sigs[0].s + (*pub_key * e); if (R == sigs[0].A) { return true; } else { return false; } } ``` 5. 最后,你需要实现一个哈希函数,用于将椭圆曲线上的点和公钥转换为标量。在下面的示例中,我们使用的是SHA-256哈希函数: ``` Big hash_to_scalar(ECn A, ECn *pub_key, Big s) { // 计算哈希值 sha256 sh; shs_init(&sh); int len = A.get_size(); char *buf = new char[len]; A.get(buf, len); shs_process(&sh, buf, len); len = pub_key->get_size(); buf = new char[len]; pub_key->get(buf, len); shs_process(&sh, buf, len); len = s.size(); buf = new char[len]; s.getbytes(buf, len); shs_process(&sh, buf, len); char *hash_buf = new char[shs_final(&sh, NULL)]; shs_final(&sh, hash_buf); Big e = from_binary(sh.hash, shs_final(&sh)); return e; } ``` 这样,你就可以使用MIRACL密码库实现Schnorr批量签名验证了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值