package tkn20
import "github.com/cloudflare/circl/abe/cpabe/tkn20"
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
Update v1.3.8
As of v1.3.8, ciphertext format changed to use wider prefixes. Ciphertexts in the previous format are still decryptable. The following functions are backwards-compatible:
Example¶
Code:play
package main
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 main() {
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)
}
fmt.Printf("plaintext size: %v bytes\n", len(msgStr))
fmt.Printf("ciphertext size: %v bytes\n", len(ct))
// 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) plaintext size: 27 bytes ciphertext size: 2747 bytes Successfully recovered plaintext
Index ¶
- func Setup(rand io.Reader) (PublicKey, SystemSecretKey, error)
- type AttributeKey
- func (s *AttributeKey) Decrypt(ct []byte) ([]byte, error)
- func (s *AttributeKey) Equal(s2 *AttributeKey) bool
- func (s *AttributeKey) MarshalBinary() ([]byte, error)
- func (s *AttributeKey) UnmarshalBinary(data []byte) error
- type Attributes
- func (a *Attributes) CouldDecrypt(ciphertext []byte) bool
- func (a *Attributes) Equal(a2 *Attributes) bool
- func (a *Attributes) FromMap(in map[string]string)
- type Policy
- func (p *Policy) Equal(p2 *Policy) bool
- func (p *Policy) ExtractAttributeValuePairs() map[string][]string
- func (p *Policy) ExtractFromCiphertext(ct []byte) error
- func (p *Policy) FromString(str string) error
- func (p *Policy) Satisfaction(a Attributes) bool
- func (p *Policy) String() string
- type PublicKey
- func (p *PublicKey) Encrypt(rand io.Reader, policy Policy, msg []byte) ([]byte, error)
- func (p *PublicKey) Equal(p2 *PublicKey) bool
- func (p *PublicKey) MarshalBinary() ([]byte, error)
- func (p *PublicKey) UnmarshalBinary(data []byte) error
- type SystemSecretKey
Examples ¶
Functions ¶
func Setup ¶
func Setup(rand io.Reader) (PublicKey, SystemSecretKey, error)
Types ¶
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 (*Policy) ExtractAttributeValuePairs ¶
func (*Policy) ExtractFromCiphertext ¶
func (*Policy) FromString ¶
func (*Policy) Satisfaction ¶
func (p *Policy) Satisfaction(a Attributes) bool
func (*Policy) String ¶
type PublicKey ¶
type PublicKey struct {
// contains filtered or unexported fields
}
func (*PublicKey) Encrypt ¶
func (*PublicKey) Equal ¶
func (*PublicKey) MarshalBinary ¶
func (*PublicKey) UnmarshalBinary ¶
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
Source Files ¶
Directories ¶
| Path | Synopsis |
|---|---|
| abe/cpabe/tkn20/internal |
- Version
- v1.6.1 (latest)
- Published
- Apr 9, 2025
- Platform
- linux/amd64
- Imports
- 4 packages
- Last checked
- 22 hours ago –
Tools for package owners.