github.com/hhwill/poc-eth@v0.0.0-20240218063348-3bb107c90dbf/crypto/curve25519/api.go (about) 1 package curve25519 2 3 import ( 4 "bytes" 5 "crypto/rand" 6 "crypto/sha256" 7 "io" 8 9 goCurve25519 "golang.org/x/crypto/curve25519" 10 ) 11 12 type Signature [64]byte 13 14 func NewSignature(bytes []byte) (s *Signature) { 15 s = new(Signature) 16 copy(s[:], bytes) 17 return 18 } 19 20 func (s *Signature) isCanonical() bool { 21 return isCanonicalSignature(s[:]) 22 } 23 24 type PublicKey [32]byte 25 26 func NewPublicKey(bytes []byte) (pk *PublicKey) { 27 pk = new(PublicKey) 28 copy(pk[:], bytes) 29 return 30 } 31 32 func (pk *PublicKey) isCanonical() bool { 33 return isCanonicalPublicKey(pk[:]) 34 } 35 36 type PrivateKey struct { 37 raw [32]byte 38 } 39 40 func GenerateKey() (sk *PrivateKey) { 41 sk = new(PrivateKey) 42 _, _ = io.ReadFull(rand.Reader, sk.raw[:]) 43 clamp(sk.raw[:]) 44 return sk 45 } 46 47 func NewPrivateKey(bytes []byte) (sk *PrivateKey) { 48 sk = new(PrivateKey) 49 copy(sk.raw[:], bytes) 50 clamp(sk.raw[:]) 51 return sk 52 } 53 54 func (sk *PrivateKey) toBytes(bytes []byte) []byte { 55 if bytes == nil { 56 bytes = make([]byte, 32) 57 } 58 copy(bytes, sk.raw[:]) 59 return nil 60 } 61 62 func (sk *PrivateKey) Public() (pk *PublicKey) { 63 pk = new(PublicKey) 64 goCurve25519.ScalarBaseMult((*[32]byte)(pk), &sk.raw) 65 return 66 } 67 68 func (sk *PrivateKey) SharedSecret(pk *PublicKey) []byte { 69 var ss [32]byte 70 goCurve25519.ScalarMult(&ss, &sk.raw, (*[32]byte)(pk)) 71 return ss[:] 72 } 73 74 func (sk *PrivateKey) myPublic() (pk *PublicKey) { 75 pk = new(PublicKey) 76 keygen(pk[:], nil, sk.raw[:]) 77 return 78 } 79 80 func (sk *PrivateKey) mySharedSecret(pk *PublicKey) (ss []byte) { 81 ss = make([]byte, 32) 82 curve(ss, sk.raw[:], pk[:]) 83 return 84 } 85 86 func (sk *PrivateKey) Sign(message []byte) (signature *Signature) { 87 publicKey := make([]byte, 32) 88 signingKey := make([]byte, 32) 89 keygen(publicKey, signingKey, sk.raw[:]) 90 91 hash := sha256.New() 92 hash.Write(message) 93 messageDigest := hash.Sum(nil) 94 95 hash.Reset() 96 hash.Write(messageDigest) 97 hash.Write(signingKey) 98 x := hash.Sum(nil) 99 y := make([]byte, 32) 100 keygen(y, nil, x) 101 102 hash.Reset() 103 hash.Write(messageDigest) 104 hash.Write(y) 105 h := hash.Sum(nil) 106 107 signature = new(Signature) 108 sign(signature[:], h, x, signingKey) 109 copy(signature[32:], h) 110 return 111 } 112 113 func Verify(message []byte, signature *Signature, pk *PublicKey, enforceCanonical bool) bool { 114 if enforceCanonical { 115 if !signature.isCanonical() { 116 return false 117 } 118 if !pk.isCanonical() { 119 return false 120 } 121 } 122 123 Y := make([]byte, 32) 124 v := signature[:32] 125 h := signature[32:] 126 127 verify(Y, v, h, pk[:]) 128 129 hash := sha256.New() 130 hash.Write(message) 131 messageDigest := hash.Sum(nil) 132 133 hash.Reset() 134 hash.Write(messageDigest) 135 hash.Write(Y) 136 h2 := hash.Sum(nil) 137 138 return bytes.Equal(h, h2) 139 }