github.com/cloudflare/circl@v1.5.0/abe/cpabe/tkn20/internal/tkn/policy_test.go (about)

     1  package tkn
     2  
     3  import (
     4  	"testing"
     5  )
     6  
     7  var AttrHashKey = []byte("attribute value hashing")
     8  
     9  func TestWireSerialization(t *testing.T) {
    10  	in := &Wire{"a", "0", HashStringToScalar(AttrHashKey, "0"), true}
    11  	data, err := in.MarshalBinary()
    12  	if err != nil {
    13  		t.Fatalf("error in marshaling: %s", err)
    14  	}
    15  	out := &Wire{}
    16  	err = out.UnmarshalBinary(data)
    17  	if err != nil {
    18  		t.Fatalf("error in unmarshaling: %s", err)
    19  	}
    20  	if !in.Equal(out) {
    21  		t.Fatalf("failure to round trip")
    22  	}
    23  }
    24  
    25  func TestPolicySerialization(t *testing.T) {
    26  	in := Policy{
    27  		Inputs: []Wire{
    28  			{"a", "1", HashStringToScalar(AttrHashKey, "1"), true},
    29  			{"b", "xx", HashStringToScalar(AttrHashKey, "xx"), true},
    30  			{"c", "3", HashStringToScalar(AttrHashKey, "3"), true},
    31  		},
    32  		F: Formula{
    33  			Gates: []Gate{
    34  				{Andgate, 0, 1, 3},
    35  				{Andgate, 2, 3, 4},
    36  			},
    37  		},
    38  	}
    39  	data, err := in.MarshalBinary()
    40  	if err != nil {
    41  		t.Fatalf("error in marshalling: %s", err)
    42  	}
    43  	out := Policy{}
    44  	err = out.UnmarshalBinary(data)
    45  	if err != nil {
    46  		t.Fatalf("error in unmarshaling: %s", err)
    47  	}
    48  	if !in.F.Equal(out.F) {
    49  		t.Fatalf("formulas do not match")
    50  	}
    51  	for i, input := range in.Inputs {
    52  		if !input.Equal(&out.Inputs[i]) {
    53  			t.Fatal("failure to round trip: inputs do not match")
    54  		}
    55  	}
    56  }
    57  
    58  type TestCase struct {
    59  	p *Policy
    60  	a *Attributes
    61  }
    62  
    63  func TestSatisfaction(t *testing.T) {
    64  	testCases := []TestCase{
    65  		{
    66  			&Policy{
    67  				Inputs: []Wire{
    68  					{"a", "0", ToScalar(0), true},
    69  				},
    70  				F: Formula{
    71  					Gates: []Gate{},
    72  				},
    73  			},
    74  			&Attributes{
    75  				"a": {
    76  					wild:  false,
    77  					Value: ToScalar(0),
    78  				},
    79  			},
    80  		},
    81  		{
    82  			&Policy{
    83  				Inputs: []Wire{
    84  					{"a", "1", ToScalar(1), true},
    85  					{"b", "2", ToScalar(2), true},
    86  					{"c", "3", ToScalar(3), true},
    87  				},
    88  				F: Formula{
    89  					Gates: []Gate{
    90  						{Andgate, 0, 1, 3},
    91  						{Andgate, 2, 3, 4},
    92  					},
    93  				},
    94  			},
    95  			&Attributes{
    96  				"d": {
    97  					wild:  false,
    98  					Value: ToScalar(4),
    99  				},
   100  				"c": {
   101  					wild:  false,
   102  					Value: ToScalar(3),
   103  				},
   104  				"b": {
   105  					wild:  false,
   106  					Value: ToScalar(2),
   107  				},
   108  				"a": {
   109  					wild:  false,
   110  					Value: ToScalar(1),
   111  				},
   112  			},
   113  		},
   114  		{
   115  			&Policy{
   116  				Inputs: []Wire{
   117  					{"a", "1", ToScalar(1), false},
   118  					{"b", "2", ToScalar(2), true},
   119  					{"c", "3", ToScalar(3), true},
   120  				},
   121  				F: Formula{
   122  					Gates: []Gate{
   123  						{Andgate, 0, 1, 3},
   124  						{Andgate, 2, 3, 4},
   125  					},
   126  				},
   127  			},
   128  			&Attributes{
   129  				"d": {
   130  					wild:  false,
   131  					Value: ToScalar(4),
   132  				},
   133  				"c": {
   134  					wild:  false,
   135  					Value: ToScalar(3),
   136  				},
   137  				"b": {
   138  					wild:  false,
   139  					Value: ToScalar(2),
   140  				},
   141  				"a": {
   142  					wild:  false,
   143  					Value: ToScalar(2),
   144  				},
   145  			},
   146  		},
   147  	}
   148  
   149  	for _, args := range testCases {
   150  		sat, err := args.p.Satisfaction(args.a)
   151  		if err != nil {
   152  			t.Fatalf("no satisfaction found for valid program: %s", err)
   153  		}
   154  		for i := 0; i < len(sat.matches); i++ {
   155  			match := sat.matches[i]
   156  			if args.p.Inputs[match.wire].Positive {
   157  				if args.p.Inputs[match.wire].Value.IsEqual((*args.a)[match.label].Value) == 0 || match.label != args.p.Inputs[match.wire].Label {
   158  					t.Errorf("mismatch of Attribute name or Value")
   159  				}
   160  			} else {
   161  				if match.label != args.p.Inputs[match.wire].Label {
   162  					t.Errorf("mismatch of Attribute name")
   163  				}
   164  			}
   165  		}
   166  	}
   167  }
   168  
   169  func TestMarshalAttribute(t *testing.T) {
   170  	in := Attribute{true, ToScalar(1)}
   171  	data, err := in.marshalBinary()
   172  	if err != nil {
   173  		t.Fatalf("error in marshaling: %s", err)
   174  	}
   175  	out := Attribute{}
   176  	err = out.unmarshalBinary(data)
   177  	if err != nil {
   178  		t.Fatalf("error in unmarshaling: %s", err)
   179  	}
   180  	if !in.Equal(&out) {
   181  		t.Fatal("failure to roundtrip")
   182  	}
   183  }
   184  
   185  func TestMarshalAttributes(t *testing.T) {
   186  	in := Attributes{
   187  		"cat": {
   188  			wild:  true,
   189  			Value: ToScalar(0),
   190  		},
   191  		"bree": {
   192  			wild:  false,
   193  			Value: ToScalar(2),
   194  		},
   195  		"a": {
   196  			wild:  true,
   197  			Value: ToScalar(2),
   198  		},
   199  	}
   200  	data, err := in.marshalBinary()
   201  	if err != nil {
   202  		t.Fatalf("error in marshaling: %s", err)
   203  	}
   204  
   205  	// check if deserializing into non-empty struct works
   206  	out := &Attributes{
   207  		"evil": {
   208  			wild:  true,
   209  			Value: ToScalar(0),
   210  		},
   211  		"bree": {
   212  			wild:  false,
   213  			Value: ToScalar(2),
   214  		},
   215  		"a": {
   216  			wild:  true,
   217  			Value: ToScalar(2),
   218  		},
   219  	}
   220  	if in.Equal(out) {
   221  		t.Fatalf("shouldn't be equal")
   222  	}
   223  	err = out.unmarshalBinary(data)
   224  	if err != nil {
   225  		t.Fatalf("error in unmarshaling: %s", err)
   226  	}
   227  	if !in.Equal(out) {
   228  		t.Fatal("failure to roundtrip")
   229  	}
   230  
   231  	err = out.unmarshalBinary(append(data, 0))
   232  	if err == nil {
   233  		t.Fatalf("data has excess bytes, deserialization should fail")
   234  	}
   235  }