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  )