mirror of
https://github.com/Mbed-TLS/mbedtls-framework.git
synced 2026-10-17 14:17:24 +00:00
Ground support for multiple key formats
Prepare to support 3 different private key representations: seed only, standard expanded private key format, or joined (seed + expanded). This commit only defines new auxiliary functions. Subsequent commits will use these functions to simplify the code and support tuning the test data for different formats. Signed-off-by: Gilles Peskine <[email protected]>
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
||||
|
||||
import collections
|
||||
import enum
|
||||
import functools
|
||||
from typing import Callable, Iterator, List, Optional, Sequence, Tuple
|
||||
|
||||
@@ -34,6 +35,22 @@ SEEDS = [
|
||||
b'\x00' * 32,
|
||||
]
|
||||
|
||||
|
||||
class PrivateKeyFormat(enum.Enum):
|
||||
"""Key representation to pass to the signature function."""
|
||||
SEED = 0 # key = 32-byte seed
|
||||
EXPANDED = 1 # key in the standard expanded format
|
||||
SEED_PLUS_EXPANDED = 2 # key = join(seed, standard-expanded-format)
|
||||
|
||||
def descr(self) -> str:
|
||||
"""A short textual description of the format."""
|
||||
return [
|
||||
'seed',
|
||||
'expanded',
|
||||
'joined',
|
||||
][self.value]
|
||||
|
||||
|
||||
class Key:
|
||||
"""An MLDSA key pair."""
|
||||
#pylint: disable=too-few-public-methods
|
||||
@@ -43,6 +60,17 @@ class Key:
|
||||
self.seed = seed
|
||||
self.public, self.secret = PURE[kl]._keygen_internal(seed)
|
||||
|
||||
def private_representation(self,
|
||||
pkf: Optional[PrivateKeyFormat] = None) -> bytes:
|
||||
if pkf == PrivateKeyFormat.SEED or pkf is None:
|
||||
return self.seed
|
||||
elif pkf == PrivateKeyFormat.EXPANDED:
|
||||
return self.secret
|
||||
elif pkf == PrivateKeyFormat.SEED_PLUS_EXPANDED:
|
||||
return self.seed + self.secret
|
||||
else:
|
||||
raise ValueError(f'Unsupported private key format: {pkf}')
|
||||
|
||||
@functools.lru_cache(maxsize=9999)
|
||||
def sign_message(self, message: bytes, deterministic: bool) -> bytes:
|
||||
PURE[self.kl].set_drbg_seed(bytes(48))
|
||||
@@ -66,6 +94,9 @@ MESSAGES = [
|
||||
class Generator:
|
||||
"""Abstract base class to generate tests for one API."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.private_key_formats: Sequence[PrivateKeyFormat] = [PrivateKeyFormat.SEED]
|
||||
|
||||
@classmethod
|
||||
def function(cls, func: str, kl: int) -> str:
|
||||
raise NotImplementedError
|
||||
@@ -90,6 +121,18 @@ class Generator:
|
||||
# b'ABCDE...' wrapping around and repeating every 256 bytes
|
||||
return bytes(b & 0xff for b in range(65, 65 + length))
|
||||
|
||||
def describe_private_key_formats(self,
|
||||
space_before: bool = False,
|
||||
space_after: bool = False,
|
||||
) -> Iterator[Tuple[PrivateKeyFormat, str]]:
|
||||
if len(self.private_key_formats) == 1:
|
||||
yield (self.private_key_formats[0], '')
|
||||
return
|
||||
for pkf in self.private_key_formats:
|
||||
yield (pkf, ''.join([' ' if space_before else '',
|
||||
'(', pkf.descr(), ')',
|
||||
' ' if space_after else '']))
|
||||
|
||||
def chunks_for_lengths(self,
|
||||
lengths: Sequence[int],
|
||||
arity: Optional[int] = None,
|
||||
|
||||
Reference in New Issue
Block a user