github.com/status-im/status-go@v1.1.0/protocol/identity/utils.go (about)

     1  package identity
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"math/big"
     7  	"testing"
     8  
     9  	"github.com/ethereum/go-ethereum/crypto/secp256k1"
    10  )
    11  
    12  func ToColorID(pubkey string) (int64, error) {
    13  	const colorPalletLength = 12
    14  
    15  	pubkeyValue, ok := new(big.Int).SetString(pubkey, 0)
    16  	if !ok {
    17  		return 0, fmt.Errorf("invalid pubkey: %s", pubkey)
    18  	}
    19  
    20  	colorID := new(big.Int).Mod(pubkeyValue, new(big.Int).SetInt64(colorPalletLength-1)).Int64()
    21  
    22  	return colorID, nil
    23  }
    24  
    25  func ToBigBase(value *big.Int, base uint64) (res [](uint64)) {
    26  	toBigBaseImpl(value, base, &res)
    27  	return
    28  }
    29  
    30  func toBigBaseImpl(value *big.Int, base uint64, res *[](uint64)) {
    31  	bigBase := new(big.Int).SetUint64(base)
    32  	quotient := new(big.Int).Div(value, bigBase)
    33  	if quotient.Cmp(new(big.Int).SetUint64(0)) != 0 {
    34  		toBigBaseImpl(quotient, base, res)
    35  	}
    36  
    37  	*res = append(*res, new(big.Int).Mod(value, bigBase).Uint64())
    38  }
    39  
    40  // compressedPubKey = |1.5 bytes chars cutoff|20 bytes emoji hash|10 bytes color hash|1.5 bytes chars cutoff|
    41  func Slices(compressedPubkey []byte) (res [4][]byte, err error) {
    42  	if len(compressedPubkey) != 33 {
    43  		return res, errors.New("incorrect compressed pubkey")
    44  	}
    45  
    46  	getSlice := func(low, high int, and string, rsh uint) []byte {
    47  		sliceValue := new(big.Int).SetBytes(compressedPubkey[low:high])
    48  		andValue, _ := new(big.Int).SetString(and, 0)
    49  		andRes := new(big.Int).And(sliceValue, andValue)
    50  		return new(big.Int).Rsh(andRes, rsh).Bytes()
    51  	}
    52  
    53  	res[0] = getSlice(0, 2, "0xFFF0", 4)
    54  	res[1] = getSlice(1, 22, "0x0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", 4)
    55  	res[2] = getSlice(21, 32, "0x0FFFFFFFFFFFFFFFFFFFF0", 4)
    56  	res[3] = getSlice(31, 33, "0x0FFF", 0)
    57  
    58  	return res, nil
    59  }
    60  
    61  func ToCompressedKey(pubkey string) ([]byte, error) {
    62  	pubkeyValue, ok := new(big.Int).SetString(pubkey, 0)
    63  	if !ok {
    64  		return nil, fmt.Errorf("invalid pubkey: %s", pubkey)
    65  	}
    66  
    67  	x, y := secp256k1.S256().Unmarshal(pubkeyValue.Bytes())
    68  	if x == nil || !secp256k1.S256().IsOnCurve(x, y) {
    69  		return nil, fmt.Errorf("invalid pubkey: %s", pubkey)
    70  	}
    71  
    72  	return secp256k1.CompressPubkey(x, y), nil
    73  }
    74  
    75  func ToBigInt(t *testing.T, str string) *big.Int {
    76  	res, ok := new(big.Int).SetString(str, 0)
    77  	if !ok {
    78  		t.Errorf("invalid conversion to int from %s", str)
    79  	}
    80  	return res
    81  }