Skip to main content

ergo_lib_c_core/
secret_key.rs

1//! Secret key
2use ergo_lib::ergotree_interpreter::sigma_protocol::private_input::DlogProverInput;
3use ergo_lib::wallet;
4use std::convert::TryInto;
5
6use crate::address::{Address, AddressPtr};
7use crate::util::{const_ptr_as_ref, mut_ptr_as_mut};
8use crate::Error;
9
10/// Secret key for the prover
11#[derive(PartialEq, Eq, Debug, Clone)]
12pub struct SecretKey(pub(crate) wallet::secret_key::SecretKey);
13pub type SecretKeyPtr = *mut SecretKey;
14pub type ConstSecretKeyPtr = *const SecretKey;
15
16/// Parse dlog secret key from bytes (SEC-1-encoded scalar)
17pub unsafe fn secret_key_from_bytes(
18    bytes_ptr: *const u8,
19    secret_key_out: *mut SecretKeyPtr,
20) -> Result<(), Error> {
21    if bytes_ptr.is_null() {
22        return Err(Error::Misc("bytes_ptr is null".into()));
23    }
24    let bytes = std::slice::from_raw_parts(bytes_ptr, DlogProverInput::SIZE_BYTES);
25    let sized_bytes: &[u8; DlogProverInput::SIZE_BYTES] = bytes.try_into()?;
26    if let Some(k) = wallet::secret_key::SecretKey::dlog_from_bytes(sized_bytes).map(SecretKey) {
27        *secret_key_out = Box::into_raw(Box::new(k));
28        Ok(())
29    } else {
30        Err(Error::Misc("failed to parse scalar".into()))
31    }
32}
33
34/// Generate random key
35pub unsafe fn secret_key_generate_random(secret_key_out: *mut SecretKeyPtr) -> Result<(), Error> {
36    *secret_key_out = Box::into_raw(Box::new(SecretKey(
37        wallet::secret_key::SecretKey::random_dlog(),
38    )));
39    Ok(())
40}
41
42/// Address (encoded public image)
43pub unsafe fn secret_key_get_address(
44    secret_key_ptr: ConstSecretKeyPtr,
45    address_out: *mut AddressPtr,
46) -> Result<(), Error> {
47    let secret_key = const_ptr_as_ref(secret_key_ptr, "secret_key_ptr")?;
48    let address_out = mut_ptr_as_mut(address_out, "address_out")?;
49    *address_out = Box::into_raw(Box::new(Address(
50        secret_key.0.get_address_from_public_image(),
51    )));
52    Ok(())
53}
54
55/// Convert to serialized bytes. Key assumption: 32 bytes have been allocated at the address
56/// pointed-to by `output`.
57pub unsafe fn secret_key_to_bytes(
58    secret_key_ptr: ConstSecretKeyPtr,
59    output: *mut u8,
60) -> Result<(), Error> {
61    let secret_key = const_ptr_as_ref(secret_key_ptr, "secret_key_ptr")?;
62    let src = secret_key.0.to_bytes();
63    std::ptr::copy_nonoverlapping(src.as_ptr(), output, DlogProverInput::SIZE_BYTES);
64    Ok(())
65}