diff --git a/src/keri/core/coring.py b/src/keri/core/coring.py index c7e662f9..84bd0893 100644 --- a/src/keri/core/coring.py +++ b/src/keri/core/coring.py @@ -655,15 +655,15 @@ class TagCodex: Undefined are left out so that inclusion(exclusion) via 'in' operator works. """ Tag1: str = '0J' # 1 B64 char tag with 1 pre pad - Tag2: str = '0K' # 1 B64 char tag - Tag3: str = 'X' # 1 B64 char tag - Tag4: str = '1AAF' # 1 B64 char tag - Tag5: str = '0L' # 1 B64 char tag with 1 pre pad - Tag6: str = '0M' # 1 B64 char tag - Tag7: str = 'Y' # 1 B64 char tag - Tag8: str = '1AAN' # 1 B64 char tag - Tag9: str = '0N' # 1 B64 char tag with 1 pre pad - Tag10: str = '0O' # 1 B64 char tag + Tag2: str = '0K' # 2 B64 char tag + Tag3: str = 'X' # 3 B64 char tag + Tag4: str = '1AAF' # 4 B64 char tag + Tag5: str = '0L' # 5 B64 char tag with 1 pre pad + Tag6: str = '0M' # 6 B64 char tag + Tag7: str = 'Y' # 7 B64 char tag + Tag8: str = '1AAN' # 8 B64 char tag + Tag9: str = '0N' # 9 B64 char tag with 1 pre pad + Tag10: str = '0O' # 10 B64 char tag def __iter__(self): return iter(astuple(self)) @@ -672,26 +672,6 @@ def __iter__(self): TagDex = TagCodex() # Make instance -@dataclass(frozen=True) -class PadTagCodex: - """ - TagCodex is codex of Base64 derivation codes for compactly representing - various small Base64 tag values as prepadded special code soft part values. - Prepad is 1 B64 char. - - Only provide defined codes. - Undefined are left out so that inclusion(exclusion) via 'in' operator works. - """ - Tag1: str = '0J' # 1 B64 char tag with 1 pre pad - Tag5: str = '0L' # 1 B64 char tag with 1 pre pad - Tag9: str = '0N' # 1 B64 char tag with 1 pre pad - - def __iter__(self): - return iter(astuple(self)) - - -PadTagDex = PadTagCodex() # Make instance - @dataclass(frozen=True) class PreCodex: @@ -727,9 +707,10 @@ def __iter__(self): # namedtuple for size entries in Matter and Counter derivation code tables # hs is the hard size int number of chars in hard (stable) part of code # ss is the soft size int number of chars in soft (unstable) part of code +# xs is the xtra size into number of xtra (pre-pad) chars as part of soft # fs is the full size int number of chars in code plus appended material if any # ls is the lead size int number of bytes to pre-pad pre-converted raw binary -Sizage = namedtuple("Sizage", "hs ss fs ls") +Sizage = namedtuple("Sizage", "hs ss xs fs ls") class Matter: @@ -746,6 +727,9 @@ class Matter: Hards (dict): hard sizes keyed by qb64 selector Bards (dict): hard size keyed by qb2 selector Sizes (dict): sizes tables for codes + Codes (dict): maps code name to code + Names (dict): maps code to code name + Pad (str): B64 pad char for xtra size pre-padded soft values Calss Methods: @@ -755,7 +739,7 @@ class Matter: Properties: code (str): hard part of derivation code to indicate cypher suite hard (str): hard part of derivation code. alias for code - soft (str | bytes): soft part of derivation code fs any. + soft (str | bytes): soft part of full code exclusive of xs xtra prepad. Empty when ss = 0. both (str): hard + soft parts of full text code size (int | None): Number of quadlets/triplets of chars/bytes including @@ -790,6 +774,8 @@ class Matter: Special soft values are indicated when fn in table is None and ss > 0. """ + Codex = MtrDex # class variable holding MatterDex reference + # Hards table maps from bytes Base64 first code char to int of hard size, hs, # (stable) of code. The soft size, ss, (unstable) is always 0 for Matter # unless fs is None which allows for variable size multiple of 4, i.e. @@ -805,107 +791,105 @@ class Matter: Bards = ({codeB64ToB2(c): hs for c, hs in Hards.items()}) # Sizes table maps from value of hs chars of code to Sizage namedtuple of - # (hs, ss, fs, ls) where hs is hard size, ss is soft size, and fs is full size - # and ls is lead size - # soft size, ss, should always be 0 for Matter unless fs is None which allows - # for variable size multiple of 4, i.e. not (hs + ss) % 4. + # (hs, ss, xs, fs, ls) where hs is hard size, ss is soft size, + # xs is extra size of soft, fs is full size, and ls is lead size of raw. Sizes = { - 'A': Sizage(hs=1, ss=0, fs=44, ls=0), - 'B': Sizage(hs=1, ss=0, fs=44, ls=0), - 'C': Sizage(hs=1, ss=0, fs=44, ls=0), - 'D': Sizage(hs=1, ss=0, fs=44, ls=0), - 'E': Sizage(hs=1, ss=0, fs=44, ls=0), - 'F': Sizage(hs=1, ss=0, fs=44, ls=0), - 'G': Sizage(hs=1, ss=0, fs=44, ls=0), - 'H': Sizage(hs=1, ss=0, fs=44, ls=0), - 'I': Sizage(hs=1, ss=0, fs=44, ls=0), - 'J': Sizage(hs=1, ss=0, fs=44, ls=0), - 'K': Sizage(hs=1, ss=0, fs=76, ls=0), - 'L': Sizage(hs=1, ss=0, fs=76, ls=0), - 'M': Sizage(hs=1, ss=0, fs=4, ls=0), - 'N': Sizage(hs=1, ss=0, fs=12, ls=0), - 'O': Sizage(hs=1, ss=0, fs=44, ls=0), - 'P': Sizage(hs=1, ss=0, fs=124, ls=0), - 'Q': Sizage(hs=1, ss=0, fs=44, ls=0), - 'R': Sizage(hs=1, ss=0, fs=8, ls=0), - 'S': Sizage(hs=1, ss=0, fs=16, ls=0), - 'T': Sizage(hs=1, ss=0, fs=20, ls=0), - 'U': Sizage(hs=1, ss=0, fs=24, ls=0), - 'V': Sizage(hs=1, ss=0, fs=4, ls=1), - 'W': Sizage(hs=1, ss=0, fs=4, ls=0), - 'X': Sizage(hs=1, ss=3, fs=4, ls=0), - 'Y': Sizage(hs=1, ss=7, fs=8, ls=0), - 'Z': Sizage(hs=1, ss=0, fs=44, ls=0), - '0A': Sizage(hs=2, ss=0, fs=24, ls=0), - '0B': Sizage(hs=2, ss=0, fs=88, ls=0), - '0C': Sizage(hs=2, ss=0, fs=88, ls=0), - '0D': Sizage(hs=2, ss=0, fs=88, ls=0), - '0E': Sizage(hs=2, ss=0, fs=88, ls=0), - '0F': Sizage(hs=2, ss=0, fs=88, ls=0), - '0G': Sizage(hs=2, ss=0, fs=88, ls=0), - '0H': Sizage(hs=2, ss=0, fs=8, ls=0), - '0I': Sizage(hs=2, ss=0, fs=88, ls=0), - '0J': Sizage(hs=2, ss=2, fs=4, ls=0), - '0K': Sizage(hs=2, ss=2, fs=4, ls=0), - '0L': Sizage(hs=2, ss=6, fs=8, ls=0), - '0M': Sizage(hs=2, ss=6, fs=8, ls=0), - '0N': Sizage(hs=2, ss=10, fs=12, ls=0), - '0O': Sizage(hs=2, ss=10, fs=12, ls=0), - '1AAA': Sizage(hs=4, ss=0, fs=48, ls=0), - '1AAB': Sizage(hs=4, ss=0, fs=48, ls=0), - '1AAC': Sizage(hs=4, ss=0, fs=80, ls=0), - '1AAD': Sizage(hs=4, ss=0, fs=80, ls=0), - '1AAE': Sizage(hs=4, ss=0, fs=56, ls=0), - '1AAF': Sizage(hs=4, ss=4, fs=8, ls=0), - '1AAG': Sizage(hs=4, ss=0, fs=36, ls=0), - '1AAH': Sizage(hs=4, ss=0, fs=100, ls=0), - '1AAI': Sizage(hs=4, ss=0, fs=48, ls=0), - '1AAJ': Sizage(hs=4, ss=0, fs=48, ls=0), - '1AAK': Sizage(hs=4, ss=0, fs=4, ls=0), - '1AAL': Sizage(hs=4, ss=0, fs=4, ls=0), - '1AAM': Sizage(hs=4, ss=0, fs=4, ls=0), - '1AAN': Sizage(hs=4, ss=8, fs=12, ls=0), - '1__-': Sizage(hs=4, ss=2, fs=12, ls=0), - '1___': Sizage(hs=4, ss=0, fs=8, ls=0), - '2__-': Sizage(hs=4, ss=2, fs=12, ls=1), - '2___': Sizage(hs=4, ss=0, fs=8, ls=1), - '3__-': Sizage(hs=4, ss=2, fs=12, ls=2), - '3___': Sizage(hs=4, ss=0, fs=8, ls=2), - '4A': Sizage(hs=2, ss=2, fs=None, ls=0), - '5A': Sizage(hs=2, ss=2, fs=None, ls=1), - '6A': Sizage(hs=2, ss=2, fs=None, ls=2), - '7AAA': Sizage(hs=4, ss=4, fs=None, ls=0), - '8AAA': Sizage(hs=4, ss=4, fs=None, ls=1), - '9AAA': Sizage(hs=4, ss=4, fs=None, ls=2), - '4B': Sizage(hs=2, ss=2, fs=None, ls=0), - '5B': Sizage(hs=2, ss=2, fs=None, ls=1), - '6B': Sizage(hs=2, ss=2, fs=None, ls=2), - '7AAB': Sizage(hs=4, ss=4, fs=None, ls=0), - '8AAB': Sizage(hs=4, ss=4, fs=None, ls=1), - '9AAB': Sizage(hs=4, ss=4, fs=None, ls=2), - '4C': Sizage(hs=2, ss=2, fs=None, ls=0), - '5C': Sizage(hs=2, ss=2, fs=None, ls=1), - '6C': Sizage(hs=2, ss=2, fs=None, ls=2), - '7AAC': Sizage(hs=4, ss=4, fs=None, ls=0), - '8AAC': Sizage(hs=4, ss=4, fs=None, ls=1), - '9AAC': Sizage(hs=4, ss=4, fs=None, ls=2), - '4D': Sizage(hs=2, ss=2, fs=None, ls=0), - '5D': Sizage(hs=2, ss=2, fs=None, ls=1), - '6D': Sizage(hs=2, ss=2, fs=None, ls=2), - '7AAD': Sizage(hs=4, ss=4, fs=None, ls=0), - '8AAD': Sizage(hs=4, ss=4, fs=None, ls=1), - '9AAD': Sizage(hs=4, ss=4, fs=None, ls=2), - '4E': Sizage(hs=2, ss=2, fs=None, ls=0), - '5E': Sizage(hs=2, ss=2, fs=None, ls=1), - '6E': Sizage(hs=2, ss=2, fs=None, ls=2), - '7AAE': Sizage(hs=4, ss=4, fs=None, ls=0), - '8AAE': Sizage(hs=4, ss=4, fs=None, ls=1), - '9AAE': Sizage(hs=4, ss=4, fs=None, ls=2), + 'A': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'B': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'C': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'D': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'E': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'F': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'G': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'H': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'I': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'J': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'K': Sizage(hs=1, ss=0, xs=0, fs=76, ls=0), + 'L': Sizage(hs=1, ss=0, xs=0, fs=76, ls=0), + 'M': Sizage(hs=1, ss=0, xs=0, fs=4, ls=0), + 'N': Sizage(hs=1, ss=0, xs=0, fs=12, ls=0), + 'O': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'P': Sizage(hs=1, ss=0, xs=0, fs=124, ls=0), + 'Q': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'R': Sizage(hs=1, ss=0, xs=0, fs=8, ls=0), + 'S': Sizage(hs=1, ss=0, xs=0, fs=16, ls=0), + 'T': Sizage(hs=1, ss=0, xs=0, fs=20, ls=0), + 'U': Sizage(hs=1, ss=0, xs=0, fs=24, ls=0), + 'V': Sizage(hs=1, ss=0, xs=0, fs=4, ls=1), + 'W': Sizage(hs=1, ss=0, xs=0, fs=4, ls=0), + 'X': Sizage(hs=1, ss=3, xs=0, fs=4, ls=0), + 'Y': Sizage(hs=1, ss=7, xs=0, fs=8, ls=0), + 'Z': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + '0A': Sizage(hs=2, ss=0, xs=0, fs=24, ls=0), + '0B': Sizage(hs=2, ss=0, xs=0, fs=88, ls=0), + '0C': Sizage(hs=2, ss=0, xs=0, fs=88, ls=0), + '0D': Sizage(hs=2, ss=0, xs=0, fs=88, ls=0), + '0E': Sizage(hs=2, ss=0, xs=0, fs=88, ls=0), + '0F': Sizage(hs=2, ss=0, xs=0, fs=88, ls=0), + '0G': Sizage(hs=2, ss=0, xs=0, fs=88, ls=0), + '0H': Sizage(hs=2, ss=0, xs=0, fs=8, ls=0), + '0I': Sizage(hs=2, ss=0, xs=0, fs=88, ls=0), + '0J': Sizage(hs=2, ss=2, xs=1, fs=4, ls=0), + '0K': Sizage(hs=2, ss=2, xs=0, fs=4, ls=0), + '0L': Sizage(hs=2, ss=6, xs=1, fs=8, ls=0), + '0M': Sizage(hs=2, ss=6, xs=0, fs=8, ls=0), + '0N': Sizage(hs=2, ss=10, xs=1, fs=12, ls=0), + '0O': Sizage(hs=2, ss=10, xs=0, fs=12, ls=0), + '1AAA': Sizage(hs=4, ss=0, xs=0, fs=48, ls=0), + '1AAB': Sizage(hs=4, ss=0, xs=0, fs=48, ls=0), + '1AAC': Sizage(hs=4, ss=0, xs=0, fs=80, ls=0), + '1AAD': Sizage(hs=4, ss=0, xs=0, fs=80, ls=0), + '1AAE': Sizage(hs=4, ss=0, xs=0, fs=56, ls=0), + '1AAF': Sizage(hs=4, ss=4, xs=0, fs=8, ls=0), + '1AAG': Sizage(hs=4, ss=0, xs=0, fs=36, ls=0), + '1AAH': Sizage(hs=4, ss=0, xs=0, fs=100, ls=0), + '1AAI': Sizage(hs=4, ss=0, xs=0, fs=48, ls=0), + '1AAJ': Sizage(hs=4, ss=0, xs=0, fs=48, ls=0), + '1AAK': Sizage(hs=4, ss=0, xs=0, fs=4, ls=0), + '1AAL': Sizage(hs=4, ss=0, xs=0, fs=4, ls=0), + '1AAM': Sizage(hs=4, ss=0, xs=0, fs=4, ls=0), + '1AAN': Sizage(hs=4, ss=8, xs=0, fs=12, ls=0), + '1__-': Sizage(hs=4, ss=2, xs=0, fs=12, ls=0), + '1___': Sizage(hs=4, ss=0, xs=0, fs=8, ls=0), + '2__-': Sizage(hs=4, ss=2, xs=1, fs=12, ls=1), + '2___': Sizage(hs=4, ss=0, xs=0, fs=8, ls=1), + '3__-': Sizage(hs=4, ss=2, xs=0, fs=12, ls=2), + '3___': Sizage(hs=4, ss=0, xs=0, fs=8, ls=2), + '4A': Sizage(hs=2, ss=2, xs=0, fs=None, ls=0), + '5A': Sizage(hs=2, ss=2, xs=0, fs=None, ls=1), + '6A': Sizage(hs=2, ss=2, xs=0, fs=None, ls=2), + '7AAA': Sizage(hs=4, ss=4, xs=0, fs=None, ls=0), + '8AAA': Sizage(hs=4, ss=4, xs=0, fs=None, ls=1), + '9AAA': Sizage(hs=4, ss=4, xs=0, fs=None, ls=2), + '4B': Sizage(hs=2, ss=2, xs=0, fs=None, ls=0), + '5B': Sizage(hs=2, ss=2, xs=0, fs=None, ls=1), + '6B': Sizage(hs=2, ss=2, xs=0, fs=None, ls=2), + '7AAB': Sizage(hs=4, ss=4, xs=0, fs=None, ls=0), + '8AAB': Sizage(hs=4, ss=4, xs=0, fs=None, ls=1), + '9AAB': Sizage(hs=4, ss=4, xs=0, fs=None, ls=2), + '4C': Sizage(hs=2, ss=2, xs=0, fs=None, ls=0), + '5C': Sizage(hs=2, ss=2, xs=0, fs=None, ls=1), + '6C': Sizage(hs=2, ss=2, xs=0, fs=None, ls=2), + '7AAC': Sizage(hs=4, ss=4, xs=0, fs=None, ls=0), + '8AAC': Sizage(hs=4, ss=4, xs=0, fs=None, ls=1), + '9AAC': Sizage(hs=4, ss=4, xs=0, fs=None, ls=2), + '4D': Sizage(hs=2, ss=2, xs=0, fs=None, ls=0), + '5D': Sizage(hs=2, ss=2, xs=0, fs=None, ls=1), + '6D': Sizage(hs=2, ss=2, xs=0, fs=None, ls=2), + '7AAD': Sizage(hs=4, ss=4, xs=0, fs=None, ls=0), + '8AAD': Sizage(hs=4, ss=4, xs=0, fs=None, ls=1), + '9AAD': Sizage(hs=4, ss=4, xs=0, fs=None, ls=2), + '4E': Sizage(hs=2, ss=2, xs=0, fs=None, ls=0), + '5E': Sizage(hs=2, ss=2, xs=0, fs=None, ls=1), + '6E': Sizage(hs=2, ss=2, xs=0, fs=None, ls=2), + '7AAE': Sizage(hs=4, ss=4, xs=0, fs=None, ls=0), + '8AAE': Sizage(hs=4, ss=4, xs=0, fs=None, ls=1), + '9AAE': Sizage(hs=4, ss=4, xs=0, fs=None, ls=2), } Codes = asdict(MtrDex) # map code name to code Names = {val : key for key, val in Codes.items()} # invert map code to code name - + Pad = '_' # B64 pad char for special codes with xtra size pre-padded soft values def __init__(self, raw=None, code=MtrDex.Ed25519N, soft='', rize=None, @@ -916,7 +900,7 @@ def __init__(self, raw=None, code=MtrDex.Ed25519N, soft='', rize=None, raw (bytes | bytearray | None): unqualified crypto material usable for crypto operations. code (str): stable (hard) part of derivation code - soft (str | bytes): soft part for special codes + soft (str | bytes): soft part exclusive of prepad for special codes rize (int | None): raw size in bytes when variable sized material not including lead bytes if any Otherwise None @@ -953,9 +937,10 @@ def __init__(self, raw=None, code=MtrDex.Ed25519N, soft='', rize=None, if code not in self.Sizes: raise InvalidCodeError(f"Unsupported {code=}.") - hs, ss, fs, ls = self.Sizes[code] # assumes unit tests force valid sizes + hs, ss, xs, fs, ls = self.Sizes[code] # assumes unit tests force valid sizes if fs is None: # variable sized assumes code[0] in SmallVrzDex or LargeVrzDex + # assumes xs must be 0 when variable sized if rize: # use rsize to determine length of raw to extract if rize < 0: raise InvalidVarRawSizeError(f"Missing var raw size for " @@ -998,12 +983,13 @@ def __init__(self, raw=None, code=MtrDex.Ed25519N, soft='', rize=None, else: # fixed size but raw may be empty and/or special soft rize = Matter._rawSize(code) # get raw size from Sizes for code + # if raw then ls may be nonzero if ss > 0: # special soft size, so soft must be provided - soft = soft[:ss] - if len(soft) != ss: + soft = soft[:ss-xs] # + if len(soft) != ss - xs: raise SoftMaterialError(f"Not enough chars in {soft=} " - f"with {ss=} for {code=}.") + f"with {ss=} {xs=} for {code=}.") if not Reb64.match(soft.encode("utf-8")): raise InvalidSoftError(f"Non Base64 chars in {soft=}.") @@ -1016,13 +1002,13 @@ def __init__(self, raw=None, code=MtrDex.Ed25519N, soft='', rize=None, raise RawMaterialError(f"Not enougth raw bytes for code={code}" f"expected {rize=} got {len(raw)}.") - self._code = code # str hard part of code - self._soft = soft # str soft part of code, empty when ss=0 + self._code = code # str hard part of full code + self._soft = soft # str soft part of full code exclusive of xs prepad, empty when ss=0 self._raw = bytes(raw) # crypto ops require bytes not bytearray - elif soft and code: # fixed size and special when raw None - hs, ss, fs, ls = self.Sizes[code] # assumes unit tests force valid sizes - if not fs: # variable sized code so can't be soft + elif soft and code: # raw None so ls == 0 with fixed size and special + hs, ss, xs, fs, ls = self.Sizes[code] # assumes unit tests force valid sizes + if not fs: # variable sized code so can't be special soft raise InvalidSoftError(f"Unsupported variable sized {code=} " f" with {fs=} for special {soft=}.") @@ -1030,17 +1016,17 @@ def __init__(self, raw=None, code=MtrDex.Ed25519N, soft='', rize=None, raise InvalidSoftError("Invalid soft size={ss} or lead={ls} " f" or {code=} {fs=} when special soft.") - soft = soft[:ss] - if len(soft) != ss: + soft = soft[:ss-xs] + if len(soft) != ss - xs: raise SoftMaterialError(f"Not enough chars in {soft=} " - f"with {ss=} for {code=}.") + f"with {ss=} {xs=} for {code=}.") if not Reb64.match(soft.encode("utf-8")): raise InvalidSoftError(f"Non Base64 chars in {soft=}.") self._code = code # str hard part of code self._soft = soft # str soft part of code, empty when ss=0 - self._raw = b'' # make raw empty when None and when special soft + self._raw = b'' # force raw empty when None given and special soft elif qb64b is not None: self._exfil(qb64b) @@ -1069,7 +1055,7 @@ def _rawSize(cls, code): Parameters: code (str): derivation code Base64 """ - hs, ss, fs, ls = cls.Sizes[code] # get sizes + hs, ss, xs, fs, ls = cls.Sizes[code] # get sizes cs = hs + ss # both hard + soft code size if fs is None: raise InvalidCodeSizeError(f"Non-fixed raw size code {code}.") @@ -1084,9 +1070,19 @@ def _leadSize(cls, code): Parameters: code (str): derivation code Base64 """ - _, _, _, ls = cls.Sizes[code] # get lead size from .Sizes table + _, _, _, _, ls = cls.Sizes[code] # get lead size from .Sizes table return ls + @classmethod + def _xtraSize(cls, code): + """ + Returns xtra size in bytes for a given code + Parameters: + code (str): derivation code Base64 + """ + _, _, xs, _, _ = cls.Sizes[code] # get lead size from .Sizes table + return xs + @classmethod def _special(cls, code): @@ -1097,7 +1093,7 @@ def _special(cls, code): False otherwise """ - hs, ss, fs, ls = cls.Sizes[code] + hs, ss, xs, fs, ls = cls.Sizes[code] return (fs is not None and ss > 0) @@ -1178,7 +1174,9 @@ def both(self): #else: #return (f"{self.code}{self.soft}") - return (f"{self.code}{self.soft}") + _, _, xs, _, _ = self.Sizes[self.code] + + return (f"{self.code}{self.Pad * xs}{self.soft}") @property @@ -1188,7 +1186,7 @@ def fullSize(self): Fixed size codes returns fs from .Sizes Variable size codes where fs==None computes fs from .size and sizes """ - hs, ss, fs, _ = self.Sizes[self.code] # get sizes + hs, ss, _, fs, _ = self.Sizes[self.code] # get sizes if fs is None: # compute fs from ss characters in code fs = hs + ss + (self.size * 4) @@ -1288,6 +1286,8 @@ def composable(self): def _infil(self): """ + Create text domain representation + Returns: primitive (bytes): fully qualified base64 characters. """ @@ -1295,7 +1295,7 @@ def _infil(self): both = self.both # code + soft, soft may be empty raw = self.raw # bytes or bytearray, raw may be empty rs = len(raw) # raw size - hs, ss, fs, ls = self.Sizes[code] + hs, ss, xs, fs, ls = self.Sizes[code] cs = hs + ss # assumes unit tests on Matter.Sizes ensure valid size entries @@ -1342,13 +1342,15 @@ def _infil(self): if (len(full) % 4) or (fs and len(full) != fs): raise InvalidCodeSizeError(f"Invalid full size given code{both=} " f" with raw size={rs}, {cs=}, {hs=}, " - f"{ss=}, {fs=}, and {ls=}.") + f"{ss=}, {xs=} {fs=}, and {ls=}.") return full def _binfil(self): """ + Create binary domain representation + Returns bytes of fully qualified base2 bytes, that is .qb2 self.code converted to Base2 + self.raw left shifted with pad bits equivalent of Base64 decode of .qb64 into .qb2 @@ -1357,7 +1359,7 @@ def _binfil(self): both = self.both # code + soft, soft may be empty raw = self.raw # bytes or bytearray may be empty - hs, ss, fs, ls = self.Sizes[code] + hs, ss, xs, fs, ls = self.Sizes[code] cs = hs + ss # assumes unit tests on Matter.Sizes ensure valid size entries n = sceil(cs * 3 / 4) # number of b2 bytes to hold b64 code @@ -1416,13 +1418,23 @@ def _exfil(self, qb64b): if hard not in self.Sizes: raise UnexpectedCodeError(f"Unsupported code ={hard}.") - hs, ss, fs, ls = self.Sizes[hard] # assumes hs in both tables match + hs, ss, xs, fs, ls = self.Sizes[hard] # assumes hs in both tables match cs = hs + ss # both hs and ss # assumes that unit tests on Matter .Sizes .Hards and .Bards ensure that # these are well formed. # when fs is None then ss > 0 otherwise fs > hs + ss when ss > 0 - soft = qb64b[hs:hs + ss] # extract soft chars, empty when ss==0 + xtra = qb64b[hs:hs+xs] # extract xtra prepad chars of soft, empty when xs==0 + if isinstance(xtra, memoryview): + xtra = bytes(xtra) + if hasattr(xtra, "decode"): + xtra = xtra.decode() # converts bytes/bytearray to str + if xtra != f"{self.Pad * xs}": + raise UnexpectedCodeError(f"Invalid prepad xtra ={xtra}.") + + # extract soft chars excluding xtra, empty when ss==0 and xs == 0 + # assumes that when ss == 0 then xs must be 0 + soft = qb64b[hs+xs:hs+ss] if isinstance(soft, memoryview): soft = bytes(soft) if hasattr(soft, "decode"): @@ -1493,7 +1505,7 @@ def _bexfil(self, qb2): if hard not in self.Sizes: raise UnexpectedCodeError(f"Unsupported code ={hard}.") - hs, ss, fs, ls = self.Sizes[hard] + hs, ss, xs, fs, ls = self.Sizes[hard] cs = hs + ss # both hs and ss # assumes that unit tests on Matter .Sizes .Hards and .Bards ensure that # these are well formed. @@ -1504,7 +1516,13 @@ def _bexfil(self, qb2): raise ShortageError("Need {} more bytes.".format(bcs - len(qb2))) both = codeB2ToB64(qb2, cs) # extract and convert both hard and soft part of code - soft = both[hs:hs + ss] # get soft may be empty + xtra = both[hs:hs+xs] # extract xtra prepad chars of soft, empty when xs==0 + if xtra != f"{self.Pad * xs}": + raise UnexpectedCodeError(f"Invalid prepad xtra ={xtra}.") + + # extract soft chars excluding xtra, empty when ss==0 and xs == 0 + # assumes that when ss == 0 then xs must be 0 + soft = both[hs+xs:hs+ss] # get soft may be empty if not fs: # compute fs from size chars in ss part of code if len(qb2) < bcs: # need more bytes @@ -2068,7 +2086,7 @@ class Tagger(Matter): composable (bool): True when .qb64b and .qb2 are 24 bit aligned and round trip Properties: - tag (str): B64 primitive without prepad (strips prepad from soft) + tag (str): B64 primitive without prepad (alias of .soft) Inherited Hidden: (See Matter) @@ -2089,11 +2107,9 @@ class Tagger(Matter): Methods: - def __init__(self, raw=None, code=MtrDex.Ed25519N, soft='', rize=None, - qb64b=None, qb64=None, qb2=None, strip=False): """ - Pad = '_' # B64 pad char for tag codes with pre-padded soft values + def __init__(self, tag='', soft='', code=None, **kwa): """ @@ -2112,7 +2128,7 @@ def __init__(self, tag='', soft='', code=None, **kwa): bytearray after parsing qb64b or qb2. False means do not strip Parameters: - tag (str | bytes): Base64 plain. Prepad is added as needed. + tag (str | bytes): Base64 automatic sets code given size of tag """ if tag: @@ -2120,15 +2136,13 @@ def __init__(self, tag='', soft='', code=None, **kwa): tag = tag.decode("utf-8") if not Reb64.match(tag.encode("utf-8")): raise InvalidSoftError(f"Non Base64 chars in {tag=}.") + # TagDex tags appear in order of size 1 to 10, at indices 0 to 9 codes = astuple(TagDex) l = len(tag) # soft not empty so l > 0 if l > len(codes): raise InvalidSoftError("Oversized tag={soft}.") - code = codes[l-1] # get code for size of soft - if code in PadTagDex: - soft = self.Pad + tag # pre pad for those that need it - else: - soft = tag + code = codes[l-1] # get code for for tag of len where (index = len - 1) + soft = tag super(Tagger, self).__init__(soft=soft, code=code, **kwa) @@ -2139,17 +2153,10 @@ def __init__(self, tag='', soft='', code=None, **kwa): @property def tag(self): """Returns: - tag (str): B64 primitive without prepad (strips prepad from soft) + tag (str): B64 primitive without prepad (alias of self.soft) """ - tag = self.soft - if self.code in PadTagDex: - pad = self.soft[0] - tag = self.soft[1:] - if pad != self.Pad: - raise InvalidSoftError("Invaid pre {pad=} for {tag=}.") - - return tag + return self.soft class Ilker(Tagger): @@ -2735,7 +2742,7 @@ def bext(self): Property bext: Base64 text value portion of qualified b64 str Returns the value portion of .qb64 with text code and leader removed """ - _, _, _, ls = self.Sizes[self.code] + _, _, _, _, ls = self.Sizes[self.code] bext = encodeB64(bytes([0] * ls) + self.raw) ws = 0 if ls == 0 and bext: diff --git a/src/keri/core/counting.py b/src/keri/core/counting.py index 0a5ca96f..4fc8774d 100644 --- a/src/keri/core/counting.py +++ b/src/keri/core/counting.py @@ -17,7 +17,7 @@ from .. import kering from ..kering import (Versionage, Vrsn_1_0, Vrsn_2_0) -from ..core.coring import Sizage, MapDom +from ..core.coring import MapDom @@ -42,9 +42,6 @@ def __iter__(self): GenDex = GenusCodex() # Make instance - - - @dataclass(frozen=True) class CounterCodex_1_0(MapDom): """ @@ -187,6 +184,12 @@ def __iter__(self): SealDex_2_0 = SealCodex_2_0() +# namedtuple for size entries in Counter derivation code tables +# hs is the hard size int number of chars in hard (stable) part of code +# ss is the soft size int number of chars in soft (unstable) part of code +# fs is the full size int number of chars in code +Cizage = namedtuple("Cizage", "hs ss fs") + class Counter: """ @@ -333,7 +336,7 @@ class Counter: # Sizes table indexes size tables first by major version and then by # lastest minor version - # Each size table maps hs chars of code to Sizage namedtuple of (hs, ss, fs) + # Each size table maps hs chars of code to Cizage namedtuple of (hs, ss, fs) # where hs is hard size, ss is soft size, and fs is full size # soft size, ss, should always be > 0 and hs+ss=fs for Counter Sizes = \ @@ -342,82 +345,82 @@ class Counter: { Vrsn_1_0.minor: \ { - '-A': Sizage(hs=2, ss=2, fs=4, ls=0), - '-B': Sizage(hs=2, ss=2, fs=4, ls=0), - '-C': Sizage(hs=2, ss=2, fs=4, ls=0), - '-D': Sizage(hs=2, ss=2, fs=4, ls=0), - '-E': Sizage(hs=2, ss=2, fs=4, ls=0), - '-F': Sizage(hs=2, ss=2, fs=4, ls=0), - '-G': Sizage(hs=2, ss=2, fs=4, ls=0), - '-H': Sizage(hs=2, ss=2, fs=4, ls=0), - '-I': Sizage(hs=2, ss=2, fs=4, ls=0), - '-J': Sizage(hs=2, ss=2, fs=4, ls=0), - '-K': Sizage(hs=2, ss=2, fs=4, ls=0), - '-L': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0L': Sizage(hs=3, ss=5, fs=8, ls=0), - '-V': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0V': Sizage(hs=3, ss=5, fs=8, ls=0), - '-Z': Sizage(hs=2, ss=2, fs=4, ls=0), - '--AAA': Sizage(hs=5, ss=3, fs=8, ls=0), + '-A': Cizage(hs=2, ss=2, fs=4), + '-B': Cizage(hs=2, ss=2, fs=4), + '-C': Cizage(hs=2, ss=2, fs=4), + '-D': Cizage(hs=2, ss=2, fs=4), + '-E': Cizage(hs=2, ss=2, fs=4), + '-F': Cizage(hs=2, ss=2, fs=4), + '-G': Cizage(hs=2, ss=2, fs=4), + '-H': Cizage(hs=2, ss=2, fs=4), + '-I': Cizage(hs=2, ss=2, fs=4), + '-J': Cizage(hs=2, ss=2, fs=4), + '-K': Cizage(hs=2, ss=2, fs=4), + '-L': Cizage(hs=2, ss=2, fs=4), + '-0L': Cizage(hs=3, ss=5, fs=8), + '-V': Cizage(hs=2, ss=2, fs=4), + '-0V': Cizage(hs=3, ss=5, fs=8), + '-Z': Cizage(hs=2, ss=2, fs=4), + '--AAA': Cizage(hs=5, ss=3, fs=8), }, }, Vrsn_2_0.major: \ { Vrsn_2_0.minor: \ { - '-A': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0A': Sizage(hs=3, ss=5, fs=8, ls=0), - '-B': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0B': Sizage(hs=3, ss=5, fs=8, ls=0), - '-C': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0C': Sizage(hs=3, ss=5, fs=8, ls=0), - '-D': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0D': Sizage(hs=3, ss=5, fs=8, ls=0), - '-E': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0E': Sizage(hs=3, ss=5, fs=8, ls=0), - '-F': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0F': Sizage(hs=3, ss=5, fs=8, ls=0), - '-G': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0G': Sizage(hs=3, ss=5, fs=8, ls=0), - '-H': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0H': Sizage(hs=3, ss=5, fs=8, ls=0), - '-I': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0I': Sizage(hs=3, ss=5, fs=8, ls=0), - '-J': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0J': Sizage(hs=3, ss=5, fs=8, ls=0), - '-K': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0K': Sizage(hs=3, ss=5, fs=8, ls=0), - '-L': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0L': Sizage(hs=3, ss=5, fs=8, ls=0), - '-M': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0M': Sizage(hs=3, ss=5, fs=8, ls=0), - '-N': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0N': Sizage(hs=3, ss=5, fs=8, ls=0), - '-O': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0O': Sizage(hs=3, ss=5, fs=8, ls=0), - '-P': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0P': Sizage(hs=3, ss=5, fs=8, ls=0), - '-Q': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0Q': Sizage(hs=3, ss=5, fs=8, ls=0), - '-R': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0R': Sizage(hs=3, ss=5, fs=8, ls=0), - '-S': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0S': Sizage(hs=3, ss=5, fs=8, ls=0), - '-T': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0T': Sizage(hs=3, ss=5, fs=8, ls=0), - '-U': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0U': Sizage(hs=3, ss=5, fs=8, ls=0), - '-V': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0V': Sizage(hs=3, ss=5, fs=8, ls=0), - '-W': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0W': Sizage(hs=3, ss=5, fs=8, ls=0), - '-X': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0X': Sizage(hs=3, ss=5, fs=8, ls=0), - '-Y': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0Y': Sizage(hs=3, ss=5, fs=8, ls=0), - '-Z': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0Z': Sizage(hs=3, ss=5, fs=8, ls=0), - '--AAA': Sizage(hs=5, ss=3, fs=8, ls=0), + '-A': Cizage(hs=2, ss=2, fs=4), + '-0A': Cizage(hs=3, ss=5, fs=8), + '-B': Cizage(hs=2, ss=2, fs=4), + '-0B': Cizage(hs=3, ss=5, fs=8), + '-C': Cizage(hs=2, ss=2, fs=4), + '-0C': Cizage(hs=3, ss=5, fs=8), + '-D': Cizage(hs=2, ss=2, fs=4), + '-0D': Cizage(hs=3, ss=5, fs=8), + '-E': Cizage(hs=2, ss=2, fs=4), + '-0E': Cizage(hs=3, ss=5, fs=8), + '-F': Cizage(hs=2, ss=2, fs=4), + '-0F': Cizage(hs=3, ss=5, fs=8), + '-G': Cizage(hs=2, ss=2, fs=4), + '-0G': Cizage(hs=3, ss=5, fs=8,), + '-H': Cizage(hs=2, ss=2, fs=4), + '-0H': Cizage(hs=3, ss=5, fs=8), + '-I': Cizage(hs=2, ss=2, fs=4), + '-0I': Cizage(hs=3, ss=5, fs=8), + '-J': Cizage(hs=2, ss=2, fs=4,), + '-0J': Cizage(hs=3, ss=5, fs=8), + '-K': Cizage(hs=2, ss=2, fs=4), + '-0K': Cizage(hs=3, ss=5, fs=8), + '-L': Cizage(hs=2, ss=2, fs=4), + '-0L': Cizage(hs=3, ss=5, fs=8), + '-M': Cizage(hs=2, ss=2, fs=4), + '-0M': Cizage(hs=3, ss=5, fs=8), + '-N': Cizage(hs=2, ss=2, fs=4), + '-0N': Cizage(hs=3, ss=5, fs=8), + '-O': Cizage(hs=2, ss=2, fs=4), + '-0O': Cizage(hs=3, ss=5, fs=8), + '-P': Cizage(hs=2, ss=2, fs=4), + '-0P': Cizage(hs=3, ss=5, fs=8), + '-Q': Cizage(hs=2, ss=2, fs=4), + '-0Q': Cizage(hs=3, ss=5, fs=8), + '-R': Cizage(hs=2, ss=2, fs=4), + '-0R': Cizage(hs=3, ss=5, fs=8), + '-S': Cizage(hs=2, ss=2, fs=4), + '-0S': Cizage(hs=3, ss=5, fs=8), + '-T': Cizage(hs=2, ss=2, fs=4), + '-0T': Cizage(hs=3, ss=5, fs=8), + '-U': Cizage(hs=2, ss=2, fs=4), + '-0U': Cizage(hs=3, ss=5, fs=8), + '-V': Cizage(hs=2, ss=2, fs=4), + '-0V': Cizage(hs=3, ss=5, fs=8), + '-W': Cizage(hs=2, ss=2, fs=4), + '-0W': Cizage(hs=3, ss=5, fs=8), + '-X': Cizage(hs=2, ss=2, fs=4), + '-0X': Cizage(hs=3, ss=5, fs=8), + '-Y': Cizage(hs=2, ss=2, fs=4), + '-0Y': Cizage(hs=3, ss=5, fs=8), + '-Z': Cizage(hs=2, ss=2, fs=4), + '-0Z': Cizage(hs=3, ss=5, fs=8), + '--AAA': Cizage(hs=5, ss=3, fs=8), }, }, } @@ -484,7 +487,7 @@ def __init__(self, code=None, *, count=None, countB64=None, except Exception as ex: raise kering.InvalidCodeError(f"Unsupported {code=}.") from ex - hs, ss, fs, ls = self._sizes[code] # get sizes for code + hs, ss, fs = self._sizes[code] # get sizes for code cs = hs + ss # both hard + soft code size if hs < 2 or fs != cs or cs % 4: # fs must be bs and multiple of 4 for count codes raise kering.InvalidCodeSizeError(f"Whole code size not full " @@ -555,13 +558,6 @@ def codes(self): """ return self._codes - #@property - #def tags(self): - #""" - #Returns tags for current .version - #Makes .tags read only - #""" - #return self.Tags[self.version] # use own version @property def sizes(self): @@ -624,7 +620,7 @@ def soft(self): quadlets/triples chars/bytes of material framed by counter. Converts .count to b64 """ - _, ss, _, _ = self.sizes[self.code] + _, ss, _ = self.sizes[self.code] return intToB64(self._count, l=ss) @@ -643,7 +639,7 @@ def fullSize(self): Returns full size of counter in bytes """ - _, _, fs, _ = self.sizes[self.code] # get from sizes table + _, _, fs = self.sizes[self.code] # get from sizes table return fs @@ -685,7 +681,7 @@ def countToB64(self, l=None): """ if l is None: - _, ss, _, _ = self._sizes[self.code] + _, ss, _ = self._sizes[self.code] l = ss return (intToB64(self.count, l=l)) @@ -766,7 +762,7 @@ def _infil(self): code = self.code # codex value chars hard code count = self.count # index value int used for soft - hs, ss, fs, ls = self._sizes[code] + hs, ss, fs = self._sizes[code] # assumes fs = hs + ss # both hard + soft size # assumes unit tests ensure ._sizes table entries are consistent # hs >= 2, ss > 0 fs == hs + ss, not (fs % 4) @@ -794,7 +790,7 @@ def _binfil(self): code = self.code # codex chars hard code count = self.count # index value int used for soft - hs, ss, fs, ls = self._sizes[code] + hs, ss, fs = self._sizes[code] # assumes fs = hs + ss # assumes unit tests ensure ._sizes table entries are consistent # hs >= 2, ss>0 fs == hs + ss, not (fs % 4) @@ -838,7 +834,7 @@ def _exfil(self, qb64b): if hard not in self._sizes: # Sizes needs str not bytes raise kering.UnexpectedCodeError("Unsupported code ={}.".format(hard)) - hs, ss, fs, ls = self._sizes[hard] # assumes hs consistent in both tables + hs, ss, fs = self._sizes[hard] # assumes hs consistent in both tables # assumes fs = hs + ss # both hard + soft code size # assumes that unit tests on Counter and CounterCodex ensure that # .Codes and .Sizes are well formed. @@ -880,7 +876,7 @@ def _bexfil(self, qb2): if hard not in self._sizes: raise kering.UnexpectedCodeError("Unsupported code ={}.".format(hard)) - hs, ss, fs, ls = self._sizes[hard] + hs, ss, fs = self._sizes[hard] # assumes fs = hs + ss # both hs and ss # assumes that unit tests on Counter and CounterCodex ensure that # .Codes and .Sizes are well formed. diff --git a/tests/core/test_coring.py b/tests/core/test_coring.py index 952a75b0..2dc1344e 100644 --- a/tests/core/test_coring.py +++ b/tests/core/test_coring.py @@ -40,7 +40,7 @@ from keri.core import coring from keri.core.coring import (Saids, Sadder, Tholder, Seqner, NumDex, Number, Dater, Bexter, Texter, - TagDex, PadTagDex, Tagger, Ilker, Traitor, + TagDex, Tagger, Ilker, Traitor, Verser, Versage, ) from keri.core.coring import Kindage, Kinds from keri.core.coring import (Sizage, MtrDex, Matter) @@ -204,6 +204,9 @@ def test_matter_class(): """ Test Matter class attributes """ + assert Matter.Codex == MtrDex + + assert Matter.Pad == '_' assert Matter.Codes == \ { @@ -411,102 +414,103 @@ def test_matter_class(): # Codes table with sizes of code (hard) and full primitive material assert Matter.Sizes == \ { - 'A': Sizage(hs=1, ss=0, fs=44, ls=0), - 'B': Sizage(hs=1, ss=0, fs=44, ls=0), - 'C': Sizage(hs=1, ss=0, fs=44, ls=0), - 'D': Sizage(hs=1, ss=0, fs=44, ls=0), - 'E': Sizage(hs=1, ss=0, fs=44, ls=0), - 'F': Sizage(hs=1, ss=0, fs=44, ls=0), - 'G': Sizage(hs=1, ss=0, fs=44, ls=0), - 'H': Sizage(hs=1, ss=0, fs=44, ls=0), - 'I': Sizage(hs=1, ss=0, fs=44, ls=0), - 'J': Sizage(hs=1, ss=0, fs=44, ls=0), - 'K': Sizage(hs=1, ss=0, fs=76, ls=0), - 'L': Sizage(hs=1, ss=0, fs=76, ls=0), - 'M': Sizage(hs=1, ss=0, fs=4, ls=0), - 'N': Sizage(hs=1, ss=0, fs=12, ls=0), - 'O': Sizage(hs=1, ss=0, fs=44, ls=0), - 'P': Sizage(hs=1, ss=0, fs=124, ls=0), - 'Q': Sizage(hs=1, ss=0, fs=44, ls=0), - 'R': Sizage(hs=1, ss=0, fs=8, ls=0), - 'S': Sizage(hs=1, ss=0, fs=16, ls=0), - 'T': Sizage(hs=1, ss=0, fs=20, ls=0), - 'U': Sizage(hs=1, ss=0, fs=24, ls=0), - 'V': Sizage(hs=1, ss=0, fs=4, ls=1), - 'W': Sizage(hs=1, ss=0, fs=4, ls=0), - 'X': Sizage(hs=1, ss=3, fs=4, ls=0), - 'Y': Sizage(hs=1, ss=7, fs=8, ls=0), - 'Z': Sizage(hs=1, ss=0, fs=44, ls=0), - '0A': Sizage(hs=2, ss=0, fs=24, ls=0), - '0B': Sizage(hs=2, ss=0, fs=88, ls=0), - '0C': Sizage(hs=2, ss=0, fs=88, ls=0), - '0D': Sizage(hs=2, ss=0, fs=88, ls=0), - '0E': Sizage(hs=2, ss=0, fs=88, ls=0), - '0F': Sizage(hs=2, ss=0, fs=88, ls=0), - '0G': Sizage(hs=2, ss=0, fs=88, ls=0), - '0H': Sizage(hs=2, ss=0, fs=8, ls=0), - '0I': Sizage(hs=2, ss=0, fs=88, ls=0), - '0J': Sizage(hs=2, ss=2, fs=4, ls=0), - '0K': Sizage(hs=2, ss=2, fs=4, ls=0), - '0L': Sizage(hs=2, ss=6, fs=8, ls=0), - '0M': Sizage(hs=2, ss=6, fs=8, ls=0), - '0N': Sizage(hs=2, ss=10, fs=12, ls=0), - '0O': Sizage(hs=2, ss=10, fs=12, ls=0), - '1AAA': Sizage(hs=4, ss=0, fs=48, ls=0), - '1AAB': Sizage(hs=4, ss=0, fs=48, ls=0), - '1AAC': Sizage(hs=4, ss=0, fs=80, ls=0), - '1AAD': Sizage(hs=4, ss=0, fs=80, ls=0), - '1AAE': Sizage(hs=4, ss=0, fs=56, ls=0), - '1AAF': Sizage(hs=4, ss=4, fs=8, ls=0), - '1AAG': Sizage(hs=4, ss=0, fs=36, ls=0), - '1AAH': Sizage(hs=4, ss=0, fs=100, ls=0), - '1AAI': Sizage(hs=4, ss=0, fs=48, ls=0), - '1AAJ': Sizage(hs=4, ss=0, fs=48, ls=0), - '1AAK': Sizage(hs=4, ss=0, fs=4, ls=0), - '1AAL': Sizage(hs=4, ss=0, fs=4, ls=0), - '1AAM': Sizage(hs=4, ss=0, fs=4, ls=0), - '1AAN': Sizage(hs=4, ss=8, fs=12, ls=0), - '1__-': Sizage(hs=4, ss=2, fs=12, ls=0), - '1___': Sizage(hs=4, ss=0, fs=8, ls=0), - '2__-': Sizage(hs=4, ss=2, fs=12, ls=1), - '2___': Sizage(hs=4, ss=0, fs=8, ls=1), - '3__-': Sizage(hs=4, ss=2, fs=12, ls=2), - '3___': Sizage(hs=4, ss=0, fs=8, ls=2), - '4A': Sizage(hs=2, ss=2, fs=None, ls=0), - '5A': Sizage(hs=2, ss=2, fs=None, ls=1), - '6A': Sizage(hs=2, ss=2, fs=None, ls=2), - '7AAA': Sizage(hs=4, ss=4, fs=None, ls=0), - '8AAA': Sizage(hs=4, ss=4, fs=None, ls=1), - '9AAA': Sizage(hs=4, ss=4, fs=None, ls=2), - '4B': Sizage(hs=2, ss=2, fs=None, ls=0), - '5B': Sizage(hs=2, ss=2, fs=None, ls=1), - '6B': Sizage(hs=2, ss=2, fs=None, ls=2), - '7AAB': Sizage(hs=4, ss=4, fs=None, ls=0), - '8AAB': Sizage(hs=4, ss=4, fs=None, ls=1), - '9AAB': Sizage(hs=4, ss=4, fs=None, ls=2), - '4C': Sizage(hs=2, ss=2, fs=None, ls=0), - '5C': Sizage(hs=2, ss=2, fs=None, ls=1), - '6C': Sizage(hs=2, ss=2, fs=None, ls=2), - '7AAC': Sizage(hs=4, ss=4, fs=None, ls=0), - '8AAC': Sizage(hs=4, ss=4, fs=None, ls=1), - '9AAC': Sizage(hs=4, ss=4, fs=None, ls=2), - '4D': Sizage(hs=2, ss=2, fs=None, ls=0), - '5D': Sizage(hs=2, ss=2, fs=None, ls=1), - '6D': Sizage(hs=2, ss=2, fs=None, ls=2), - '7AAD': Sizage(hs=4, ss=4, fs=None, ls=0), - '8AAD': Sizage(hs=4, ss=4, fs=None, ls=1), - '9AAD': Sizage(hs=4, ss=4, fs=None, ls=2), - '4E': Sizage(hs=2, ss=2, fs=None, ls=0), - '5E': Sizage(hs=2, ss=2, fs=None, ls=1), - '6E': Sizage(hs=2, ss=2, fs=None, ls=2), - '7AAE': Sizage(hs=4, ss=4, fs=None, ls=0), - '8AAE': Sizage(hs=4, ss=4, fs=None, ls=1), - '9AAE': Sizage(hs=4, ss=4, fs=None, ls=2) + 'A': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'B': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'C': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'D': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'E': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'F': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'G': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'H': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'I': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'J': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'K': Sizage(hs=1, ss=0, xs=0, fs=76, ls=0), + 'L': Sizage(hs=1, ss=0, xs=0, fs=76, ls=0), + 'M': Sizage(hs=1, ss=0, xs=0, fs=4, ls=0), + 'N': Sizage(hs=1, ss=0, xs=0, fs=12, ls=0), + 'O': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'P': Sizage(hs=1, ss=0, xs=0, fs=124, ls=0), + 'Q': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + 'R': Sizage(hs=1, ss=0, xs=0, fs=8, ls=0), + 'S': Sizage(hs=1, ss=0, xs=0, fs=16, ls=0), + 'T': Sizage(hs=1, ss=0, xs=0, fs=20, ls=0), + 'U': Sizage(hs=1, ss=0, xs=0, fs=24, ls=0), + 'V': Sizage(hs=1, ss=0, xs=0, fs=4, ls=1), + 'W': Sizage(hs=1, ss=0, xs=0, fs=4, ls=0), + 'X': Sizage(hs=1, ss=3, xs=0, fs=4, ls=0), + 'Y': Sizage(hs=1, ss=7, xs=0, fs=8, ls=0), + 'Z': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), + '0A': Sizage(hs=2, ss=0, xs=0, fs=24, ls=0), + '0B': Sizage(hs=2, ss=0, xs=0, fs=88, ls=0), + '0C': Sizage(hs=2, ss=0, xs=0, fs=88, ls=0), + '0D': Sizage(hs=2, ss=0, xs=0, fs=88, ls=0), + '0E': Sizage(hs=2, ss=0, xs=0, fs=88, ls=0), + '0F': Sizage(hs=2, ss=0, xs=0, fs=88, ls=0), + '0G': Sizage(hs=2, ss=0, xs=0, fs=88, ls=0), + '0H': Sizage(hs=2, ss=0, xs=0, fs=8, ls=0), + '0I': Sizage(hs=2, ss=0, xs=0, fs=88, ls=0), + '0J': Sizage(hs=2, ss=2, xs=1, fs=4, ls=0), + '0K': Sizage(hs=2, ss=2, xs=0, fs=4, ls=0), + '0L': Sizage(hs=2, ss=6, xs=1, fs=8, ls=0), + '0M': Sizage(hs=2, ss=6, xs=0, fs=8, ls=0), + '0N': Sizage(hs=2, ss=10, xs=1, fs=12, ls=0), + '0O': Sizage(hs=2, ss=10, xs=0, fs=12, ls=0), + '1AAA': Sizage(hs=4, ss=0, xs=0, fs=48, ls=0), + '1AAB': Sizage(hs=4, ss=0, xs=0, fs=48, ls=0), + '1AAC': Sizage(hs=4, ss=0, xs=0, fs=80, ls=0), + '1AAD': Sizage(hs=4, ss=0, xs=0, fs=80, ls=0), + '1AAE': Sizage(hs=4, ss=0, xs=0, fs=56, ls=0), + '1AAF': Sizage(hs=4, ss=4, xs=0, fs=8, ls=0), + '1AAG': Sizage(hs=4, ss=0, xs=0, fs=36, ls=0), + '1AAH': Sizage(hs=4, ss=0, xs=0, fs=100, ls=0), + '1AAI': Sizage(hs=4, ss=0, xs=0, fs=48, ls=0), + '1AAJ': Sizage(hs=4, ss=0, xs=0, fs=48, ls=0), + '1AAK': Sizage(hs=4, ss=0, xs=0, fs=4, ls=0), + '1AAL': Sizage(hs=4, ss=0, xs=0, fs=4, ls=0), + '1AAM': Sizage(hs=4, ss=0, xs=0, fs=4, ls=0), + '1AAN': Sizage(hs=4, ss=8, xs=0, fs=12, ls=0), + '1__-': Sizage(hs=4, ss=2, xs=0, fs=12, ls=0), + '1___': Sizage(hs=4, ss=0, xs=0, fs=8, ls=0), + '2__-': Sizage(hs=4, ss=2, xs=1, fs=12, ls=1), + '2___': Sizage(hs=4, ss=0, xs=0, fs=8, ls=1), + '3__-': Sizage(hs=4, ss=2, xs=0, fs=12, ls=2), + '3___': Sizage(hs=4, ss=0, xs=0, fs=8, ls=2), + '4A': Sizage(hs=2, ss=2, xs=0, fs=None, ls=0), + '5A': Sizage(hs=2, ss=2, xs=0, fs=None, ls=1), + '6A': Sizage(hs=2, ss=2, xs=0, fs=None, ls=2), + '7AAA': Sizage(hs=4, ss=4, xs=0, fs=None, ls=0), + '8AAA': Sizage(hs=4, ss=4, xs=0, fs=None, ls=1), + '9AAA': Sizage(hs=4, ss=4, xs=0, fs=None, ls=2), + '4B': Sizage(hs=2, ss=2, xs=0, fs=None, ls=0), + '5B': Sizage(hs=2, ss=2, xs=0, fs=None, ls=1), + '6B': Sizage(hs=2, ss=2, xs=0, fs=None, ls=2), + '7AAB': Sizage(hs=4, ss=4, xs=0, fs=None, ls=0), + '8AAB': Sizage(hs=4, ss=4, xs=0, fs=None, ls=1), + '9AAB': Sizage(hs=4, ss=4, xs=0, fs=None, ls=2), + '4C': Sizage(hs=2, ss=2, xs=0, fs=None, ls=0), + '5C': Sizage(hs=2, ss=2, xs=0, fs=None, ls=1), + '6C': Sizage(hs=2, ss=2, xs=0, fs=None, ls=2), + '7AAC': Sizage(hs=4, ss=4, xs=0, fs=None, ls=0), + '8AAC': Sizage(hs=4, ss=4, xs=0, fs=None, ls=1), + '9AAC': Sizage(hs=4, ss=4, xs=0, fs=None, ls=2), + '4D': Sizage(hs=2, ss=2, xs=0, fs=None, ls=0), + '5D': Sizage(hs=2, ss=2, xs=0, fs=None, ls=1), + '6D': Sizage(hs=2, ss=2, xs=0, fs=None, ls=2), + '7AAD': Sizage(hs=4, ss=4, xs=0, fs=None, ls=0), + '8AAD': Sizage(hs=4, ss=4, xs=0, fs=None, ls=1), + '9AAD': Sizage(hs=4, ss=4, xs=0, fs=None, ls=2), + '4E': Sizage(hs=2, ss=2, xs=0, fs=None, ls=0), + '5E': Sizage(hs=2, ss=2, xs=0, fs=None, ls=1), + '6E': Sizage(hs=2, ss=2, xs=0, fs=None, ls=2), + '7AAE': Sizage(hs=4, ss=4, xs=0, fs=None, ls=0), + '8AAE': Sizage(hs=4, ss=4, xs=0, fs=None, ls=1), + '9AAE': Sizage(hs=4, ss=4, xs=0, fs=None, ls=2) } assert Matter.Sizes['A'].hs == 1 # hard size assert Matter.Sizes['A'].ss == 0 # soft size + assert Matter.Sizes['A'].xs == 0 # xtra size assert Matter.Sizes['A'].fs == 44 # full size assert Matter.Sizes['A'].ls == 0 # lead size @@ -515,17 +519,18 @@ def test_matter_class(): for code, val in Matter.Sizes.items(): # hard code hs = val.hs ss = val.ss + xs = val.xs fs = val.fs ls = val.ls cs = hs + ss assert (isinstance(hs, int) and isinstance(ss, int) and isinstance(ls, int)) - assert hs > 0 and ss >= 0 and ls in (0, 1, 2) + assert hs > 0 and ss >= 0 and xs in (0, 1, 2) and ls in (0, 1, 2) assert len(code) == hs if fs is None: # variable sized - assert ss > 0 and not (cs % 4) # full code is 24 bit aligned + assert ss > 0 and xs == 0 and not (cs % 4) # full code is 24 bit aligned # assumes that Matter methods also ensure (ls + rs) % 3 == 0 i.e. # variable raw with lead is 24 bit aligned, where rs is raw size. assert code[0] in coring.SmallVrzDex or code[0] in coring.LargeVrzDex @@ -561,10 +566,12 @@ def test_matter_class(): assert not (code[0] in coring.SmallVrzDex or code[0] in coring.LargeVrzDex) assert isinstance(fs, int) and fs > 0 and not fs % 4 assert fs >= cs + assert xs <= ss # xs must be zero if ss is assert cs % 4 != 3 # prevent ambiguous conversion if ss > 0 and fs == cs: # special soft value with raw empty assert ls == 0 # no lead assert Matter._rawSize(code) == 0 + assert xs < ss # soft must not be empty, not all prepad # verify correct sizes given raw size. Assumes properties above rs = ((fs - cs) * 3 // 4) - ls # raw size bytes sans lead @@ -599,6 +606,7 @@ def test_matter_class(): assert Matter._rawSize(MtrDex.Ed25519) == 32 assert Matter._leadSize(MtrDex.Ed25519) == 0 + assert Matter._xtraSize(MtrDex.Ed25519) == 0 assert not Matter._special(MtrDex.Ed25519) assert Matter._special(MtrDex.Tag3) @@ -1977,7 +1985,7 @@ def test_matter_special(): # Test TBD0S '1__-' # soft special but valid non-empty raw as part of primitive - code = MtrDex.TBD0S # sizes '1__-': Sizage(hs=4, ss=2, fs=12, ls=0), + code = MtrDex.TBD0S # sizes '1__-': Sizage(hs=4, ss=2, xs=0, fs=12, ls=0), rs = Matter._rawSize(code) # raw size soft = 'TG' qb64 = '1__-TGB1dnd4' @@ -2038,11 +2046,11 @@ def test_matter_special(): # Test TBD1S '2__-' # soft special but valid non-empty raw as part of primitive - code = MtrDex.TBD1S # sizes '2__-': Sizage(hs=4, ss=2, fs=12, ls=1), + code = MtrDex.TBD1S # sizes '2__-': Sizage(hs=4, ss=2, xs=1, fs=12, ls=1), rs = Matter._rawSize(code) # raw size - soft = 'TG' - qb64 = '2__-TGAAdXZ3' # see lead byte - qb2 = b'\xdb\xff\xfeL`\x00uvw' + soft = 'T' + qb64 = '2__-_TAAdXZ3' # see prepad and see lead byte + qb2 = b'\xdb\xff\xfe\xfd0\x00uvw' raw = b'uvw' assert rs == 3 @@ -2079,8 +2087,8 @@ def test_matter_special(): # Same as above but raw all zeros - qb64 = '2__-TGAAAAAA' - qb2 = b'\xdb\xff\xfeL`\x00\x00\x00\x00' + qb64 = '2__-_TAAAAAA' + qb2 = b'\xdb\xff\xfe\xfd0\x00\x00\x00\x00' raw = b'\x00\x00\x00' assert rs == 3 @@ -3359,7 +3367,6 @@ def test_tagger(): # Tag1 tag = 'v' code = MtrDex.Tag1 - soft = '_v' qb64 = '0J_v' qb64b = qb64.encode("utf-8") qb2 = decodeB64(qb64b) @@ -3367,7 +3374,7 @@ def test_tagger(): tagger = Tagger(tag=tag) # defaults assert tagger.code == tagger.hard == code - assert tagger.soft == soft + assert tagger.soft == tag assert tagger.raw == raw assert tagger.qb64 == qb64 assert tagger.qb2 == qb2 @@ -3377,7 +3384,7 @@ def test_tagger(): tagger = Tagger(qb2=qb2) assert tagger.code == tagger.hard == code - assert tagger.soft == soft + assert tagger.soft == tag assert tagger.raw == raw assert tagger.qb64 == qb64 assert tagger.qb2 == qb2 @@ -3387,7 +3394,7 @@ def test_tagger(): tagger = Tagger(qb64=qb64) assert tagger.code == tagger.hard == code - assert tagger.soft == soft + assert tagger.soft == tag assert tagger.raw == raw assert tagger.qb64 == qb64 assert tagger.qb2 == qb2 @@ -3397,7 +3404,7 @@ def test_tagger(): tagger = Tagger(qb64b=qb64b) assert tagger.code == tagger.hard == code - assert tagger.soft == soft + assert tagger.soft == tag assert tagger.raw == raw assert tagger.qb64 == qb64 assert tagger.qb2 == qb2 @@ -5784,7 +5791,6 @@ def test_tholder(): test_traitor() test_verser() #test_texter() - #test_counter() #test_prodex() #test_indexer() test_number() diff --git a/tests/core/test_counting.py b/tests/core/test_counting.py index 3433127a..7ec6cfbe 100644 --- a/tests/core/test_counting.py +++ b/tests/core/test_counting.py @@ -21,7 +21,7 @@ from keri.core import counting -from keri.core.counting import GenDex, Sizage, MapDom, Counter, Codens +from keri.core.counting import GenDex, Cizage, Counter, Codens from keri.core.counting import Versionage, Vrsn_1_0, Vrsn_2_0 @@ -383,90 +383,90 @@ def test_counter_class(): # Codes table with sizes of code (hard) and full primitive material assert Counter.Sizes == \ - { - Vrsn_1_0.major: \ { - Vrsn_1_0.minor: \ + 1: { - '-A': Sizage(hs=2, ss=2, fs=4, ls=0), - '-B': Sizage(hs=2, ss=2, fs=4, ls=0), - '-C': Sizage(hs=2, ss=2, fs=4, ls=0), - '-D': Sizage(hs=2, ss=2, fs=4, ls=0), - '-E': Sizage(hs=2, ss=2, fs=4, ls=0), - '-F': Sizage(hs=2, ss=2, fs=4, ls=0), - '-G': Sizage(hs=2, ss=2, fs=4, ls=0), - '-H': Sizage(hs=2, ss=2, fs=4, ls=0), - '-I': Sizage(hs=2, ss=2, fs=4, ls=0), - '-J': Sizage(hs=2, ss=2, fs=4, ls=0), - '-K': Sizage(hs=2, ss=2, fs=4, ls=0), - '-L': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0L': Sizage(hs=3, ss=5, fs=8, ls=0), - '-V': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0V': Sizage(hs=3, ss=5, fs=8, ls=0), - '-Z': Sizage(hs=2, ss=2, fs=4, ls=0), - '--AAA': Sizage(hs=5, ss=3, fs=8, ls=0) + 0: + { + '-A': Cizage(hs=2, ss=2, fs=4), + '-B': Cizage(hs=2, ss=2, fs=4), + '-C': Cizage(hs=2, ss=2, fs=4), + '-D': Cizage(hs=2, ss=2, fs=4), + '-E': Cizage(hs=2, ss=2, fs=4), + '-F': Cizage(hs=2, ss=2, fs=4), + '-G': Cizage(hs=2, ss=2, fs=4), + '-H': Cizage(hs=2, ss=2, fs=4), + '-I': Cizage(hs=2, ss=2, fs=4), + '-J': Cizage(hs=2, ss=2, fs=4), + '-K': Cizage(hs=2, ss=2, fs=4), + '-L': Cizage(hs=2, ss=2, fs=4), + '-0L': Cizage(hs=3, ss=5, fs=8), + '-V': Cizage(hs=2, ss=2, fs=4), + '-0V': Cizage(hs=3, ss=5, fs=8), + '-Z': Cizage(hs=2, ss=2, fs=4), + '--AAA': Cizage(hs=5, ss=3, fs=8) + } }, - }, - Vrsn_2_0.major: \ - { - Vrsn_2_0.minor: \ + 2: { - '-A': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0A': Sizage(hs=3, ss=5, fs=8, ls=0), - '-B': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0B': Sizage(hs=3, ss=5, fs=8, ls=0), - '-C': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0C': Sizage(hs=3, ss=5, fs=8, ls=0), - '-D': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0D': Sizage(hs=3, ss=5, fs=8, ls=0), - '-E': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0E': Sizage(hs=3, ss=5, fs=8, ls=0), - '-F': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0F': Sizage(hs=3, ss=5, fs=8, ls=0), - '-G': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0G': Sizage(hs=3, ss=5, fs=8, ls=0), - '-H': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0H': Sizage(hs=3, ss=5, fs=8, ls=0), - '-I': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0I': Sizage(hs=3, ss=5, fs=8, ls=0), - '-J': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0J': Sizage(hs=3, ss=5, fs=8, ls=0), - '-K': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0K': Sizage(hs=3, ss=5, fs=8, ls=0), - '-L': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0L': Sizage(hs=3, ss=5, fs=8, ls=0), - '-M': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0M': Sizage(hs=3, ss=5, fs=8, ls=0), - '-N': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0N': Sizage(hs=3, ss=5, fs=8, ls=0), - '-O': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0O': Sizage(hs=3, ss=5, fs=8, ls=0), - '-P': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0P': Sizage(hs=3, ss=5, fs=8, ls=0), - '-Q': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0Q': Sizage(hs=3, ss=5, fs=8, ls=0), - '-R': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0R': Sizage(hs=3, ss=5, fs=8, ls=0), - '-S': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0S': Sizage(hs=3, ss=5, fs=8, ls=0), - '-T': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0T': Sizage(hs=3, ss=5, fs=8, ls=0), - '-U': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0U': Sizage(hs=3, ss=5, fs=8, ls=0), - '-V': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0V': Sizage(hs=3, ss=5, fs=8, ls=0), - '-W': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0W': Sizage(hs=3, ss=5, fs=8, ls=0), - '-X': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0X': Sizage(hs=3, ss=5, fs=8, ls=0), - '-Y': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0Y': Sizage(hs=3, ss=5, fs=8, ls=0), - '-Z': Sizage(hs=2, ss=2, fs=4, ls=0), - '-0Z': Sizage(hs=3, ss=5, fs=8, ls=0), - '--AAA': Sizage(hs=5, ss=3, fs=8, ls=0) - }, - }, - } + 0: + { + '-A': Cizage(hs=2, ss=2, fs=4), + '-0A': Cizage(hs=3, ss=5, fs=8), + '-B': Cizage(hs=2, ss=2, fs=4), + '-0B': Cizage(hs=3, ss=5, fs=8), + '-C': Cizage(hs=2, ss=2, fs=4), + '-0C': Cizage(hs=3, ss=5, fs=8), + '-D': Cizage(hs=2, ss=2, fs=4), + '-0D': Cizage(hs=3, ss=5, fs=8), + '-E': Cizage(hs=2, ss=2, fs=4), + '-0E': Cizage(hs=3, ss=5, fs=8), + '-F': Cizage(hs=2, ss=2, fs=4), + '-0F': Cizage(hs=3, ss=5, fs=8), + '-G': Cizage(hs=2, ss=2, fs=4), + '-0G': Cizage(hs=3, ss=5, fs=8), + '-H': Cizage(hs=2, ss=2, fs=4), + '-0H': Cizage(hs=3, ss=5, fs=8), + '-I': Cizage(hs=2, ss=2, fs=4), + '-0I': Cizage(hs=3, ss=5, fs=8), + '-J': Cizage(hs=2, ss=2, fs=4), + '-0J': Cizage(hs=3, ss=5, fs=8), + '-K': Cizage(hs=2, ss=2, fs=4), + '-0K': Cizage(hs=3, ss=5, fs=8), + '-L': Cizage(hs=2, ss=2, fs=4), + '-0L': Cizage(hs=3, ss=5, fs=8), + '-M': Cizage(hs=2, ss=2, fs=4), + '-0M': Cizage(hs=3, ss=5, fs=8), + '-N': Cizage(hs=2, ss=2, fs=4), + '-0N': Cizage(hs=3, ss=5, fs=8), + '-O': Cizage(hs=2, ss=2, fs=4), + '-0O': Cizage(hs=3, ss=5, fs=8), + '-P': Cizage(hs=2, ss=2, fs=4), + '-0P': Cizage(hs=3, ss=5, fs=8), + '-Q': Cizage(hs=2, ss=2, fs=4), + '-0Q': Cizage(hs=3, ss=5, fs=8), + '-R': Cizage(hs=2, ss=2, fs=4), + '-0R': Cizage(hs=3, ss=5, fs=8), + '-S': Cizage(hs=2, ss=2, fs=4), + '-0S': Cizage(hs=3, ss=5, fs=8), + '-T': Cizage(hs=2, ss=2, fs=4), + '-0T': Cizage(hs=3, ss=5, fs=8), + '-U': Cizage(hs=2, ss=2, fs=4), + '-0U': Cizage(hs=3, ss=5, fs=8), + '-V': Cizage(hs=2, ss=2, fs=4), + '-0V': Cizage(hs=3, ss=5, fs=8), + '-W': Cizage(hs=2, ss=2, fs=4), + '-0W': Cizage(hs=3, ss=5, fs=8), + '-X': Cizage(hs=2, ss=2, fs=4), + '-0X': Cizage(hs=3, ss=5, fs=8), + '-Y': Cizage(hs=2, ss=2, fs=4), + '-0Y': Cizage(hs=3, ss=5, fs=8), + '-Z': Cizage(hs=2, ss=2, fs=4), + '-0Z': Cizage(hs=3, ss=5, fs=8), + '--AAA': Cizage(hs=5, ss=3, fs=8) + } + } + } # Ensure there is an entry in Sizes for each entry in Codes assert Counter.Codes.keys() == Counter.Sizes.keys() @@ -481,13 +481,10 @@ def test_counter_class(): assert Counter.Sizes[Vrsn_1_0.major][Vrsn_1_0.minor]['-A'].hs == 2 # hard size assert Counter.Sizes[Vrsn_1_0.major][Vrsn_1_0.minor]['-A'].ss == 2 # soft size assert Counter.Sizes[Vrsn_1_0.major][Vrsn_1_0.minor]['-A'].fs == 4 # full size - assert Counter.Sizes[Vrsn_1_0.major][Vrsn_1_0.minor]['-A'].ls == 0 # lead size assert Counter.Sizes[Vrsn_2_0.major][Vrsn_2_0.minor]['-0A'].hs == 3 # hard size assert Counter.Sizes[Vrsn_2_0.major][Vrsn_2_0.minor]['-0A'].ss == 5 # soft size assert Counter.Sizes[Vrsn_2_0.major][Vrsn_2_0.minor]['-0A'].fs == 8 # full size - assert Counter.Sizes[Vrsn_2_0.major][Vrsn_2_0.minor]['-0A'].ls == 0 # lead size - # first character of code with hard size of code assert Counter.Hards == \