Skip to content

Commit ffaffdc

Browse files
committed
Update LVS document
1 parent 177844e commit ffaffdc

3 files changed

Lines changed: 193 additions & 66 deletions

File tree

docs/src/lvs/binary-format.rst

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
Binary Format
2+
=============
3+
4+
5+
The format of compiled LVS file is defined as follows.
6+
This page describes version ``0x00011000``.
7+
8+
.. code-block:: abnf
9+
10+
LvsModel = LVS-MODEL-TYPE TLV-LENGTH
11+
Version
12+
StartId
13+
NamedPatternCnt
14+
*Node
15+
*TagSymbol
16+
17+
Version = VERSION-TYPE
18+
TLV-LENGTH ; == 4
19+
NonNegativeInteger
20+
StartId = NODE-ID-TYPE TLV-LENGTH NonNegativeInteger
21+
NamedPatternCnt = NAMED-PATTERN-NUM-TYPE TLV-LENGTH NonNegativeInteger
22+
23+
Node = NODE-TYPE TLV-LENGTH
24+
NodeId
25+
[Parent]
26+
*RuleName
27+
*ValueEdge
28+
*PatternEdge
29+
*SignConstraint
30+
31+
NodeId = NODE-TYPE TLV-LENGTH NonNegativeInteger
32+
Parent = NODE-TYPE TLV-LENGTH NonNegativeInteger
33+
SignConstraint = KEY-NODE-ID-TYPE TLV-LENGTH NonNegativeInteger
34+
RuleName = IDENTIFIER-TYPE TLV-LENGTH CNAME
35+
CNAME = ("_" / ALPHA) *("_" / ALPHA / DIGIT)
36+
37+
ValueEdge = VALUE-EDGE-TYPE TLV-LENGTH
38+
Destination
39+
Value
40+
Destination = NodeId
41+
Value = COMPONENT-VALUE-TYPE TLV-LENGTH NameComponent
42+
43+
PatternEdge = PATTERN-EDGE-TYPE TLV-LENGTH
44+
Destination
45+
Tag
46+
*Constraint
47+
Tag = PATTERN-TAG-TYPE TLV-LENGTH NonNegativeInteger
48+
49+
Constraint = CONSTRAINT-TYPE TLV-LENGTH *ConstraintOption
50+
ConstraintOption = CONS-OPTION-TYPE TLV-LENGTH (Value / Tag / UserFnCall)
51+
52+
UserFnCall = USER-FN-CALL-TYPE TLV-LENGTH
53+
FnId
54+
*UserFnArg
55+
FnId = USER-FN-ID-TYPE TLV-LENGTH CNAME
56+
UserFnArg = USER-FN-ARG-TYPE TLV-LENGTH (Value / Tag)
57+
58+
TagSymbol = TAG-SYMBOL-TYPE TLV-LENGTH
59+
Tag
60+
Identifier
61+
62+
Identifier = IDENTIFIER-TYPE TLV-LENGTH CNAME
63+
64+
65+
TLV numbers:
66+
67+
.. code-block:: abnf
68+
69+
COMPONENT-VALUE-TYPE = 0x21
70+
PATTERN-TAG-TYPE = 0x23
71+
NODE-ID-TYPE = 0x25
72+
USER-FN-ID-TYPE = 0x27
73+
IDENTIFIER-TYPE = 0x29
74+
USER-FN-CALL-TYPE = 0x31
75+
FN-ARGS-TYPE = 0x33
76+
CONS-OPTION-TYPE = 0x41
77+
CONSTRAINT-TYPE = 0x43
78+
VALUE-EDGE-TYPE = 0x51
79+
PATTERN-EDGE-TYPE = 0x53
80+
KEY-NODE-ID-TYPE = 0x55
81+
PARENT-ID-TYPE = 0x57
82+
VERSION-TYPE = 0x61
83+
NODE-TYPE = 0x63
84+
TAG-SYMBOL-TYPE = 0x67
85+
NAMED-PATTERN-NUM-TYPE = 0x69
86+
87+
88+
Explanation
89+
~~~~~~~~~~~
90+
91+
LvsModel
92+
--------
93+
94+
``Version`` is the version number of the LVS model.
95+
Everytime the behavior changes, the version number will increase.
96+
There is no commitment for different versions to implement the same behavior, even the field names are the same.
97+
The application should only accept the model if the version number is recognized.
98+
99+
Every node has an integer ID, which equals to the index it occurs in the LVS model, starting from ``0``.
100+
``StartId`` is the ID of the root Node of the LVS tree.
101+
In current compiler implemented in python-ndn, it is ``0`` to indicate that the first Node is the root,
102+
but there is no guarantee in future and a checker should not rely on this convention.
103+
104+
Every pattern edge is also assigned with a number.
105+
If the number is lower than ``NamedPatternCnt``, then it is a named pattern edge.
106+
If it is larger than or equal to ``NamedPatternCnt``, then it is a temporary named pattern ``_``.
107+
Note that since TLV encoding does not support negative numbers, we use ``NamedPatternCnt`` to differentiate temporary and normal named patterns.
108+
A checker does not need to tell whether a pattern edge is named or not,
109+
if it only checks the signature validity, since every temporary pattern edge is assigned with a different tag.
110+
Tag symbol information is only needed if the checker needs the name identifiers of named patterns.
111+
112+
``TagSymbol`` describes the identifiers for each named pattern edge.
113+
It is ununsed and can be safely discarded if a checker does not dump error reason after verification fails.
114+
The TLV-Type is still marked as critical for sanity check reason expressed in the next section.
115+
116+
Node
117+
----
118+
119+
``NodeId`` always equal to the index it occurs in the LVS model, starting from ``0``.
120+
121+
``RuleName`` is the identifier used to identify this node in the original LVS schema.
122+
It is ununsed if a checker does not dump error reason after verification fails.
123+
124+
``ValueEdge`` and ``PatternEdge`` are edges to children under its subtree.
125+
A ``ValueEdge`` requests an exact match; a ``PatternEdge`` specifies a match of a constraint set,
126+
and assigns the component value to the corresponding pattern variable.
127+
A checker must always check ``ValueEdge`` for exact matches before it uses ``PatternEdge`` to match.
128+
When multiple ``PatternEdge`` can match, the first one occuring in the file should hit.
129+
130+
``SignConstraint`` indicates zero or more node IDs.
131+
When a packet name matches the current node, the signing key should match one of the nodes specified by ``SignConstraint``.
132+
A node without any ``SignConstraint`` implies all signature verification fail on this node,
133+
and thus no packets matching this node should be fetched from network.
134+
The trust anchor can match a node without ``SignConstraint``, as it will never be fetched from network.
135+
136+
Constraint
137+
----------
138+
139+
Constraints only applies to ``PatternEdge`` as conditions.
140+
If specified, each ``PatternEdge`` may have one or multiple constraints and each constraint may have one or multiple constraint options.
141+
The constraints form a conjunctive normal form, i.e. AND of ORs:
142+
143+
- A constraint is satisfied if any of its options is satisfied
144+
- A ``PatternEdge`` is satisfied if all of its constraints are satisfied
145+
146+
Each constraint option can be the form of ``Value`` (which makes it similar to a ``ValueEdge``),
147+
``Tag`` which matches the Component with a previously matched pattern variable,
148+
or a ``UserFn`` which is an external function provided by the application.
149+
150+
Sanity Check
151+
~~~~~~~~~~~~
152+
153+
When loading a compiled LVS model, the following sanity check should be made before executing it.
154+
155+
- ``Version`` is supported.
156+
- Every node's ``NodeId`` equals to its index in the array.
157+
- All edges refer to existing destination node ID.
158+
- Every ``SignConstraint`` refers to an existing destination node ID.
159+
- For each ``ConstraintOption``, exactly one of ``Value``, ``Tag`` and ``UserFn`` is set.
160+
- Every edge's destination sets parent to the source of the edge.
161+
This guarantees all nodes reachable from the root is a tree.
162+
163+
The following sanity checks are recommended but not required.
164+
165+
- After the application finishes providing user functions, check all user functions used in the programs are given.
166+
- If the implementation chooses not to do so, it should let the verifcation fail whenever an unknown user function is triggered.
167+
- After the application finishes providing trust anchors, check all leaf nodes without signing constraint are provided with a trust anchor.
168+
- If the implementation chooses not to do so, it should let the verifcation fail whenever reaches a leaf node without sign constraint.
169+
- No unreachable nodes. (python-ndn does not check this)
170+
171+
User Functions
172+
~~~~~~~~~~~~~~
173+
174+
User functions are provided by the application and there is no guarantee on their exact behavior.
175+
Specific implementations may provide built-in user functions for the application.
176+
However, the application is responsible for the correctness of all user functions used, including built-in ones.
177+
That is to say, different library implementations do not necessarily provide the same set of built-in user functions,
178+
and the application developer is responsible to check if the built-in implementation is correct.
179+
180+
python-ndn provides the following built-in functions:
181+
182+
- ``$eq``: compares two components.
183+
- ``$eq_type``: compares the type of two components.

