我目前正在浏览器中生成一个私钥,并使用高贵-Secp256k1 javascript库导出其公钥:
const privKey = secp.utils.randomPrivateKey()
const pubKey = Buffer.from(secp.schnorr.getPublicKey(privKey)).toString('hex')
然后,我将公钥发送到服务器,服务器使用secp256k1库来验证我传递的有效负载签名。当我试图实例化公钥时,这会失败:
pub_key = secp256k1.PublicKey(binascii.unhexlify(hex_pub_key), raw=True)
如果我使用python (python -m secp256k1 privkey -p
)构建密钥对,但是如果我发送在客户机上生成的密钥,服务器将引发一个错误:
Exception: unknown public key size (expected 33 or 65)
python库生成一个66个字符的十六进制编码公钥。客户端使用secp.schnorr.getPublicKey
方法生成64个字符的十六进制编码公钥,并使用secp.getPublicKey
方法生成130个字符的十六进制编码公钥。有办法让我的python库接受在前端生成的schnorr公共密钥吗?我能读到secp256k1和schnorr之间的半重叠是什么意思吗?
发布于 2022-05-27 22:26:34
NodeJS库(高贵-Secp256k1)的32字节公钥必须用前导0x02扩展到33个字节,然后可以由Python (secp256k1)导入:
...we为P选择该选项,这样,我们的X唯一公钥就等同于一个压缩公钥,即以字节0x02为前缀的X唯一密钥.
来自BIP0340的文档,秒。设计,隐式Y坐标。
测试:
以下NodeJS代码使用NodeJS库并生成密钥对和Schnorr签名:
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);
})();
具有以下可能的输出:
Public key (hex): f9a10a9bbb93e14a35d82c514f4eb052734ba55b93f6553f12366d6e887b76ee
Signature (hex) : b08a0e9d02da2bbb3e2220b90e591c82ebcfc337aaac36ebe2f91eec288c79b3b9513b1018126526f99697abb78c60041f0683bbce6760b8ff76cb53a4c87137
Verified : true
下面的Python代码使用Python库并使用由NodeJS代码导出的密钥验证Schnorr签名,该密钥由前导0x02扩展:
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))
产出如下:
Verified: True
即成功的核查。
注意:即使使用了0x03 (而不是0x02),验证也是成功的。可能库只检查键是否被压缩(0x02或0x03),如果是,则简单地截断前导字节。
https://stackoverflow.com/questions/72396085
复制相似问题