github.com/cloudflare/circl@v1.5.0/abe/cpabe/tkn20/internal/dsl/ast.go (about) 1 package dsl 2 3 import ( 4 "fmt" 5 6 "github.com/cloudflare/circl/abe/cpabe/tkn20/internal/tkn" 7 ) 8 9 var operators = map[string]int{ 10 "and": tkn.Andgate, 11 "or": tkn.Orgate, 12 } 13 14 type attrValue struct { 15 value string 16 positive bool 17 } 18 19 type attr struct { 20 key string 21 id int 22 } 23 24 type gate struct { 25 op string 26 in1 attr 27 in2 attr 28 out attr 29 } 30 31 type Ast struct { 32 wires map[attr]attrValue 33 gates []gate 34 } 35 36 func (t *Ast) RunPasses() (*tkn.Policy, error) { 37 inputs, err := t.hashAttrValues() 38 if err != nil { 39 return nil, fmt.Errorf("attribute values could not be hashed: %s", err) 40 } 41 42 gates, err := t.transformGates() 43 if err != nil { 44 return nil, fmt.Errorf("gates could not be converted into a formula: %s", err) 45 } 46 47 return &tkn.Policy{ 48 Inputs: inputs, 49 F: tkn.Formula{Gates: gates}, 50 }, nil 51 } 52 53 func (t *Ast) hashAttrValues() ([]tkn.Wire, error) { 54 wires := make([]tkn.Wire, len(t.wires)) 55 for k, v := range t.wires { 56 value := tkn.HashStringToScalar(AttrHashKey, v.value) 57 if value == nil { 58 return nil, fmt.Errorf("error on hashing") 59 } 60 wire := tkn.Wire{ 61 Label: k.key, 62 RawValue: v.value, 63 Value: value, 64 Positive: v.positive, 65 } 66 wires[k.id] = wire 67 } 68 return wires, nil 69 } 70 71 func (t *Ast) transformGates() ([]tkn.Gate, error) { 72 lenGates := len(t.gates) 73 gates := make([]tkn.Gate, lenGates) 74 for i, g := range t.gates { 75 class, ok := operators[g.op] 76 if !ok { 77 return nil, fmt.Errorf("invalid operator %s", g.op) 78 } 79 wireIDs := [3]int{g.in1.id, g.in2.id, g.out.id} 80 for j, wireID := range wireIDs { 81 if wireID < 0 { 82 wireIDs[j] = -1*wireID + lenGates 83 } 84 } 85 gate := tkn.Gate{ 86 Class: class, 87 In0: wireIDs[0], 88 In1: wireIDs[1], 89 Out: wireIDs[2], 90 } 91 gates[i] = gate 92 } 93 return gates, nil 94 }