rust: move secp256k1 funcs from keystore.rs to secp256k1.rs
What changed, and why it matters
This commit is a simple code reorganization: it moves functions that perform secp256k1 cryptographic signing from a file named keystore.rs into a file named secp256k1.rs. The actual behavior of the code, including how private keys are used and how signatures are produced, does not change. It is a refactoring, not a security fix or vulnerability.
No security action required. Treat as routine refactoring. Review the subsequent commit mentioned in the message (which will deal with keystore.c functions) for any actual security relevance.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change relocates secp256k1_sign and secp256k1_nonce_commit (and their FFI wrappers _secp256k1_sign/_secp256k1_nonce_commit) from bitbox02-rust/src/keystore.rs and bitbox02/src/keystore.rs into bitbox02-rust/src/secp256k1.rs and bitbox02/src/secp256k1.rs respectively. Call sites in Bitcoin and Ethereum signing modules are updated from keystore::… to crate::secp256k1::… or bitbox02::secp256k1::… The underlying unsafe FFI calls to bitbox02_sys::keystore_secp256k1_sign and bitbox02_sys::keystore_secp256k1_nonce_commit remain identical, as do the SignResult and EC_PUBLIC_KEY_LEN definitions. Tests are moved but unchanged. No logic, input validation, or cryptographic behavior is modified.
Changed components
src/rust/bitbox02-rust/src/keystore.rssrc/rust/bitbox02-rust/src/secp256k1.rssrc/rust/bitbox02/src/keystore.rssrc/rust/bitbox02/src/secp256k1.rssrc/rust/bitbox02-rust/src/hww/api/bitcoin/signmsg.rssrc/rust/bitbox02-rust/src/hww/api/bitcoin/signtx.rssrc/rust/bitbox02-rust/src/hww/api/ethereum/sign.rssrc/rust/bitbox02-rust/src/hww/api/ethereum/sign_typed_msg.rssrc/rust/bitbox02-rust/src/hww/api/ethereum/signmsg.rsInspect captured patch +188 / −174
diff --git a/src/rust/bitbox02-rust/src/hww/api/bitcoin/signmsg.rs b/src/rust/bitbox02-rust/src/hww/api/bitcoin/signmsg.rs
index 370b593..c74183e 100644
--- a/src/rust/bitbox02-rust/src/hww/api/bitcoin/signmsg.rs
+++ b/src/rust/bitbox02-rust/src/hww/api/bitcoin/signmsg.rs
@@ -97,7 +97,7 @@ pub async fn process(
let host_nonce = match request.host_nonce_commitment {
// Engage in the anti-klepto protocol if the host sends a host nonce commitment.
Some(pb::AntiKleptoHostNonceCommitment { ref commitment }) => {
- let signer_commitment = keystore::secp256k1_nonce_commit(
+ let signer_commitment = crate::secp256k1::secp256k1_nonce_commit(
keystore::secp256k1_get_private_key(hal, keypath)?
.as_slice()
.try_into()
@@ -117,7 +117,7 @@ pub async fn process(
None => [0; 32],
};
- let sign_result = keystore::secp256k1_sign(
+ let sign_result = crate::secp256k1::secp256k1_sign(
keystore::secp256k1_get_private_key(hal, keypath)?
.as_slice()
.try_into()
diff --git a/src/rust/bitbox02-rust/src/hww/api/bitcoin/signtx.rs b/src/rust/bitbox02-rust/src/hww/api/bitcoin/signtx.rs
index 78adb11..5170192 100644
--- a/src/rust/bitbox02-rust/src/hww/api/bitcoin/signtx.rs
+++ b/src/rust/bitbox02-rust/src/hww/api/bitcoin/signtx.rs
@@ -1237,7 +1237,7 @@ async fn _process(
// Engage in the Anti-Klepto protocol if the host sends a host nonce commitment.
let host_nonce: [u8; 32] = match tx_input.host_nonce_commitment {
Some(pb::AntiKleptoHostNonceCommitment { ref commitment }) => {
- let signer_commitment = crate::keystore::secp256k1_nonce_commit(
+ let signer_commitment = crate::secp256k1::secp256k1_nonce_commit(
private_key.as_slice().try_into().unwrap(),
&sighash,
commitment
@@ -1261,7 +1261,7 @@ async fn _process(
None => [0; 32],
};
- let sign_result = crate::keystore::secp256k1_sign(
+ let sign_result = crate::secp256k1::secp256k1_sign(
private_key.as_slice().try_into().unwrap(),
&sighash,
&host_nonce,
diff --git a/src/rust/bitbox02-rust/src/hww/api/ethereum/sign.rs b/src/rust/bitbox02-rust/src/hww/api/ethereum/sign.rs
index 38bf3aa..a141cd4 100644
--- a/src/rust/bitbox02-rust/src/hww/api/ethereum/sign.rs
+++ b/src/rust/bitbox02-rust/src/hww/api/ethereum/sign.rs
@@ -388,7 +388,7 @@ pub async fn _process(
let host_nonce = match request.host_nonce_commitment() {
// Engage in the anti-klepto protocol if the host sends a host nonce commitment.
Some(pb::AntiKleptoHostNonceCommitment { commitment }) => {
- let signer_commitment = keystore::secp256k1_nonce_commit(
+ let signer_commitment = crate::secp256k1::secp256k1_nonce_commit(
&keystore::secp256k1_get_private_key(hal, request.keypath())?
.as_slice()
.try_into()
@@ -407,7 +407,7 @@ pub async fn _process(
// Return signature directly without the anti-klepto protocol, for backwards compatibility.
None => [0; 32],
};
- let sign_result = keystore::secp256k1_sign(
+ let sign_result = crate::secp256k1::secp256k1_sign(
&keystore::secp256k1_get_private_key(hal, request.keypath())?
.as_slice()
.try_into()
diff --git a/src/rust/bitbox02-rust/src/hww/api/ethereum/sign_typed_msg.rs b/src/rust/bitbox02-rust/src/hww/api/ethereum/sign_typed_msg.rs
index 54318a9..0671b6e 100644
--- a/src/rust/bitbox02-rust/src/hww/api/ethereum/sign_typed_msg.rs
+++ b/src/rust/bitbox02-rust/src/hww/api/ethereum/sign_typed_msg.rs
@@ -562,7 +562,7 @@ pub async fn process(
let host_nonce = match request.host_nonce_commitment {
Some(pb::AntiKleptoHostNonceCommitment { ref commitment }) => {
- let signer_commitment = keystore::secp256k1_nonce_commit(
+ let signer_commitment = crate::secp256k1::secp256k1_nonce_commit(
keystore::secp256k1_get_private_key(hal, &request.keypath)?
.as_slice()
.try_into()
@@ -581,7 +581,7 @@ pub async fn process(
_ => return Err(Error::InvalidInput),
};
- let sign_result = keystore::secp256k1_sign(
+ let sign_result = crate::secp256k1::secp256k1_sign(
keystore::secp256k1_get_private_key(hal, &request.keypath)?
.as_slice()
.try_into()
diff --git a/src/rust/bitbox02-rust/src/hww/api/ethereum/signmsg.rs b/src/rust/bitbox02-rust/src/hww/api/ethereum/signmsg.rs
index 79b6b07..94682d8 100644
--- a/src/rust/bitbox02-rust/src/hww/api/ethereum/signmsg.rs
+++ b/src/rust/bitbox02-rust/src/hww/api/ethereum/signmsg.rs
@@ -66,7 +66,7 @@ pub async fn process(
let host_nonce = match request.host_nonce_commitment {
// Engage in the anti-klepto protocol if the host sends a host nonce commitment.
Some(pb::AntiKleptoHostNonceCommitment { ref commitment }) => {
- let signer_commitment = keystore::secp256k1_nonce_commit(
+ let signer_commitment = crate::secp256k1::secp256k1_nonce_commit(
keystore::secp256k1_get_private_key(hal, &request.keypath)?
.as_slice()
.try_into()
@@ -86,7 +86,7 @@ pub async fn process(
None => [0; 32],
};
- let sign_result = keystore::secp256k1_sign(
+ let sign_result = crate::secp256k1::secp256k1_sign(
keystore::secp256k1_get_private_key(hal, &request.keypath)?
.as_slice()
.try_into()
diff --git a/src/rust/bitbox02-rust/src/keystore.rs b/src/rust/bitbox02-rust/src/keystore.rs
index 725f09a..ab9affe 100644
--- a/src/rust/bitbox02-rust/src/keystore.rs
+++ b/src/rust/bitbox02-rust/src/keystore.rs
@@ -20,8 +20,6 @@ use alloc::vec::Vec;
use crate::bip32;
use crate::hal::{Memory, Random, SecureChip};
-use bitbox02::keystore;
-pub use bitbox02::keystore::SignResult;
use util::bip32::HARDENED;
use util::cell::SyncCell;
@@ -30,9 +28,6 @@ use crate::secp256k1::SECP256K1;
use bitcoin::hashes::{Hash, HashEngine, Hmac, HmacEngine, sha256, sha512};
-/// Length of a compressed secp256k1 pubkey.
-const EC_PUBLIC_KEY_LEN: usize = 33;
-
/// aes256cbc-hmac cipher adds 16 bytes IV, 16 bytes padding, 32 bytes hmac.
const ENCRYPTION_OVERHEAD: usize = 64;
@@ -682,56 +677,6 @@ pub fn bip85_ln(
/// Sign message with private key using the given private key.
///
-/// Details about `host_nonce`, the host nonce contribution. Instead of using plain rfc6979 to
-/// generate the nonce in this signature, the following formula is used:
-///
-/// r = rfc6979(..., additional_data=Hash_d(host_nonce))
-/// R = r * G (pubkey to secret r)
-/// nonce = r + Hash_p(R, host_nonce)
-/// `Hash_d(msg)` and `Hash_p(msg)` are tagged hashes: `sha256(sha256(tag)||sha256(tag)||msg)`.
-/// Tag for `Hash_d`: "s2c/ecdsa/data".
-/// Tag for `Hash_p`: "s2c/ecdsa/point".
-/// This is part of the ECDSA Anti-Klepto protocol, preventing this function to leak any secrets via
-/// the signatures (see the ecdsa-s2c module in secp256k1-zpk for more details).
-///
-/// # Arguments
-/// * `private_key` - 32 byte private key
-/// * `msg` - 32 byte message to sign
-/// * `host_nonce` - 32 byte nonce contribution. Cannot be NULL.
-/// Intended to be a contribution by the host. If there is none available, use 32 zero bytes.
-///
-/// # Returns
-/// * `Ok(SignResult)` containing signature in compact format and recoverable id on success
-/// * `Err(())` if the keystore is locked
-pub fn secp256k1_sign(
- private_key: &[u8; 32],
- msg: &[u8; 32],
- host_nonce: &[u8; 32],
-) -> Result<SignResult, ()> {
- keystore::_secp256k1_sign(SECP256K1, private_key, msg, host_nonce)
-}
-
-/// Get a commitment to the original nonce before tweaking it with the host nonce. This is part of
-/// the ECDSA Anti-Klepto Protocol. For more details, check the docs of
-/// `secp256k1_ecdsa_anti_exfil_signer_commit`.
-///
-/// # Arguments
-/// * `private_key` - 32 byte private key
-/// * `msg` - 32 byte message which will be signed by `secp256k1_sign`
-/// * `host_commitment` - must be `sha256(sha256(tag)||sha256(tag)||host_nonce)` where
-/// host_nonce is passed to `secp256k1_sign()`. See `secp256k1_ecdsa_anti_exfil_host_commit()`.
-///
-/// # Returns
-/// * `Ok([u8; EC_PUBLIC_KEY_LEN])` - EC_PUBLIC_KEY_LEN bytes compressed signer nonce pubkey on success
-/// * `Err(())` on failure
-pub fn secp256k1_nonce_commit(
- private_key: &[u8; 32],
- msg: &[u8; 32],
- host_commitment: &[u8; 32],
-) -> Result<[u8; EC_PUBLIC_KEY_LEN], ()> {
- keystore::_secp256k1_nonce_commit(SECP256K1, private_key, msg, host_commitment)
-}
-
/// Sign a message using the private key at the keypath, which is optionally tweaked with the given
/// tweak.
pub fn secp256k1_schnorr_sign(
@@ -1858,54 +1803,6 @@ mod tests {
}
}
- #[test]
- fn test_secp256k1_sign() {
- let private_key = hex!("a2d8cf543c60d65162b5a06f0cef9760c883f8aa09f31236859faa85d0b74c7c");
- let msg = [0x88u8; 32];
- let host_nonce = [0x56u8; 32];
-
- let sign_result = secp256k1_sign(&private_key, &msg, &host_nonce).unwrap();
-
- // Verify signature against expected pubkey.
-
- let expected_pubkey = {
- let pubkey = hex!("023ffb4a4e41444d40e4e1e4c6cc329bcba2be50d0ef380aea19d490c373be58fb");
- secp256k1::PublicKey::from_slice(&pubkey).unwrap()
- };
- let msg = secp256k1::Message::from_digest_slice(&msg).unwrap();
- // Test recid by recovering the public key from the signature and checking against the
- // expected public key.
- let recoverable_sig = secp256k1::ecdsa::RecoverableSignature::from_compact(
- &sign_result.signature,
- secp256k1::ecdsa::RecoveryId::from_i32(sign_result.recid as i32).unwrap(),
- )
- .unwrap();
-
- let recovered_pubkey = SECP256K1.recover_ecdsa(&msg, &recoverable_sig).unwrap();
- assert_eq!(recovered_pubkey, expected_pubkey);
-
- // Verify signature.
- assert!(
- SECP256K1
- .verify_ecdsa(&msg, &recoverable_sig.to_standard(), &expected_pubkey)
- .is_ok()
- );
- }
-
- #[test]
- fn test_secp256k1_nonce_commit() {
- let private_key = hex!("a2d8cf543c60d65162b5a06f0cef9760c883f8aa09f31236859faa85d0b74c7c");
- let msg = [0x88u8; 32];
- let host_commitment = [0xabu8; 32];
-
- let client_commitment =
- secp256k1_nonce_commit(&private_key, &msg, &host_commitment).unwrap();
- assert_eq!(
- hex::encode(client_commitment),
- "0381e4136251c87f2947b735159c6dd644a7b58d35b437e20c878e5129f1320e5e",
- );
- }
-
#[test]
fn test_secp256k1_antiklepto_protocol() {
mock_unlocked();
@@ -1934,11 +1831,16 @@ mod tests {
let public_key = secret_key.public_key(SECP256K1);
// Commit - protocol step 2.
- let signer_commitment =
- secp256k1_nonce_commit(&private_key_bytes, &msg, &host_commitment).unwrap();
+ let signer_commitment = crate::secp256k1::secp256k1_nonce_commit(
+ &private_key_bytes,
+ &msg,
+ &host_commitment,
+ )
+ .unwrap();
// Protocol step 3: host_nonce sent from host to signer to be used in step 4.
// Sign - protocol step 4.
- let sign_result = secp256k1_sign(&private_key_bytes, &msg, &host_nonce).unwrap();
+ let sign_result =
+ crate::secp256k1::secp256k1_sign(&private_key_bytes, &msg, &host_nonce).unwrap();
let signature =
secp256k1::ecdsa::Signature::from_compact(&sign_result.signature).unwrap();
diff --git a/src/rust/bitbox02-rust/src/secp256k1.rs b/src/rust/bitbox02-rust/src/secp256k1.rs
index e07e4bd..99be685 100644
--- a/src/rust/bitbox02-rust/src/secp256k1.rs
+++ b/src/rust/bitbox02-rust/src/secp256k1.rs
@@ -16,6 +16,8 @@ use bitcoin::secp256k1::{All, Secp256k1};
use core::cell::OnceCell;
use core::ops::Deref;
+pub use bitbox02::secp256k1::SignResult;
+
#[derive(Debug, Copy, Clone)]
pub struct GlobalContext {
__private: (), // prevents direct init
@@ -43,3 +45,115 @@ impl Deref for GlobalContext {
})
}
}
+
+/// Length of a compressed secp256k1 pubkey.
+const EC_PUBLIC_KEY_LEN: usize = 33;
+
+/// Sign message with private key using the given private key.
+///
+/// Details about `host_nonce`, the host nonce contribution. Instead of using plain rfc6979 to
+/// generate the nonce in this signature, the following formula is used:
+///
+/// r = rfc6979(..., additional_data=Hash_d(host_nonce))
+/// R = r * G (pubkey to secret r)
+/// nonce = r + Hash_p(R, host_nonce)
+/// `Hash_d(msg)` and `Hash_p(msg)` are tagged hashes: `sha256(sha256(tag)||sha256(tag)||msg)`.
+/// Tag for `Hash_d`: "s2c/ecdsa/data".
+/// Tag for `Hash_p`: "s2c/ecdsa/point".
+/// This is part of the ECDSA Anti-Klepto protocol, preventing this function to leak any secrets via
+/// the signatures (see the ecdsa-s2c module in secp256k1-zpk for more details).
+///
+/// # Arguments
+/// * `private_key` - 32 byte private key
+/// * `msg` - 32 byte message to sign
+/// * `host_nonce` - 32 byte nonce contribution. Cannot be NULL.
+/// Intended to be a contribution by the host. If there is none available, use 32 zero bytes.
+///
+/// # Returns
+/// * `Ok(SignResult)` containing signature in compact format and recoverable id on success
+/// * `Err(())` if the keystore is locked
+pub fn secp256k1_sign(
+ private_key: &[u8; 32],
+ msg: &[u8; 32],
+ host_nonce: &[u8; 32],
+) -> Result<SignResult, ()> {
+ bitbox02::secp256k1::_secp256k1_sign(SECP256K1, private_key, msg, host_nonce)
+}
+
+/// Get a commitment to the original nonce before tweaking it with the host nonce. This is part of
+/// the ECDSA Anti-Klepto Protocol. For more details, check the docs of
+/// `secp256k1_ecdsa_anti_exfil_signer_commit`.
+///
+/// # Arguments
+/// * `private_key` - 32 byte private key
+/// * `msg` - 32 byte message which will be signed by `secp256k1_sign`
+/// * `host_commitment` - must be `sha256(sha256(tag)||sha256(tag)||host_nonce)` where
+/// host_nonce is passed to `secp256k1_sign()`. See `secp256k1_ecdsa_anti_exfil_host_commit()`.
+///
+/// # Returns
+/// * `Ok([u8; EC_PUBLIC_KEY_LEN])` - EC_PUBLIC_KEY_LEN bytes compressed signer nonce pubkey on success
+/// * `Err(())` on failure
+pub fn secp256k1_nonce_commit(
+ private_key: &[u8; 32],
+ msg: &[u8; 32],
+ host_commitment: &[u8; 32],
+) -> Result<[u8; EC_PUBLIC_KEY_LEN], ()> {
+ bitbox02::secp256k1::_secp256k1_nonce_commit(SECP256K1, private_key, msg, host_commitment)
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ use hex_lit::hex;
+
+ use bitcoin::secp256k1;
+
+ #[test]
+ fn test_secp256k1_sign() {
+ let private_key = hex!("a2d8cf543c60d65162b5a06f0cef9760c883f8aa09f31236859faa85d0b74c7c");
+ let msg = [0x88u8; 32];
+ let host_nonce = [0x56u8; 32];
+
+ let sign_result = secp256k1_sign(&private_key, &msg, &host_nonce).unwrap();
+
+ // Verify signature against expected pubkey.
+
+ let expected_pubkey = {
+ let pubkey = hex!("023ffb4a4e41444d40e4e1e4c6cc329bcba2be50d0ef380aea19d490c373be58fb");
+ secp256k1::PublicKey::from_slice(&pubkey).unwrap()
+ };
+ let msg = secp256k1::Message::from_digest_slice(&msg).unwrap();
+ // Test recid by recovering the public key from the signature and checking against the
+ // expected public key.
+ let recoverable_sig = secp256k1::ecdsa::RecoverableSignature::from_compact(
+ &sign_result.signature,
+ secp256k1::ecdsa::RecoveryId::from_i32(sign_result.recid as i32).unwrap(),
+ )
+ .unwrap();
+
+ let recovered_pubkey = SECP256K1.recover_ecdsa(&msg, &recoverable_sig).unwrap();
+ assert_eq!(recovered_pubkey, expected_pubkey);
+
+ // Verify signature.
+ assert!(
+ SECP256K1
+ .verify_ecdsa(&msg, &recoverable_sig.to_standard(), &expected_pubkey)
+ .is_ok()
+ );
+ }
+
+ #[test]
+ fn test_secp256k1_nonce_commit() {
+ let private_key = hex!("a2d8cf543c60d65162b5a06f0cef9760c883f8aa09f31236859faa85d0b74c7c");
+ let msg = [0x88u8; 32];
+ let host_commitment = [0xabu8; 32];
+
+ let client_commitment =
+ secp256k1_nonce_commit(&private_key, &msg, &host_commitment).unwrap();
+ assert_eq!(
+ hex::encode(client_commitment),
+ "0381e4136251c87f2947b735159c6dd644a7b58d35b437e20c878e5129f1320e5e",
+ );
+ }
+}
diff --git a/src/rust/bitbox02/src/keystore.rs b/src/rust/bitbox02/src/keystore.rs
index d2ea790..782b35e 100644
--- a/src/rust/bitbox02/src/keystore.rs
+++ b/src/rust/bitbox02/src/keystore.rs
@@ -12,61 +12,4 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-extern crate alloc;
-
-use bitcoin::secp256k1::{All, Secp256k1};
-
-/// Length of a compressed secp256k1 pubkey.
-const EC_PUBLIC_KEY_LEN: usize = 33;
-
-pub struct SignResult {
- pub signature: [u8; 64],
- pub recid: u8,
-}
-
-pub fn _secp256k1_sign(
- secp: &Secp256k1<All>,
- private_key: &[u8; 32],
- msg: &[u8; 32],
- host_nonce: &[u8; 32],
-) -> Result<SignResult, ()> {
- let mut signature = [0u8; 64];
- let mut recid: core::ffi::c_int = 0;
- match unsafe {
- bitbox02_sys::keystore_secp256k1_sign(
- secp.ctx().as_ptr().cast(),
- private_key.as_ptr(),
- msg.as_ptr(),
- host_nonce.as_ptr(),
- signature.as_mut_ptr(),
- &mut recid,
- )
- } {
- true => Ok(SignResult {
- signature,
- recid: recid.try_into().unwrap(),
- }),
- false => Err(()),
- }
-}
-
-pub fn _secp256k1_nonce_commit(
- secp: &Secp256k1<All>,
- private_key: &[u8; 32],
- msg: &[u8; 32],
- host_commitment: &[u8; 32],
-) -> Result<[u8; EC_PUBLIC_KEY_LEN], ()> {
- let mut signer_commitment = [0u8; EC_PUBLIC_KEY_LEN];
- match unsafe {
- bitbox02_sys::keystore_secp256k1_nonce_commit(
- secp.ctx().as_ptr().cast(),
- private_key.as_ptr(),
- msg.as_ptr(),
- host_commitment.as_ptr(),
- signer_commitment.as_mut_ptr(),
- )
- } {
- true => Ok(signer_commitment),
- false => Err(()),
- }
-}
+// Keystore-related wrappers live in other modules.
diff --git a/src/rust/bitbox02/src/secp256k1.rs b/src/rust/bitbox02/src/secp256k1.rs
index bf619eb..a2e4170 100644
--- a/src/rust/bitbox02/src/secp256k1.rs
+++ b/src/rust/bitbox02/src/secp256k1.rs
@@ -18,6 +18,61 @@ use bitcoin::secp256k1::{All, Secp256k1};
use alloc::vec::Vec;
+/// Length of a compressed secp256k1 pubkey.
+pub const EC_PUBLIC_KEY_LEN: usize = 33;
+
+pub struct SignResult {
+ pub signature: [u8; 64],
+ pub recid: u8,
+}
+
+pub fn _secp256k1_sign(
+ secp: &Secp256k1<All>,
+ private_key: &[u8; 32],
+ msg: &[u8; 32],
+ host_nonce: &[u8; 32],
+) -> Result<SignResult, ()> {
+ let mut signature = [0u8; 64];
+ let mut recid: core::ffi::c_int = 0;
+ match unsafe {
+ bitbox02_sys::keystore_secp256k1_sign(
+ secp.ctx().as_ptr().cast(),
+ private_key.as_ptr(),
+ msg.as_ptr(),
+ host_nonce.as_ptr(),
+ signature.as_mut_ptr(),
+ &mut recid,
+ )
+ } {
+ true => Ok(SignResult {
+ signature,
+ recid: recid.try_into().unwrap(),
+ }),
+ false => Err(()),
+ }
+}
+
+pub fn _secp256k1_nonce_commit(
+ secp: &Secp256k1<All>,
+ private_key: &[u8; 32],
+ msg: &[u8; 32],
+ host_commitment: &[u8; 32],
+) -> Result<[u8; EC_PUBLIC_KEY_LEN], ()> {
+ let mut signer_commitment = [0u8; EC_PUBLIC_KEY_LEN];
+ match unsafe {
+ bitbox02_sys::keystore_secp256k1_nonce_commit(
+ secp.ctx().as_ptr().cast(),
+ private_key.as_ptr(),
+ msg.as_ptr(),
+ host_commitment.as_ptr(),
+ signer_commitment.as_mut_ptr(),
+ )
+ } {
+ true => Ok(signer_commitment),
+ false => Err(()),
+ }
+}
+
pub fn ecdsa_anti_exfil_host_commit(secp: &Secp256k1<All>, rand32: &[u8]) -> Result<Vec<u8>, ()> {
let mut out = [0u8; 32];
match unsafe {
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.