aboutsummaryrefslogtreecommitdiff
path: root/pyecsca/ec/key_generation.py
blob: f67ad67f6c1ce30c3a7cce1d2f1166986b5acffe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
"""Provides a key generator for elliptic curve keypairs."""

from typing import Tuple

from public import public

from pyecsca.ec.context import ResultAction
from pyecsca.ec.mod import Mod
from pyecsca.ec.mult import ScalarMultiplier
from pyecsca.ec.params import DomainParameters
from pyecsca.ec.point import Point


@public
class KeygenAction(ResultAction):
    """A key generation."""

    params: DomainParameters

    def __init__(self, params: DomainParameters):
        super().__init__()
        self.params = params

    def __repr__(self):
        return f"{self.__class__.__name__}({self.params})"


@public
class KeyGeneration:
    """
    Key generator.

    :param mult: The scalar multiplier to use during key generation.
    :param params: The domain parameters over which to generate the keypair.
    :param affine: Whether to transform the public key point to the affine form during key generation.
    """

    mult: ScalarMultiplier
    params: DomainParameters
    affine: bool

    def __init__(
        self, mult: ScalarMultiplier, params: DomainParameters, affine: bool = False
    ):
        self.mult = mult
        self.params = params
        self.mult.init(self.params, self.params.generator)
        self.affine = affine

    def generate(self) -> Tuple[Mod, Point]:
        """
        Generate a keypair.

        :return: The generated keypair, a `tuple` of the private key (scalar) and the public key (point).
        """
        with KeygenAction(self.params) as action:
            privkey = Mod.random(self.params.order)
            pubkey = self.mult.multiply(int(privkey.x))
            if self.affine:
                pubkey = pubkey.to_affine()
            return action.exit((privkey, pubkey))