Skip to main content

dlccryptlib_py/
lib.rs

1use dlccryptlib;
2
3use pyo3::prelude::*;
4use pyo3::exceptions::PyException;
5use pyo3::wrap_pyfunction;
6
7
8// ##### Facade functions for easy Python invocations (pyo3/maturin)
9
10/// Initialize the library, load secret from encrypted file. Return the XPUB.
11#[pyfunction]
12pub fn init(path_for_secret_file: String, encryption_password: String) -> PyResult<String> {
13    dlccryptlib::init(&path_for_secret_file, &encryption_password, false)
14        .map_err(|e| PyErr::new::<PyException, _>(e))
15}
16
17#[pyfunction]
18pub fn reinit_for_testing(
19    path_for_secret_file: String,
20    encryption_password: String,
21) -> PyResult<String> {
22    dlccryptlib::init(&path_for_secret_file, &encryption_password, true)
23        .map_err(|e| PyErr::new::<PyException, _>(e))
24}
25
26/// network: "bitcoin", or "signet".
27// #[cfg(test)]
28#[pyfunction]
29pub fn init_with_entropy(entropy: String, network: String) -> PyResult<String> {
30    dlccryptlib::init_with_entropy(&entropy, &network).map_err(|e| PyErr::new::<PyException, _>(e))
31}
32
33/// Return the XPUB
34#[pyfunction]
35pub fn get_xpub() -> PyResult<String> {
36    dlccryptlib::get_xpub().map_err(|e| PyErr::new::<PyException, _>(e))
37}
38
39/// Return a child public key (specified by its index).
40#[pyfunction]
41pub fn get_public_key(index4: u32, index5: u32) -> PyResult<String> {
42    dlccryptlib::get_public_key(index4, index5).map_err(|e| PyErr::new::<PyException, _>(e))
43}
44
45/// Return a child address (specified by index).
46#[pyfunction]
47pub fn get_address(index4: u32, index5: u32) -> PyResult<String> {
48    dlccryptlib::get_address(index4, index5).map_err(|e| PyErr::new::<PyException, _>(e))
49}
50
51/// Verify a child public key.
52#[pyfunction]
53pub fn verify_public_key(index4: u32, index5: u32, pubkey: String) -> PyResult<bool> {
54    dlccryptlib::verify_public_key(index4, index5, &pubkey).map_err(|e| PyErr::new::<PyException, _>(e))
55}
56
57/// Sign a hash with a child private key (specified by index).
58#[pyfunction]
59pub fn sign_hash_ecdsa(hash: String, signer_index4: u32, signer_index5: u32, signer_pubkey: String) -> PyResult<String> {
60    dlccryptlib::sign_hash_ecdsa(&hash, signer_index4, signer_index5, &signer_pubkey)
61        .map_err(|e| PyErr::new::<PyException, _>(e))
62}
63
64/// Create a nonce value deterministically
65#[pyfunction]
66pub fn create_deterministic_nonce(
67    event_id: String,
68    nonce_index: u32,
69) -> PyResult<(String, String)> {
70    dlccryptlib::create_deterministic_nonce(&event_id, nonce_index)
71        .map_err(|e| PyErr::new::<PyException, _>(e))
72}
73
74/// Sign a message using Schnorr, with a nonce, using a child key
75#[pyfunction]
76pub fn sign_schnorr_with_nonce(msg: String, nonce_sec_hex: String, index4: u32, index5: u32) -> PyResult<String> {
77    dlccryptlib::sign_schnorr_with_nonce(&msg, &nonce_sec_hex, index4, index5)
78        .map_err(|e| PyErr::new::<PyException, _>(e))
79}
80
81/// Verify a Schnorr signature over a message, using a child key
82#[pyfunction]
83pub fn verify_schnorr(msg: String, signature_hex: String, index4: u32, index5: u32) -> PyResult<bool> {
84    dlccryptlib::verify_schnorr(&msg, &signature_hex, index4, index5)
85        .map_err(|e| PyErr::new::<PyException, _>(e))
86}
87
88/// Combine a number of public keys into one
89#[pyfunction]
90pub fn combine_pubkeys(keys_hex: String) -> PyResult<String> {
91    dlccryptlib::combine_pubkeys(&keys_hex).map_err(|e| PyErr::new::<PyException, _>(e))
92}
93
94/// Combine a number of secret keys into one.
95/// Warning: Handle secret keys with caution!
96#[pyfunction]
97pub fn combine_seckeys(keys_hex: String) -> PyResult<String> {
98    dlccryptlib::combine_seckeys(&keys_hex).map_err(|e| PyErr::new::<PyException, _>(e))
99}
100
101/// Create adaptor signatures for a number of CETs
102#[pyfunction]
103pub fn create_cet_adaptor_sigs(
104    num_digits: u8,
105    num_cets: u64,
106    digit_string_template: String,
107    oracle_pubkey: String,
108    signing_key_index4: u32,
109    signing_key_index5: u32,
110    signing_pubkey: String,
111    nonces: String,
112    interval_wildcards: String,
113    sighashes: String,
114) -> PyResult<String> {
115    dlccryptlib::create_cet_adaptor_sigs(
116        num_digits,
117        num_cets,
118        &digit_string_template,
119        &oracle_pubkey,
120        signing_key_index4,
121        signing_key_index5,
122        &signing_pubkey,
123        &nonces,
124        &interval_wildcards,
125        &sighashes,
126    )
127    .map_err(|e| PyErr::new::<PyException, _>(e))
128}
129
130/// Verify adaptor signatures for a number of CETs
131#[pyfunction]
132pub fn verify_cet_adaptor_sigs(
133    num_digits: u8,
134    num_cets: u64,
135    digit_string_template: String,
136    oracle_pubkey: String,
137    signing_pubkey: String,
138    nonces: String,
139    interval_wildcards: String,
140    sighashes: String,
141    signatures: String,
142) -> PyResult<bool> {
143    dlccryptlib::verify_cet_adaptor_sigs(
144        num_digits,
145        num_cets,
146        &digit_string_template,
147        &oracle_pubkey,
148        &signing_pubkey,
149        &nonces,
150        &interval_wildcards,
151        &sighashes,
152        &signatures,
153    )
154    .map_err(|e| PyErr::new::<PyException, _>(e))
155}
156
157/// Perform final signing of a CET
158#[pyfunction]
159pub fn create_final_cet_sigs(
160    signing_key_index4: u32,
161    signing_key_index5: u32,
162    signing_pubkey: String,
163    other_pubkey: String,
164    num_digits: u8,
165    oracle_signatures: String,
166    cet_value_wildcard: String,
167    cet_sighash: String,
168    other_adaptor_signature: String,
169) -> PyResult<String> {
170    dlccryptlib::create_final_cet_sigs(
171        signing_key_index4,
172        signing_key_index5,
173        &signing_pubkey,
174        &other_pubkey,
175        num_digits,
176        &oracle_signatures,
177        &cet_value_wildcard,
178        &cet_sighash,
179        &other_adaptor_signature,
180    )
181    .map_err(|e| PyErr::new::<PyException, _>(e))
182}
183
184#[pymodule]
185fn dlccryptlib_py(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
186    m.add_function(wrap_pyfunction!(init, m)?)?;
187    m.add_function(wrap_pyfunction!(reinit_for_testing, m)?)?;
188    m.add_function(wrap_pyfunction!(init_with_entropy, m)?)?;
189    m.add_function(wrap_pyfunction!(get_xpub, m)?)?;
190    m.add_function(wrap_pyfunction!(get_public_key, m)?)?;
191    m.add_function(wrap_pyfunction!(get_address, m)?)?;
192    m.add_function(wrap_pyfunction!(verify_public_key, m)?)?;
193    m.add_function(wrap_pyfunction!(sign_hash_ecdsa, m)?)?;
194    m.add_function(wrap_pyfunction!(create_deterministic_nonce, m)?)?;
195    m.add_function(wrap_pyfunction!(sign_schnorr_with_nonce, m)?)?;
196    m.add_function(wrap_pyfunction!(verify_schnorr, m)?)?;
197    m.add_function(wrap_pyfunction!(combine_pubkeys, m)?)?;
198    m.add_function(wrap_pyfunction!(combine_seckeys, m)?)?;
199    m.add_function(wrap_pyfunction!(create_cet_adaptor_sigs, m)?)?;
200    m.add_function(wrap_pyfunction!(verify_cet_adaptor_sigs, m)?)?;
201    m.add_function(wrap_pyfunction!(create_final_cet_sigs, m)?)?;
202    Ok(())
203}
204