EcPoint to recovery y coordinate from x in Rust using openssl - Stack Overflow

admin2025-04-16  5

i have public key when i do extract the y coordinate is missing , so i need to recovery / uncompressed it using x coordinate

this is how i extract it

use openssl::bn::{BigNum, BigNumContext};
use openssl::ec::{EcGroup, EcKey, EcPoint};
use openssl::nid::Nid;

fn extract_public_key_from_cose(
        &self,
        cose_key_value: ciborium::value::Value,
    ) -> Option<Vec<u8>> {
        if let ciborium::value::Value::Map(cose_key_map) = cose_key_value.clone() {
            let mut x = None;
            let mut y = None;
            let mut x_bytes = None;

            for (key, value) in cose_key_map {
                log_custom(
                    LogLevelCustom::Info,
                    format!("Key: {:?}, Value: {:?}", key, value),
                );

                if let ciborium::value::Value::Integer(param) = key {
                    if param == ciborium::value::Integer::from(-2) {
                        if let ciborium::value::Value::Bytes(bytes) = value {
                            x = Some(bytes.clone());
                            x_bytes = Some(bytes);
                        }
                    } else if param == ciborium::value::Integer::from(-3) {
                        if let ciborium::value::Value::Bytes(bytes) = value {
                            y = Some(bytes);
                        }
                    }
                }
            }

            log_custom(
                LogLevelCustom::Info,
                format!("Extracted x: {:?}, y: {:?}", x, y),
            );

            if let Some(x) = x {
                let group = EcGroup::from_curve_name(openssl::nid::Nid::X9_62_PRIME256V1).ok()?;
                let x_bn = openssl::bn::BigNum::from_slice(&x).ok()?;

                // If y is None, attempt decompression
                let y_bn = if let Some(y_bytes) = y {
                    openssl::bn::BigNum::from_slice(&y_bytes).ok()?
                } else if let Some(x_bytes) = x_bytes {

                    // Decompress the key
                    let mut compressed_point = vec![0x04]; // Uncompressed point prefix
                    compressed_point.extend_from_slice(&x_bytes);
                    let mut bn_ctx = openssl::bn::BigNumContext::new().ok()?;
                    let ec_point = EcPoint::from_bytes(&group, &compressed_point, &mut bn_ctx).ok()?;
                    let mut y_bn = openssl::bn::BigNum::new().ok()?;
                    let mut x_bn = openssl::bn::BigNum::new().ok()?;
                    ec_point.affine_coordinates_gfp(&group, &mut x_bn, &mut y_bn, &mut bn_ctx).ok()?;
                    y_bn
                } else {
                    return None;
                };

                let ec_key =
                    EcKey::from_public_key_affine_coordinates(&group, &x_bn, &y_bn).ok()?;
                let pkey = openssl::pkey::PKey::from_ec_key(ec_key).ok()?;
                let der_key = pkey.public_key_to_der().ok()?;
                return Some(der_key);
            }
        }

        log_custom(
            LogLevelCustom::Error,
            format!(
                "Failed to extract public key from COSE key value: {:?}",
                cose_key_value
            ),
        );

        None
    }

i got stack error like this

elliptic curve routien, EC_POINT_set_affine_coordinate point is notion curve

i am new for this and has been stuck for few dayys,

is that any correctly to recover the Y coordinate missing in public key for openssl rust ??

thanks

转载请注明原文地址:http://www.anycun.com/QandA/1744769560a87368.html