fn process_configure_account(
    program_id: &Pubkey,
    accounts: &[AccountInfo],
    ConfigureAccountInstructionData {
        elgamal_pubkey,
        decryptable_zero_balance,
    }: &ConfigureAccountInstructionData,
) -> ProgramResult {
    let account_info_iter = &mut accounts.iter();
    let token_account_info = next_account_info(account_info_iter)?;
    let mint_info = next_account_info(account_info_iter)?;
    let authority_info = next_account_info(account_info_iter)?;
    let authority_info_data_len = authority_info.data_len();

    check_program_account(token_account_info.owner)?;
    let token_account_data = &mut token_account_info.data.borrow_mut();
    let mut token_account = StateWithExtensionsMut::<Account>::unpack(token_account_data)?;

    if token_account.base.mint != *mint_info.key {
        return Err(TokenError::MintMismatch.into());
    }

    Processor::validate_owner(
        program_id,
        token_account_info.owner,
        authority_info,
        authority_info_data_len,
        account_info_iter.as_slice(),
    )?;

    check_program_account(mint_info.owner)?;
    let mint_data = &mut mint_info.data.borrow();
    let mint = StateWithExtensions::<Mint>::unpack(mint_data)?;
    let ct_mint = mint.get_extension::<ConfidentialTransferMint>()?;

    // Note: The caller is expected to use the `Reallocate` instruction to ensure there is
    // sufficient room in their token account for the new `ConfidentialTransferAccount` extension
    let mut ct_token_account = token_account.init_extension::<ConfidentialTransferAccount>()?;
    ct_token_account.approved = ct_mint.auto_approve_new_accounts;
    ct_token_account.elgamal_pubkey = *elgamal_pubkey;
    ct_token_account.decryptable_available_balance = *decryptable_zero_balance;

    /*
        An ElGamal ciphertext is of the form
          ElGamalCiphertext {
            msg_comm: r * H + x * G
            decrypt_handle: r * P
          }

        where
        - G, H: constants for the system (RistrettoPoint)
        - P: ElGamal public key component (RistrettoPoint)
        - r: encryption randomness (Scalar)
        - x: message (Scalar)

        Upon receiving a `ConfigureAccount` instruction, the ZK Token program should encrypt x=0 (i.e.
        Scalar::zero()) and store it as `pending_balance` and `available_balance`.

        For regular encryption, it is important that r is generated from a proper randomness source. But
        for the `ConfigureAccount` instruction, it is already known that x is always 0. So r can just be
        set Scalar::zero().

        This means that the ElGamalCiphertext should simply be
          ElGamalCiphertext {
            msg_comm: 0 * H + 0 * G = 0
            decrypt_handle: 0 * P = 0
          }

        This should just be encoded as [0; 64]
    */
    ct_token_account.pending_balance = pod::ElGamalCiphertext::zeroed();
    ct_token_account.available_balance = pod::ElGamalCiphertext::zeroed();

    Ok(())
}
/// Processes a [ConfigureAccount] instruction.
Processes a [ConfigureAccount] instruction.
Processes a [ ConfigureAccount ] instruction .
fn process_configure_account(
    program_id: &Pubkey,
    accounts: &[AccountInfo],
    ConfigureAccountInstructionData {
        elgamal_pubkey,
        decryptable_zero_balance,
    }: &ConfigureAccountInstructionData,
) -> ProgramResult {
    let account_info_iter = &mut accounts.iter();
    let token_account_info = next_account_info(account_info_iter)?;
    let mint_info = next_account_info(account_info_iter)?;
    let authority_info = next_account_info(account_info_iter)?;
    let authority_info_data_len = authority_info.data_len();
    check_program_account(token_account_info.owner)?;
    let token_account_data = &mut token_account_info.data.borrow_mut();
    let mut token_account = StateWithExtensionsMut::<Account>::unpack(token_account_data)?;
    if token_account.base.mint != *mint_info.key {
        return Err(TokenError::MintMismatch.into());
    }
    Processor::validate_owner(
        program_id,
        token_account_info.owner,
        authority_info,
        authority_info_data_len,
        account_info_iter.as_slice(),
    )?;
    check_program_account(mint_info.owner)?;
    let mint_data = &mut mint_info.data.borrow();
    let mint = StateWithExtensions::<Mint>::unpack(mint_data)?;
    let ct_mint = mint.get_extension::<ConfidentialTransferMint>()?;
    // Note: The caller is expected to use the `Reallocate` instruction to ensure there is
    // sufficient room in their token account for the new `ConfidentialTransferAccount` extension
    let mut ct_token_account = token_account.init_extension::<ConfidentialTransferAccount>()?;
    ct_token_account.approved = ct_mint.auto_approve_new_accounts;
    ct_token_account.elgamal_pubkey = *elgamal_pubkey;
    ct_token_account.decryptable_available_balance = *decryptable_zero_balance;
    /*
        An ElGamal ciphertext is of the form
          ElGamalCiphertext {
            msg_comm: r * H + x * G
            decrypt_handle: r * P
          }
        where
        - G, H: constants for the system (RistrettoPoint)
        - P: ElGamal public key component (RistrettoPoint)
        - r: encryption randomness (Scalar)
        - x: message (Scalar)
        Upon receiving a `ConfigureAccount` instruction, the ZK Token program should encrypt x=0 (i.e.
        Scalar::zero()) and store it as `pending_balance` and `available_balance`.
        For regular encryption, it is important that r is generated from a proper randomness source. But
        for the `ConfigureAccount` instruction, it is already known that x is always 0. So r can just be
        set Scalar::zero().
        This means that the ElGamalCiphertext should simply be
          ElGamalCiphertext {
            msg_comm: 0 * H + 0 * G = 0
            decrypt_handle: 0 * P = 0
          }
        This should just be encoded as [0; 64]
    */
    ct_token_account.pending_balance = pod::ElGamalCiphertext::zeroed();
    ct_token_account.available_balance = pod::ElGamalCiphertext::zeroed();
    Ok(())
}
fn process_configure_account ( program_id : & Pubkey , accounts : & [ AccountInfo ] , ConfigureAccountInstructionData { elgamal_pubkey , decryptable_zero_balance , } : & ConfigureAccountInstructionData , ) -> ProgramResult { let account_info_iter = & mut accounts . iter ( ) ; let token_account_info = next_account_info ( account_info_iter ) ? ; let mint_info = next_account_info ( account_info_iter ) ? ; let authority_info = next_account_info ( account_info_iter ) ? ; let authority_info_data_len = authority_info . data_len ( ) ; check_program_account ( token_account_info . owner ) ? ; let token_account_data = & mut token_account_info . data . borrow_mut ( ) ; let mut token_account = StateWithExtensionsMut :: < Account > :: unpack ( token_account_data ) ? ; if token_account . base . mint != * mint_info . key { return Err ( TokenError :: MintMismatch . into ( ) ) ; } Processor :: validate_owner ( program_id , token_account_info . owner , authority_info , authority_info_data_len , account_info_iter . as_slice ( ) , ) ? ; check_program_account ( mint_info . owner ) ? ; let mint_data = & mut mint_info . data . borrow ( ) ; let mint = StateWithExtensions :: < Mint > :: unpack ( mint_data ) ? ; let ct_mint = mint . get_extension :: < ConfidentialTransferMint > ( ) ? ; // Note: The caller is expected to use the `Reallocate` instruction to ensure there is // sufficient room in their token account for the new `ConfidentialTransferAccount` extension let mut ct_token_account = token_account . init_extension :: < ConfidentialTransferAccount > ( ) ? ; ct_token_account . approved = ct_mint . auto_approve_new_accounts ; ct_token_account . elgamal_pubkey = * elgamal_pubkey ; ct_token_account . decryptable_available_balance = * decryptable_zero_balance ; /*
        An ElGamal ciphertext is of the form
          ElGamalCiphertext {
            msg_comm: r * H + x * G
            decrypt_handle: r * P
          }

        where
        - G, H: constants for the system (RistrettoPoint)
        - P: ElGamal public key component (RistrettoPoint)
        - r: encryption randomness (Scalar)
        - x: message (Scalar)

        Upon receiving a `ConfigureAccount` instruction, the ZK Token program should encrypt x=0 (i.e.
        Scalar::zero()) and store it as `pending_balance` and `available_balance`.

        For regular encryption, it is important that r is generated from a proper randomness source. But
        for the `ConfigureAccount` instruction, it is already known that x is always 0. So r can just be
        set Scalar::zero().

        This means that the ElGamalCiphertext should simply be
          ElGamalCiphertext {
            msg_comm: 0 * H + 0 * G = 0
            decrypt_handle: 0 * P = 0
          }

        This should just be encoded as [0; 64]
    */ ct_token_account . pending_balance = pod :: ElGamalCiphertext :: zeroed ( ) ; ct_token_account . available_balance = pod :: ElGamalCiphertext :: zeroed ( ) ; Ok ( ( ) ) }
Processes a [ConfigureAccount] instruction.
Processes a [ ConfigureAccount ] instruction .
program_id
&Pubkey
accounts
&ConfigureAccountInstructionData
program_id
&Pubkey
accounts
&ConfigureAccountInstructionData