首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >secp256k1/schnorr库不会相互交谈

secp256k1/schnorr库不会相互交谈
EN

Stack Overflow用户
提问于 2022-05-26 17:55:00
回答 1查看 184关注 0票数 1

我目前正在浏览器中生成一个私钥,并使用高贵-Secp256k1 javascript库导出其公钥:

代码语言:javascript
运行
复制
const privKey = secp.utils.randomPrivateKey()
const pubKey = Buffer.from(secp.schnorr.getPublicKey(privKey)).toString('hex')

然后,我将公钥发送到服务器,服务器使用secp256k1库来验证我传递的有效负载签名。当我试图实例化公钥时,这会失败:

代码语言:javascript
运行
复制
pub_key = secp256k1.PublicKey(binascii.unhexlify(hex_pub_key), raw=True)

如果我使用python (python -m secp256k1 privkey -p)构建密钥对,但是如果我发送在客户机上生成的密钥,服务器将引发一个错误:

代码语言:javascript
运行
复制
Exception: unknown public key size (expected 33 or 65)

python库生成一个66个字符的十六进制编码公钥。客户端使用secp.schnorr.getPublicKey方法生成64个字符的十六进制编码公钥,并使用secp.getPublicKey方法生成130个字符的十六进制编码公钥。有办法让我的python库接受在前端生成的schnorr公共密钥吗?我能读到secp256k1和schnorr之间的半重叠是什么意思吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-27 22:26:34

NodeJS库(高贵-Secp256k1)的32字节公钥必须用前导0x02扩展到33个字节,然后可以由Python (secp256k1)导入:

...we为P选择该选项,这样,我们的X唯一公钥就等同于一个压缩公钥,即以字节0x02为前缀的X唯一密钥.

来自BIP0340的文档,秒。设计,隐式Y坐标。

测试:

以下NodeJS代码使用NodeJS库并生成密钥对和Schnorr签名:

代码语言:javascript
运行
复制
var secp = require("@noble/secp256k1");

(async () => {
    const privateKey = secp.utils.randomPrivateKey();
    const publicKey = secp.schnorr.getPublicKey(privateKey) 
    const msgHash = await secp.utils.sha256("hello world");
    const signature = await secp.schnorr.sign(msgHash, privateKey);
    const isValid = await secp.schnorr.verify(signature, msgHash, publicKey);  
    console.log("Public key (hex):", Buffer.from(publicKey).toString('hex'))
    console.log("Signature (hex) :", Buffer.from(signature).toString('hex'))
    console.log("Verified        :", isValid);
})();

具有以下可能的输出:

代码语言:javascript
运行
复制
Public key (hex): f9a10a9bbb93e14a35d82c514f4eb052734ba55b93f6553f12366d6e887b76ee
Signature (hex) : b08a0e9d02da2bbb3e2220b90e591c82ebcfc337aaac36ebe2f91eec288c79b3b9513b1018126526f99697abb78c60041f0683bbce6760b8ff76cb53a4c87137
Verified        : true

下面的Python代码使用Python库并使用由NodeJS代码导出的密钥验证Schnorr签名,该密钥由前导0x02扩展:

代码语言:javascript
运行
复制
import secp256k1
import hashlib

publicKeyHexFromNodeJS = 'f9a10a9bbb93e14a35d82c514f4eb052734ba55b93f6553f12366d6e887b76ee'
signatureHexFromNodeJS = 'b08a0e9d02da2bbb3e2220b90e591c82ebcfc337aaac36ebe2f91eec288c79b3b9513b1018126526f99697abb78c60041f0683bbce6760b8ff76cb53a4c87137'

digest = hashlib.sha256()
digest.update(b'hello world')
msgHash = digest.digest()

publicKey = secp256k1.PublicKey(bytes.fromhex('02' + publicKeyHexFromNodeJS), raw=True)
signature = bytes.fromhex(signatureHexFromNodeJS)
isValid = publicKey.schnorr_verify(msgHash, signature, '', raw=True)
print("Verified: " + str(isValid))

产出如下:

代码语言:javascript
运行
复制
Verified: True

即成功的核查。

注意:即使使用了0x03 (而不是0x02),验证也是成功的。可能库只检查键是否被压缩(0x02或0x03),如果是,则简单地截断前导字节。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72396085

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档