/// Computes a receiver's threshold secret key.
///
/// # Arguments
/// * `receiver_secret_key` - the receiver's secret key, used to decrypt the
///   threshold key.
/// * `transcript` - contains all the threshold keys, including the public
///   coefficients and (encrypted) secret keys.
/// * `dkg_id` - the key distribution ID, needed when decrypting the threshold
///   key as the `IDkgId` is not in the transcript.
/// # Returns
/// Returns the threshold secret key, if one was issued for this node, and None
/// otherwise.
/// # Panics
/// This method is not expected to panic.
/// # Errors
/// This method MUST return an error if:
/// * any of the arguments is malformed.
/// * the computed secret threshold key is not consistent with the public
///   coefficients.
Computes a receiver's threshold secret key.
Computes a receiver ' s threshold secret key .
pub fn compute_private_key(
    receiver_secret_key_bytes: EphemeralSecretKeyBytes,
    transcript: &CLibTranscriptBytes,
    dkg_id: IDkgId,
) -> Result<Option<ThresholdSecretKeyBytes>, DkgLoadPrivateKeyError> {
    let receiver_secret_key = EphemeralSecretKey::try_from(receiver_secret_key_bytes)
        .map_err(DkgLoadPrivateKeyError::MalformedSecretKeyError)?;
    let receiver_public_key = EphemeralPublicKey::from(&receiver_secret_key);
    let receiver_public_key_bytes: EphemeralPublicKeyBytes = receiver_public_key.clone().into();
    let record_maybe: Option<(NodeIndex, EncryptedShareBytes)> =
        transcript.get_receiver_data(receiver_public_key_bytes);
    if let Some((receiver_index, encrypted_share_bytes)) = record_maybe {
        let dealer_public_keys: Vec<EphemeralPublicKey> = {
            let parsed: Result<Vec<_>, _> = transcript
                .dealer_public_keys
                .iter()
                .map(|dealer_public_key_bytes| {
                    EphemeralPublicKey::try_from(dealer_public_key_bytes)
                        .map_err(|e| DkgLoadPrivateKeyError::MalformedTranscriptError(e.into()))
                })
                .collect();
            parsed?
        };
        let encryption_keys = dealer_public_keys.iter().map(|dealer_public_key| {
            let diffie_hellman = dealer_public_key.clone() * &receiver_secret_key;
            key_encryption_key(
                dkg_id,
                dealer_public_key,
                receiver_public_key.clone(),
                diffie_hellman,
            )
        });
        let share: ThresholdSecretKey = {
            let mut share = EncryptedShare::try_from(encrypted_share_bytes)
                .map_err(DkgLoadPrivateKeyError::MalformedTranscriptError)?;
            if let Some(dealer_reshare_indices) = &transcript.dealer_reshare_indices {
                let dealer_reshare_x: Vec<ThresholdSecretKey> = dealer_reshare_indices
                    .iter()
                    .map(|index| x_for_index(*index))
                    .collect();
                let lagrange_coefficients: Vec<ThresholdSecretKey> =
                    PublicCoefficients::lagrange_coefficients_at_zero(&dealer_reshare_x)
                        .expect("cannot fail");
                for key_encryption_key in
                    encryption_keys
                        .zip(&lagrange_coefficients)
                        .map(|(mut key, coefficient)| {
                            key.mul_assign(coefficient);
                            key
                        })
                {
                    share.sub_assign(&key_encryption_key);
                }
            } else {
                for key_encryption_key in encryption_keys {
                    share.sub_assign(&key_encryption_key);
                }
            }
            share
        };
        let public_coefficients: PublicCoefficients =
            PublicCoefficients::try_from(&transcript.public_coefficients).map_err(|_| {
                DkgLoadPrivateKeyError::MalformedTranscriptError(MalformedDataError {
                    algorithm: AlgorithmId::Secp256k1, /* Note: This is the algorithm of the
                                                        * method rather than of the type, which
                                                        * is Bls12_381. */
                    internal_error: "Could not parse public coefficients".to_string(),
                    data: None,
                })
            })?;
        if !secret_key_is_consistent(share, &public_coefficients, receiver_index) {
            return Err(DkgLoadPrivateKeyError::InvalidTranscriptError(
                InvalidArgumentError {
                    message: "Cannot reconstruct secret".to_string(),
                },
            ));
        }
        Ok(Some(ThresholdSecretKeyBytes::from(share))) // Return threshold
                                                       // secret key
    } else {
        Ok(None) // This receiver is not participating.
    }
}
pub fn compute_private_key ( receiver_secret_key_bytes : EphemeralSecretKeyBytes , transcript : & CLibTranscriptBytes , dkg_id : IDkgId , ) -> Result < Option < ThresholdSecretKeyBytes > , DkgLoadPrivateKeyError > { let receiver_secret_key = EphemeralSecretKey :: try_from ( receiver_secret_key_bytes ) . map_err ( DkgLoadPrivateKeyError :: MalformedSecretKeyError ) ? ; let receiver_public_key = EphemeralPublicKey :: from ( & receiver_secret_key ) ; let receiver_public_key_bytes : EphemeralPublicKeyBytes = receiver_public_key . clone ( ) . into ( ) ; let record_maybe : Option < ( NodeIndex , EncryptedShareBytes ) > = transcript . get_receiver_data ( receiver_public_key_bytes ) ; if let Some ( ( receiver_index , encrypted_share_bytes ) ) = record_maybe { let dealer_public_keys : Vec < EphemeralPublicKey > = { let parsed : Result < Vec < _ > , _ > = transcript . dealer_public_keys . iter ( ) . map ( | dealer_public_key_bytes | { EphemeralPublicKey :: try_from ( dealer_public_key_bytes ) . map_err ( | e | DkgLoadPrivateKeyError :: MalformedTranscriptError ( e . into ( ) ) ) } ) . collect ( ) ; parsed ? } ; let encryption_keys = dealer_public_keys . iter ( ) . map ( | dealer_public_key | { let diffie_hellman = dealer_public_key . clone ( ) * & receiver_secret_key ; key_encryption_key ( dkg_id , dealer_public_key , receiver_public_key . clone ( ) , diffie_hellman , ) } ) ; let share : ThresholdSecretKey = { let mut share = EncryptedShare :: try_from ( encrypted_share_bytes ) . map_err ( DkgLoadPrivateKeyError :: MalformedTranscriptError ) ? ; if let Some ( dealer_reshare_indices ) = & transcript . dealer_reshare_indices { let dealer_reshare_x : Vec < ThresholdSecretKey > = dealer_reshare_indices . iter ( ) . map ( | index | x_for_index ( * index ) ) . collect ( ) ; let lagrange_coefficients : Vec < ThresholdSecretKey > = PublicCoefficients :: lagrange_coefficients_at_zero ( & dealer_reshare_x ) . expect ( " " ) ; for key_encryption_key in encryption_keys . zip ( & lagrange_coefficients ) . map ( | ( mut key , coefficient ) | { key . mul_assign ( coefficient ) ; key } ) { share . sub_assign ( & key_encryption_key ) ; } } else { for key_encryption_key in encryption_keys { share . sub_assign ( & key_encryption_key ) ; } } share } ; let public_coefficients : PublicCoefficients = PublicCoefficients :: try_from ( & transcript . public_coefficients ) . map_err ( | _ | { DkgLoadPrivateKeyError :: MalformedTranscriptError ( MalformedDataError { algorithm : AlgorithmId :: Secp256k1 , /* Note: This is the algorithm of the
                                                        * method rather than of the type, which
                                                        * is Bls12_381. */ internal_error : " " . to_string ( ) , data : None , } ) } ) ? ; if ! secret_key_is_consistent ( share , & public_coefficients , receiver_index ) { return Err ( DkgLoadPrivateKeyError :: InvalidTranscriptError ( InvalidArgumentError { message : " " . to_string ( ) , } , ) ) ; } Ok ( Some ( ThresholdSecretKeyBytes :: from ( share ) ) ) // Return threshold // secret key } else { Ok ( None ) // This receiver is not participating. } }
Computes a receiver's threshold secret key.
Computes a receiver ' s threshold secret key .
Returns the threshold secret key, if one was issued for this node, and None
otherwise.
Returns the threshold secret key if one was issued for this node and None otherwise .
receiver_secret_key_bytes
EphemeralSecretKeyBytes
transcript
&CLibTranscriptBytes
dkg_id
IDkgId
panics
This method is not expected to panic.
This method is not expected to panic .
errors
This method MUST return an error if:
any of the arguments is malformed.
the computed secret threshold key is not consistent with the public
coefficients.
This method MUST return an error if : any of the arguments is malformed . the computed secret threshold key is not consistent with the public coefficients .