git.gammaspectra.live/P2Pool/consensus@v0.0.0-20240403173234-a039820b20c9/monero/crypto/private.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 PrivateKey interface { 14 AsSlice() PrivateKeySlice 15 AsBytes() PrivateKeyBytes 16 AsScalar() *PrivateKeyScalar 17 18 PublicKey() PublicKey 19 20 // GetDerivation derives a secret via a peer PublicKey, ECDH 21 GetDerivation(public PublicKey) PublicKey 22 23 // GetDerivationCofactor derives a secret via a peer PublicKey, ECDH, making sure it is in the proper range (*8) 24 GetDerivationCofactor(public PublicKey) PublicKey 25 26 String() string 27 UnmarshalJSON(b []byte) error 28 MarshalJSON() ([]byte, error) 29 } 30 31 const PrivateKeySize = 32 32 33 var ZeroPrivateKeyBytes PrivateKeyBytes 34 35 type PrivateKeyScalar edwards25519.Scalar 36 37 func (p *PrivateKeyScalar) AsSlice() PrivateKeySlice { 38 return p.Scalar().Bytes() 39 } 40 41 func (p *PrivateKeyScalar) AsBytes() (buf PrivateKeyBytes) { 42 copy(buf[:], p.AsSlice()) 43 return 44 } 45 46 func (p *PrivateKeyScalar) AsScalar() *PrivateKeyScalar { 47 return p 48 } 49 50 func PrivateKeyFromScalar(scalar *edwards25519.Scalar) *PrivateKeyScalar { 51 return (*PrivateKeyScalar)(scalar) 52 } 53 54 func (p *PrivateKeyScalar) Scalar() *edwards25519.Scalar { 55 return (*edwards25519.Scalar)(p) 56 } 57 58 func (p *PrivateKeyScalar) PublicKey() PublicKey { 59 return PublicKeyFromPoint(GetEdwards25519Point().ScalarBaseMult(p.Scalar())) 60 } 61 62 func (p *PrivateKeyScalar) GetDerivation(public PublicKey) PublicKey { 63 return deriveKeyExchangeSecret(p, public.AsPoint()) 64 } 65 66 func (p *PrivateKeyScalar) GetDerivationCofactor(public PublicKey) PublicKey { 67 return deriveKeyExchangeSecretCofactor(p, public.AsPoint()) 68 } 69 70 func (p *PrivateKeyScalar) String() string { 71 return hex.EncodeToString(p.Scalar().Bytes()) 72 } 73 74 func (p *PrivateKeyScalar) UnmarshalJSON(b []byte) error { 75 var s string 76 if err := utils.UnmarshalJSON(b, &s); err != nil { 77 return err 78 } 79 80 if buf, err := hex.DecodeString(s); err != nil { 81 return err 82 } else { 83 if len(buf) != PrivateKeySize { 84 return errors.New("wrong key size") 85 } 86 87 if _, err = p.Scalar().SetCanonicalBytes(buf); err != nil { 88 return err 89 } 90 91 return nil 92 } 93 } 94 95 func (p *PrivateKeyScalar) MarshalJSON() ([]byte, error) { 96 return []byte("\"" + p.String() + "\""), nil 97 } 98 99 type PrivateKeyBytes [PrivateKeySize]byte 100 101 func (k *PrivateKeyBytes) AsSlice() PrivateKeySlice { 102 return (*k)[:] 103 } 104 105 func (k *PrivateKeyBytes) AsBytes() PrivateKeyBytes { 106 return *k 107 } 108 109 func (k *PrivateKeyBytes) AsScalar() *PrivateKeyScalar { 110 secret, _ := GetEdwards25519Scalar().SetCanonicalBytes((*k)[:]) 111 return PrivateKeyFromScalar(secret) 112 } 113 114 func (k *PrivateKeyBytes) PublicKey() PublicKey { 115 return PublicKeyFromPoint(GetEdwards25519Point().ScalarBaseMult(k.AsScalar().Scalar())) 116 } 117 118 func (k *PrivateKeyBytes) GetDerivation(public PublicKey) PublicKey { 119 return k.AsScalar().GetDerivation(public) 120 } 121 122 func (k *PrivateKeyBytes) GetDerivationCofactor(public PublicKey) PublicKey { 123 return k.AsScalar().GetDerivationCofactor(public) 124 } 125 126 func (k *PrivateKeyBytes) String() string { 127 return hex.EncodeToString(k.AsSlice()) 128 } 129 130 func (k *PrivateKeyBytes) Scan(src any) error { 131 if src == nil { 132 return nil 133 } else if buf, ok := src.([]byte); ok { 134 if len(buf) == 0 { 135 return nil 136 } 137 if len(buf) != PrivateKeySize { 138 return errors.New("invalid key size") 139 } 140 copy((*k)[:], buf) 141 142 return nil 143 } 144 return errors.New("invalid type") 145 } 146 147 func (k *PrivateKeyBytes) Value() (driver.Value, error) { 148 var zeroPrivKey PrivateKeyBytes 149 if *k == zeroPrivKey { 150 return nil, nil 151 } 152 return []byte((*k)[:]), nil 153 } 154 155 func (k *PrivateKeyBytes) UnmarshalJSON(b []byte) error { 156 if len(b) == 0 || len(b) == 2 { 157 return nil 158 } 159 160 if len(b) != PrivateKeySize*2+2 { 161 return errors.New("wrong key size") 162 } 163 164 if _, err := fasthex.Decode(k[:], b[1:len(b)-1]); err != nil { 165 return err 166 } else { 167 return nil 168 } 169 } 170 171 func (k *PrivateKeyBytes) MarshalJSON() ([]byte, error) { 172 var buf [PrivateKeySize*2 + 2]byte 173 buf[0] = '"' 174 buf[PrivateKeySize*2+1] = '"' 175 fasthex.Encode(buf[1:], k[:]) 176 return buf[:], nil 177 } 178 179 type PrivateKeySlice []byte 180 181 func (k *PrivateKeySlice) AsSlice() PrivateKeySlice { 182 return *k 183 } 184 185 func (k *PrivateKeySlice) AsBytes() (buf PrivateKeyBytes) { 186 copy(buf[:], *k) 187 return 188 } 189 190 func (k *PrivateKeySlice) AsScalar() *PrivateKeyScalar { 191 secret, _ := GetEdwards25519Scalar().SetCanonicalBytes(*k) 192 return PrivateKeyFromScalar(secret) 193 } 194 195 func (k *PrivateKeySlice) PublicKey() PublicKey { 196 return PublicKeyFromPoint(GetEdwards25519Point().ScalarBaseMult(k.AsScalar().Scalar())) 197 } 198 199 func (k *PrivateKeySlice) GetDerivation(public PublicKey) PublicKey { 200 return k.AsScalar().GetDerivation(public) 201 } 202 203 func (k *PrivateKeySlice) GetDerivationCofactor(public PublicKey) PublicKey { 204 return k.AsScalar().GetDerivationCofactor(public) 205 } 206 207 func (k *PrivateKeySlice) String() string { 208 return hex.EncodeToString(*k) 209 } 210 211 func (k *PrivateKeySlice) Scan(src any) error { 212 if src == nil { 213 return nil 214 } else if buf, ok := src.([]byte); ok { 215 if len(buf) == 0 { 216 return nil 217 } 218 if len(buf) != PrivateKeySize { 219 return errors.New("invalid key size") 220 } 221 copy(*k, buf) 222 223 return nil 224 } 225 return errors.New("invalid type") 226 } 227 228 func (k *PrivateKeySlice) Value() (driver.Value, error) { 229 var zeroPrivKey PublicKeyBytes 230 if bytes.Compare(*k, zeroPrivKey[:]) == 0 { 231 return nil, nil 232 } 233 return []byte(*k), nil 234 } 235 236 func (k *PrivateKeySlice) UnmarshalJSON(b []byte) error { 237 var s string 238 if err := utils.UnmarshalJSON(b, &s); err != nil { 239 return err 240 } 241 242 if buf, err := hex.DecodeString(s); err != nil { 243 return err 244 } else { 245 if len(buf) != PrivateKeySize { 246 return errors.New("wrong key size") 247 } 248 249 *k = buf 250 return nil 251 } 252 } 253 254 func (k *PrivateKeySlice) MarshalJSON() ([]byte, error) { 255 var buf [PrivateKeySize*2 + 2]byte 256 buf[0] = '"' 257 buf[PrivateKeySize*2+1] = '"' 258 fasthex.Encode(buf[1:], (*k)[:]) 259 return buf[:], nil 260 } 261 262 func deriveKeyExchangeSecretCofactor(private *PrivateKeyScalar, public *PublicKeyPoint) *PublicKeyPoint { 263 return public.Multiply(private).Cofactor() 264 } 265 266 func deriveKeyExchangeSecret(private *PrivateKeyScalar, public *PublicKeyPoint) *PublicKeyPoint { 267 return public.Multiply(private) 268 }