-1

I have written the Python version of the conversion method, but the Rust version I don't know how to write,

Rust cannot be written using the openssl package,

I query the data and it seems to be available k256="0.13.1" der = "0.7.5" replace

Currently known public keys are of Vec type I don't know how to convert the public key from SEC1 encoding to ASN.1 DER encoding

Below is part of the code I implemented

use der::{Encoder, Length};
use k256::elliptic_curve::sec1::{ToEncodedPoint, FromEncodedPoint};
use k256::{PublicKey, EncodedPoint};
use der::asn1::{BitString, ObjectIdentifier};

fn sec1_to_der(sec1_key: &[u8]) -> Result<Vec<u8>, der::Error> {
    // Load the SEC1-encoded ECDSA public key as the public key object
    let public_key = PublicKey::from_sec1_bytes(sec1_key).expect("error");

    // Define the OID for secp256k1 (1.3.132.0.10)
    let secp256k1_oid: ObjectIdentifier = k256::pkcs8::ObjectIdentifier::new("1.3.132.0.10");

    // TODO: How to serialize SEC1-encoded ECDSA to ASN.1 DER format here

}

fn main() {
    let der_encoded_public_key:Vec<u8> = vec![3, 89, 191, 147, 51, 6, 188, 19, 231, 106, 80, 5, 56, 106, 114, 19, 115, 17, 94, 22, 217, 162, 205, 241, 154, 223, 129, 72, 143, 27, 102, 251, 246];;
    let der_key = sec1_to_der(&der_encoded_public_key);
    match der_key {
        Ok(der_key) => {
            println!("{:?}", der_key);
        }
        Err(e) => {
            println!("{:?}", e);
        }
    }
}

Edit: Expected result (see comment):

[48, 86, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 10, 3, 66, 0, 4, 89, 191, 147, 51, 6, 188, 19, 231, 106, 80, 5, 56, 106, 114, 19, 115, 17, 94, 22, 217, 162, 205, 241, 154, 223, 129, 72, 143, 27, 102, 251, 246, 250, 38, 107, 239, 240, 74, 233, 61, 164, 22, 115, 130, 240, 115, 219, 245, 176, 223, 219, 226, 248, 174, 2, 113, 126, 158, 15, 175, 50, 83, 25, 191]
Topaco
  • 40,594
  • 4
  • 35
  • 62
hewm
  • 5
  • 5

2 Answers2

0

In your code, use der::{Encoder..., Encoder doesn't exist on the der crate. You can convert the public key from SEC1 encoding to ASN.1 DER encoding:

main.rs file:

use num_bigint::{BigUint, BigInt, Sign};
use simple_asn1::{to_der, ASN1Block};

fn main() {
    let sec1: Vec<u8> = vec![
        3, 89, 191, 147, 51, 6, 188, 19, 231, 106, 80, 5, 56, 106, 114, 19, 115, 17, 94, 22, 217,
        162, 205, 241, 154, 223, 129, 72, 143, 27, 102, 251,
    ];
    let x = &sec1[..32];
    let y = &sec1[32..];
    let x_val = BigUint::from_bytes_be(x);
    let y_val = BigUint::from_bytes_be(y);
    let x_bigint = BigInt::from_biguint(Sign::Plus, x_val);
    let y_bigint = BigInt::from_biguint(Sign::Plus, y_val);
    let der = to_der(&ASN1Block::Sequence(
        0,
        vec![
            ASN1Block::Integer(0, x_bigint),
            ASN1Block::Integer(0, y_bigint),
        ],
    ))
        .unwrap();
    println!("{:?}", der);
}

The output of which is:

Finished dev [unoptimized + debuginfo] target(s) in 7.25s
     Running `target/debug/soTesting2`
[48, 37, 2, 32, 3, 89, 191, 147, 51, 6, 188, 19, 231, 106, 80, 5, 56, 106, 114, 19, 115, 17, 94, 22, 217, 162, 205, 241, 154, 223, 129, 72, 143, 27, 102, 251, 2, 1, 0]

Cargo.toml file:

[package]
name = "soTesting2"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
num-bigint = "0.4"
simple_asn1 = "0.5"
Jishan Shaikh
  • 1,572
  • 2
  • 13
  • 31
  • I use the Python program to verify The output should be [48, 86, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 10, 3, 66, 0, 4, 89, 191, 147, 51, 6, 188, 19, 231, 106, 80, 5, 56, 106, 114, 19, 115, 17, 94, 22, 217, 162, 205, 241, 154, 223, 129, 72, 143, 27, 102, 251, 246, 250, 38, 107, 239, 240, 74, 233, 61, 164, 22, 115, 130, 240, 115, 219, 245, 176, 223, 219, 226, 248, 174, 2, 113, 126, 158, 15, 175, 50, 83, 25, 191] length is 88 bits – hewm May 05 '23 at 09:34
0

The posted example key is a compressed public key that is to be exported as ASN.1/DER encoded public key in X.509/SPKI format.
The import is possible with k256::PublicKey::from_sec1_bytes() (as already known), the export with k256::pkcs8::EncodePublicKey::to_public_key_der().
Note that it is not necessary to specify the curve (or an OID) because crate k256 is explicit for curve secp256k1.

Sample implementation:

use k256;

fn main() {
    let public_key_compressed:Vec<u8> = vec![3, 89, 191, 147, 51, 6, 188, 19, 231, 106, 80, 5, 56, 106, 114, 19, 115, 17, 94, 22, 217, 162, 205, 241, 154, 223, 129, 72, 143, 27, 102, 251, 246];    
    let public_key = k256::PublicKey::from_sec1_bytes(&public_key_compressed).expect("import error");
    let public_key_der = k256::pkcs8::EncodePublicKey::to_public_key_der(&public_key).expect("export error");
    println!("{:?}", public_key_der.to_vec()); // [48, 86, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0, 10, 3, 66, 0, 4, 89, 191, 147, 51, 6, 188, 19, 231, 106, 80, 5, 56, 106, 114, 19, 115, 17, 94, 22, 217, 162, 205, 241, 154, 223, 129, 72, 143, 27, 102, 251, 246, 250, 38, 107, 239, 240, 74, 233, 61, 164, 22, 115, 130, 240, 115, 219, 245, 176, 223, 219, 226, 248, 174, 2, 113, 126, 158, 15, 175, 50, 83, 25, 191]
}
Topaco
  • 40,594
  • 4
  • 35
  • 62