docs/src/lvs/lvs.rst

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ User Functions
195195

196196
User functions are named in the format of ``$function``.
197197
They should be provided as a dictionary via Checker's construction function by the application code using the trust schema.
198-
The name ``function`` of one user function should be the dictionary key and the corresponding function definition should be the dictionary value.
198+
The name ``function`` of one user function should be the dictionary key and the corresponding function definition should be the dictionary value.
199199
A user function can take arguments of type component values and patterns.
200200
For example, ``$fn("component", pattern)`` is a valid function call.
201201
When used as a component constraint,
@@ -215,7 +215,7 @@ For example, there is a user function called ``fn``. It should be defined and pr
215215
user_fn={"fn": fn}
216216
checker=Checker(lvs_model,user_fn)
217217
218-
In the trust schema, the user function can be called as
218+
In the trust schema, the user function can be called as
219219

220220
.. code-block:: text
221221
@@ -283,9 +283,9 @@ Tutorial
283283

284284
Suppose that there is a blog platform that contains three roles: admin, author and reader. It follows these specifications:
285285
1. The prefix of this platform is ``/ndn/blog``. The trust anchor is ``/ndn/blog/KEY/<key-id>/<issuer>/<cert-id>``.
286-
2. There is a root certificate in this platform.
287-
3. Admin has its certificate signed by root certificate.
288-
4. The certificates of both author and reader are signed by admin's certificate.
286+
2. There is a root certificate in this platform.
287+
3. Admin has its certificate signed by root certificate.
288+
4. The certificates of both author and reader are signed by admin's certificate.
289289
5. The IDs of both author and reader should be a 6-digit number.
290290
6. Both author and admin can post the articles.
291291
7. The name of a posted article should be ``/ndn/blog/ID/post/<year>/<id>``. The "year" must be a 4-digit number.
@@ -302,14 +302,14 @@ Based on the above specifications, the trust schema can be written as:
302302
#root: #platform/#KEY
303303
// Admin's certificate definition. The non-sharp patterns, role and adminID, are sent from the application. Each pattern can match an arbitrary components, but the matched components for the same pattern should be the same. The constraint shows that the component "_role" must be "admin". The underscore means that the matched components for the pattern "_role" may not be identical in the chain. The admin's certificate must be signed by the root certificate.
304304
#admin: #platform/_role/adminID/#KEY & {_role: "admin"} <= #root
305-
// author's certificate definition. The ID is verified by a user function. Both constraints must be met. It can only be signed by the admin's certificate.
305+
// author's certificate definition. The ID is verified by a user function. Both constraints must be met. It can only be signed by the admin's certificate.
306306
#author: #platform/_role/ID/#KEY & {_role: "author", ID: $isValidID()} <= #admin
307-
// author's and reader's certificate definition. The role can be either "reader" or "author". The ID is verified by a user function. Both constraints must be met. It can only be signed by the admin's certificate.
307+
// author's and reader's certificate definition. The role can be either "reader" or "author". The ID is verified by a user function. Both constraints must be met. It can only be signed by the admin's certificate.
308308
#user: #platform/_role/ID/#KEY & {_role: "reader"|"author", ID: $isValidID()} <= #admin
309309
// article's trust schema. The component "year" is verified by a user function. The article can be signed by the admin's certificate or one author's certificate.
310310
#article: #platform/ID/"post"/year/articleID & {year: $isValidYear()} <= #admin | #author
311311
312-
To build the checker of the above trust schema, we must define the user functions by using lambda expressions first.
312+
To build the checker of the above trust schema, we must define the user functions by using lambda expressions first.
313313

