...

Package tkn20

import "github.com/cloudflare/circl/abe/cpabe/tkn20"
Overview
Index
Examples
Subdirectories

Overview ▾

Package tkn20 implements a ciphertext-policy ABE by Tomida, Kawahara, Nishimaki.

This is an implementation of an IND-CCA2 secure variant of the Ciphertext-Policy Attribute Based Encryption (CP-ABE) scheme by J. Tomida, Y. Kawahara, and R. Nishimaki. Fast, compact, and expressive attribute-based encryption. In A. Kiayias, M. Kohlweiss, P. Wallden, and V. Zikas, editors, PKC, volume 12110 of Lecture Notes in Computer Science, pages 3–33. Springer, 2020. https://eprint.iacr.org/2019/966

Example

Code:

package tkn20_test

import (
    "bytes"
    "crypto/rand"
    "fmt"
    "log"
    "strconv"

    cpabe "github.com/cloudflare/circl/abe/cpabe/tkn20"
)

func checkPolicy(in map[string][]string) bool {
    possiblePairs := map[string][]string{
        "occupation": {"wizard", "doctor", "ghost"},
        "country":    {"US", "croatia"},
        "age":        {},
    }
    isValid := func(key string, value string) bool {
        vs, ok := possiblePairs[key]
        if !ok {
            return false
        }
        if key == "age" {
            age, err := strconv.Atoi(value)
            if err != nil {
                return false
            }
            if age < 13 || age > 100 {
                return false
            }
        } else {
            for _, v := range vs {
                if value == v {
                    return true
                }
            }
        }
        return false
    }
    for k, v := range in {
        for _, value := range v {
            if !isValid(k, value) {
                return false
            }
        }
    }
    return true
}

func Example() {
    policyStr := `(occupation: doctor) and (country: US)`
    invalidPolicyStr := `(title: doctor) and (country: pacific)`
    msgStr := `must have the precious 🎃`
    wrongAttrsMap := map[string]string{"occupation": "doctor", "country": "croatia"}
    rightAttrsMap := map[string]string{"occupation": "doctor", "country": "US", "age": "16"}

    publicKey, systemSecretKey, err := cpabe.Setup(rand.Reader)
    if err != nil {
        log.Fatalf("%s", err)
    }

    policy := cpabe.Policy{}
    err = policy.FromString(policyStr)
    if err != nil {
        log.Fatal(err)
    }
    if !checkPolicy(policy.ExtractAttributeValuePairs()) {
        log.Fatalf("policy check failed for valid policy")
    }

    fmt.Println(policy.String())
    invalidPolicy := cpabe.Policy{}
    err = invalidPolicy.FromString(invalidPolicyStr)
    if err != nil {
        log.Fatal(err)
    }
    if checkPolicy(invalidPolicy.ExtractAttributeValuePairs()) {
        log.Fatalf("policy check should fail for invalid policy")
    }

    // encrypt the secret message for a given policy
    ct, err := publicKey.Encrypt(rand.Reader, policy, []byte(msgStr))
    if err != nil {
        log.Fatalf("%s", err)
    }

    // generate secret key for certain set of attributes
    wrongAttrs := cpabe.Attributes{}
    wrongAttrs.FromMap(wrongAttrsMap)
    rightAttrs := cpabe.Attributes{}
    rightAttrs.FromMap(rightAttrsMap)

    wrongSecretKey, _ := systemSecretKey.KeyGen(rand.Reader, wrongAttrs)
    rightSecretKey, _ := systemSecretKey.KeyGen(rand.Reader, rightAttrs)

    wrongSat := policy.Satisfaction(wrongAttrs)
    if wrongSat {
        log.Fatalf("wrong attributes should not satisfy policy")
    }
    rightSat := policy.Satisfaction(rightAttrs)
    if !rightSat {
        log.Fatalf("right attributes should satisfy policy")
    }

    // wrong attrs should not satisfy ciphertext
    wrongCtSat := wrongAttrs.CouldDecrypt(ct)
    if wrongCtSat {
        log.Fatalf("wrong attrs should not satisfy ciphertext")
    }
    rightCtSat := rightAttrs.CouldDecrypt(ct)
    if rightCtSat == false {
        log.Fatalf("right attrs should satisfy ciphertext")
    }

    // attempt to decrypt with wrong attributes should fail
    pt, err := wrongSecretKey.Decrypt(ct)
    if err == nil {
        log.Fatalf("decryption using wrong attrs should have failed, plaintext: %s", pt)
    }

    pt, err = rightSecretKey.Decrypt(ct)
    if err != nil {
        log.Fatalf("decryption using right attrs should have succeeded, plaintext: %s", pt)
    }
    if !bytes.Equal(pt, []byte(msgStr)) {
        log.Fatalf("recovered plaintext: %s is not equal to original msg: %s", pt, msgStr)
    }
    fmt.Println("Successfully recovered plaintext")
    // Output: (occupation:doctor and country:US)
    // Successfully recovered plaintext
}

