github.com/cloudflare/circl@v1.5.0/abe/cpabe/tkn20/internal/tkn/tk.go (about)

     1  // Implements the scheme of https://eprint.iacr.org/2019/966
     2  
     3  package tkn
     4  
     5  import (
     6  	"crypto/subtle"
     7  	"encoding/binary"
     8  	"fmt"
     9  	"io"
    10  
    11  	pairing "github.com/cloudflare/circl/ecc/bls12381"
    12  )
    13  
    14  type PublicParams struct {
    15  	b2  *matrixG2
    16  	wb1 *matrixG1
    17  	btk *matrixGT
    18  }
    19  
    20  func (p *PublicParams) MarshalBinary() ([]byte, error) {
    21  	b2Bytes, err := p.b2.marshalBinary()
    22  	if err != nil {
    23  		return nil, fmt.Errorf("PublicParams serializing failed: %w", err)
    24  	}
    25  	ret := appendLenPrefixed(nil, b2Bytes)
    26  
    27  	wb1Bytes, err := p.wb1.marshalBinary()
    28  	if err != nil {
    29  		return nil, fmt.Errorf("PublicParams serializing failed: %w", err)
    30  	}
    31  	ret = appendLenPrefixed(ret, wb1Bytes)
    32  
    33  	btkBytes, err := p.btk.marshalBinary()
    34  	if err != nil {
    35  		return nil, fmt.Errorf("PublicParams serializing failed: %w", err)
    36  	}
    37  	ret = appendLenPrefixed(ret, btkBytes)
    38  
    39  	return ret, nil
    40  }
    41  
    42  func (p *PublicParams) UnmarshalBinary(data []byte) error {
    43  	b2Bytes, data, err := removeLenPrefixed(data)
    44  	if err != nil {
    45  		return fmt.Errorf("PublicParams deserialization failure: %w", err)
    46  	}
    47  	p.b2 = newMatrixG2(0, 0)
    48  	err = p.b2.unmarshalBinary(b2Bytes)
    49  	if err != nil {
    50  		return fmt.Errorf("PublicParams deserialization failure: %w", err)
    51  	}
    52  
    53  	wb1Bytes, data, err := removeLenPrefixed(data)
    54  	if err != nil {
    55  		return fmt.Errorf("PublicParams deserialization failure: %w", err)
    56  	}
    57  	p.wb1 = newMatrixG1(0, 0)
    58  	err = p.wb1.unmarshalBinary(wb1Bytes)
    59  	if err != nil {
    60  		return fmt.Errorf("PublicParams deserialization failure: %w", err)
    61  	}
    62  
    63  	btkBytes, data, err := removeLenPrefixed(data)
    64  	if err != nil {
    65  		return fmt.Errorf("PublicParams deserialization failure: %w", err)
    66  	}
    67  	p.btk = newMatrixGT(0, 0)
    68  	err = p.btk.unmarshalBinary(btkBytes)
    69  	if err != nil {
    70  		return fmt.Errorf("PublicParams deserialization failure: %w", err)
    71  	}
    72  
    73  	if len(data) != 0 {
    74  		return fmt.Errorf("PublicParams deserialization failed: excess bytes remain in data")
    75  	}
    76  	return nil
    77  }
    78  
    79  func (p *PublicParams) Equal(p2 *PublicParams) bool {
    80  	return p.b2.Equal(p2.b2) && p.wb1.Equal(p2.wb1) && p.btk.Equal(p2.btk)
    81  }
    82  
    83  type SecretParams struct {
    84  	a       *matrixZp
    85  	wtA     *matrixZp
    86  	bstar   *matrixZp
    87  	bstar12 *matrixZp
    88  	k       *matrixZp // vectors are represented as 1 x n matrices
    89  	prfKey  []byte
    90  }
    91  
    92  func (s *SecretParams) MarshalBinary() ([]byte, error) {
    93  	aBytes, err := s.a.marshalBinary()
    94  	if err != nil {
    95  		return nil, fmt.Errorf("SecretParams serializing failed: %w", err)
    96  	}
    97  	wtABytes, err := s.wtA.marshalBinary()
    98  	if err != nil {
    99  		return nil, fmt.Errorf("SecretParams serializing failed: %w", err)
   100  	}
   101  	bstarBytes, err := s.bstar.marshalBinary()
   102  	if err != nil {
   103  		return nil, fmt.Errorf("SecretParams serializing failed: %w", err)
   104  	}
   105  	bstar12Bytes, err := s.bstar12.marshalBinary()
   106  	if err != nil {
   107  		return nil, fmt.Errorf("SecretParams serializing failed: %w", err)
   108  	}
   109  	kBytes, err := s.k.marshalBinary()
   110  	if err != nil {
   111  		return nil, fmt.Errorf("SecretParams serializing failed: %w", err)
   112  	}
   113  	bufs := [][]byte{
   114  		aBytes, wtABytes, bstarBytes, bstar12Bytes, kBytes, s.prfKey,
   115  	}
   116  
   117  	ret := appendLenPrefixed(nil, bufs[0])
   118  	for _, buf := range bufs[1:] {
   119  		ret = appendLenPrefixed(ret, buf)
   120  	}
   121  	return ret, nil
   122  }
   123  
   124  func (s *SecretParams) UnmarshalBinary(data []byte) error {
   125  	aBytes, data, err := removeLenPrefixed(data)
   126  	if err != nil {
   127  		return fmt.Errorf("SecretParams deserialization failure: %w", err)
   128  	}
   129  	s.a = newMatrixZp(0, 0)
   130  	err = s.a.unmarshalBinary(aBytes)
   131  	if err != nil {
   132  		return fmt.Errorf("SecretParams deserialization failure: %w", err)
   133  	}
   134  	wtABytes, data, err := removeLenPrefixed(data)
   135  	if err != nil {
   136  		return fmt.Errorf("SecretParams deserialization failure: %w", err)
   137  	}
   138  	s.wtA = newMatrixZp(0, 0)
   139  	err = s.wtA.unmarshalBinary(wtABytes)
   140  	if err != nil {
   141  		return fmt.Errorf("SecretParams deserialization failure: %w", err)
   142  	}
   143  	bstarBytes, data, err := removeLenPrefixed(data)
   144  	if err != nil {
   145  		return fmt.Errorf("SecretParams deserialization failure: %w", err)
   146  	}
   147  	s.bstar = newMatrixZp(0, 0)
   148  	err = s.bstar.unmarshalBinary(bstarBytes)
   149  	if err != nil {
   150  		return fmt.Errorf("SecretParams deserialization failure: %w", err)
   151  	}
   152  	bstar12Bytes, data, err := removeLenPrefixed(data)
   153  	if err != nil {
   154  		return fmt.Errorf("SecretParams deserialization failure: %w", err)
   155  	}
   156  	s.bstar12 = newMatrixZp(0, 0)
   157  	err = s.bstar12.unmarshalBinary(bstar12Bytes)
   158  	if err != nil {
   159  		return fmt.Errorf("SecretParams deserialization failure: %w", err)
   160  	}
   161  	kBytes, data, err := removeLenPrefixed(data)
   162  	if err != nil {
   163  		return fmt.Errorf("SecretParams deserialization failure: %w", err)
   164  	}
   165  	s.k = newMatrixZp(0, 0)
   166  	err = s.k.unmarshalBinary(kBytes)
   167  	if err != nil {
   168  		return fmt.Errorf("SecretParams deserialization failure: %w", err)
   169  	}
   170  	prfBytes, data, err := removeLenPrefixed(data)
   171  	if err != nil {
   172  		return fmt.Errorf("SecretParams deserialization failure: %w", err)
   173  	}
   174  	s.prfKey = prfBytes
   175  
   176  	if len(data) != 0 {
   177  		return fmt.Errorf("SecretParams deserialization failed: excess bytes remain in data")
   178  	}
   179  	return nil
   180  }
   181  
   182  func (s *SecretParams) Equal(s2 *SecretParams) bool {
   183  	return s.a.Equal(s2.a) && s.wtA.Equal(s2.wtA) && s.bstar.Equal(s2.bstar) &&
   184  		s.bstar12.Equal(s2.bstar12) && s.k.Equal(s2.k) &&
   185  		subtle.ConstantTimeCompare(s.prfKey, s2.prfKey) == 1
   186  }
   187  
   188  type AttributesKey struct {
   189  	a      *Attributes
   190  	k1     *matrixG2
   191  	k2     *matrixG1
   192  	k3     map[string]*matrixG1
   193  	k3wild map[string]*matrixG1 // only contains wildcards
   194  }
   195  
   196  func (a *AttributesKey) MarshalBinary() ([]byte, error) {
   197  	aBytes, err := a.a.marshalBinary()
   198  	if err != nil {
   199  		return nil, fmt.Errorf("AttributesKey serializing failed: %w", err)
   200  	}
   201  	ret := appendLenPrefixed(nil, aBytes)
   202  	k1Bytes, err := a.k1.marshalBinary()
   203  	if err != nil {
   204  		return nil, fmt.Errorf("AttributesKey serializing failed: %w", err)
   205  	}
   206  	ret = appendLenPrefixed(ret, k1Bytes)
   207  	k2Bytes, err := a.k2.marshalBinary()
   208  	if err != nil {
   209  		return nil, fmt.Errorf("AttributesKey serializing failed: %w", err)
   210  	}
   211  	ret = appendLenPrefixed(ret, k2Bytes)
   212  	ret = append(ret, 0, 0)
   213  	binary.LittleEndian.PutUint16(ret[len(ret)-2:], uint16(len(a.k3)))
   214  	k3Bytes, err := marshalBinarySortedMapMatrixG1(a.k3)
   215  	if err != nil {
   216  		return nil, fmt.Errorf("AttributesKey serializing failed: %w", err)
   217  	}
   218  	ret = append(ret, k3Bytes...)
   219  
   220  	ret = append(ret, 0, 0)
   221  	binary.LittleEndian.PutUint16(ret[len(ret)-2:], uint16(len(a.k3wild)))
   222  	k3wildBytes, err := marshalBinarySortedMapMatrixG1(a.k3wild)
   223  	if err != nil {
   224  		return nil, fmt.Errorf("AttributesKey serializing failed: %w", err)
   225  	}
   226  	ret = append(ret, k3wildBytes...)
   227  
   228  	return ret, nil
   229  }
   230  
   231  func (a *AttributesKey) UnmarshalBinary(data []byte) error {
   232  	aBytes, data, err := removeLenPrefixed(data)
   233  	if err != nil {
   234  		return fmt.Errorf("AttributesKey deserialization failure: %w", err)
   235  	}
   236  	a.a = &Attributes{}
   237  	err = a.a.unmarshalBinary(aBytes)
   238  	if err != nil {
   239  		return fmt.Errorf("AttributesKey deserialization failure: %w", err)
   240  	}
   241  	k1Bytes, data, err := removeLenPrefixed(data)
   242  	if err != nil {
   243  		return fmt.Errorf("AttributesKey deserialization failure: %w", err)
   244  	}
   245  	a.k1 = newMatrixG2(0, 0)
   246  	err = a.k1.unmarshalBinary(k1Bytes)
   247  	if err != nil {
   248  		return fmt.Errorf("AttributesKey deserialization failure: %w", err)
   249  	}
   250  	k2Bytes, data, err := removeLenPrefixed(data)
   251  	if err != nil {
   252  		return fmt.Errorf("AttributesKey deserialization failure: %w", err)
   253  	}
   254  	a.k2 = newMatrixG1(0, 0)
   255  	err = a.k2.unmarshalBinary(k2Bytes)
   256  	if err != nil {
   257  		return fmt.Errorf("AttributesKey deserialization failure: %w", err)
   258  	}
   259  
   260  	if len(data) < 2 {
   261  		return fmt.Errorf("AttributesKey deserialization failure: data too short")
   262  	}
   263  	n := int(binary.LittleEndian.Uint16(data))
   264  	data = data[2:]
   265  	a.k3 = make(map[string]*matrixG1, n)
   266  	for i := 0; i < n; i++ {
   267  		sBytes, rem, err := removeLenPrefixed(data)
   268  		if err != nil {
   269  			return fmt.Errorf("AttributesKey deserialization failure: %w", err)
   270  		}
   271  		mBytes, rem, err := removeLenPrefixed(rem)
   272  		if err != nil {
   273  			return fmt.Errorf("AttributesKey deserialization failure: %w", err)
   274  		}
   275  		m := newMatrixG1(0, 0)
   276  		err = m.unmarshalBinary(mBytes)
   277  		if err != nil {
   278  			return fmt.Errorf("AttributesKey deserialization failure: %w", err)
   279  		}
   280  		a.k3[string(sBytes)] = m
   281  		data = rem
   282  	}
   283  
   284  	if len(data) < 2 {
   285  		return fmt.Errorf("AttributesKey deserialization failure: data too short")
   286  	}
   287  	n = int(binary.LittleEndian.Uint16(data))
   288  	data = data[2:]
   289  	a.k3wild = make(map[string]*matrixG1, n)
   290  	for i := 0; i < n; i++ {
   291  		sBytes, rem, err := removeLenPrefixed(data)
   292  		if err != nil {
   293  			return fmt.Errorf("AttributesKey deserialization failure: %w", err)
   294  		}
   295  		mBytes, rem, err := removeLenPrefixed(rem)
   296  		if err != nil {
   297  			return fmt.Errorf("AttributesKey deserialization failure: %w", err)
   298  		}
   299  		m := newMatrixG1(0, 0)
   300  		err = m.unmarshalBinary(mBytes)
   301  		if err != nil {
   302  			return fmt.Errorf("AttributesKey deserialization failure: %w", err)
   303  		}
   304  		a.k3wild[string(sBytes)] = m
   305  		data = rem
   306  	}
   307  	if len(data) != 0 {
   308  		return fmt.Errorf("AttributesKey deserialization failed: excess bytes remain in data")
   309  	}
   310  	return nil
   311  }
   312  
   313  func (a *AttributesKey) Equal(b *AttributesKey) bool {
   314  	if !a.a.Equal(b.a) || !a.k1.Equal(b.k1) || !a.k2.Equal(b.k2) {
   315  		return false
   316  	}
   317  	if len(a.k3) != len(b.k3) || len(a.k3wild) != len(b.k3wild) {
   318  		return false
   319  	}
   320  	for k, v := range a.k3 {
   321  		if !b.k3[k].Equal(v) {
   322  			return false
   323  		}
   324  	}
   325  	for k, v := range a.k3wild {
   326  		if !b.k3wild[k].Equal(v) {
   327  			return false
   328  		}
   329  	}
   330  	return true
   331  }
   332  
   333  type ciphertextHeader struct {
   334  	p     *Policy
   335  	c1    *matrixG2
   336  	c2    []*matrixG2
   337  	c3    []*matrixG1
   338  	c3neg []*matrixG1 // additional vector for negated attributes
   339  }
   340  
   341  func (hdr *ciphertextHeader) marshalBinary() ([]byte, error) {
   342  	pBytes, err := hdr.p.MarshalBinary()
   343  	if err != nil {
   344  		return nil, err
   345  	}
   346  	ret := appendLenPrefixed(nil, pBytes)
   347  
   348  	c1Bytes, err := hdr.c1.marshalBinary()
   349  	if err != nil {
   350  		return nil, fmt.Errorf("c1 serializing: %w", err)
   351  	}
   352  	ret = appendLenPrefixed(ret, c1Bytes)
   353  
   354  	// Now we need to indicate how long c2, c3, c3neg are.
   355  	// Each array will be the same size (or nil), so with more work we can specialize
   356  	// but for now we will ignore that.
   357  
   358  	c2Len := len(hdr.c2)
   359  
   360  	ret = append(ret, 0, 0)
   361  	binary.LittleEndian.PutUint16(ret[len(ret)-2:], uint16(c2Len))
   362  	for i := 0; i < c2Len; i++ {
   363  		c2dat, errM := hdr.c2[i].marshalBinary()
   364  		if errM != nil {
   365  			return nil, fmt.Errorf("c2 serializing %d: %w", i, errM)
   366  		}
   367  		ret = appendLenPrefixed(ret, c2dat)
   368  	}
   369  	c3Len := len(hdr.c3)
   370  	ret = append(ret, 0, 0)
   371  	binary.LittleEndian.PutUint16(ret[len(ret)-2:], uint16(c3Len))
   372  	for i := 0; i < c3Len; i++ {
   373  		c3dat, errM := hdr.c3[i].marshalBinary()
   374  		if errM != nil {
   375  			return nil, fmt.Errorf("c3 serializing %d: %w", i, errM)
   376  		}
   377  		ret = appendLenPrefixed(ret, c3dat)
   378  	}
   379  	for i := 0; i < c3Len; i++ {
   380  		var c3negdat []byte
   381  		if hdr.c3neg[i] != nil {
   382  			c3negdat, err = hdr.c3neg[i].marshalBinary()
   383  			if err != nil {
   384  				return nil, fmt.Errorf("c3neg serializing %d: %w", i, err)
   385  			}
   386  		} else {
   387  			c3negdat = nil
   388  		}
   389  		ret = appendLenPrefixed(ret, c3negdat)
   390  	}
   391  	return ret, nil
   392  }
   393  
   394  func (hdr *ciphertextHeader) unmarshalBinary(data []byte) error {
   395  	pBytes, data, err := removeLenPrefixed(data)
   396  	if err != nil {
   397  		return err
   398  	}
   399  	hdr.p = new(Policy)
   400  	err = hdr.p.UnmarshalBinary(pBytes)
   401  	if err != nil {
   402  		return err
   403  	}
   404  	c1Bytes, data, err := removeLenPrefixed(data)
   405  	if err != nil {
   406  		return err
   407  	}
   408  	hdr.c1 = newMatrixG2(0, 0)
   409  	err = hdr.c1.unmarshalBinary(c1Bytes)
   410  	if err != nil {
   411  		return err
   412  	}
   413  	c2Len := int(binary.LittleEndian.Uint16(data))
   414  	hdr.c2 = make([]*matrixG2, c2Len)
   415  	data = data[2:]
   416  	var c2data []byte
   417  	var c3data []byte
   418  	var c3negdata []byte
   419  
   420  	for i := 0; i < c2Len; i++ {
   421  		c2data, data, err = removeLenPrefixed(data)
   422  		if err != nil {
   423  			return err
   424  		}
   425  		hdr.c2[i] = newMatrixG2(0, 0)
   426  		err = hdr.c2[i].unmarshalBinary(c2data)
   427  		if err != nil {
   428  			return err
   429  		}
   430  	}
   431  
   432  	c3Len := int(binary.LittleEndian.Uint16(data))
   433  	hdr.c3 = make([]*matrixG1, c3Len)
   434  	hdr.c3neg = make([]*matrixG1, c3Len)
   435  	data = data[2:]
   436  
   437  	for i := 0; i < c3Len; i++ {
   438  		c3data, data, err = removeLenPrefixed(data)
   439  		if err != nil {
   440  			return err
   441  		}
   442  		hdr.c3[i] = newMatrixG1(0, 0)
   443  		err = hdr.c3[i].unmarshalBinary(c3data)
   444  		if err != nil {
   445  			return err
   446  		}
   447  	}
   448  
   449  	for i := 0; i < c3Len; i++ {
   450  		c3negdata, data, err = removeLenPrefixed(data)
   451  		if err != nil {
   452  			return err
   453  		}
   454  
   455  		if len(c3negdata) != 0 {
   456  			hdr.c3neg[i] = newMatrixG1(0, 0)
   457  			err = hdr.c3neg[i].unmarshalBinary(c3negdata)
   458  			if err != nil {
   459  				return err
   460  			}
   461  		}
   462  	}
   463  
   464  	return nil
   465  }
   466  
   467  func GenerateParams(rand io.Reader) (*PublicParams, *SecretParams, error) {
   468  	A, err := sampleDlin(rand)
   469  	if err != nil {
   470  		return nil, nil, err
   471  	}
   472  	Bbar, err := randomMatrixZp(rand, 4, 4)
   473  	if err != nil {
   474  		return nil, nil, err
   475  	}
   476  	W, err := randomMatrixZp(rand, 3, 4)
   477  	if err != nil {
   478  		return nil, nil, err
   479  	}
   480  	k, err := randomMatrixZp(rand, 4, 1)
   481  	if err != nil {
   482  		return nil, nil, err
   483  	}
   484  	prfKey := make([]byte, 16)
   485  	_, err = io.ReadFull(rand, prfKey)
   486  	if err != nil {
   487  		return nil, nil, err
   488  	}
   489  
   490  	B := newMatrixZp(0, 0)
   491  	B.colsel(Bbar, []int{0, 1})
   492  	wb := newMatrixZp(0, 0)
   493  	wb.mul(W, B)
   494  
   495  	Bt := newMatrixZp(0, 0)
   496  	Bt.transpose(B)
   497  	BtKp := newMatrixZp(0, 0)
   498  	BtKp.mul(Bt, k)
   499  
   500  	pp := PublicParams{}
   501  	pp.b2 = newMatrixG2(0, 0)
   502  	pp.b2.exp(B)
   503  	pp.wb1 = newMatrixG1(0, 0)
   504  	pp.wb1.exp(wb)
   505  	pp.btk = newMatrixGT(0, 0)
   506  	pp.btk.exp(BtKp)
   507  
   508  	sp := SecretParams{}
   509  	sp.a = A
   510  	sp.wtA = newMatrixZp(0, 0)
   511  	wt := newMatrixZp(0, 0)
   512  	wt.transpose(W)
   513  	sp.wtA.mul(wt, A)
   514  
   515  	BbarTinv := newMatrixZp(0, 0)
   516  	BbarT := newMatrixZp(0, 0)
   517  	BbarT.transpose(Bbar)
   518  	err = BbarTinv.inverse(BbarT)
   519  	if err != nil {
   520  		return nil, nil, err
   521  	}
   522  
   523  	sp.bstar = newMatrixZp(0, 0)
   524  	sp.bstar.colsel(BbarTinv, []int{0, 1})
   525  
   526  	sp.bstar12 = newMatrixZp(0, 0)
   527  	sp.bstar12.colsel(BbarTinv, []int{2, 3})
   528  
   529  	sp.k = k
   530  	sp.prfKey = prfKey
   531  
   532  	return &pp, &sp, nil
   533  }
   534  
   535  func max(in []int) int {
   536  	max := 0
   537  	for i := 0; i < len(in); i++ {
   538  		if in[i] > max {
   539  			max = in[i]
   540  		}
   541  	}
   542  	return max
   543  }
   544  
   545  // encapsulate creates a new ephemeral key and header that can be opened to it. This is
   546  // the transformation of an Elgamal like scheme to a KEM.
   547  func encapsulate(rand io.Reader, pp *PublicParams, policy *Policy) (*ciphertextHeader, *pairing.Gt, error) {
   548  	pi := policy.pi()
   549  	d := max(pi) + 1
   550  	ri := make([]*matrixZp, d)
   551  	r, err := randomMatrixZp(rand, 2, 1)
   552  	if err != nil {
   553  		return nil, nil, err
   554  	}
   555  	for i := 0; i < d; i++ {
   556  		ri[i], err = randomMatrixZp(rand, 2, 1)
   557  		if err != nil {
   558  			return nil, nil, err
   559  		}
   560  	}
   561  	rshares, err := policy.F.share(rand, r)
   562  	if err != nil {
   563  		return nil, nil, err
   564  	}
   565  	tmp := newMatrixZp(2, 1)
   566  	wshares := make([]*matrixG1, len(rshares))
   567  	for i := 0; i < len(rshares); i++ {
   568  		wshares[i] = newMatrixG1(0, 0)
   569  		wshares[i].rightMult(pp.wb1, rshares[i])
   570  	}
   571  
   572  	c1 := newMatrixG2(0, 0)
   573  	c1.rightMult(pp.b2, r)
   574  
   575  	c2 := make([]*matrixG2, d)
   576  	for i := 0; i < d; i++ {
   577  		c2[i] = newMatrixG2(0, 0)
   578  		c2[i].rightMult(pp.b2, ri[i])
   579  	}
   580  
   581  	c4mat := newMatrixGT(1, 1)
   582  	tmp.transpose(r)
   583  	c4mat.leftMult(tmp, pp.btk)
   584  	if c4mat.rows != 1 || c4mat.cols != 1 {
   585  		panic("failure to get the encryption right")
   586  	}
   587  
   588  	c3 := make([]*matrixG1, len(policy.Inputs))
   589  	c3neg := make([]*matrixG1, len(policy.Inputs))
   590  	for i := 0; i < len(policy.Inputs); i++ {
   591  		U0, U1 := oracle([]byte(policy.Inputs[i].Label))
   592  		if policy.Inputs[i].Positive {
   593  			c3[i] = newMatrixG1(0, 0)
   594  
   595  			c3[i].scalarMult(policy.Inputs[i].Value, U0)
   596  			c3[i].add(c3[i], U1)
   597  			c3[i].rightMult(c3[i], ri[pi[i]])
   598  			c3[i].add(c3[i], wshares[i])
   599  			c3neg[i] = nil
   600  		} else {
   601  			c3[i] = newMatrixG1(0, 0)
   602  			c3[i].rightMult(U0, ri[pi[i]])
   603  			c3[i].sub(c3[i], wshares[i])
   604  
   605  			c3neg[i] = newMatrixG1(0, 0)
   606  			c3neg[i].rightMult(U1, ri[pi[i]])
   607  			tmpmat := newMatrixG1(0, 0)
   608  			tmpmat.scalarMult(policy.Inputs[i].Value, wshares[i])
   609  			c3neg[i].add(c3neg[i], tmpmat)
   610  		}
   611  	}
   612  	return &ciphertextHeader{
   613  		p:     policy,
   614  		c1:    c1,
   615  		c2:    c2,
   616  		c3:    c3,
   617  		c3neg: c3neg,
   618  	}, &c4mat.entries[0], nil
   619  }
   620  
   621  func deriveAttributeKeys(rand io.Reader, sp *SecretParams, attrs *Attributes) (*AttributesKey, error) {
   622  	s, err := randomMatrixZp(rand, 2, 1)
   623  	if err != nil {
   624  		return nil, err
   625  	}
   626  	As := newMatrixZp(0, 0)
   627  
   628  	k1 := newMatrixG2(0, 0)
   629  	As.mul(sp.a, s)
   630  	k1.exp(As)
   631  	Ast := newMatrixZp(0, 0)
   632  	Ast.transpose(As)
   633  
   634  	k2 := newMatrixG1(0, 0)
   635  	tmp := newMatrixZp(0, 0)
   636  	tmp.mul(sp.wtA, s)
   637  	tmp.add(tmp, sp.k)
   638  	k2.exp(tmp)
   639  
   640  	k3 := make(map[string]*matrixG1)
   641  	k3wild := make(map[string]*matrixG1)
   642  	for label, attr := range *attrs {
   643  		if attr.wild {
   644  			// For wild k3 is y term, k3wild is constant term
   645  			U0, U1 := oracle([]byte(label))
   646  			V0, V1, err := prf(sp.prfKey, []byte(label))
   647  			if err != nil {
   648  				return nil, err
   649  			}
   650  			k3[label] = newMatrixG1(0, 0)
   651  			k3wild[label] = newMatrixG1(0, 0)
   652  			left := newMatrixG1(0, 0)
   653  			right := newMatrixG1(0, 0)
   654  
   655  			left.transpose(U0)
   656  			left.leftMult(sp.bstar, left)
   657  			left.rightMult(left, As)
   658  
   659  			tmp.transpose(V0)
   660  			tmp.mul(sp.bstar12, tmp)
   661  			tmp.mul(tmp, As)
   662  
   663  			right.exp(tmp)
   664  
   665  			k3[label].add(left, right)
   666  
   667  			left.transpose(U1)
   668  			left.leftMult(sp.bstar, left)
   669  			left.rightMult(left, As)
   670  
   671  			tmp.transpose(V1)
   672  			tmp.mul(sp.bstar12, tmp)
   673  			tmp.mul(tmp, As)
   674  
   675  			right.exp(tmp)
   676  
   677  			k3wild[label].add(left, right)
   678  		} else {
   679  			U0, U1 := oracle([]byte(label))
   680  			V0, V1, err := prf(sp.prfKey, []byte(label))
   681  			if err != nil {
   682  				return nil, err
   683  			}
   684  
   685  			k3[label] = newMatrixG1(0, 0)
   686  			left := newMatrixG1(0, 0)
   687  			right := newMatrixG1(0, 0)
   688  
   689  			left.scalarMult(attr.Value, U0)
   690  			left.add(U1, left)
   691  			left.transpose(left)
   692  			left.leftMult(sp.bstar, left)
   693  			left.rightMult(left, As)
   694  
   695  			tmp.scalarmul(attr.Value, V0)
   696  			tmp.add(tmp, V1)
   697  			tmp.transpose(tmp)
   698  			tmp.mul(sp.bstar12, tmp)
   699  			tmp.mul(tmp, As)
   700  
   701  			right.exp(tmp)
   702  
   703  			k3[label].add(left, right)
   704  		}
   705  	}
   706  
   707  	return &AttributesKey{
   708  		a:      attrs,
   709  		k1:     k1,
   710  		k2:     k2,
   711  		k3:     k3,
   712  		k3wild: k3wild,
   713  	}, nil
   714  }
   715  
   716  // Decapsulate decapsulates
   717  func decapsulate(header *ciphertextHeader, key *AttributesKey) (*pairing.Gt, error) {
   718  	// First we need to determine the satisfying assignment: which attributes in attr
   719  	// are needed.
   720  
   721  	// We use pi to determine which D to sum into
   722  	pi := header.p.pi()
   723  	d := max(pi) + 1
   724  	// p1, p2 are the left halves of the pairings.
   725  	p1 := make([]*matrixG1, d)
   726  	p2 := make([]*matrixG1, d)
   727  
   728  	sat, err := header.p.Satisfaction(key.a)
   729  	if err != nil {
   730  		return nil, err
   731  	}
   732  	for k := 0; k < len(sat.matches); k++ {
   733  		match := sat.matches[k]
   734  		j := pi[match.wire]
   735  
   736  		if p1[j] == nil {
   737  			p1[j] = newMatrixG1(header.c3[match.wire].rows, header.c3[match.wire].cols)
   738  		}
   739  		if p2[j] == nil {
   740  			p2[j] = newMatrixG1(key.k3[match.label].rows, key.k3[match.label].cols)
   741  		}
   742  		if header.p.Inputs[match.wire].Positive {
   743  			p1[j].add(p1[j], header.c3[match.wire])
   744  
   745  			if (*key.a)[match.label].wild {
   746  				if key.k3wild[match.label] == nil {
   747  					return nil, fmt.Errorf("missing wildcard data for Label %s", match.label)
   748  				}
   749  				y := header.p.Inputs[match.wire].Value
   750  				tmp1 := newMatrixG1(0, 0)
   751  				tmp1.scalarMult(y, key.k3[match.label])
   752  				tmp1.add(tmp1, key.k3wild[match.label])
   753  				p2[j].add(p2[j], tmp1)
   754  			} else {
   755  				p2[j].add(p2[j], key.k3[match.label])
   756  			}
   757  		} else {
   758  			keymat := newMatrixG1(0, 0)
   759  			y := &pairing.Scalar{}
   760  
   761  			if (*key.a)[match.label].wild {
   762  				y.Add(header.p.Inputs[match.wire].Value, ToScalar(1))
   763  				keymat.scalarMult(y, key.k3[match.label])
   764  				keymat.add(keymat, key.k3wild[match.label])
   765  			} else {
   766  				y.Set((*(key.a))[match.label].Value)
   767  				keymat.set(key.k3[match.label])
   768  			}
   769  			diff := &pairing.Scalar{}
   770  
   771  			diff.Sub(header.p.Inputs[match.wire].Value, y)
   772  			diff.Inv(diff)
   773  			p1add := newMatrixG1(0, 0)
   774  			p1add.scalarMult(y, header.c3[match.wire])
   775  			p1add.add(p1add, header.c3neg[match.wire])
   776  			p1add.scalarMult(diff, p1add)
   777  
   778  			p2add := newMatrixG1(0, 0)
   779  			p2add.scalarMult(diff, keymat)
   780  
   781  			p1[j].add(p1[j], p1add)
   782  			p2[j].add(p2[j], p2add)
   783  		}
   784  	}
   785  
   786  	pairs := &pairAccum{}
   787  
   788  	var pTot *matrixG1
   789  	for i := 0; i < d; i++ {
   790  		if p1[i] != nil {
   791  			if pTot == nil {
   792  				pTot = newMatrixG1(p1[i].rows, p1[i].cols)
   793  			}
   794  			pTot.add(pTot, p1[i])
   795  			pairs.addDuals(p2[i], header.c2[i], 1)
   796  		}
   797  	}
   798  	pairs.addDuals(pTot, key.k1, -1)
   799  	pairs.addDuals(key.k2.copy(), header.c1, 1)
   800  
   801  	return pairs.eval(), nil
   802  }