verity_ic/crypto/
ecdsa.rs

1#![allow(dead_code)]
2
3use candid::{CandidType, Principal};
4use serde::{Deserialize, Serialize};
5
6use super::config::Config;
7
8// Structure to hold public key reply data
9#[derive(CandidType, Serialize, Debug)]
10pub struct PublicKeyReply {
11    pub sec1_pk: String,    // SEC1 formatted public key
12    pub etherum_pk: String, // Ethereum formatted public key
13}
14
15// Structure to hold signature reply data
16#[derive(CandidType, Serialize, Debug)]
17pub struct SignatureReply {
18    pub signature_hex: String, // Signature in hexadecimal format
19}
20
21// Structure to hold signature verification reply data
22#[derive(CandidType, Serialize, Debug)]
23pub struct SignatureVerificationReply {
24    pub is_signature_valid: bool, // Boolean indicating if the signature is valid
25}
26
27// Type alias for CanisterId using Principal
28type CanisterId = Principal;
29
30// Structure to request an ECDSA public key
31#[derive(CandidType, Serialize, Debug)]
32pub struct ECDSAPublicKey {
33    pub canister_id: Option<CanisterId>, // Optional canister ID
34    pub derivation_path: Vec<Vec<u8>>,   // Derivation path for key generation
35    pub key_id: EcdsaKeyId,              // Identifier for the ECDSA key
36}
37
38// Structure to hold the reply for an ECDSA public key request
39#[derive(CandidType, Deserialize, Debug)]
40pub struct ECDSAPublicKeyReply {
41    pub public_key: Vec<u8>, // The derived public key
42    pub chain_code: Vec<u8>, // Chain code associated with the key
43}
44
45// Structure to request signing with ECDSA
46#[derive(CandidType, Serialize, Debug)]
47pub struct SignWithECDSA {
48    pub message_hash: Vec<u8>,         // Hash of the message to be signed
49    pub derivation_path: Vec<Vec<u8>>, // Derivation path for key generation
50    pub key_id: EcdsaKeyId,            // Identifier for the ECDSA key
51}
52
53// Structure to hold the reply for an ECDSA signing request
54#[derive(CandidType, Deserialize, Debug)]
55pub struct SignWithECDSAReply {
56    pub signature: Vec<u8>, // The generated signature
57}
58
59// Structure to represent an ECDSA key identifier
60#[derive(CandidType, Serialize, Debug, Clone)]
61pub struct EcdsaKeyId {
62    pub curve: EcdsaCurve, // The curve used for the key
63    pub name: String,      // Name of the key
64}
65
66// Enumeration of supported ECDSA curves
67#[derive(CandidType, Serialize, Debug, Clone)]
68pub enum EcdsaCurve {
69    #[serde(rename = "secp256k1")]
70    Secp256k1, // The secp256k1 curve
71}
72
73// Enumeration of ECDSA key identifiers
74#[derive(CandidType, Deserialize, Debug, Clone)]
75pub enum EcdsaKeyIds {
76    #[allow(unused)]
77    TestKeyLocalDevelopment, // Key for local development
78    #[allow(unused)]
79    TestKey1, // Test key 1
80    #[allow(unused)]
81    ProductionKey1, // Production key 1
82}
83
84// Implementation of methods for EcdsaKeyIds
85impl EcdsaKeyIds {
86    // Convert EcdsaKeyIds to EcdsaKeyId
87    pub fn to_key_id(&self) -> EcdsaKeyId {
88        EcdsaKeyId {
89            curve: EcdsaCurve::Secp256k1, // Use secp256k1 curve
90            name: (match self {
91                Self::TestKeyLocalDevelopment => "dfx_test_key",
92                Self::TestKey1 => "test_key_1",
93                Self::ProductionKey1 => "key_1",
94            })
95            .to_string(),
96        }
97    }
98}
99
100// Asynchronous function to derive a public key
101pub async fn derive_pk(config: &Config) -> Vec<u8> {
102    // Create a request for the ECDSA public key
103    let request = ECDSAPublicKey {
104        canister_id: None,              // No specific canister ID
105        derivation_path: vec![],        // Empty derivation path
106        key_id: config.key.to_key_id(), // Convert config key to EcdsaKeyId
107    };
108
109    // Call the management canister to get the ECDSA public key
110    let (res,): (ECDSAPublicKeyReply,) = ic_cdk::call(
111        Principal::management_canister(),
112        "ecdsa_public_key",
113        (request,),
114    )
115    .await
116    .map_err(|e| format!("ECDSA_PUBLIC_KEY_FAILED: {}\t,Error_code:{:?}", e.1, e.0))
117    .unwrap();
118
119    // Return the derived public key
120    res.public_key
121}