openzeppelin_relayer/utils/
der.rs

1//! DER (Distinguished Encoding Rules) operations for cryptographic keys.
2//!
3//! This module provides utilities for parsing and extracting information from
4//! DER-encoded cryptographic keys, particularly for ECDSA operations.
5
6use k256::pkcs8::DecodePublicKey;
7
8#[derive(Debug, thiserror::Error)]
9pub enum DerError {
10    #[error("Parse Error: {0}")]
11    ParseError(String),
12}
13
14/// Extract raw 64-byte key from DER encoded key.
15pub fn extract_public_key_from_der(der: &[u8]) -> Result<[u8; 64], DerError> {
16    let pk = k256::ecdsa::VerifyingKey::from_public_key_der(der)
17        .map_err(|e| DerError::ParseError(format!("ASN.1 parse error: {e}")))?
18        .to_encoded_point(false)
19        .as_bytes()
20        .to_vec();
21    let pub_key_no_prefix = &pk[1..];
22
23    let mut array = [0u8; 64];
24    array.copy_from_slice(pub_key_no_prefix);
25
26    Ok(array)
27}
28
29#[cfg(test)]
30mod tests {
31    use super::*;
32
33    const VALID_SECP256K1_PEM: &str = "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEjJaJh5wfZwvj8b3bQ4GYikqDTLXWUjMh\nkFs9lGj2N9B17zo37p4PSy99rDio0QHLadpso0rtTJDSISRW9MdOqA==\n-----END PUBLIC KEY-----\n"; // noboost
34
35    #[test]
36    fn test_extract_public_key_from_der_with_invalid_data() {
37        let invalid_der = &[1, 2, 3];
38        let result = extract_public_key_from_der(invalid_der);
39        assert!(result.is_err());
40
41        assert!(matches!(result, Err(DerError::ParseError(_))));
42    }
43
44    #[test]
45    fn test_extract_public_key_from_der_with_valid_secp256k1() {
46        let pem = pem::parse(VALID_SECP256K1_PEM).unwrap();
47        let der = pem.contents();
48        let result = extract_public_key_from_der(der);
49
50        assert!(result.is_ok());
51        let public_key = result.unwrap();
52
53        // Verify the public key is 64 bytes
54        assert_eq!(public_key.len(), 64);
55
56        // Verify the expected public key value
57        assert_eq!(
58            format!("0x{}", hex::encode(public_key)),
59            "0x8c9689879c1f670be3f1bddb4381988a4a834cb5d6523321905b3d9468f637d075ef3a37ee9e0f4b2f7dac38a8d101cb69da6ca34aed4c90d2212456f4c74ea8"
60        );
61    }
62}