github.com/cloudflare/circl@v1.5.0/abe/cpabe/tkn20/example_test.go (about) 1 package tkn20_test 2 3 import ( 4 "bytes" 5 "crypto/rand" 6 "fmt" 7 "log" 8 "strconv" 9 10 cpabe "github.com/cloudflare/circl/abe/cpabe/tkn20" 11 ) 12 13 func checkPolicy(in map[string][]string) bool { 14 possiblePairs := map[string][]string{ 15 "occupation": {"wizard", "doctor", "ghost"}, 16 "country": {"US", "croatia"}, 17 "age": {}, 18 } 19 isValid := func(key string, value string) bool { 20 vs, ok := possiblePairs[key] 21 if !ok { 22 return false 23 } 24 if key == "age" { 25 age, err := strconv.Atoi(value) 26 if err != nil { 27 return false 28 } 29 if age < 13 || age > 100 { 30 return false 31 } 32 } else { 33 for _, v := range vs { 34 if value == v { 35 return true 36 } 37 } 38 } 39 return false 40 } 41 for k, v := range in { 42 for _, value := range v { 43 if !isValid(k, value) { 44 return false 45 } 46 } 47 } 48 return true 49 } 50 51 func Example() { 52 policyStr := `(occupation: doctor) and (country: US)` 53 invalidPolicyStr := `(title: doctor) and (country: pacific)` 54 msgStr := `must have the precious 🎃` 55 wrongAttrsMap := map[string]string{"occupation": "doctor", "country": "croatia"} 56 rightAttrsMap := map[string]string{"occupation": "doctor", "country": "US", "age": "16"} 57 58 publicKey, systemSecretKey, err := cpabe.Setup(rand.Reader) 59 if err != nil { 60 log.Fatalf("%s", err) 61 } 62 63 policy := cpabe.Policy{} 64 err = policy.FromString(policyStr) 65 if err != nil { 66 log.Fatal(err) 67 } 68 if !checkPolicy(policy.ExtractAttributeValuePairs()) { 69 log.Fatalf("policy check failed for valid policy") 70 } 71 72 fmt.Println(policy.String()) 73 invalidPolicy := cpabe.Policy{} 74 err = invalidPolicy.FromString(invalidPolicyStr) 75 if err != nil { 76 log.Fatal(err) 77 } 78 if checkPolicy(invalidPolicy.ExtractAttributeValuePairs()) { 79 log.Fatalf("policy check should fail for invalid policy") 80 } 81 82 // encrypt the secret message for a given policy 83 ct, err := publicKey.Encrypt(rand.Reader, policy, []byte(msgStr)) 84 if err != nil { 85 log.Fatalf("%s", err) 86 } 87 fmt.Printf("plaintext size: %v bytes\n", len(msgStr)) 88 fmt.Printf("ciphertext size: %v bytes\n", len(ct)) 89 90 // generate secret key for certain set of attributes 91 wrongAttrs := cpabe.Attributes{} 92 wrongAttrs.FromMap(wrongAttrsMap) 93 rightAttrs := cpabe.Attributes{} 94 rightAttrs.FromMap(rightAttrsMap) 95 96 wrongSecretKey, _ := systemSecretKey.KeyGen(rand.Reader, wrongAttrs) 97 rightSecretKey, _ := systemSecretKey.KeyGen(rand.Reader, rightAttrs) 98 99 wrongSat := policy.Satisfaction(wrongAttrs) 100 if wrongSat { 101 log.Fatalf("wrong attributes should not satisfy policy") 102 } 103 rightSat := policy.Satisfaction(rightAttrs) 104 if !rightSat { 105 log.Fatalf("right attributes should satisfy policy") 106 } 107 108 // wrong attrs should not satisfy ciphertext 109 wrongCtSat := wrongAttrs.CouldDecrypt(ct) 110 if wrongCtSat { 111 log.Fatalf("wrong attrs should not satisfy ciphertext") 112 } 113 rightCtSat := rightAttrs.CouldDecrypt(ct) 114 if rightCtSat == false { 115 log.Fatalf("right attrs should satisfy ciphertext") 116 } 117 118 // attempt to decrypt with wrong attributes should fail 119 pt, err := wrongSecretKey.Decrypt(ct) 120 if err == nil { 121 log.Fatalf("decryption using wrong attrs should have failed, plaintext: %s", pt) 122 } 123 124 pt, err = rightSecretKey.Decrypt(ct) 125 if err != nil { 126 log.Fatalf("decryption using right attrs should have succeeded, plaintext: %s", pt) 127 } 128 if !bytes.Equal(pt, []byte(msgStr)) { 129 log.Fatalf("recovered plaintext: %s is not equal to original msg: %s", pt, msgStr) 130 } 131 fmt.Println("Successfully recovered plaintext") 132 // Output: 133 // (occupation:doctor and country:US) 134 // plaintext size: 27 bytes 135 // ciphertext size: 2747 bytes 136 // Successfully recovered plaintext 137 }