From 120ad5c42f11ccf7e7730fa0e6f6f5c1db5805e7 Mon Sep 17 00:00:00 2001 From: Samuel M Smith Date: Fri, 26 Jul 2024 11:05:17 -0600 Subject: [PATCH 1/7] decouple sizes from Matter use new Cizage named tuple instead of Sizage. This way can add entries to Matter sizes table without have to change Counter . --- src/keri/core/counting.py | 174 ++++++++++++++++++------------------ tests/core/test_counting.py | 165 +++++++++++++++++----------------- 2 files changed, 166 insertions(+), 173 deletions(-) diff --git a/src/keri/core/counting.py b/src/keri/core/counting.py index 0a5ca96f..33325e5f 100644 --- a/src/keri/core/counting.py +++ b/src/keri/core/counting.py @@ -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_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 == \ From 668550dbac0866e26e7242d21097d6cda7ea14f8 Mon Sep 17 00:00:00 2001 From: Samuel M Smith Date: Fri, 26 Jul 2024 11:48:18 -0600 Subject: [PATCH 2/7] added xs field to Sizage prepatory to making soft prepad part of matter not bolt on in Tagger --- src/keri/core/coring.py | 207 +++++++++++++++++++------------------- src/keri/core/counting.py | 2 +- tests/core/test_coring.py | 187 +++++++++++++++++----------------- 3 files changed, 199 insertions(+), 197 deletions(-) diff --git a/src/keri/core/coring.py b/src/keri/core/coring.py index c7e662f9..cc18ac22 100644 --- a/src/keri/core/coring.py +++ b/src/keri/core/coring.py @@ -727,9 +727,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: @@ -810,97 +811,97 @@ class Matter: # 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. 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=0, fs=4, ls=0), + '0K': Sizage(hs=2, ss=2, xs=0, fs=4, ls=0), + '0L': Sizage(hs=2, ss=6, xs=0, fs=8, ls=0), + '0M': Sizage(hs=2, ss=6, xs=0, fs=8, ls=0), + '0N': Sizage(hs=2, ss=10, xs=0, 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=0, 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 @@ -953,7 +954,7 @@ 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 if rize: # use rsize to determine length of raw to extract @@ -1021,7 +1022,7 @@ def __init__(self, raw=None, code=MtrDex.Ed25519N, soft='', rize=None, 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 + hs, ss, xs, fs, ls = self.Sizes[code] # assumes unit tests force valid sizes if not fs: # variable sized code so can't be soft raise InvalidSoftError(f"Unsupported variable sized {code=} " f" with {fs=} for special {soft=}.") @@ -1069,7 +1070,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,7 +1085,7 @@ 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 @@ -1097,7 +1098,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) @@ -1188,7 +1189,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) @@ -1295,7 +1296,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 @@ -1357,7 +1358,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,7 +1417,7 @@ 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. @@ -1493,7 +1494,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. @@ -2735,7 +2736,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 33325e5f..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 diff --git a/tests/core/test_coring.py b/tests/core/test_coring.py index 952a75b0..78e51ba8 100644 --- a/tests/core/test_coring.py +++ b/tests/core/test_coring.py @@ -411,102 +411,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=0, fs=4, ls=0), + '0K': Sizage(hs=2, ss=2, xs=0, fs=4, ls=0), + '0L': Sizage(hs=2, ss=6, xs=0, fs=8, ls=0), + '0M': Sizage(hs=2, ss=6, xs=0, fs=8, ls=0), + '0N': Sizage(hs=2, ss=10, xs=0, 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=0, 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,13 +516,14 @@ 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 @@ -5784,7 +5786,6 @@ def test_tholder(): test_traitor() test_verser() #test_texter() - #test_counter() #test_prodex() #test_indexer() test_number() From bc9c0f982a210f8c1b4119694d7fa597c7808466 Mon Sep 17 00:00:00 2001 From: Samuel M Smith Date: Sat, 27 Jul 2024 10:52:53 -0600 Subject: [PATCH 3/7] added xs and comments to Matter Sizes --- src/keri/core/coring.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/keri/core/coring.py b/src/keri/core/coring.py index cc18ac22..9d4ddcec 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)) @@ -806,10 +806,8 @@ 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, xs=0, fs=44, ls=0), 'B': Sizage(hs=1, ss=0, xs=0, fs=44, ls=0), @@ -2121,11 +2119,12 @@ 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 + code = codes[l-1] # get code for for tag of len where (index = len - 1) if code in PadTagDex: soft = self.Pad + tag # pre pad for those that need it else: From db1ec092dc398ec6bf133dc7377f8a4b61eb6caf Mon Sep 17 00:00:00 2001 From: Samuel M Smith Date: Sat, 27 Jul 2024 13:08:56 -0600 Subject: [PATCH 4/7] added xs xtra prepad support to Matter --- src/keri/core/coring.py | 75 +++++++++++++++++++++++++++++---------- tests/core/test_coring.py | 8 ++++- 2 files changed, 64 insertions(+), 19 deletions(-) diff --git a/src/keri/core/coring.py b/src/keri/core/coring.py index 9d4ddcec..161c06e8 100644 --- a/src/keri/core/coring.py +++ b/src/keri/core/coring.py @@ -747,6 +747,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: @@ -756,7 +759,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 @@ -791,6 +794,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. @@ -904,7 +909,7 @@ class Matter: 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, @@ -915,7 +920,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 @@ -955,6 +960,7 @@ def __init__(self, raw=None, code=MtrDex.Ed25519N, soft='', rize=None, 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 " @@ -997,12 +1003,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=}.") @@ -1015,13 +1022,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 + 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 soft + 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=}.") @@ -1029,17 +1036,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) @@ -1086,6 +1093,16 @@ def _leadSize(cls, code): _, _, _, _, 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): @@ -1177,7 +1194,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 @@ -1287,6 +1306,8 @@ def composable(self): def _infil(self): """ + Create text domain representation + Returns: primitive (bytes): fully qualified base64 characters. """ @@ -1341,13 +1362,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 @@ -1421,7 +1444,17 @@ def _exfil(self, qb64b): # 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"): @@ -1503,7 +1536,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 diff --git a/tests/core/test_coring.py b/tests/core/test_coring.py index 78e51ba8..5206a2d7 100644 --- a/tests/core/test_coring.py +++ b/tests/core/test_coring.py @@ -204,6 +204,9 @@ def test_matter_class(): """ Test Matter class attributes """ + assert Matter.Codex == MtrDex + + assert Matter.Pad == '_' assert Matter.Codes == \ { @@ -527,7 +530,7 @@ def test_matter_class(): 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 @@ -563,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 @@ -601,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) From de5c84a47efb96e55e50e04f6e0ed698e5667607 Mon Sep 17 00:00:00 2001 From: Samuel M Smith Date: Sat, 27 Jul 2024 13:37:33 -0600 Subject: [PATCH 5/7] added test vector for xs --- src/keri/core/coring.py | 27 ++++++++++++++------------- tests/core/test_coring.py | 31 +++++++++++++++---------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/keri/core/coring.py b/src/keri/core/coring.py index 161c06e8..6bbc3c10 100644 --- a/src/keri/core/coring.py +++ b/src/keri/core/coring.py @@ -849,11 +849,11 @@ class Matter: '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=0, fs=4, 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=0, fs=8, 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=0, fs=12, 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), @@ -871,7 +871,7 @@ class Matter: '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=0, fs=12, ls=1), + '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), @@ -2164,10 +2164,11 @@ def __init__(self, tag='', soft='', code=None, **kwa): if l > len(codes): raise InvalidSoftError("Oversized tag={soft}.") code = codes[l-1] # get code for for tag of len where (index = len - 1) - if code in PadTagDex: - soft = self.Pad + tag # pre pad for those that need it - else: - soft = tag + #if code in PadTagDex: + #soft = self.Pad + tag # pre pad for those that need it + #else: + #soft = tag + soft = tag super(Tagger, self).__init__(soft=soft, code=code, **kwa) @@ -2182,11 +2183,11 @@ def tag(self): """ 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=}.") + #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 diff --git a/tests/core/test_coring.py b/tests/core/test_coring.py index 5206a2d7..6eca06a4 100644 --- a/tests/core/test_coring.py +++ b/tests/core/test_coring.py @@ -449,11 +449,11 @@ def test_matter_class(): '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=0, fs=4, 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=0, fs=8, 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=0, fs=12, 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), @@ -471,7 +471,7 @@ def test_matter_class(): '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=0, fs=12, ls=1), + '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), @@ -1985,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' @@ -2046,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 @@ -2087,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 @@ -3367,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) @@ -3375,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 @@ -3385,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 @@ -3395,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 @@ -3405,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 From f5840bc78794171ea832c368d4b1e2b0cce32fd2 Mon Sep 17 00:00:00 2001 From: Samuel M Smith Date: Sat, 27 Jul 2024 13:51:17 -0600 Subject: [PATCH 6/7] fixed up comments removed dead code. Now Tagger does not have to fix up prepad after the fact but is natively supported by Matter with xtra xs code table size field. --- src/keri/core/coring.py | 41 ++++----------------------------------- tests/core/test_coring.py | 2 +- 2 files changed, 5 insertions(+), 38 deletions(-) diff --git a/src/keri/core/coring.py b/src/keri/core/coring.py index 6bbc3c10..552fffca 100644 --- a/src/keri/core/coring.py +++ b/src/keri/core/coring.py @@ -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: @@ -2106,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) @@ -2127,8 +2107,6 @@ 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 @@ -2150,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: @@ -2164,10 +2142,6 @@ def __init__(self, tag='', soft='', code=None, **kwa): if l > len(codes): raise InvalidSoftError("Oversized tag={soft}.") code = codes[l-1] # get code for for tag of len where (index = len - 1) - #if code in PadTagDex: - #soft = self.Pad + tag # pre pad for those that need it - #else: - #soft = tag soft = tag @@ -2179,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): diff --git a/tests/core/test_coring.py b/tests/core/test_coring.py index 6eca06a4..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) From b63a9f9629d7bf5541f699ab98c622d295e2d6c8 Mon Sep 17 00:00:00 2001 From: Samuel M Smith Date: Sat, 27 Jul 2024 13:53:37 -0600 Subject: [PATCH 7/7] removed spurious Pad, now in super class --- src/keri/core/coring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/keri/core/coring.py b/src/keri/core/coring.py index 552fffca..84bd0893 100644 --- a/src/keri/core/coring.py +++ b/src/keri/core/coring.py @@ -2109,7 +2109,7 @@ class Tagger(Matter): """ - Pad = '_' # B64 pad char for tag codes with pre-padded soft values + def __init__(self, tag='', soft='', code=None, **kwa): """