对于结果,我想使用公式this计算值X作为apiKey
Pubkey1 = Privkey1 * G
Pubkey2 = Privkey2 * G
然后我们得到
Privkey2 * Pubkey1 = Privkey1 * Pubkey2
也等于
Privkey2 * Privkey1 * G = Privkey1 * Privkey2 * G = X
然后服务和客户端可以使用X作为签名的密钥。
我是golang和ED25519或ECDSA中的新成员,如果我错了,希望有人能弄清楚,谢谢!!
我使用的库是crypto/ed25519
在这个库中,我找到了一个功能齐全的GeDoubleScalarMultVartime(),它可以使用公式进行计算
r = a*A + b*B
我不知道如何计算X,所以我考虑是否设置 b = 0 ,
r = a*A + 0*B = a*A
然后我写一些代码进行验证。
在lib crypto / ed25519中,所有内核func都位于内部文件夹中,所以我写了一些func公开给我
// get ProjectiveGroupElement struct
func GetProjectiveGroupElement() edwards25519.ProjectiveGroupElement {
var R edwards25519.ProjectiveGroupElement
return R
}
// get GeDoubleScalarMultVartime function
func GeDoubleScalar(r *edwards25519.ProjectiveGroupElement, a * [32]byte, A *edwards25519.ExtendedGroupElement, b *[32]byte) {
edwards25519.GeDoubleScalarMultVartime(r, a, A, b)
}
// return PublicKey correspondence ExtendedGroupElement immediate, which used in GeDoubleScalarMultVartime() as param A instead PublicKey
func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, edwards25519.ExtendedGroupElement, error) {
if rand == nil {
rand = cryptorand.Reader
}
seed := make([]byte, SeedSize)
if _, err := io.ReadFull(rand, seed); err != nil {
var B edwards25519.ExtendedGroupElement
return nil, nil, B, err
}
privateKey, A := NewKeyFromSeed(seed)
publicKey := make([]byte, PublicKeySize)
copy(publicKey, privateKey[32:])
return publicKey, privateKey, A, nil
}
func NewKeyFromSeed(seed []byte) (PrivateKey, edwards25519.ExtendedGroupElement){
if l := len(seed); l != SeedSize {
panic("ed25519: bad seed length: " + strconv.Itoa(l))
}
digest := sha512.Sum512(seed)
digest[0] &= 248
digest[31] &= 127
digest[31] |= 64
var A edwards25519.ExtendedGroupElement
var hBytes [32]byte
copy(hBytes[:], digest[:])
edwards25519.GeScalarMultBase(&A, &hBytes)
var publicKeyBytes [32]byte
A.ToBytes(&publicKeyBytes)
privateKey := make([]byte, PrivateKeySize)
copy(privateKey, seed)
copy(privateKey[32:], publicKeyBytes[:])
return privateKey, A
}
这是测试代码
package main
import (
"crypto/rand"
"golang.org/x/crypto/ed25519"
)
func main() {
pubK, privK, localA, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
log.Printf("error")
}
var R = ed25519.GetProjectiveGroupElement()
var testpubKey [32]byte
var testprivKey [32]byte
for i,v := range pubK {
testpubKey[i] = v
}
for i,v := range privK {
if i < 32 {
testprivKey[i] = v
}
}
var apikey1 [32]byte
var b [32]byte //set b = 0
log.Printf("localA:%x\n", localA)
pubK2, privK2, localB, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
log.Printf("error")
}
var R2 = ed25519.GetProjectiveGroupElement()
var testpubKey2 [32]byte
var testprivKey2 [32]byte
for i,v := range pubK2 {
testpubKey2[i] = v
}
for i,v := range privK2 {
if i < 32 {
testprivKey2[i] = v
}
}
var apikey2 [32]byte
var b2 [32]byte //set b = 0
log.Printf("localB:%x\n", localB)
ed25519.GeDoubleScalar(&R2, &testprivKey2, &localA, &b2)
R2.ToBytes(&apikey2)
log.Printf("apikey2:%x\n", apikey2)
log.Printf("privK2:%x\n", privK2)
ed25519.GeDoubleScalar(&R, &testprivKey, &localB, &b)
R.ToBytes(&apikey1)
log.Printf("apikey:%x\n", apikey1)
log.Printf("privK1:%x\n", privK)
}
结果
2018/08/28 11:17:23 apikey2:c025975d177059792498509fc4d4a8586b0039273d80c62760cf52064d2555bb
2018/08/28 11:17:23 privK2:ebd70f9b2254bee1de3a105e274fc6b0d65da8d66b1ba47d760a47a3f8b5fe866bc1d3fa1db801b49dc5521cf0b440c84894dd03e2871581c2a84cdc9c92e037
2018/08/28 11:17:23 apikey:0cfd0e75e8ec990d93d2768b101c70c0bf42e38e869afacfcbc1e61183fdd03d
2018/08/28 11:17:23 privK1:5eee36a68309f49fb73e1a93338c3a9173ce37cf5b2c0d27d344b45a7f441c37cd021701c36a5322eacbba6e4a49eda2fbfa32bfe5baf859d9851ecff714721a
两个apikey不同,我是否以错误的方式使用了lib? 还是我对ed25519的认识有误? 希望有人能帮助我。谢谢
我的英语不太好,如果您对我的说明感到困惑,请弄清楚,再次感谢
答案 0 :(得分:0)
出乎意料的是,我想说这可能是因为您正在使用GenerateKey
并调用NewKeyFromSeed
,其中实际是从种子copy(privateKey, seed)
复制了privateKey,所以您使用种子而不是digest
中实际使用的NewKeyFromSeed
,但是为了执行您想做的标量技巧,您必须在计算中使用实际的私有标量,上下限位设置应有的。
改为修改您的NewKeyFromSeed
来执行以下操作:
copy(privateKey, digest)
也许它将按预期工作。
免责声明:我只在脑海中编译了这段代码,所以我可能会退出。 如果您需要更多帮助,则应该发布MWE,甚至可以前往StackOverflow,因为它更像是调试代码问题而不是加密问题。