github.com/cloudflare/circl@v1.5.0/abe/cpabe/tkn20/internal/tkn/util.go (about) 1 package tkn 2 3 import ( 4 "encoding/binary" 5 "errors" 6 "fmt" 7 "sort" 8 9 pairing "github.com/cloudflare/circl/ecc/bls12381" 10 "golang.org/x/crypto/blake2b" 11 ) 12 13 var gtBaseVal *pairing.Gt 14 15 func init() { 16 // This should really be a constant, but what can I do? 17 g1 := pairing.G1Generator() 18 g2 := pairing.G2Generator() 19 gtBaseVal = pairing.Pair(g1, g2) 20 } 21 22 func ToScalar(n int) *pairing.Scalar { 23 ret := &pairing.Scalar{} 24 ret.SetUint64(uint64(n)) 25 return ret 26 } 27 28 func HashStringToScalar(key []byte, value string) *pairing.Scalar { 29 xof, err := blake2b.NewXOF(blake2b.OutputLengthUnknown, key) 30 if err != nil { 31 return nil 32 } 33 _, err = xof.Write([]byte(value)) 34 if err != nil { 35 return nil 36 } 37 s := &pairing.Scalar{} 38 err = s.Random(xof) 39 if err != nil { 40 return nil 41 } 42 return s 43 } 44 45 func appendLen16Prefixed(a []byte, b []byte) []byte { 46 a = append(a, 0, 0) 47 binary.LittleEndian.PutUint16(a[len(a)-2:], uint16(len(b))) 48 a = append(a, b...) 49 return a 50 } 51 52 func removeLen16Prefixed(data []byte) (next []byte, remainder []byte, err error) { 53 if len(data) < 2 { 54 return nil, nil, fmt.Errorf("data too short") 55 } 56 itemLen := int(binary.LittleEndian.Uint16(data)) 57 if (2 + itemLen) > len(data) { 58 return nil, nil, fmt.Errorf("data too short") 59 } 60 return data[2 : 2+itemLen], data[2+itemLen:], nil 61 } 62 63 var ( 64 appendLenPrefixed = appendLen16Prefixed 65 removeLenPrefixed = removeLen16Prefixed 66 ) 67 68 func appendLen32Prefixed(a []byte, b []byte) []byte { 69 a = append(a, 0, 0, 0, 0) 70 binary.LittleEndian.PutUint32(a[len(a)-4:], uint32(len(b))) 71 a = append(a, b...) 72 return a 73 } 74 75 func removeLen32Prefixed(data []byte) (next []byte, remainder []byte, err error) { 76 if len(data) < 4 { 77 return nil, nil, fmt.Errorf("data too short") 78 } 79 itemLen := int(binary.LittleEndian.Uint32(data)) 80 if (4 + itemLen) > len(data) { 81 return nil, nil, fmt.Errorf("data too short") 82 } 83 return data[4 : 4+itemLen], data[4+itemLen:], nil 84 } 85 86 func marshalBinarySortedMapMatrixG1(m map[string]*matrixG1) ([]byte, error) { 87 sortedKeys := make([]string, 0, len(m)) 88 for key := range m { 89 sortedKeys = append(sortedKeys, key) 90 } 91 sort.Strings(sortedKeys) 92 93 ret := []byte{} 94 for _, key := range sortedKeys { 95 b, err := m[key].marshalBinary() 96 if err != nil { 97 return nil, err 98 } 99 100 ret = appendLenPrefixed(ret, []byte(key)) 101 ret = appendLenPrefixed(ret, b) 102 } 103 104 return ret, nil 105 } 106 107 func marshalBinarySortedMapAttribute(m map[string]Attribute) ([]byte, error) { 108 sortedKeys := make([]string, 0, len(m)) 109 for key := range m { 110 sortedKeys = append(sortedKeys, key) 111 } 112 sort.Strings(sortedKeys) 113 114 ret := []byte{} 115 for _, key := range sortedKeys { 116 a := m[key] 117 b, err := a.marshalBinary() 118 if err != nil { 119 return nil, err 120 } 121 122 ret = appendLenPrefixed(ret, []byte(key)) 123 ret = append(ret, b...) 124 } 125 126 return ret, nil 127 } 128 129 var ( 130 errBadMatrixSize = errors.New("matrix inputs do not conform") 131 errMatrixNonInvertible = errors.New("matrix has no inverse") 132 )