Algorithms
ecutils.algorithms
Cryptographic algorithms built on top of the core elliptic curve primitives.
DigitalSignature dataclass
ECDSA signature generation and verification.
Attributes:
| Name | Type | Description |
|---|---|---|
private_key | int | The private scalar (integer). |
curve_name | str | Name of the curve (e.g. |
Source code in ecutils/algorithms/digital_signature.py
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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | |
public_key: Point property
Compute the public key: private_key * G.
sign(message_hash)
Generate an ECDSA signature for a message hash.
Algorithm
- Choose random k ∈ [1, n-1]
- R = k·G, r = R.x mod n
- s = (m + r·d) · k⁻¹ mod n (d = private key, m = hash)
.. warning::
The nonce k must never be reused across different messages. Reusing k leaks the private key (as demonstrated in the 2010 Sony PS3 ECDSA attack).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message_hash | int | Integer hash of the message (e.g. SHA-256). | required |
Returns:
| Type | Description |
|---|---|
tuple[int, int] | A tuple |
Source code in ecutils/algorithms/digital_signature.py
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 | |
sign_message(message, hash_func=hashlib.sha256)
Hash a message and sign it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message | bytes | The raw message bytes to sign. | required |
hash_func | Callable[[bytes], Any] | Hash constructor (default | sha256 |
Returns:
| Type | Description |
|---|---|
tuple[int, int] | A tuple |
Source code in ecutils/algorithms/digital_signature.py
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | |
verify(public_key, message_hash, r, s)
Verify an ECDSA signature.
Algorithm
- w = s⁻¹ mod n
- u₁ = m·w mod n, u₂ = r·w mod n
- R' = u₁·G + u₂·Q (Q = public key)
- Accept iff R'.x mod n = r
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
public_key | Point | The signer's public key point. | required |
message_hash | int | Integer hash of the signed message. | required |
r | int | First component of the signature. | required |
s | int | Second component of the signature. | required |
Returns:
| Type | Description |
|---|---|
bool |
|
Raises:
| Type | Description |
|---|---|
ValueError | If |
Source code in ecutils/algorithms/digital_signature.py
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | |
verify_message(public_key, message, r, s, hash_func=hashlib.sha256)
Hash a message and verify its ECDSA signature.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
public_key | Point | The signer's public key point. | required |
message | bytes | The raw message bytes. | required |
r | int | First component of the signature. | required |
s | int | Second component of the signature. | required |
hash_func | Callable[[bytes], Any] | Hash constructor (default | sha256 |
Returns:
| Type | Description |
|---|---|
tuple[int, int] | bool |
|
Source code in ecutils/algorithms/digital_signature.py
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | |
Koblitz dataclass
Koblitz message encoding/decoding on an elliptic curve.
Encoding algorithm
- Convert the message string to an integer m using base-α positional encoding (α = alphabet_size).
- For j = 1, 2, ..., d-1 compute x = d·m + j (mod p).
- Test if x³ + ax + b is a quadratic residue mod p (see :func:
ecutils.utils.math.is_quadratic_residue). - If yes, compute y = √(x³ + ax + b) mod p and return
(Point(x, y), j).
With d = 100 the probability of failure per attempt is ≈ 1/2, so the overall failure probability after 99 attempts is ≈ 2⁻⁹⁹.
Attributes:
| Name | Type | Description |
|---|---|---|
curve_name | str | Name of the curve (e.g. |
alphabet_size | int | Character set size. 256 for ASCII, 65536 for Unicode. |
Source code in ecutils/algorithms/koblitz.py
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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | |
decode(point, j)
Decode a curve point back into the original text message.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
point | Point | The encoded point (as returned by :meth: | required |
j | int | The auxiliary value returned alongside the point. | required |
Returns:
| Type | Description |
|---|---|
str | The original text message. |
Source code in ecutils/algorithms/koblitz.py
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | |
encode(message)
Encode a text message into a point on the curve.
The message is first converted to an integer, then Koblitz's method is used to find a valid curve point derived from that integer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message | str | The text to encode (limited by curve size). | required |
Returns:
| Type | Description |
|---|---|
tuple[Point, int] | A tuple |
Raises:
| Type | Description |
|---|---|
ValueError | If no valid point is found (extremely unlikely). |
Source code in ecutils/algorithms/koblitz.py
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 | |