Skip to content

Commit fbc64c7

Browse files
committed
Add opaque parity type
Two functions in the FFI secp code return and accept a parity int. Currently we are manually converting this to a bool. Doing so forces readers of the code to think what the bool means even though understanding this bool is not needed since in is just passed back down to the FFI code. We can abstract this away by using an opaque type to hold the original int and not converting it to a boolean value. Add 'Return' and 'Error' sections to `tweak_add_assign` while fixing the docs to describe the new opaque parity type.
1 parent 1b768b2 commit fbc64c7

File tree

1 file changed

+27
-10
lines changed

1 file changed

+27
-10
lines changed

src/key.rs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -824,15 +824,18 @@ impl XOnlyPublicKey {
824824

825825
/// Tweak an x-only PublicKey by adding the generator multiplied with the given tweak to it.
826826
///
827-
/// Returns a boolean representing the parity of the tweaked key, which can be provided to
827+
/// # Return
828+
/// An opaque type representing the parity of the tweaked key, this should be provided to
828829
/// `tweak_add_check` which can be used to verify a tweak more efficiently than regenerating
829-
/// it and checking equality. Will return an error if the resulting key would be invalid or
830-
/// if the tweak was not a 32-byte length slice.
830+
/// it and checking equality.
831+
///
832+
/// # Error
833+
/// If the resulting key would be invalid or if the tweak was not a 32-byte length slice.
831834
pub fn tweak_add_assign<V: Verification>(
832835
&mut self,
833836
secp: &Secp256k1<V>,
834837
tweak: &[u8],
835-
) -> Result<bool, Error> {
838+
) -> Result<Parity, Error> {
836839
if tweak.len() != 32 {
837840
return Err(Error::InvalidTweak);
838841
}
@@ -856,12 +859,11 @@ impl XOnlyPublicKey {
856859
&mut parity,
857860
&pubkey,
858861
);
859-
860862
if err == 0 {
861-
Err(Error::InvalidPublicKey)
862-
} else {
863-
Ok(parity != 0)
863+
return Err(Error::InvalidPublicKey);
864864
}
865+
866+
Ok(parity.into())
865867
}
866868
}
867869

@@ -878,15 +880,15 @@ impl XOnlyPublicKey {
878880
&self,
879881
secp: &Secp256k1<V>,
880882
tweaked_key: &Self,
881-
tweaked_parity: bool,
883+
tweaked_parity: Parity,
882884
tweak: [u8; 32],
883885
) -> bool {
884886
let tweaked_ser = tweaked_key.serialize();
885887
unsafe {
886888
let err = ffi::secp256k1_xonly_pubkey_tweak_add_check(
887889
secp.ctx,
888890
tweaked_ser.as_c_ptr(),
889-
if tweaked_parity { 1 } else { 0 },
891+
tweaked_parity.into(),
890892
&self.0,
891893
tweak.as_c_ptr(),
892894
);
@@ -896,6 +898,21 @@ impl XOnlyPublicKey {
896898
}
897899
}
898900

901+
/// Opaque type used to hold the parity passed between FFI function calls.
902+
pub struct Parity(i32);
903+
904+
impl From<i32> for Parity {
905+
fn from(parity: i32) -> Parity {
906+
Parity(parity)
907+
}
908+
}
909+
910+
impl From<Parity> for i32 {
911+
fn from(parity: Parity) -> i32 {
912+
parity.0
913+
}
914+
}
915+
899916
impl CPtr for XOnlyPublicKey {
900917
type Target = ffi::XOnlyPublicKey;
901918
fn as_c_ptr(&self) -> *const Self::Target {

0 commit comments

Comments
 (0)