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

     1  //go:generate go run gen_testdata.go
     2  
     3  // Package tkn20 implements a ciphertext-policy ABE by Tomida, Kawahara, Nishimaki.
     4  //
     5  // This is an implementation of an IND-CCA2 secure variant of the Ciphertext-Policy
     6  // Attribute Based Encryption (CP-ABE) scheme by
     7  // J. Tomida, Y. Kawahara, and R. Nishimaki. Fast, compact, and expressive
     8  // attribute-based encryption. In A. Kiayias, M. Kohlweiss, P. Wallden, and
     9  // V. Zikas, editors, PKC, volume 12110 of Lecture Notes in Computer Science,
    10  // pages 3–33. Springer, 2020. https://eprint.iacr.org/2019/966
    11  //
    12  // # Update v1.3.8
    13  //
    14  // As of v1.3.8, ciphertext format changed to use wider prefixes.
    15  // Ciphertexts in the previous format are still decryptable.
    16  // The following functions are backwards-compatible:
    17  //   - [AttributeKey.Decrypt]
    18  //   - [Attributes.CouldDecrypt]
    19  //   - [Policy.ExtractFromCiphertext]
    20  package tkn20
    21  
    22  import (
    23  	cryptoRand "crypto/rand"
    24  	"io"
    25  
    26  	"github.com/cloudflare/circl/abe/cpabe/tkn20/internal/dsl"
    27  	"github.com/cloudflare/circl/abe/cpabe/tkn20/internal/tkn"
    28  )
    29  
    30  type PublicKey struct {
    31  	pp tkn.PublicParams
    32  }
    33  
    34  func (p *PublicKey) MarshalBinary() ([]byte, error) {
    35  	return p.pp.MarshalBinary()
    36  }
    37  
    38  func (p *PublicKey) UnmarshalBinary(data []byte) error {
    39  	return p.pp.UnmarshalBinary(data)
    40  }
    41  
    42  func (p *PublicKey) Equal(p2 *PublicKey) bool {
    43  	return p.pp.Equal(&p2.pp)
    44  }
    45  
    46  func (p *PublicKey) Encrypt(rand io.Reader, policy Policy, msg []byte) ([]byte, error) {
    47  	if rand == nil {
    48  		rand = cryptoRand.Reader
    49  	}
    50  	return tkn.EncryptCCA(rand, &p.pp, &policy.policy, msg)
    51  }
    52  
    53  type SystemSecretKey struct {
    54  	sp tkn.SecretParams
    55  }
    56  
    57  func (msk *SystemSecretKey) MarshalBinary() ([]byte, error) {
    58  	return msk.sp.MarshalBinary()
    59  }
    60  
    61  func (msk *SystemSecretKey) UnmarshalBinary(data []byte) error {
    62  	return msk.sp.UnmarshalBinary(data)
    63  }
    64  
    65  func (msk *SystemSecretKey) Equal(msk2 *SystemSecretKey) bool {
    66  	return msk.sp.Equal(&msk2.sp)
    67  }
    68  
    69  func (msk *SystemSecretKey) KeyGen(rand io.Reader, attrs Attributes) (AttributeKey, error) {
    70  	if rand == nil {
    71  		rand = cryptoRand.Reader
    72  	}
    73  	sk, err := tkn.DeriveAttributeKeysCCA(rand, &msk.sp, &attrs.attrs)
    74  	if err != nil {
    75  		return AttributeKey{}, err
    76  	}
    77  	return AttributeKey{*sk}, nil
    78  }
    79  
    80  type AttributeKey struct {
    81  	ak tkn.AttributesKey
    82  }
    83  
    84  func (s *AttributeKey) MarshalBinary() ([]byte, error) {
    85  	return s.ak.MarshalBinary()
    86  }
    87  
    88  func (s *AttributeKey) UnmarshalBinary(data []byte) error {
    89  	return s.ak.UnmarshalBinary(data)
    90  }
    91  
    92  func (s *AttributeKey) Equal(s2 *AttributeKey) bool {
    93  	return s.ak.Equal(&s2.ak)
    94  }
    95  
    96  func (s *AttributeKey) Decrypt(ct []byte) ([]byte, error) {
    97  	return tkn.DecryptCCA(ct, &s.ak)
    98  }
    99  
   100  type Policy struct {
   101  	policy tkn.Policy
   102  }
   103  
   104  func (p *Policy) FromString(str string) error {
   105  	policy, err := dsl.Run(str)
   106  	if err != nil {
   107  		return err
   108  	}
   109  	p.policy = *policy
   110  	return nil
   111  }
   112  
   113  func (p *Policy) String() string {
   114  	return p.policy.String()
   115  }
   116  
   117  func (p *Policy) ExtractFromCiphertext(ct []byte) error {
   118  	return p.policy.ExtractFromCiphertext(ct)
   119  }
   120  
   121  func (p *Policy) ExtractAttributeValuePairs() map[string][]string {
   122  	pairs := make(map[string][]string, len(p.policy.Inputs))
   123  	for _, w := range p.policy.Inputs {
   124  		pairs[w.Label] = append(pairs[w.Label], w.RawValue)
   125  	}
   126  	return pairs
   127  }
   128  
   129  func (p *Policy) Equal(p2 *Policy) bool {
   130  	return p.policy.Equal(&p2.policy)
   131  }
   132  
   133  func (p *Policy) Satisfaction(a Attributes) bool {
   134  	_, err := p.policy.Satisfaction(&a.attrs)
   135  	return err == nil
   136  }
   137  
   138  type Attributes struct {
   139  	attrs tkn.Attributes
   140  }
   141  
   142  func (a *Attributes) Equal(a2 *Attributes) bool {
   143  	return a.attrs.Equal(&a2.attrs)
   144  }
   145  
   146  func (a *Attributes) CouldDecrypt(ciphertext []byte) bool {
   147  	return tkn.CouldDecrypt(ciphertext, &a.attrs)
   148  }
   149  
   150  func (a *Attributes) FromMap(in map[string]string) {
   151  	attrs := make(map[string]tkn.Attribute, len(in))
   152  	for k, v := range in {
   153  		attrs[k] = tkn.Attribute{
   154  			Value: tkn.HashStringToScalar(dsl.AttrHashKey, v),
   155  		}
   156  	}
   157  	a.attrs = attrs
   158  }
   159  
   160  func Setup(rand io.Reader) (PublicKey, SystemSecretKey, error) {
   161  	if rand == nil {
   162  		rand = cryptoRand.Reader
   163  	}
   164  	pp, sp, err := tkn.GenerateParams(rand)
   165  	if err != nil {
   166  		return PublicKey{}, SystemSecretKey{}, err
   167  	}
   168  	return PublicKey{*pp}, SystemSecretKey{*sp}, nil
   169  }