3100
vendor/github.com/status-im/status-go/protocol/identity/alias/data.go
generated
vendored
Normal file
3100
vendor/github.com/status-im/status-go/protocol/identity/alias/data.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
27
vendor/github.com/status-im/status-go/protocol/identity/alias/flfsr.go
generated
vendored
Normal file
27
vendor/github.com/status-im/status-go/protocol/identity/alias/flfsr.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
package alias
|
||||
|
||||
// For details: https://en.wikipedia.org/wiki/Linear-feedback_shift_register
|
||||
type LSFR struct {
|
||||
data uint64
|
||||
poly uint64
|
||||
}
|
||||
|
||||
func newLSFR(poly uint64, seed uint64) *LSFR {
|
||||
return &LSFR{data: seed, poly: poly}
|
||||
}
|
||||
|
||||
func (f *LSFR) next() uint64 {
|
||||
var bit uint64
|
||||
var i uint64
|
||||
|
||||
for i = 0; i < 64; i++ {
|
||||
if f.poly&(1<<i) != 0 {
|
||||
bit ^= (f.data >> i)
|
||||
}
|
||||
}
|
||||
bit &= 0x01
|
||||
|
||||
f.data = (f.data << 1) | bit
|
||||
|
||||
return f.data
|
||||
}
|
||||
45
vendor/github.com/status-im/status-go/protocol/identity/alias/generate.go
generated
vendored
Normal file
45
vendor/github.com/status-im/status-go/protocol/identity/alias/generate.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
package alias
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/crypto"
|
||||
)
|
||||
|
||||
const poly uint64 = 0xB8
|
||||
|
||||
func generate(seed uint64) string {
|
||||
generator := newLSFR(poly, seed)
|
||||
adjective1Index := generator.next() % uint64(len(adjectives))
|
||||
adjective2Index := generator.next() % uint64(len(adjectives))
|
||||
animalIndex := generator.next() % uint64(len(animals))
|
||||
adjective1 := adjectives[adjective1Index]
|
||||
adjective2 := adjectives[adjective2Index]
|
||||
animal := animals[animalIndex]
|
||||
|
||||
return fmt.Sprintf("%s %s %s", adjective1, adjective2, animal)
|
||||
}
|
||||
|
||||
// GenerateFromPublicKey returns the 3 words name given an *ecdsa.PublicKey
|
||||
func GenerateFromPublicKey(publicKey *ecdsa.PublicKey) string {
|
||||
// Here we truncate the public key to the least significant 64 bits
|
||||
return generate(uint64(publicKey.X.Int64()))
|
||||
}
|
||||
|
||||
// GenerateFromPublicKeyString returns the 3 words name given a public key
|
||||
// prefixed with 0x
|
||||
func GenerateFromPublicKeyString(publicKeyString string) (string, error) {
|
||||
publicKeyBytes, err := hex.DecodeString(publicKeyString[2:])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
publicKey, err := crypto.UnmarshalPubkey(publicKeyBytes)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return GenerateFromPublicKey(publicKey), nil
|
||||
}
|
||||
33
vendor/github.com/status-im/status-go/protocol/identity/alias/ops.go
generated
vendored
Normal file
33
vendor/github.com/status-im/status-go/protocol/identity/alias/ops.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
package alias
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func IsAdjective(val string) bool {
|
||||
for _, v := range adjectives {
|
||||
if v == val {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsAnimal(val string) bool {
|
||||
for _, v := range animals {
|
||||
if v == val {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsAlias(alias string) bool {
|
||||
aliasParts := strings.Fields(alias)
|
||||
if len(aliasParts) == 3 {
|
||||
if IsAdjective(strings.Title(aliasParts[0])) && IsAdjective(strings.Title(aliasParts[1])) && IsAnimal(strings.Title(aliasParts[2])) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
74
vendor/github.com/status-im/status-go/protocol/identity/colorhash/colorhash.go
generated
vendored
Normal file
74
vendor/github.com/status-im/status-go/protocol/identity/colorhash/colorhash.go
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
package colorhash
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/status-im/status-go/multiaccounts"
|
||||
"github.com/status-im/status-go/protocol/identity"
|
||||
)
|
||||
|
||||
const (
|
||||
colorHashSegmentMaxLen = 5
|
||||
colorHashColorsCount = 32
|
||||
)
|
||||
|
||||
var colorHashAlphabet [][]int
|
||||
|
||||
func GenerateFor(pubkey string) (hash multiaccounts.ColorHash, err error) {
|
||||
if len(colorHashAlphabet) == 0 {
|
||||
colorHashAlphabet = makeColorHashAlphabet(colorHashSegmentMaxLen, colorHashColorsCount)
|
||||
}
|
||||
|
||||
compressedKey, err := identity.ToCompressedKey(pubkey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
slices, err := identity.Slices(compressedKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return toColorHash(new(big.Int).SetBytes(slices[2]), &colorHashAlphabet, colorHashColorsCount), nil
|
||||
}
|
||||
|
||||
// [[1 0] [1 1] [1 2] ... [units, colors-1]]
|
||||
// [3 12] => 3 units length, 12 color index
|
||||
func makeColorHashAlphabet(units, colors int) (res [][]int) {
|
||||
res = make([][]int, units*colors)
|
||||
idx := 0
|
||||
for i := 0; i < units; i++ {
|
||||
for j := 0; j < colors; j++ {
|
||||
res[idx] = make([]int, 2)
|
||||
res[idx][0] = i + 1
|
||||
res[idx][1] = j
|
||||
idx++
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func toColorHash(value *big.Int, alphabet *[][]int, colorsCount int) (hash multiaccounts.ColorHash) {
|
||||
alphabetLen := len(*alphabet)
|
||||
indexes := identity.ToBigBase(value, uint64(alphabetLen))
|
||||
hash = make(multiaccounts.ColorHash, len(indexes))
|
||||
for i, v := range indexes {
|
||||
hash[i] = [2]int{}
|
||||
hash[i][0] = (*alphabet)[v][0]
|
||||
hash[i][1] = (*alphabet)[v][1]
|
||||
}
|
||||
|
||||
// colors can't repeat themselves
|
||||
// this makes color hash not fully collision resistant
|
||||
prevColorIdx := hash[0][1]
|
||||
hashLen := len(hash)
|
||||
for i := 1; i < hashLen; i++ {
|
||||
colorIdx := hash[i][1]
|
||||
if colorIdx == prevColorIdx {
|
||||
hash[i][1] = (colorIdx + 1) % colorsCount
|
||||
}
|
||||
prevColorIdx = hash[i][1]
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
94
vendor/github.com/status-im/status-go/protocol/identity/emojihash/emojihash.go
generated
vendored
Normal file
94
vendor/github.com/status-im/status-go/protocol/identity/emojihash/emojihash.go
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
package emojihash
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"math/big"
|
||||
"strings"
|
||||
|
||||
"github.com/status-im/status-go/protocol/identity"
|
||||
"github.com/status-im/status-go/static"
|
||||
)
|
||||
|
||||
const (
|
||||
emojiAlphabetLen = 2757 // 20bytes of data described by 14 emojis requires at least 2757 length alphabet
|
||||
emojiHashLen = 14
|
||||
)
|
||||
|
||||
var emojisAlphabet []string
|
||||
|
||||
func GenerateFor(pubkey string) ([]string, error) {
|
||||
if len(emojisAlphabet) == 0 {
|
||||
alphabet, err := loadAlphabet()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
emojisAlphabet = *alphabet
|
||||
}
|
||||
|
||||
compressedKey, err := identity.ToCompressedKey(pubkey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
slices, err := identity.Slices(compressedKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return toEmojiHash(new(big.Int).SetBytes(slices[1]), emojiHashLen, &emojisAlphabet)
|
||||
}
|
||||
|
||||
func loadAlphabet() (*[]string, error) {
|
||||
data, err := static.Asset("emojis.txt")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
alphabet := make([]string, 0, emojiAlphabetLen)
|
||||
|
||||
scanner := bufio.NewScanner(bytes.NewReader(data))
|
||||
for scanner.Scan() {
|
||||
alphabet = append(alphabet, strings.Replace(scanner.Text(), "\n", "", -1))
|
||||
}
|
||||
|
||||
// current alphabet contains more emojis than needed, just in case some emojis needs to be removed
|
||||
// make sure only necessary part is loaded
|
||||
if len(alphabet) > emojiAlphabetLen {
|
||||
alphabet = alphabet[:emojiAlphabetLen]
|
||||
}
|
||||
|
||||
return &alphabet, nil
|
||||
}
|
||||
|
||||
func toEmojiHash(value *big.Int, hashLen int, alphabet *[]string) (hash []string, err error) {
|
||||
valueBitLen := value.BitLen()
|
||||
alphabetLen := new(big.Int).SetInt64(int64(len(*alphabet)))
|
||||
|
||||
indexes := identity.ToBigBase(value, alphabetLen.Uint64())
|
||||
if hashLen == 0 {
|
||||
hashLen = len(indexes)
|
||||
} else if hashLen > len(indexes) {
|
||||
prependLen := hashLen - len(indexes)
|
||||
for i := 0; i < prependLen; i++ {
|
||||
indexes = append([](uint64){0}, indexes...)
|
||||
}
|
||||
}
|
||||
|
||||
// alphabetLen^hashLen
|
||||
possibleCombinations := new(big.Int).Exp(alphabetLen, new(big.Int).SetInt64(int64(hashLen)), nil)
|
||||
|
||||
// 2^valueBitLen
|
||||
requiredCombinations := new(big.Int).Exp(new(big.Int).SetInt64(2), new(big.Int).SetInt64(int64(valueBitLen)), nil)
|
||||
|
||||
if possibleCombinations.Cmp(requiredCombinations) == -1 {
|
||||
return nil, errors.New("alphabet or hash length is too short to encode given value")
|
||||
}
|
||||
|
||||
for _, v := range indexes {
|
||||
hash = append(hash, (*alphabet)[v])
|
||||
}
|
||||
|
||||
return hash, nil
|
||||
}
|
||||
61
vendor/github.com/status-im/status-go/protocol/identity/identicon/identicon.go
generated
vendored
Normal file
61
vendor/github.com/status-im/status-go/protocol/identity/identicon/identicon.go
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
package identicon
|
||||
|
||||
import (
|
||||
"crypto/md5" // nolint: gosec
|
||||
"image/color"
|
||||
|
||||
"github.com/lucasb-eyer/go-colorful"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultSaturation = 0.5
|
||||
defaultLightness = 0.7
|
||||
)
|
||||
|
||||
type Identicon struct {
|
||||
bitmap []byte
|
||||
color color.Color
|
||||
}
|
||||
|
||||
func generate(key string) Identicon {
|
||||
hash := md5.Sum([]byte(key)) // nolint: gosec
|
||||
return Identicon{
|
||||
convertPatternToBinarySwitch(generatePatternFromHash(hash)),
|
||||
getColorFromHash(hash),
|
||||
}
|
||||
}
|
||||
|
||||
func getColorFromHash(h [16]byte) color.Color {
|
||||
// Take the last 3 relevant bytes, and convert to a float between [0..360]
|
||||
sum := float64(h[13]) + float64(h[14]) + float64(h[15])
|
||||
t := (sum / 765) * 360
|
||||
return colorful.Hsl(t, defaultSaturation, defaultLightness)
|
||||
}
|
||||
|
||||
func generatePatternFromHash(sum [16]byte) []byte {
|
||||
p := make([]byte, 25)
|
||||
for i := 0; i < 5; i++ {
|
||||
for j := 0; j < 5; j++ {
|
||||
jCount := j
|
||||
|
||||
if j > 2 {
|
||||
jCount = 4 - j
|
||||
}
|
||||
|
||||
p[5*i+j] = sum[3*i+jCount]
|
||||
}
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func convertPatternToBinarySwitch(pattern []byte) []byte {
|
||||
b := make([]byte, 25)
|
||||
for i, v := range pattern {
|
||||
if v%2 == 0 {
|
||||
b[i] = 1
|
||||
} else {
|
||||
b[i] = 0
|
||||
}
|
||||
}
|
||||
return b
|
||||
}
|
||||
73
vendor/github.com/status-im/status-go/protocol/identity/identicon/renderer.go
generated
vendored
Normal file
73
vendor/github.com/status-im/status-go/protocol/identity/identicon/renderer.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
package identicon
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/draw"
|
||||
"image/png"
|
||||
)
|
||||
|
||||
const (
|
||||
Width = 50
|
||||
Height = 50
|
||||
)
|
||||
|
||||
func renderBase64(id Identicon) (string, error) {
|
||||
img, err := render(id)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
encodedString := base64.StdEncoding.EncodeToString(img)
|
||||
image := "data:image/png;base64," + encodedString
|
||||
return image, nil
|
||||
}
|
||||
|
||||
func setBackgroundTransparent(img *image.RGBA) {
|
||||
draw.Draw(img, img.Bounds(), &image.Uniform{C: color.Transparent}, image.Point{}, draw.Src)
|
||||
}
|
||||
|
||||
func drawRect(rgba *image.RGBA, i int, c color.Color) {
|
||||
sizeSquare := 6
|
||||
maxRow := 5
|
||||
|
||||
r := image.Rect(
|
||||
10+(i%maxRow)*sizeSquare,
|
||||
10+(i/maxRow)*sizeSquare,
|
||||
10+(i%maxRow)*sizeSquare+sizeSquare,
|
||||
10+(i/maxRow)*sizeSquare+sizeSquare,
|
||||
)
|
||||
|
||||
draw.Draw(rgba, r, &image.Uniform{C: c}, image.Point{}, draw.Src)
|
||||
}
|
||||
|
||||
func render(id Identicon) ([]byte, error) {
|
||||
img := image.NewRGBA(image.Rect(0, 0, Width, Height))
|
||||
var buff bytes.Buffer
|
||||
|
||||
setBackgroundTransparent(img)
|
||||
|
||||
for i, v := range id.bitmap {
|
||||
if v == 1 {
|
||||
drawRect(img, i, id.color)
|
||||
}
|
||||
}
|
||||
|
||||
if err := png.Encode(&buff, img); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buff.Bytes(), nil
|
||||
}
|
||||
|
||||
// GenerateBase64 generates an identicon in base64 png format given a string
|
||||
func GenerateBase64(id string) (string, error) {
|
||||
i := generate(id)
|
||||
return renderBase64(i)
|
||||
}
|
||||
|
||||
func Generate(id string) ([]byte, error) {
|
||||
i := generate(id)
|
||||
return render(i)
|
||||
}
|
||||
91
vendor/github.com/status-im/status-go/protocol/identity/ring/ring.go
generated
vendored
Normal file
91
vendor/github.com/status-im/status-go/protocol/identity/ring/ring.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
package ring
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/png"
|
||||
"math"
|
||||
|
||||
"github.com/fogleman/gg"
|
||||
|
||||
"github.com/status-im/status-go/multiaccounts"
|
||||
)
|
||||
|
||||
type Theme int
|
||||
|
||||
const (
|
||||
LightTheme Theme = 1
|
||||
DarkTheme Theme = 2
|
||||
)
|
||||
|
||||
var (
|
||||
lightThemeIdenticonRingColors = []string{
|
||||
"#000000", "#726F6F", "#C4C4C4", "#E7E7E7", "#FFFFFF", "#00FF00",
|
||||
"#009800", "#B8FFBB", "#FFC413", "#9F5947", "#FFFF00", "#A8AC00",
|
||||
"#FFFFB0", "#FF5733", "#FF0000", "#9A0000", "#FF9D9D", "#FF0099",
|
||||
"#C80078", "#FF00FF", "#900090", "#FFB0FF", "#9E00FF", "#0000FF",
|
||||
"#000086", "#9B81FF", "#3FAEF9", "#9A6600", "#00FFFF", "#008694",
|
||||
"#C2FFFF", "#00F0B6"}
|
||||
darkThemeIdenticonRingColors = []string{
|
||||
"#000000", "#726F6F", "#C4C4C4", "#E7E7E7", "#FFFFFF", "#00FF00",
|
||||
"#009800", "#B8FFBB", "#FFC413", "#9F5947", "#FFFF00", "#A8AC00",
|
||||
"#FFFFB0", "#FF5733", "#FF0000", "#9A0000", "#FF9D9D", "#FF0099",
|
||||
"#C80078", "#FF00FF", "#900090", "#FFB0FF", "#9E00FF", "#0000FF",
|
||||
"#000086", "#9B81FF", "#3FAEF9", "#9A6600", "#00FFFF", "#008694",
|
||||
"#C2FFFF", "#00F0B6"}
|
||||
)
|
||||
|
||||
type DrawRingParam struct {
|
||||
Theme Theme `json:"theme"`
|
||||
ColorHash multiaccounts.ColorHash `json:"colorHash"`
|
||||
ImageBytes []byte `json:"imageBytes"`
|
||||
Height int `json:"height"`
|
||||
Width int `json:"width"`
|
||||
RingWidth float64 `json:"ringWidth"`
|
||||
}
|
||||
|
||||
func DrawRing(param *DrawRingParam) ([]byte, error) {
|
||||
var colors []string
|
||||
switch param.Theme {
|
||||
case LightTheme:
|
||||
colors = lightThemeIdenticonRingColors
|
||||
case DarkTheme:
|
||||
colors = darkThemeIdenticonRingColors
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown theme")
|
||||
}
|
||||
|
||||
dc := gg.NewContext(param.Width, param.Height)
|
||||
img, _, err := image.Decode(bytes.NewReader(param.ImageBytes))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dc.DrawImage(img, 0, 0)
|
||||
|
||||
radius := (float64(param.Height) - param.RingWidth) / 2
|
||||
arcPos := 0.0
|
||||
|
||||
totalRingUnits := 0
|
||||
for i := 0; i < len(param.ColorHash); i++ {
|
||||
totalRingUnits += param.ColorHash[i][0]
|
||||
}
|
||||
unitRadLen := 2 * math.Pi / float64(totalRingUnits)
|
||||
|
||||
for i := 0; i < len(param.ColorHash); i++ {
|
||||
dc.SetHexColor(colors[param.ColorHash[i][1]])
|
||||
dc.DrawArc(float64(param.Width/2), float64(param.Height/2), radius, arcPos, arcPos+unitRadLen*float64(param.ColorHash[i][0]))
|
||||
dc.SetLineWidth(param.RingWidth)
|
||||
dc.SetLineCapButt()
|
||||
dc.Stroke()
|
||||
arcPos += unitRadLen * float64(param.ColorHash[i][0])
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
err = png.Encode(buf, dc.Image())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
95
vendor/github.com/status-im/status-go/protocol/identity/social_links.go
generated
vendored
Normal file
95
vendor/github.com/status-im/status-go/protocol/identity/social_links.go
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
package identity
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/status-im/status-go/protocol/protobuf"
|
||||
)
|
||||
|
||||
// static links which need to be decorated by the UI clients
|
||||
const (
|
||||
TwitterID = "__twitter"
|
||||
PersonalSiteID = "__personal_site"
|
||||
GithubID = "__github"
|
||||
YoutubeID = "__youtube"
|
||||
DiscordID = "__discord"
|
||||
TelegramID = "__telegram"
|
||||
)
|
||||
|
||||
type SocialLink struct {
|
||||
Text string `json:"text"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
type SocialLinks []*SocialLink
|
||||
|
||||
type SocialLinksInfo struct {
|
||||
Links []*SocialLink `json:"links"`
|
||||
Removed bool `json:"removed"`
|
||||
}
|
||||
|
||||
func NewSocialLinks(links []*protobuf.SocialLink) SocialLinks {
|
||||
res := SocialLinks{}
|
||||
for _, link := range links {
|
||||
res = append(res, &SocialLink{Text: link.Text, URL: link.Url})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (s *SocialLink) ToProtobuf() *protobuf.SocialLink {
|
||||
return &protobuf.SocialLink{
|
||||
Text: s.Text,
|
||||
Url: s.URL,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SocialLink) Equal(link *SocialLink) bool {
|
||||
return s.Text == link.Text && s.URL == link.URL
|
||||
}
|
||||
|
||||
func (s *SocialLinks) ToProtobuf() []*protobuf.SocialLink {
|
||||
res := []*protobuf.SocialLink{}
|
||||
for _, link := range *s {
|
||||
res = append(res, link.ToProtobuf())
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (s *SocialLinks) ToSyncProtobuf(clock uint64) *protobuf.SyncSocialLinks {
|
||||
res := &protobuf.SyncSocialLinks{
|
||||
Clock: clock,
|
||||
}
|
||||
for _, link := range *s {
|
||||
res.SocialLinks = append(res.SocialLinks, link.ToProtobuf())
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// Equal means the same links at the same order
|
||||
func (s *SocialLinks) Equal(links SocialLinks) bool {
|
||||
if len(*s) != len(links) {
|
||||
return false
|
||||
}
|
||||
for i := range *s {
|
||||
if !(*s)[i].Equal(links[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *SocialLinks) Contains(link *SocialLink) bool {
|
||||
if len(*s) == 0 {
|
||||
return false
|
||||
}
|
||||
for _, l := range *s {
|
||||
if l.Equal(link) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *SocialLinks) Serialize() ([]byte, error) {
|
||||
return json.Marshal(*s)
|
||||
}
|
||||
81
vendor/github.com/status-im/status-go/protocol/identity/utils.go
generated
vendored
Normal file
81
vendor/github.com/status-im/status-go/protocol/identity/utils.go
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
package identity
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/crypto/secp256k1"
|
||||
)
|
||||
|
||||
func ToColorID(pubkey string) (int64, error) {
|
||||
const colorPalletLength = 12
|
||||
|
||||
pubkeyValue, ok := new(big.Int).SetString(pubkey, 0)
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("invalid pubkey: %s", pubkey)
|
||||
}
|
||||
|
||||
colorID := new(big.Int).Mod(pubkeyValue, new(big.Int).SetInt64(colorPalletLength-1)).Int64()
|
||||
|
||||
return colorID, nil
|
||||
}
|
||||
|
||||
func ToBigBase(value *big.Int, base uint64) (res [](uint64)) {
|
||||
toBigBaseImpl(value, base, &res)
|
||||
return
|
||||
}
|
||||
|
||||
func toBigBaseImpl(value *big.Int, base uint64, res *[](uint64)) {
|
||||
bigBase := new(big.Int).SetUint64(base)
|
||||
quotient := new(big.Int).Div(value, bigBase)
|
||||
if quotient.Cmp(new(big.Int).SetUint64(0)) != 0 {
|
||||
toBigBaseImpl(quotient, base, res)
|
||||
}
|
||||
|
||||
*res = append(*res, new(big.Int).Mod(value, bigBase).Uint64())
|
||||
}
|
||||
|
||||
// compressedPubKey = |1.5 bytes chars cutoff|20 bytes emoji hash|10 bytes color hash|1.5 bytes chars cutoff|
|
||||
func Slices(compressedPubkey []byte) (res [4][]byte, err error) {
|
||||
if len(compressedPubkey) != 33 {
|
||||
return res, errors.New("incorrect compressed pubkey")
|
||||
}
|
||||
|
||||
getSlice := func(low, high int, and string, rsh uint) []byte {
|
||||
sliceValue := new(big.Int).SetBytes(compressedPubkey[low:high])
|
||||
andValue, _ := new(big.Int).SetString(and, 0)
|
||||
andRes := new(big.Int).And(sliceValue, andValue)
|
||||
return new(big.Int).Rsh(andRes, rsh).Bytes()
|
||||
}
|
||||
|
||||
res[0] = getSlice(0, 2, "0xFFF0", 4)
|
||||
res[1] = getSlice(1, 22, "0x0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", 4)
|
||||
res[2] = getSlice(21, 32, "0x0FFFFFFFFFFFFFFFFFFFF0", 4)
|
||||
res[3] = getSlice(31, 33, "0x0FFF", 0)
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func ToCompressedKey(pubkey string) ([]byte, error) {
|
||||
pubkeyValue, ok := new(big.Int).SetString(pubkey, 0)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid pubkey: %s", pubkey)
|
||||
}
|
||||
|
||||
x, y := secp256k1.S256().Unmarshal(pubkeyValue.Bytes())
|
||||
if x == nil || !secp256k1.S256().IsOnCurve(x, y) {
|
||||
return nil, fmt.Errorf("invalid pubkey: %s", pubkey)
|
||||
}
|
||||
|
||||
return secp256k1.CompressPubkey(x, y), nil
|
||||
}
|
||||
|
||||
func ToBigInt(t *testing.T, str string) *big.Int {
|
||||
res, ok := new(big.Int).SetString(str, 0)
|
||||
if !ok {
|
||||
t.Errorf("invalid conversion to int from %s", str)
|
||||
}
|
||||
return res
|
||||
}
|
||||
Reference in New Issue
Block a user