git.gammaspectra.live/P2Pool/consensus@v0.0.0-20240403173234-a039820b20c9/monero/crypto/public.go (about) 1 package crypto 2 3 import ( 4 "bytes" 5 "database/sql/driver" 6 "encoding/hex" 7 "errors" 8 "git.gammaspectra.live/P2Pool/consensus/utils" 9 "git.gammaspectra.live/P2Pool/edwards25519" 10 fasthex "github.com/tmthrgd/go-hex" 11 ) 12 13 type PublicKey interface { 14 AsSlice() PublicKeySlice 15 AsBytes() PublicKeyBytes 16 AsPoint() *PublicKeyPoint 17 18 String() string 19 UnmarshalJSON(b []byte) error 20 MarshalJSON() ([]byte, error) 21 } 22 23 const PublicKeySize = 32 24 25 var ZeroPublicKeyBytes PublicKeyBytes 26 27 type PublicKeyPoint edwards25519.Point 28 29 func (k *PublicKeyPoint) AsSlice() PublicKeySlice { 30 return k.Point().Bytes() 31 } 32 33 func (k *PublicKeyPoint) AsBytes() (buf PublicKeyBytes) { 34 copy(buf[:], k.AsSlice()) 35 return 36 } 37 38 func (k *PublicKeyPoint) AsPoint() *PublicKeyPoint { 39 return k 40 } 41 42 func (k *PublicKeyPoint) Point() *edwards25519.Point { 43 return (*edwards25519.Point)(k) 44 } 45 46 func (k *PublicKeyPoint) Add(b *PublicKeyPoint) *PublicKeyPoint { 47 return PublicKeyFromPoint(GetEdwards25519Point().Add(k.Point(), b.Point())) 48 } 49 50 func (k *PublicKeyPoint) Subtract(b *PublicKeyPoint) *PublicKeyPoint { 51 return PublicKeyFromPoint(GetEdwards25519Point().Subtract(k.Point(), b.Point())) 52 } 53 54 func (k *PublicKeyPoint) Multiply(b *PrivateKeyScalar) *PublicKeyPoint { 55 return PublicKeyFromPoint(GetEdwards25519Point().ScalarMult(b.Scalar(), k.Point())) 56 } 57 58 func (k *PublicKeyPoint) Cofactor() *PublicKeyPoint { 59 return PublicKeyFromPoint(GetEdwards25519Point().MultByCofactor(k.Point())) 60 } 61 62 func PublicKeyFromPoint(point *edwards25519.Point, _ ...any) *PublicKeyPoint { 63 return (*PublicKeyPoint)(point) 64 } 65 66 func (k *PublicKeyPoint) String() string { 67 return hex.EncodeToString(k.Point().Bytes()) 68 } 69 70 func (k *PublicKeyPoint) UnmarshalJSON(b []byte) error { 71 var s string 72 if err := utils.UnmarshalJSON(b, &s); err != nil { 73 return err 74 } 75 76 if buf, err := hex.DecodeString(s); err != nil { 77 return err 78 } else { 79 if len(buf) != PublicKeySize { 80 return errors.New("wrong key size") 81 } 82 83 if _, err = k.Point().SetBytes(buf); err != nil { 84 return err 85 } 86 87 return nil 88 } 89 } 90 91 func (k *PublicKeyPoint) MarshalJSON() ([]byte, error) { 92 return []byte("\"" + k.String() + "\""), nil 93 } 94 95 type PublicKeyBytes [PublicKeySize]byte 96 97 func (k *PublicKeyBytes) AsSlice() PublicKeySlice { 98 return (*k)[:] 99 } 100 101 func (k *PublicKeyBytes) AsBytes() PublicKeyBytes { 102 return *k 103 } 104 105 func (k *PublicKeyBytes) AsPoint() *PublicKeyPoint { 106 return PublicKeyFromPoint(GetEdwards25519Point().SetBytes(k.AsSlice())) 107 } 108 109 func (k *PublicKeyBytes) String() string { 110 return hex.EncodeToString(k.AsSlice()) 111 } 112 113 func (k *PublicKeyBytes) Scan(src any) error { 114 if src == nil { 115 return nil 116 } else if buf, ok := src.([]byte); ok { 117 if len(buf) == 0 { 118 return nil 119 } 120 if len(buf) != PublicKeySize { 121 return errors.New("invalid key size") 122 } 123 copy((*k)[:], buf) 124 125 return nil 126 } 127 return errors.New("invalid type") 128 } 129 130 func (k *PublicKeyBytes) Value() (driver.Value, error) { 131 var zeroPubKey PublicKeyBytes 132 if *k == zeroPubKey { 133 return nil, nil 134 } 135 return []byte((*k)[:]), nil 136 } 137 138 func (k *PublicKeyBytes) UnmarshalJSON(b []byte) error { 139 if len(b) == 0 || len(b) == 2 { 140 return nil 141 } 142 143 if len(b) != PublicKeySize*2+2 { 144 return errors.New("wrong key size") 145 } 146 147 if _, err := fasthex.Decode(k[:], b[1:len(b)-1]); err != nil { 148 return err 149 } else { 150 return nil 151 } 152 } 153 154 func (k *PublicKeyBytes) MarshalJSON() ([]byte, error) { 155 var buf [PublicKeySize*2 + 2]byte 156 buf[0] = '"' 157 buf[PublicKeySize*2+1] = '"' 158 fasthex.Encode(buf[1:], k[:]) 159 return buf[:], nil 160 } 161 162 type PublicKeySlice []byte 163 164 func (k *PublicKeySlice) AsSlice() PublicKeySlice { 165 return *k 166 } 167 168 func (k *PublicKeySlice) AsBytes() (buf PublicKeyBytes) { 169 copy(buf[:], *k) 170 return buf 171 } 172 173 func (k *PublicKeySlice) AsPoint() *PublicKeyPoint { 174 return PublicKeyFromPoint(GetEdwards25519Point().SetBytes(*k)) 175 } 176 177 func (k *PublicKeySlice) String() string { 178 return hex.EncodeToString(*k) 179 } 180 181 func (k *PublicKeySlice) Scan(src any) error { 182 if src == nil { 183 return nil 184 } else if buf, ok := src.([]byte); ok { 185 if len(buf) == 0 { 186 return nil 187 } 188 if len(buf) != PublicKeySize { 189 return errors.New("invalid key size") 190 } 191 copy(*k, buf) 192 193 return nil 194 } 195 return errors.New("invalid type") 196 } 197 198 func (k *PublicKeySlice) Value() (driver.Value, error) { 199 var zeroPubKey PublicKeyBytes 200 if bytes.Compare(*k, zeroPubKey[:]) == 0 { 201 return nil, nil 202 } 203 return []byte(*k), nil 204 } 205 206 func (k *PublicKeySlice) UnmarshalJSON(b []byte) error { 207 var s string 208 if err := utils.UnmarshalJSON(b, &s); err != nil { 209 return err 210 } 211 212 if buf, err := hex.DecodeString(s); err != nil { 213 return err 214 } else { 215 if len(buf) != PublicKeySize { 216 return errors.New("wrong key size") 217 } 218 219 *k = buf 220 return nil 221 } 222 } 223 224 func (k *PublicKeySlice) MarshalJSON() ([]byte, error) { 225 var buf [PublicKeySize*2 + 2]byte 226 buf[0] = '"' 227 buf[PublicKeySize*2+1] = '"' 228 fasthex.Encode(buf[1:], (*k)[:]) 229 return buf[:], nil 230 }