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  }