pub(super) fn complain_maybe<R: Rng + CryptoRng>(
    rng: &mut R,
    dkg_id: IDkgId,
    receiver_index: NodeIndex,
    receiver_secret_key: &EphemeralSecretKey,
    receiver_public_key: &EphemeralPublicKey,
    dealer_public_key_bytes: &EphemeralPublicKeyBytes,
    dealing: &CLibDealingBytes,
) -> Result<Option<CLibComplaintBytes>, DkgCreateResponseError> {
    let CLibDealingBytes {
        receiver_data,
        public_coefficients,
    } = dealing;
    // Parse:
    let my_receiver_data: ThresholdSecretKey =
        parse_my_receiver_data(receiver_data, receiver_index)?;
    let public_coefficients: PublicCoefficients =
        public_coefficients.try_into().map_err(|_: CryptoError| {
            DkgCreateResponseError::MalformedDealingError(MalformedDataError {
                algorithm: AlgorithmId::Secp256k1,
                internal_error: "Malformed public coefficients".to_string(),
                data: None,
            })
        })?;
    let dealer_public_key = EphemeralPublicKey::try_from(dealer_public_key_bytes)
        .map_err(DkgCreateResponseError::MalformedPublicKeyError)?;

    // Compute share:
    let dh_between_receiver_and_dealer: EphemeralPublicKey =
        dealer_public_key.clone() * receiver_secret_key;
    let share: ThresholdSecretKey = dh::decrypt_share(
        dkg_id,
        &dealer_public_key,
        receiver_public_key,
        &dh_between_receiver_and_dealer,
        my_receiver_data,
    );

    // Verify share or complain
    if secret_key_is_consistent(share, &public_coefficients, receiver_index) {
        Ok(None)
    } else {
        let spec_r = EphemeralSecretKey::random(rng);
        let spec_t = EphemeralPublicKey::from(&spec_r);
        let spec_u = dealer_public_key * &spec_r;
        let spec_c: EphemeralSecretKey = ChallengeDigest {
            dkg_id,
            dealer_public_key_bytes: *dealer_public_key_bytes,
            receiver_public_key_bytes: EphemeralPublicKeyBytes::from(receiver_public_key),
            diffie_hellman: EphemeralPublicKeyBytes::from(&dh_between_receiver_and_dealer),
            spec_t: EphemeralPublicKeyBytes::from(&spec_t),
            spec_u: EphemeralPublicKeyBytes::from(&spec_u),
        }
        .digest();
        let spec_s: EphemeralSecretKey = {
            let mut ans = spec_c.clone();
            ans *= receiver_secret_key; // spec: my_dh_secret
            ans += &spec_r;
            ans
        };
        Ok(Some(CLibComplaintBytes {
            diffie_hellman: EphemeralPublicKeyBytes::from(&dh_between_receiver_and_dealer),
            pok_challenge: EphemeralSecretKeyBytes::from(&spec_c),
            pok_response: EphemeralSecretKeyBytes::from(spec_s),
        }))
    }
}
/// Complains if the share in a dealing is not on the curve defined by the
/// public coefficients.
///
/// # Arguments
/// * `rng` - a random number generator used to prove that a share is bad.
/// * `dkg_id` - identifier for the key generation
/// * `receiver_index` - index of this receiver in the list of receivers
/// * `receiver_secret_key` - the ephemeral key of this receiver used to decrypt
///   the share.
/// * `receiver_public_key` - the corresponding public key, to avoid recomputing
///   it.
/// * `dealer_public_key_bytes` - the ephemeral public key of the dealer used to
///   decrypt the share.
/// * `dealing` - the dealing being examined.
/// # Panics
/// This method is not expected to panic
/// # Errors
/// * This code MAY not check that the `receiver_public_key` matches the
///   `receiver_secret_key`.  It is the caller's responsibility to ensure that
///   they are correct.
/// * This code MUST return an error if:
///   * an argument is malformed; `dealer_public_key_bytes` and `dealing` are of
///     note.
///   * the receiver has no share.
Complains if the share in a dealing is not on the curve defined by the
public coefficients.
Complains if the share in a dealing is not on the curve defined by the public coefficients .
pub(super) fn complain_maybe<R: Rng + CryptoRng>(
    rng: &mut R,
    dkg_id: IDkgId,
    receiver_index: NodeIndex,
    receiver_secret_key: &EphemeralSecretKey,
    receiver_public_key: &EphemeralPublicKey,
    dealer_public_key_bytes: &EphemeralPublicKeyBytes,
    dealing: &CLibDealingBytes,
) -> Result<Option<CLibComplaintBytes>, DkgCreateResponseError> {
    let CLibDealingBytes {
        receiver_data,
        public_coefficients,
    } = dealing;
    // Parse:
    let my_receiver_data: ThresholdSecretKey =
        parse_my_receiver_data(receiver_data, receiver_index)?;
    let public_coefficients: PublicCoefficients =
        public_coefficients.try_into().map_err(|_: CryptoError| {
            DkgCreateResponseError::MalformedDealingError(MalformedDataError {
                algorithm: AlgorithmId::Secp256k1,
                internal_error: "Malformed public coefficients".to_string(),
                data: None,
            })
        })?;
    let dealer_public_key = EphemeralPublicKey::try_from(dealer_public_key_bytes)
        .map_err(DkgCreateResponseError::MalformedPublicKeyError)?;
    // Compute share:
    let dh_between_receiver_and_dealer: EphemeralPublicKey =
        dealer_public_key.clone() * receiver_secret_key;
    let share: ThresholdSecretKey = dh::decrypt_share(
        dkg_id,
        &dealer_public_key,
        receiver_public_key,
        &dh_between_receiver_and_dealer,
        my_receiver_data,
    );
    // Verify share or complain
    if secret_key_is_consistent(share, &public_coefficients, receiver_index) {
        Ok(None)
    } else {
        let spec_r = EphemeralSecretKey::random(rng);
        let spec_t = EphemeralPublicKey::from(&spec_r);
        let spec_u = dealer_public_key * &spec_r;
        let spec_c: EphemeralSecretKey = ChallengeDigest {
            dkg_id,
            dealer_public_key_bytes: *dealer_public_key_bytes,
            receiver_public_key_bytes: EphemeralPublicKeyBytes::from(receiver_public_key),
            diffie_hellman: EphemeralPublicKeyBytes::from(&dh_between_receiver_and_dealer),
            spec_t: EphemeralPublicKeyBytes::from(&spec_t),
            spec_u: EphemeralPublicKeyBytes::from(&spec_u),
        }
        .digest();
        let spec_s: EphemeralSecretKey = {
            let mut ans = spec_c.clone();
            ans *= receiver_secret_key; // spec: my_dh_secret
            ans += &spec_r;
            ans
        };
        Ok(Some(CLibComplaintBytes {
            diffie_hellman: EphemeralPublicKeyBytes::from(&dh_between_receiver_and_dealer),
            pok_challenge: EphemeralSecretKeyBytes::from(&spec_c),
            pok_response: EphemeralSecretKeyBytes::from(spec_s),
        }))
    }
}
pub ( super ) fn complain_maybe < R : Rng + CryptoRng > ( rng : & mut R , dkg_id : IDkgId , receiver_index : NodeIndex , receiver_secret_key : & EphemeralSecretKey , receiver_public_key : & EphemeralPublicKey , dealer_public_key_bytes : & EphemeralPublicKeyBytes , dealing : & CLibDealingBytes , ) -> Result < Option < CLibComplaintBytes > , DkgCreateResponseError > { let CLibDealingBytes { receiver_data , public_coefficients , } = dealing ; // Parse: let my_receiver_data : ThresholdSecretKey = parse_my_receiver_data ( receiver_data , receiver_index ) ? ; let public_coefficients : PublicCoefficients = public_coefficients . try_into ( ) . map_err ( | _ : CryptoError | { DkgCreateResponseError :: MalformedDealingError ( MalformedDataError { algorithm : AlgorithmId :: Secp256k1 , internal_error : " " . to_string ( ) , data : None , } ) } ) ? ; let dealer_public_key = EphemeralPublicKey :: try_from ( dealer_public_key_bytes ) . map_err ( DkgCreateResponseError :: MalformedPublicKeyError ) ? ; // Compute share: let dh_between_receiver_and_dealer : EphemeralPublicKey = dealer_public_key . clone ( ) * receiver_secret_key ; let share : ThresholdSecretKey = dh :: decrypt_share ( dkg_id , & dealer_public_key , receiver_public_key , & dh_between_receiver_and_dealer , my_receiver_data , ) ; // Verify share or complain if secret_key_is_consistent ( share , & public_coefficients , receiver_index ) { Ok ( None ) } else { let spec_r = EphemeralSecretKey :: random ( rng ) ; let spec_t = EphemeralPublicKey :: from ( & spec_r ) ; let spec_u = dealer_public_key * & spec_r ; let spec_c : EphemeralSecretKey = ChallengeDigest { dkg_id , dealer_public_key_bytes : * dealer_public_key_bytes , receiver_public_key_bytes : EphemeralPublicKeyBytes :: from ( receiver_public_key ) , diffie_hellman : EphemeralPublicKeyBytes :: from ( & dh_between_receiver_and_dealer ) , spec_t : EphemeralPublicKeyBytes :: from ( & spec_t ) , spec_u : EphemeralPublicKeyBytes :: from ( & spec_u ) , } . digest ( ) ; let spec_s : EphemeralSecretKey = { let mut ans = spec_c . clone ( ) ; ans *= receiver_secret_key ; // spec: my_dh_secret ans += & spec_r ; ans } ; Ok ( Some ( CLibComplaintBytes { diffie_hellman : EphemeralPublicKeyBytes :: from ( & dh_between_receiver_and_dealer ) , pok_challenge : EphemeralSecretKeyBytes :: from ( & spec_c ) , pok_response : EphemeralSecretKeyBytes :: from ( spec_s ) , } ) ) } }
Complains if the share in a dealing is not on the curve defined by the
public coefficients.
Complains if the share in a dealing is not on the curve defined by the public coefficients .
rng
&mut R
dkg_id
IDkgId
receiver_index
NodeIndex
receiver_secret_key
&EphemeralSecretKey
receiver_public_key
&EphemeralPublicKey
dealer_public_key_bytes
&EphemeralPublicKeyBytes
dealing
&CLibDealingBytes
rng
&mut R
dkg_id
IDkgId
receiver_index
NodeIndex
receiver_secret_key
&EphemeralSecretKey
receiver_public_key
&EphemeralPublicKey
dealer_public_key_bytes
&EphemeralPublicKeyBytes
dealing
&CLibDealingBytes
panics
This method is not expected to panic
This method is not expected to panic
errors
This code MAY not check that the `receiver_public_key` matches the
`receiver_secret_key`.  It is the caller's responsibility to ensure that
they are correct.
This code MUST return an error if:
an argument is malformed; `dealer_public_key_bytes` and `dealing` are of
note.
the receiver has no share.
This code MAY not check that the ` receiver_public_key ` matches the ` receiver_secret_key ` . It is the caller ' s responsibility to ensure that they are correct . This code MUST return an error if : an argument is malformed ; ` dealer_public_key_bytes ` and ` dealing ` are of note . the receiver has no share .