-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathed25519.go
68 lines (54 loc) · 1.69 KB
/
ed25519.go
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
package jwt
import (
"crypto"
"crypto/ed25519"
"crypto/rand"
"errors"
"fmt"
)
// ErrEd25519Verification 使其可以被兩種錯誤類型判別
var ErrEd25519Verification = fmt.Errorf("%w %w",
errors.New("ed25519: verification error"),
ErrSignatureInvalid,
)
type SigningMethodED25519 struct{}
// AlgName implements the ISigningMethod interface
func (m *SigningMethodED25519) AlgName() string {
return "EdDSA"
}
// Sign implements the ISigningMethod interface
func (m *SigningMethodED25519) Sign(signingBytes []byte, key any) ([]byte, error) {
var privateKey crypto.Signer // 這是一個interface
var ok bool
// privateKey, ok := key.(ed25519.PrivateKey) // 斷言成指定物件的變化性比較低,改成crypto.Signer會更好
// return ed25519.Sign(privateKey, signingBytes), nil
privateKey, ok = key.(crypto.Signer)
if !ok {
return nil, fmt.Errorf("ed25519 sign expects crypto.Signer. %w", ErrInvalidKeyType)
}
// 用此來確保所提供的Signer,符合ed25519
if _, ok = privateKey.Public().(ed25519.PublicKey); !ok {
return nil, ErrInvalidKey
}
signature, err := privateKey.Sign(rand.Reader, signingBytes, crypto.Hash(0))
if err != nil {
return nil, err
}
return signature, nil
}
// Verify implements the ISigningMethod interface
func (m *SigningMethodED25519) Verify(signingBytes []byte, signature []byte, key any) error {
publicKey, ok := key.(ed25519.PublicKey)
if !ok {
return fmt.Errorf("ed25519 verify error. expected type: ed25519.PublicKey, got: %T. %w",
key, ErrInvalidKeyType,
)
}
if len(publicKey) != ed25519.PublicKeySize {
return ErrInvalidKey
}
if !ed25519.Verify(publicKey, signingBytes, signature) {
return ErrEd25519Verification
}
return nil
}