ECDH¶
Module for test ECDH implementations.
The crypto_condor.primitives.ECDH
module can test implementations of the
ECDH key exchange.
Test implementations¶
There are two types of test vectors available: those that provide the peer’s public key as the encoded coordinates of the point and those that provide it as a X.509 SubjectPublicKeyInfo field. Since the function signature is different, there is one test for each type.
- crypto_condor.primitives.ECDH.test_exchange_point(exchange, curve, *, compliance=True, resilience=False)¶
Tests ECDH exchange with the peer’s public key as an uncompressed point.
- Parameters:
exchange (ExchangePoint) – The implementation of the
ExchangeCoord
protocol to test.curve (Curve) – The elliptic curve to use.
- Keyword Arguments:
compliance – Whether to use compliance test vectors.
resilience – Whether to use resilience test vectors.
- Returns:
A dictionary of results.
- Return type:
Example
Let’s test PyCryptodome over P-256. We need the
ECC
module to construct the keys and theDH
module to actually perform the key exchange.>>> from Crypto.Protocol import DH >>> from Crypto.PublicKey import ECC
From crypto-condor we import the primitive.
>>> from crypto_condor.primitives import ECDH
We wrap the exchange in our function to match the
ExchangePoint
protocol.>>> def exchange_point(secret: bytes, pub_point: bytes) -> bytes: ... pk = ECC.import_key(pub_point, curve_name="P-256") ... d = int.from_bytes(secret) ... sk = ECC.construct(curve="P-256", d=d) ... return DH.key_agreement(static_priv=sk, static_pub=pk, kdf=lambda x: x)
Then we call
test_exchange_point()
.>>> curve = ECDH.Curve.P256 >>> rd = ECDH.test_exchange_point(exchange_point, curve) [P-256][NIST CAVP] Testing ExchangePoint ... >>> assert rd.check()
Added in version TODO(version): This function roughly replaces
test_exchange_nist
.
- crypto_condor.primitives.ECDH.test_exchange_x509(exchange, curve, *, compliance=True, resilience=False)¶
Tests ECDH exchange with the peer’s public X509 key.
- Parameters:
exchange (ExchangeX509) – The implementation of the
ExchangeX509
protocol to test.curve (Curve) – The elliptic curve to use.
- Keyword Arguments:
compliance – Whether to use compliance test vectors.
resilience – Whether to use resilience test vectors.
- Returns:
A dictionary of results.
- Return type:
Example
Let’s test PyCryptodome over P-256. We need the
ECC
module to construct the keys and theDH
module to actually perform the key exchange.>>> from Crypto.Protocol import DH >>> from Crypto.PublicKey import ECC
From crypto-condor we import the primitive.
>>> from crypto_condor.primitives import ECDH
We wrap the exchange in our function to match the
ExchangeX509
protocol.>>> def exchange_x509(secret: bytes, pub_point: bytes) -> bytes: ... pk = ECC.import_key(pub_point) ... d = int.from_bytes(secret) ... sk = ECC.construct(curve="P-256", d=d) ... return DH.key_agreement(static_priv=sk, static_pub=pk, kdf=lambda x: x)
Then we call
test_exchange_x509()
. There are no NIST test vectors for this test so we use theresilience
option.>>> curve = ECDH.Curve.P256 >>> rd = ECDH.test_exchange_x509(exchange_x509, curve, resilience=True) [P-256][Wycheproof] Testing ExchangeX509 ... >>> assert rd.check()
- crypto_condor.primitives.ECDH.test_exchange(ecdh, curve, *, compliance=True, resilience=False)¶
Tests an implementation of ECDH.
- Parameters:
- Keyword Arguments:
compliance – Whether to use NIST vectors.
resilience – Whether to use Wycheproof vectors.
- Returns:
A dictionary of results.
- Return type:
Notes
Internally calls the
test_exchange_nist()
andtest_exchange_wycheproof()
functions.Changed in version TODO(version): Returns
ResultsDict
instead ofResults
or None.Deprecated since version TODO(version): The test vectors have been updated and the
ECDH
protocol is now deprecated. Usetest_exchange_point()
andtest_exchange_x509()
instead.
- crypto_condor.primitives.ECDH.test_exchange_nist(ecdh, curve)¶
Tests ECDH exchange with NIST vectors.
- Parameters:
- Returns:
A dictionary of results.
- Return type:
Changed in version TODO(version): Returns
ResultsDict
instead ofResults
or None.Deprecated since version TODO(version): The test vectors have been updated and the
ECDH
protocol is now deprecated. Usetest_exchange_point()
andExchangePoint
instead.
- crypto_condor.primitives.ECDH.test_exchange_wycheproof(ecdh, curve)¶
Tests ECDH.exchange with Wycheproof vectors.
Wycheproof vectors provide X509-encoded public keys.
- Parameters:
- Returns:
A dictionary of results.
- Return type:
Changed in version TODO(version): Returns
ResultsDict
instead ofResults
or None.Deprecated since version TODO(version): The test vectors have been updated and the
ECDH
protocol is now deprecated. Usetest_exchange_x509()
andExchangeX509
instead.
Parameters¶
- enum crypto_condor.primitives.ECDH.Curve(value)¶
Elliptic curves supported for ECDH.
- Member Type:
str
Valid values are as follows:
- P192 = <Curve.P192: 'P-192'>¶
- P224 = <Curve.P224: 'P-224'>¶
- P256 = <Curve.P256: 'P-256'>¶
- P384 = <Curve.P384: 'P-384'>¶
- P521 = <Curve.P521: 'P-521'>¶
- K163 = <Curve.K163: 'K-163'>¶
- K233 = <Curve.K233: 'K-233'>¶
- K283 = <Curve.K283: 'K-283'>¶
- K409 = <Curve.K409: 'K-409'>¶
- K571 = <Curve.K571: 'K-571'>¶
- B163 = <Curve.B163: 'B-163'>¶
- B233 = <Curve.B233: 'B-233'>¶
- B283 = <Curve.B283: 'B-283'>¶
- B409 = <Curve.B409: 'B-409'>¶
- B571 = <Curve.B571: 'B-571'>¶
- BRAINPOOLP224R1 = <Curve.BRAINPOOLP224R1: 'brainpoolP224r1'>¶
- BRAINPOOLP256R1 = <Curve.BRAINPOOLP256R1: 'brainpoolP256r1'>¶
- BRAINPOOLP320R1 = <Curve.BRAINPOOLP320R1: 'brainpoolP320r1'>¶
- BRAINPOOLP384R1 = <Curve.BRAINPOOLP384R1: 'brainpoolP384r1'>¶
- BRAINPOOLP512R1 = <Curve.BRAINPOOLP512R1: 'brainpoolP512r1'>¶
- SECP256K1 = <Curve.SECP256K1: 'secp256k1'>¶
The
Enum
and its members also have the following methods:- classmethod from_name(name)¶
Gets Curve instance from the name of the curve.
Intended to be used by the wrappers, as hyphens are not allowed in function names, so for example P256 is the P-256 curve.
- get_ec_name()¶
Gets the curve name for cryptography’s
ec
module.This method is intended for test vectors that provide the public key as coordinates, and thus require converting them to a public key or encoded point.
- Returns:
The curve name.
- Return type:
str
Protocols¶
- protocol crypto_condor.primitives.ECDH.ExchangePoint¶
Represents a function that performs ECDH using an uncompresed point.
The function must behave live
__call__()
to be tested withtest_exchange_point()
.Classes that implement this protocol must have the following methods / attributes:
- __call__(secret, pub_point)¶
Performs ECDH key exchange using the peer’s uncompresed point.
- Parameters:
secret (bytes) – Party A’s secret value.
pub_point (bytes) – Party B’s public key as an uncompressed point.
- Returns:
The shared secret.
- Return type:
bytes
- protocol crypto_condor.primitives.ECDH.ExchangeX509¶
Represents a function that performs ECDH using public coordinates.
The function must behave live
__call__()
to be tested withtest_exchange_x509()
.Classes that implement this protocol must have the following methods / attributes:
- __call__(secret, pub_key)¶
Performs ECDH key exchange using the peer’s X509 public key.
- Parameters:
secret (bytes) – Party A’s secret value.
pub_key (bytes) – Party B’s public X509 key.
- Returns:
The shared secret.
- Return type:
bytes
- protocol crypto_condor.primitives.ECDH.ECDH¶
Class that implements ECDH.
Implementations use one party’s private value and the other’s public key to perform their half of the key exchange.
There are two methods to implement which depend on the test vectors used:
exchange_nist()
uses NIST vectors which provide the public key by its coordinates, while the Wycheproof vectors used byexchange_wycheproof()
provide them encoded with X509.For compliance, use
exchange_nist()
.Deprecated since version TODO(version): The test vectors have been changed so the protocols have been updated to match.
ECDH
is replaced byExchangePoint
andExchangeX509
.Classes that implement this protocol must have the following methods / attributes:
- exchange_nist(secret, pub_x, pub_y, pub_key)¶
ECDH exchange with NIST vectors.
NIST vectors provide the public key as point coordinates. In case an implementation does not deal with coordinates, but at least can deal with an SEC1-encoded point (subset of X9.62), crypto-condor constructs and provided this encoded point. However, we recommend using the coordinates whenever possible.
- Parameters:
secret (int) – Party A’s secret value.
pub_x (int) – The x-coordinate of party B’s public key.
pub_y (int) – The y-coordinate of party B’s public key.
pub_key (bytes) – The public key as a SEC1-encoded point. It does not provide information on the curve used. Constructed by crypto-condor from the coordinates.
- Returns:
The shared key.
- Return type:
bytes
- exchange_wycheproof(secret, pub_key)¶
ECDH exchange with Wycheproof vectors.
Wycheproof vectors provide the public key encoded with X509. This encoding includes information about the curve, along with the coordinates.
- Parameters:
secret (int) – Party A’s secret value.
pub_key (bytes) – Party B’s public key, encoded with X509.
- Returns:
The shared key.
- Return type:
bytes
Run a wrapper¶
- crypto_condor.primitives.ECDH.test_wrapper(wrapper, compliance, resilience)¶
Runs a ECDH wrapper.
- Parameters:
wrapper (Path) – The wrapper to test.
compliance (bool) – Whether to use NIST vectors.
resilience (bool) – Whether to use Wycheproof vectors.
- Returns:
The results of
test_exchange_point()
andtest_exchange_x509()
in a single dictionary.- Raises:
FileNotFoundError – If the wrapper could not be found.
ModuleNotFoundError – If the wrapper could not be loaded.
- Return type:
- crypto_condor.primitives.ECDH.test_wrapper_python(wrapper, compliance, resilience)¶
Runs a Python wrapper of ECDH.
- Parameters:
wrapper (Path) – The wrapper to test. The path must be valid.
compliance (bool) – Whether to use compliance test vectors.
resilience (bool) – Whether to use resilience test vectors.
- Returns:
The results of
test_exchange_point()
andtest_exchange_x509()
in a single dictionary.- Raises:
ModuleNotFoundError – If the wrapper could not be loaded.
- Return type:
Internal vectors¶
The following section describes the internal test vectors classes, which are protobuf Python classes.
Hint
The autodoc extension can’t properly document these clases so we include the
.proto
file to show the different fields each class has. IDEs should be able to
use the included .pyi
files to provide auto-completion and type checking.
syntax = "proto3";
package crypto_condor;
// A single ECDH test.
//
// A test for a single key exchange with the private key derived from the private value
// ``d`` and the public key. The public key can be either a X.509 SubjectPublicKeyInfo
// or the uncompressed coordinates of the point.
//
// The ``ss`` and ``d`` fields are required. One of ``peer_point`` and ``peer_x509`` are
// also required.
message EcdhTest {
// The test ID, unique in its set of vectors.
int32 id = 1;
// The type of test. One of: valid, invalid, acceptable.
string type = 2;
// A comment on the test.
string comment = 3;
// Flags that categorize this test.
repeated string flags = 4;
// The resulting shared secret.
bytes ss = 5;
// The private value of party A.
bytes d = 6;
oneof oneof_pk {
// The peer's public key point.
bytes peer_point = 7;
// The peer's public X509 key.
bytes peer_x509 = 8;
}
}
// A set of ECDH test vectors.
//
// It is categorized by its `curve` and `public_type` fields.
message EcdhVectors {
// The source of the test vectors.
string source = 1;
// Description of the source.
string source_desc = 2;
// The URL of the source.
string source_url = 3;
// Whether these are compliance test vectors or not.
bool compliance = 4;
// A dictionary of test flags and their description.
map<string, string> notes = 5;
// The test vectors.
repeated EcdhTest tests = 6;
// The elliptic curve used for these vectors.
string curve = 7;
// The type of public key available. One of: "x509", "point".
string public_type = 8;
}