314314
.. code-block:: python3
315315
@@ -343,7 +343,7 @@ With the string of trust schema and the user function dictionary, we can compile
343343
With the function ``check``, we can check whether one name is valid under one certificate name. Here are some testing examples.
344344

345345
.. code-block:: python3
346-
346+
347347
# Admin's certificate can be signed by the root certificate
348348
print(checker.check('/ndn/blog/admin/000001/KEY/1/root/1',
349349
'/ndn/blog/KEY/1/self/1')) # => True
@@ -385,3 +385,4 @@ References
385385
package
386386
details
387387
demonstration
388+
binary-format

src/ndn/app_support/light_versec/binary.py

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -122,60 +122,3 @@ class LvsModel(enc.TlvModel):
122122
named_pattern_cnt = enc.UintField(TypeNumber.NAMED_PATTERN_NUM)
123123
nodes = enc.RepeatedField(enc.ModelField(TypeNumber.NODE, Node))
124124
symbols = enc.RepeatedField(enc.ModelField(TypeNumber.TAG_SYMBOL, TagSymbol))
125-
126-
127-
# The following are for reference only and there is no commitment to implement them exactly as described.
128-
# The implemented format is specified by the class LvsModel above.
129-
__ABNF_FOR_REFERENCE__ = r"""
130-
LvsModel = LVS-MODEL-TYPE TLV-LENGTH
131-
Version
132-
StartId
133-
NamedPatternCnt
134-
*Node
135-
*TagSymbol
136-
137-
Version = VERSION-TYPE TLV-LENGTH NonNegativeInteger
138-
StartId = NODE-ID-TYPE TLV-LENGTH NonNegativeInteger
139-
NamedPatternCnt = NAMED-PATTERN-NUM-TYPE TLV-LENGTH NonNegativeInteger
140-
141-
Node = NODE-TYPE TLV-LENGTH
142-
NodeId
143-
[Parent]
144-
*RuleName
145-
*ValueEdge
146-
*PatternEdge
147-
*SignConstraint
148-
149-
NodeId = NODE-TYPE TLV-LENGTH NonNegativeInteger
150-
Parent = NODE-TYPE TLV-LENGTH NonNegativeInteger
151-
SignConstraint = KEY-NODE-ID-TYPE TLV-LENGTH NonNegativeInteger
152-
RuleName = IDENTIFIER-TYPE TLV-LENGTH CNAME
153-
CNAME = ("_" / ALPHA) *("_" / ALPHA / DIGIT)
154-
155-
ValueEdge = VALUE-EDGE-TYPE TLV-LENGTH
156-
Destination
157-
Value
158-
Destination = NodeId
159-
Value = COMPONENT-VALUE-TYPE TLV-LENGTH NameComponent
160-
161-
PatternEdge = PATTERN-EDGE-TYPE TLV-LENGTH
162-
Destination
163-
Tag
164-
*Constraint
165-
Tag = PATTERN-TAG-TYPE TLV-LENGTH NonNegativeInteger
166-
167-
Constraint = CONSTRAINT-TYPE TLV-LENGTH *ConstraintOption
168-
ConstraintOption = CONS-OPTION-TYPE TLV-LENGTH (Value / Tag / UserFnCall)
169-
170-
UserFnCall = USER-FN-CALL-TYPE TLV-LENGTH
171-
FnId
172-
*UserFnArg
173-
FnId = USER-FN-ID-TYPE TLV-LENGTH CNAME
174-
UserFnArg = USER-FN-ARG-TYPE TLV-LENGTH (Value / Tag)
175-
176-
TagSymbol = TAG-SYMBOL-TYPE TLV-LENGTH
177-
Tag
178-
Identifier
179-
180-
Identifier = IDENTIFIER-TYPE TLV-LENGTH CNAME
181-
"""

0 commit comments

Comments
 (0)