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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
import hashlib
from typing import Optional, Any
from public import public
from .mult import ScalarMultiplier
from .point import Point
@public
class KeyAgreement(object):
"""An EC based key agreement primitive. (ECDH)"""
mult: ScalarMultiplier
pubkey: Point
privkey: int
hash_algo: Optional[Any]
def __init__(self, mult: ScalarMultiplier, pubkey: Point, privkey: int,
hash_algo: Optional[Any] = None):
self.mult = mult
self.pubkey = pubkey
self.privkey = privkey
self.hash_algo = hash_algo
def perform_raw(self) -> Point:
"""
Perform the scalar-multiplication of the key agreement.
:return: The shared point.
"""
point = self.mult.multiply(self.privkey, self.pubkey)
return point.to_affine() # TODO: This conversion should be somehow added to the context
def perform(self) -> bytes:
"""
Perform the key agreement operation.
:return: The shared secret.
"""
affine_point = self.perform_raw()
x = int(affine_point.x)
p = self.mult.group.curve.prime
n = (p.bit_length() + 7) // 8
result = x.to_bytes(n, byteorder="big")
if self.hash_algo is not None:
result = self.hash_algo(result).digest()
return result
@public
class ECDH_NONE(KeyAgreement):
"""Raw x-coordinate ECDH."""
def __init__(self, mult: ScalarMultiplier, pubkey: Point, privkey: int):
super().__init__(mult, pubkey, privkey)
@public
class ECDH_SHA1(KeyAgreement):
"""ECDH with SHA1 of x-coordinate."""
def __init__(self, mult: ScalarMultiplier, pubkey: Point, privkey: int):
super().__init__(mult, pubkey, privkey, hashlib.sha1)
@public
class ECDH_SHA224(KeyAgreement):
"""ECDH with SHA224 of x-coordinate."""
def __init__(self, mult: ScalarMultiplier, pubkey: Point, privkey: int):
super().__init__(mult, pubkey, privkey, hashlib.sha224)
@public
class ECDH_SHA256(KeyAgreement):
"""ECDH with SHA256 of x-coordinate."""
def __init__(self, mult: ScalarMultiplier, pubkey: Point, privkey: int):
super().__init__(mult, pubkey, privkey, hashlib.sha256)
@public
class ECDH_SHA384(KeyAgreement):
"""ECDH with SHA384 of x-coordinate."""
def __init__(self, mult: ScalarMultiplier, pubkey: Point, privkey: int):
super().__init__(mult, pubkey, privkey, hashlib.sha384)
@public
class ECDH_SHA512(KeyAgreement):
"""ECDH with SHA512 of x-coordinate."""
def __init__(self, mult: ScalarMultiplier, pubkey: Point, privkey: int):
super().__init__(mult, pubkey, privkey, hashlib.sha512)
|