-
Notifications
You must be signed in to change notification settings - Fork 136
/
example_test.go
137 lines (123 loc) · 3.49 KB
/
example_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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)
}
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
}