github.com/incognitochain/go-incognito-sdk@v1.0.1/privacy/point.go (about) 1 package privacy 2 3 import ( 4 "crypto/subtle" 5 "encoding/hex" 6 "errors" 7 "fmt" 8 C25519 "github.com/incognitochain/go-incognito-sdk/privacy/curve25519" 9 ) 10 11 type Point struct { 12 key C25519.Key 13 } 14 15 func RandomPoint() *Point { 16 sc := RandomScalar() 17 return new(Point).ScalarMultBase(sc) 18 } 19 20 func (p Point) PointValid() bool { 21 var point C25519.ExtendedGroupElement 22 return point.FromBytes(&p.key) 23 } 24 25 func (p Point) GetKey() C25519.Key { 26 return p.key 27 } 28 29 func (p *Point) SetKey(a *C25519.Key) (*Point, error) { 30 if p == nil { 31 p = new(Point) 32 } 33 p.key = *a 34 35 var point C25519.ExtendedGroupElement 36 if !point.FromBytes(&p.key) { 37 return nil, errors.New("Invalid point value") 38 } 39 return p, nil 40 } 41 42 func (p *Point) Set(q *Point) *Point { 43 if p == nil { 44 p = new(Point) 45 } 46 p.key = q.key 47 return p 48 } 49 50 func (p Point) MarshalText() []byte { 51 return []byte(fmt.Sprintf("%x", p.key[:])) 52 } 53 54 func (p *Point) UnmarshalText(data []byte) (*Point, error) { 55 if p == nil { 56 p = new(Point) 57 } 58 59 byteSlice, _ := hex.DecodeString(string(data)) 60 if len(byteSlice) != Ed25519KeySize { 61 return nil, errors.New("Incorrect key size") 62 } 63 copy(p.key[:], byteSlice) 64 return p, nil 65 } 66 67 func (p Point) ToBytes() [Ed25519KeySize]byte { 68 return p.key.ToBytes() 69 } 70 71 func (p Point) ToBytesS() []byte { 72 slice := p.key.ToBytes() 73 return slice[:] 74 } 75 76 func (p *Point) FromBytes(b [Ed25519KeySize]byte) (*Point, error) { 77 if p == nil { 78 p = new(Point) 79 } 80 p.key.FromBytes(b) 81 82 var point C25519.ExtendedGroupElement 83 if !point.FromBytes(&p.key) { 84 return nil, errors.New("Invalid point value") 85 } 86 87 return p, nil 88 } 89 90 func (p *Point) FromBytesS(b []byte) (*Point, error) { 91 if len(b) != Ed25519KeySize { 92 return nil, errors.New("Invalid Ed25519 Key Size") 93 } 94 95 if p == nil { 96 p = new(Point) 97 } 98 var array [Ed25519KeySize]byte 99 copy(array[:], b) 100 p.key.FromBytes(array) 101 102 var point C25519.ExtendedGroupElement 103 if !point.FromBytes(&p.key) { 104 return nil, errors.New("Invalid point value") 105 } 106 107 return p, nil 108 } 109 110 func (p *Point) Identity() *Point { 111 if p == nil { 112 p = new(Point) 113 } 114 p.key = C25519.Identity 115 return p 116 } 117 118 func (p Point) IsIdentity() bool { 119 if p.key == C25519.Identity { 120 return true 121 } 122 return false 123 } 124 125 // does a * G where a is a scalar and G is the curve basepoint 126 func (p *Point) ScalarMultBase(a *Scalar) *Point { 127 if p == nil { 128 p = new(Point) 129 } 130 key := C25519.ScalarmultBase(&a.key) 131 p.key = *key 132 return p 133 } 134 135 func (p *Point) ScalarMult(pa *Point, a *Scalar) *Point { 136 if p == nil { 137 p = new(Point) 138 } 139 key := C25519.ScalarMultKey(&pa.key, &a.key) 140 p.key = *key 141 return p 142 } 143 144 func (p *Point) MultiScalarMultCached(scalarLs []*Scalar, pointPreComputedLs [][8]C25519.CachedGroupElement) *Point { 145 nSc := len(scalarLs) 146 147 if nSc != len(pointPreComputedLs) { 148 panic("Cannot MultiscalarMul with different size inputs") 149 } 150 151 scalarKeyLs := make([]*C25519.Key, nSc) 152 for i := 0; i < nSc; i++ { 153 scalarKeyLs[i] = &scalarLs[i].key 154 } 155 key := C25519.MultiScalarMultKeyCached(pointPreComputedLs, scalarKeyLs) 156 res, _ := new(Point).SetKey(key) 157 return res 158 } 159 160 func (p *Point) MultiScalarMult(scalarLs []*Scalar, pointLs []*Point) *Point { 161 nSc := len(scalarLs) 162 nPoint := len(pointLs) 163 164 if nSc != nPoint { 165 panic("Cannot MultiscalarMul with different size inputs") 166 } 167 168 scalarKeyLs := make([]*C25519.Key, nSc) 169 pointKeyLs := make([]*C25519.Key, nSc) 170 for i := 0; i < nSc; i++ { 171 scalarKeyLs[i] = &scalarLs[i].key 172 pointKeyLs[i] = &pointLs[i].key 173 } 174 key := C25519.MultiScalarMultKey(pointKeyLs, scalarKeyLs) 175 res, _ := new(Point).SetKey(key) 176 return res 177 } 178 179 func (p *Point) InvertScalarMultBase(a *Scalar) *Point { 180 if p == nil { 181 p = new(Point) 182 } 183 inv := new(Scalar).Invert(a) 184 p.ScalarMultBase(inv) 185 return p 186 } 187 188 func (p *Point) InvertScalarMult(pa *Point, a *Scalar) *Point { 189 inv := new(Scalar).Invert(a) 190 p.ScalarMult(pa, inv) 191 return p 192 } 193 194 func (p *Point) Derive(pa *Point, a *Scalar, b *Scalar) *Point { 195 c := new(Scalar).Add(a, b) 196 return p.InvertScalarMult(pa, c) 197 } 198 199 func (p *Point) Add(pa, pb *Point) *Point { 200 if p == nil { 201 p = new(Point) 202 } 203 res := p.key 204 C25519.AddKeys(&res, &pa.key, &pb.key) 205 p.key = res 206 return p 207 } 208 209 // aA + bB 210 func (p *Point) AddPedersen(a *Scalar, A *Point, b *Scalar, B *Point) *Point { 211 if p == nil { 212 p = new(Point) 213 } 214 215 var A_Precomputed [8]C25519.CachedGroupElement 216 Ae := new(C25519.ExtendedGroupElement) 217 Ae.FromBytes(&A.key) 218 C25519.GePrecompute(&A_Precomputed, Ae) 219 220 var B_Precomputed [8]C25519.CachedGroupElement 221 Be := new(C25519.ExtendedGroupElement) 222 Be.FromBytes(&B.key) 223 C25519.GePrecompute(&B_Precomputed, Be) 224 225 var key C25519.Key 226 C25519.AddKeys3_3(&key, &a.key, &A_Precomputed, &b.key, &B_Precomputed) 227 p.key = key 228 return p 229 } 230 231 func (p *Point) AddPedersenCached(a *Scalar, APreCompute [8]C25519.CachedGroupElement, b *Scalar, BPreCompute [8]C25519.CachedGroupElement) *Point { 232 if p == nil { 233 p = new(Point) 234 } 235 236 var key C25519.Key 237 C25519.AddKeys3_3(&key, &a.key, &APreCompute, &b.key, &BPreCompute) 238 p.key = key 239 return p 240 } 241 242 func (p *Point) Sub(pa, pb *Point) *Point { 243 if p == nil { 244 p = new(Point) 245 } 246 res := p.key 247 C25519.SubKeys(&res, &pa.key, &pb.key) 248 p.key = res 249 return p 250 } 251 252 func IsPointEqual(pa *Point, pb *Point) bool { 253 tmpa := pa.ToBytesS() 254 tmpb := pb.ToBytesS() 255 256 return subtle.ConstantTimeCompare(tmpa, tmpb) == 1 257 } 258 259 func HashToPointFromIndex(index int64, padStr string) *Point { 260 array := C25519.GBASE.ToBytes() 261 msg := array[:] 262 msg = append(msg, []byte(padStr)...) 263 msg = append(msg, []byte(string(index))...) 264 265 keyHash := C25519.Key(C25519.Keccak256(msg)) 266 keyPoint := keyHash.HashToPoint() 267 268 p, _ := new(Point).SetKey(keyPoint) 269 return p 270 } 271 272 func HashToPoint(b []byte) *Point { 273 keyHash := C25519.Key(C25519.Keccak256(b)) 274 keyPoint := keyHash.HashToPoint() 275 276 p, _ := new(Point).SetKey(keyPoint) 277 return p 278 }