Skip to content

ProofSystem/include/ProofSystem/KDFGenerator.hpp

Key Derivation Function Generator. More...

Classes

Name
class KDFGenerator
KDF Generator class.

Detailed Description

Key Derivation Function Generator.

Date: 2024-01-08 Henrique A. Klein ([email protected])

Source code

#ifndef _KDF_GENERATOR_HPP_
#define _KDF_GENERATOR_HPP_

#include <vector>
#include <string>
#include <nil/crypto3/pubkey/ecdsa.hpp>
#include <nil/crypto3/pubkey/algorithm/sign.hpp>
#include <nil/crypto3/pubkey/algorithm/verify.hpp>
#include <nil/crypto3/algebra/marshalling.hpp>
#include <nil/crypto3/hash/algorithm/hash.hpp>
#include <nil/crypto3/hash/sha2.hpp>

#include "ProofSystem/ECDSATypes.hpp"
#include "ProofSystem/ECDHEncryption.hpp"
#include "ProofSystem/ext_private_key.hpp"

template <typename PolicyType>
class KDFGenerator
{
public:
    using SignatureType = typename ecdsa_t::pubkey::public_key<PolicyType>::signature_type;
    using ECDSAPubKey   = std::string;

    static constexpr std::size_t EXPECTED_SECRET_SIZE = 192; 

    explicit KDFGenerator( const ecdsa_t::pubkey::ext_private_key<PolicyType> &own_prvt_key, const ECDSAPubKey &other_party_key );

    std::string GenerateSharedSecret( const ecdsa_t::pubkey::ext_private_key<PolicyType> &own_prvt_key, const ECDSAPubKey &other_party_key );

    ecdsa_t::scalar_field_value_type GetNewKeyFromSecret( std::string_view signed_secret, const ECDSAPubKey &signer_pubkey,
                                                          const ECDSAPubKey &verifier_pubkey );

    bool operator==( const KDFGenerator &other ) const
    {
        return ( *( this->encryptor ) == *( other.encryptor ) );
    }

    static ecdsa_t::pubkey::public_key<PolicyType> BuildPublicKeyECDSA( const ECDSAPubKey &pubkey_data );

private:
    std::shared_ptr<Encryption> encryptor; 
};

template <typename PolicyType>
KDFGenerator<PolicyType>::KDFGenerator( const ecdsa_t::pubkey::ext_private_key<PolicyType> &own_prvt_key, const ECDSAPubKey &other_party_key ) :
    encryptor( std::make_shared<ECDHEncryption<PolicyType>>( own_prvt_key, BuildPublicKeyECDSA( other_party_key ) ) )
{
}

template <typename PolicyType>
std::string KDFGenerator<PolicyType>::GenerateSharedSecret( const ecdsa_t::pubkey::ext_private_key<PolicyType> &own_prvt_key,
                                                            const ECDSAPubKey                                  &other_party_key )
{
    using namespace ecdsa_t;

    KDFGenerator::SignatureType signed_secret = sign<PolicyType>( other_party_key, own_prvt_key );
    std::vector<std::uint8_t>   signed_vector( 64 );

    nil::marshalling::bincode::field<ecdsa_t::scalar_field_type>::field_element_to_bytes<std::vector<std::uint8_t>::iterator>(
        std::get<0>( signed_secret ), signed_vector.begin(), signed_vector.begin() + signed_vector.size() / 2 );
    nil::marshalling::bincode::field<ecdsa_t::scalar_field_type>::field_element_to_bytes<std::vector<std::uint8_t>::iterator>(
        std::get<1>( signed_secret ), signed_vector.begin() + signed_vector.size() / 2, signed_vector.end() );

    auto derived_key_vector = static_cast<std::vector<std::uint8_t>>( hash<hashes::sha2<256>>( signed_vector.begin(), signed_vector.end() ) );
    signed_vector.insert( signed_vector.end(), derived_key_vector.begin(), derived_key_vector.end() );

    std::vector<std::uint8_t> key_vector = util::HexASCII2NumStr<std::uint8_t>( other_party_key.data(), other_party_key.size() );

    return util::to_string( encryptor->EncryptData( signed_vector, key_vector ) );
}
template <typename PolicyType>
ecdsa_t::scalar_field_value_type KDFGenerator<PolicyType>::GetNewKeyFromSecret( std::string_view signed_secret, const ECDSAPubKey &signer_pubkey,
                                                                                const ECDSAPubKey &verifier_pubkey )
{
    std::vector<std::uint8_t> key_vector = util::HexASCII2NumStr<std::uint8_t>( verifier_pubkey );
    const auto                signer_key = BuildPublicKeyECDSA( signer_pubkey );

    std::vector<std::uint8_t> signed_vector = util::HexASCII2NumStr<std::uint8_t>( signed_secret );

    std::vector<std::uint8_t> decoded_vector = encryptor->DecryptData( signed_vector, key_vector );

    auto sign_first_part =
        nil::marshalling::bincode::field<ecdsa_t::scalar_field_type>::field_element_from_bytes<std::vector<std::uint8_t>::iterator>(
            decoded_vector.begin(), decoded_vector.begin() + 32 );
    auto sign_second_part =
        nil::marshalling::bincode::field<ecdsa_t::scalar_field_type>::field_element_from_bytes<std::vector<std::uint8_t>::iterator>(
            decoded_vector.begin() + 32, decoded_vector.begin() + 64 );

    bool valid = static_cast<bool>(
        nil::crypto3::verify<PolicyType>( verifier_pubkey, SignatureType( sign_first_part.second, sign_second_part.second ), signer_key ) );

    if ( !valid )
    {
        throw std::runtime_error( "Can't verify the signature" );
    }
    auto derived_key_pair =
        nil::marshalling::bincode::field<ecdsa_t::scalar_field_type>::field_element_from_bytes<std::vector<std::uint8_t>::iterator>(
            decoded_vector.begin() + 64, decoded_vector.end() );

    return derived_key_pair.second;
}

template <typename PolicyType>
ecdsa_t::pubkey::public_key<PolicyType> KDFGenerator<PolicyType>::BuildPublicKeyECDSA( const ECDSAPubKey &pubkey_data )
{
    using namespace ecdsa_t;

    auto z_data_one = pubkey::public_key<PolicyType>::g1_value_type::field_type::value_type::one();

    std::vector<std::uint8_t> key_vector = util::HexASCII2NumStr<std::uint8_t>( pubkey_data.data(), pubkey_data.size() );

    auto y_data = nil::marshalling::bincode::field<ecdsa_t::base_field_type>::field_element_from_bytes<std::vector<std::uint8_t>::iterator>(
        key_vector.begin(), key_vector.begin() + key_vector.size() / 2 );
    auto x_data = nil::marshalling::bincode::field<ecdsa_t::base_field_type>::field_element_from_bytes<std::vector<std::uint8_t>::iterator>(
        key_vector.begin() + key_vector.size() / 2, key_vector.end() );

    return typename pubkey::public_key<PolicyType>::public_key_type( x_data.second, y_data.second, z_data_one );
}

#endif

Updated on 2026-03-04 at 13:10:44 -0800