github.com/incognitochain/go-incognito-sdk@v1.0.1/privacy/scalar.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 "math/big" 10 "sort" 11 ) 12 13 type Scalar struct { 14 key C25519.Key 15 } 16 17 func (sc Scalar) GetKey() C25519.Key { 18 return sc.key 19 } 20 21 func (sc Scalar) String() string { 22 return fmt.Sprintf("%x", sc.key[:]) 23 } 24 25 func (sc Scalar) MarshalText() []byte { 26 return []byte(fmt.Sprintf("%x", sc.key[:])) 27 } 28 29 func (sc *Scalar) UnmarshalText(data []byte) (*Scalar, error) { 30 if sc == nil { 31 sc = new(Scalar) 32 } 33 34 byteSlice, _ := hex.DecodeString(string(data)) 35 if len(byteSlice) != Ed25519KeySize { 36 return nil, errors.New("Incorrect key size") 37 } 38 copy(sc.key[:], byteSlice) 39 return sc, nil 40 } 41 42 func (sc Scalar) ToBytes() [Ed25519KeySize]byte { 43 return sc.key.ToBytes() 44 } 45 46 func (sc Scalar) ToBytesS() []byte { 47 slice := sc.key.ToBytes() 48 return slice[:] 49 } 50 51 func (sc *Scalar) FromBytes(b [Ed25519KeySize]byte) *Scalar { 52 if sc == nil { 53 sc = new(Scalar) 54 } 55 sc.key.FromBytes(b) 56 //if !C25519.ScValid(&sc.key) { 57 // panic("Invalid Scalar Value") 58 //} 59 return sc 60 } 61 62 func (sc *Scalar) FromBytesS(b []byte) *Scalar { 63 //if len(b) != Ed25519KeySize { 64 // panic("Invalid Ed25519 Key Size") 65 //} 66 if sc == nil { 67 sc = new(Scalar) 68 } 69 var array [Ed25519KeySize]byte 70 copy(array[:], b) 71 sc.key.FromBytes(array) 72 73 //if !C25519.ScValid(&sc.key) { 74 // panic("Invalid Scalar Value") 75 //} 76 return sc 77 } 78 79 func (sc *Scalar) SetKey(a *C25519.Key) (*Scalar, error) { 80 if sc == nil { 81 sc = new(Scalar) 82 } 83 sc.key = *a 84 if sc.ScalarValid() == false { 85 return nil, errors.New("Invalid key value") 86 } 87 return sc, nil 88 } 89 90 func (sc *Scalar) Set(a *Scalar) *Scalar { 91 if sc == nil { 92 sc = new(Scalar) 93 } 94 sc.key = a.key 95 return sc 96 } 97 98 func RandomScalar() *Scalar { 99 sc := new(Scalar) 100 key := C25519.RandomScalar() 101 sc.key = *key 102 return sc 103 } 104 105 func HashToScalar(data []byte) *Scalar { 106 key := C25519.HashToScalar(data) 107 sc, error := new(Scalar).SetKey(key) 108 if error != nil { 109 return nil 110 } 111 return sc 112 } 113 114 func (sc *Scalar) FromUint64(i uint64) *Scalar { 115 if sc == nil { 116 sc = new(Scalar) 117 } 118 sc.SetKey(d2h(i)) 119 return sc 120 } 121 122 func (sc *Scalar) ToUint64() uint64 { 123 if sc == nil { 124 return 0 125 } 126 keyBN := new(big.Int).SetBytes(sc.ToBytesS()) 127 return keyBN.Uint64() 128 } 129 130 func (sc *Scalar) Add(a, b *Scalar) *Scalar { 131 if sc == nil { 132 sc = new(Scalar) 133 } 134 var res C25519.Key 135 C25519.ScAdd(&res, &a.key, &b.key) 136 sc.key = res 137 return sc 138 } 139 140 func (sc *Scalar) Sub(a, b *Scalar) *Scalar { 141 if sc == nil { 142 sc = new(Scalar) 143 } 144 var res C25519.Key 145 C25519.ScSub(&res, &a.key, &b.key) 146 sc.key = res 147 return sc 148 } 149 150 func (sc *Scalar) Mul(a, b *Scalar) *Scalar { 151 if sc == nil { 152 sc = new(Scalar) 153 } 154 var res C25519.Key 155 C25519.ScMul(&res, &a.key, &b.key) 156 sc.key = res 157 return sc 158 } 159 160 // a*b + c % l 161 func (sc *Scalar) MulAdd(a, b, c *Scalar) *Scalar { 162 if sc == nil { 163 sc = new(Scalar) 164 } 165 var res C25519.Key 166 C25519.ScMulAdd(&res, &a.key, &b.key, &c.key) 167 sc.key = res 168 return sc 169 } 170 171 func (sc *Scalar) Exp(a *Scalar, v uint64) *Scalar { 172 if sc == nil { 173 sc = new(Scalar) 174 } 175 176 var res C25519.Key 177 C25519.ScMul(&res, &a.key, &a.key) 178 for i := 0; i < int(v)-2; i++ { 179 C25519.ScMul(&res, &res, &a.key) 180 } 181 182 sc.key = res 183 return sc 184 } 185 186 func (sc *Scalar) ScalarValid() bool { 187 if sc == nil { 188 return false 189 } 190 return C25519.ScValid(&sc.key) 191 } 192 193 func (sc *Scalar) IsOne() bool { 194 s := sc.key 195 return ((int(s[0]|s[1]|s[2]|s[3]|s[4]|s[5]|s[6]|s[7]|s[8]| 196 s[9]|s[10]|s[11]|s[12]|s[13]|s[14]|s[15]|s[16]|s[17]| 197 s[18]|s[19]|s[20]|s[21]|s[22]|s[23]|s[24]|s[25]|s[26]| 198 s[27]|s[28]|s[29]|s[30]|s[31])-1)>>8)+1 == 1 199 } 200 201 func IsScalarEqual(sc1, sc2 *Scalar) bool { 202 tmpa := sc1.ToBytesS() 203 tmpb := sc2.ToBytesS() 204 205 return subtle.ConstantTimeCompare(tmpa, tmpb) == 1 206 } 207 208 func Compare(sca, scb *Scalar) int { 209 tmpa := sca.ToBytesS() 210 tmpb := scb.ToBytesS() 211 212 for i := Ed25519KeySize - 1; i >= 0; i-- { 213 if uint64(tmpa[i]) > uint64(tmpb[i]) { 214 return 1 215 } 216 217 if uint64(tmpa[i]) < uint64(tmpb[i]) { 218 return -1 219 } 220 } 221 return 0 222 } 223 224 func (sc *Scalar) IsZero() bool { 225 if sc == nil { 226 return false 227 } 228 return C25519.ScIsZero(&sc.key) 229 } 230 231 func CheckDuplicateScalarArray(arr []*Scalar) bool { 232 sort.Slice(arr, func(i, j int) bool { 233 return Compare(arr[i], arr[j]) == -1 234 }) 235 236 for i := 0; i < len(arr)-1; i++ { 237 if IsScalarEqual(arr[i], arr[i+1]) == true { 238 return true 239 } 240 } 241 return false 242 } 243 244 func (sc *Scalar) Invert(a *Scalar) *Scalar { 245 if sc == nil { 246 sc = new(Scalar) 247 } 248 249 var inverse_result C25519.Key 250 x := a.key 251 252 reversex := Reverse(x) 253 bigX := new(big.Int).SetBytes(reversex[:]) 254 255 reverseL := Reverse(C25519.CurveOrder()) // as speed improvements it can be made constant 256 bigL := new(big.Int).SetBytes(reverseL[:]) 257 258 var inverse big.Int 259 inverse.ModInverse(bigX, bigL) 260 261 inverse_bytes := inverse.Bytes() 262 263 if len(inverse_bytes) > Ed25519KeySize { 264 panic("Inverse cannot be more than Ed25519KeySize bytes in this domain") 265 } 266 267 for i, j := 0, len(inverse_bytes)-1; i < j; i, j = i+1, j-1 { 268 inverse_bytes[i], inverse_bytes[j] = inverse_bytes[j], inverse_bytes[i] 269 } 270 copy(inverse_result[:], inverse_bytes[:]) // copy the bytes as they should be 271 272 sc.key = inverse_result 273 return sc 274 } 275 276 func Reverse(x C25519.Key) (result C25519.Key) { 277 result = x 278 // A key is in little-endian, but the big package wants the bytes in 279 // big-endian, so Reverse them. 280 blen := len(x) // its hardcoded 32 bytes, so why do len but lets do it 281 for i := 0; i < blen/2; i++ { 282 result[i], result[blen-1-i] = result[blen-1-i], result[i] 283 } 284 return 285 } 286 287 func d2h(val uint64) *C25519.Key { 288 key := new(C25519.Key) 289 for i := 0; val > 0; i++ { 290 key[i] = byte(val & 0xFF) 291 val /= 256 292 } 293 return key 294 }