Index ▾

Examples

Package

Package files

tkn20.go

func Setup

func Setup(rand io.Reader) (PublicKey, SystemSecretKey, error)

type AttributeKey

type AttributeKey struct {
    // contains filtered or unexported fields
}

func (*AttributeKey) Decrypt

func (s *AttributeKey) Decrypt(ct []byte) ([]byte, error)

func (*AttributeKey) Equal

func (s *AttributeKey) Equal(s2 *AttributeKey) bool

func (*AttributeKey) MarshalBinary

func (s *AttributeKey) MarshalBinary() ([]byte, error)

func (*AttributeKey) UnmarshalBinary

func (s *AttributeKey) UnmarshalBinary(data []byte) error

type Attributes

type Attributes struct {
    // contains filtered or unexported fields
}

func (*Attributes) CouldDecrypt

func (a *Attributes) CouldDecrypt(ciphertext []byte) bool

func (*Attributes) Equal

func (a *Attributes) Equal(a2 *Attributes) bool

func (*Attributes) FromMap

func (a *Attributes) FromMap(in map[string]string)

type Policy

type Policy struct {
    // contains filtered or unexported fields
}

func (*Policy) Equal

func (p *Policy) Equal(p2 *Policy) bool

func (*Policy) ExtractAttributeValuePairs

func (p *Policy) ExtractAttributeValuePairs() map[string][]string

func (*Policy) ExtractFromCiphertext

func (p *Policy) ExtractFromCiphertext(ct []byte) error

func (*Policy) FromString

func (p *Policy) FromString(str string) error

func (*Policy) Satisfaction

func (p *Policy) Satisfaction(a Attributes) bool

func (*Policy) String

func (p *Policy) String() string

type PublicKey

type PublicKey struct {
    // contains filtered or unexported fields
}

func (*PublicKey) Encrypt

func (p *PublicKey) Encrypt(rand io.Reader, policy Policy, msg []byte) ([]byte, error)

func (*PublicKey) Equal

func (p *PublicKey) Equal(p2 *PublicKey) bool

func (*PublicKey) MarshalBinary

func (p *PublicKey) MarshalBinary() ([]byte, error)

func (*PublicKey) UnmarshalBinary

func (p *PublicKey) UnmarshalBinary(data []byte) error

type SystemSecretKey

type SystemSecretKey struct {
    // contains filtered or unexported fields
}

func (*SystemSecretKey) Equal

func (msk *SystemSecretKey) Equal(msk2 *SystemSecretKey) bool

func (*SystemSecretKey) KeyGen

func (msk *SystemSecretKey) KeyGen(rand io.Reader, attrs Attributes) (AttributeKey, error)

func (*SystemSecretKey) MarshalBinary

func (msk *SystemSecretKey) MarshalBinary() ([]byte, error)

func (*SystemSecretKey) UnmarshalBinary

func (msk *SystemSecretKey) UnmarshalBinary(data []byte) error

Subdirectories

Name Synopsis
..