dcrypt_algorithms/ec/k256/
mod.rs1mod constants;
12mod field;
13mod point;
14mod scalar;
15
16pub use constants::{
17 K256_FIELD_ELEMENT_SIZE, K256_KEM_SHARED_SECRET_KDF_OUTPUT_SIZE, K256_POINT_COMPRESSED_SIZE,
18 K256_POINT_UNCOMPRESSED_SIZE, K256_SCALAR_SIZE,
19};
20pub use field::FieldElement;
21pub use point::{Point, PointFormat};
22pub use scalar::Scalar;
23
24use crate::error::{Error, Result};
25use crate::hash::sha2::Sha256;
26use crate::kdf::hkdf::Hkdf;
27use crate::kdf::KeyDerivationFunction as KdfTrait;
28use rand::{CryptoRng, RngCore};
29
30struct Secp256k1Params {
32 g_x: [u8; 32],
33 g_y: [u8; 32],
34}
35
36const SECP256K1: Secp256k1Params = Secp256k1Params {
37 g_x: [
38 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, 0xCE, 0x87, 0x0B,
39 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8,
40 0x17, 0x98,
41 ],
42 g_y: [
43 0x48, 0x3A, 0xDA, 0x77, 0x26, 0xA3, 0xC4, 0x65, 0x5D, 0xA4, 0xFB, 0xFC, 0x0E, 0x11, 0x08,
44 0xA8, 0xFD, 0x17, 0xB4, 0x48, 0xA6, 0x85, 0x54, 0x19, 0x9C, 0x47, 0xD0, 0x8F, 0xFB, 0x10,
45 0xD4, 0xB8,
46 ],
47};
48
49pub fn base_point_g() -> Point {
51 Point::new_uncompressed(&SECP256K1.g_x, &SECP256K1.g_y)
52 .expect("Standard base point must be valid")
53}
54
55pub fn scalar_mult_base_g(scalar: &Scalar) -> Result<Point> {
57 let g = base_point_g();
58 g.mul(scalar)
59}
60
61pub fn generate_keypair<R: CryptoRng + RngCore>(rng: &mut R) -> Result<(Scalar, Point)> {
63 let mut scalar_bytes = [0u8; K256_SCALAR_SIZE];
64 loop {
65 rng.fill_bytes(&mut scalar_bytes);
66 match Scalar::new(scalar_bytes) {
67 Ok(private_key) => {
68 let public_key = scalar_mult_base_g(&private_key)?;
69 return Ok((private_key, public_key));
70 }
71 Err(_) => continue,
72 }
73 }
74}
75
76pub fn scalar_mult(scalar: &Scalar, point: &Point) -> Result<Point> {
78 if point.is_identity() {
79 return Ok(Point::identity());
80 }
81 point.mul(scalar)
82}
83
84pub fn kdf_hkdf_sha256_for_ecdh_kem(
86 ikm: &[u8],
87 info: Option<&[u8]>,
88) -> Result<[u8; K256_KEM_SHARED_SECRET_KDF_OUTPUT_SIZE]> {
89 let hkdf_instance = <Hkdf<Sha256, 16> as KdfTrait>::new();
90
91 let derived_key_vec =
92 hkdf_instance.derive_key(ikm, None, info, K256_KEM_SHARED_SECRET_KDF_OUTPUT_SIZE)?;
93
94 let mut output_array = [0u8; K256_KEM_SHARED_SECRET_KDF_OUTPUT_SIZE];
95 if derived_key_vec.len() == K256_KEM_SHARED_SECRET_KDF_OUTPUT_SIZE {
96 output_array.copy_from_slice(&derived_key_vec);
97 Ok(output_array)
98 } else {
99 Err(Error::Length {
100 context: "KDF output for ECDH K256",
101 expected: K256_KEM_SHARED_SECRET_KDF_OUTPUT_SIZE,
102 actual: derived_key_vec.len(),
103 })
104 }
105}
106
107#[cfg(test)]
108mod tests;