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 }