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  }