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