Ed25519 Signature verification in HSE

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Ed25519 Signature verification in HSE

1,042 Views
cij45
Contributor II

Hello,

I am currently using the S32K312.

I imported a Ed25519 public key in the HSE and am attempting to verify a signature that was generated externally. However, the verification consistently returns the error code 0x55A5A164UL.

Could you please let me know if there is any issue with the parameters I am using for the Ed25519 verification service?

* If possible, I would also appreciate it if you could share a demo code or reference example for performing Ed25519 signature verification using the HSE on S32K312.

Thank you for your support!

 

const uint8_t eccPubKey[32] = {Ed25519 public key};

ImportEccKeyReq(NVM_ECC_SECUREBOOT_HANDLE, HSE_KEY_TYPE_ECC_PUB, HSE_KF_USAGE_VERIFY | HSE_KF_USAGE_AUTHORIZATION,					   				HSE_EC_25519_ED25519, 256, (HOST_ADDR)eccPubKey, NULL);

uint8_t demo_plain[16]= {input value not hashed };
uint8_t rsignature[32]= {First 32 signature};
uint8_t ssignature[32]= {Last 32 signature};
uint32_t demo_sigsize[1] = {32};
	 
EddsaVerify(NVM_ECC_SECUREBOOT_HANDLE, FALSE, 16, (uint8_t*)demo_plain, FALSE, 0, 0, demo_sigsize, rsignature, demo_sigsize, ssignature);

 

hseSrvResponse_t EddsaVerify(hseKeyHandle_t keyHandle, bool_t bHashEddsa,
                             uint32_t inputLength, const uint8_t* pInput, bool_t bInputIsHashed,
                             uint8_t userContextLength, const uint8_t* pUserContext,
                             const uint32_t* pRLen, const uint8_t* pR,
                             const uint32_t* pSLen, const uint8_t* pS)
{
    hseSignScheme_t signScheme;

    signScheme.signSch                 = HSE_SIGN_EDDSA;
    signScheme.sch.eddsa.bHashEddsa    = bHashEddsa;
    signScheme.sch.eddsa.contextLength = userContextLength;
    signScheme.sch.eddsa.pContext      = (HOST_ADDR)pUserContext;

    return VerReq(HSE_ACCESS_MODE_ONE_PASS, signScheme,
                  keyHandle, muIf, muChannelIdx,
                  inputLength, pInput, bInputIsHashed, 0,
                  pRLen, pR,
                  pSLen, pS, gSyncTxOption);
}


static hseSrvResponse_t VerReq(hseAccessMode_t accessMode, hseSignScheme_t signScheme,
                               hseKeyHandle_t keyHandle, const uint8_t muIf,
                               const uint8_t muChannelIdx, uint32_t inputLength,
                               const uint8_t* pInput, bool_t bInputIsHashed, hseSGTOption_t sgtOption,
                               const uint32_t* pSignatureLength0, const uint8_t* pSignature0,
                               const uint32_t* pSignatureLength1, const uint8_t* pSignature1,
                               hseTxOptions_t txOptions)
{
    hseSrvDescriptor_t* pHseSrvDesc = &gHseSrvDesc[muIf][muChannelIdx];
    hseSignSrv_t* pSignSrv;
    memset(pHseSrvDesc, 0, sizeof(hseSrvDescriptor_t));

    pHseSrvDesc->srvId = HSE_SRV_ID_SIGN;
    pSignSrv = &(pHseSrvDesc->hseSrv.signReq);

    pSignSrv->accessMode          = accessMode;
    pSignSrv->signScheme          = signScheme;
    pSignSrv->authDir             = HSE_AUTH_DIR_VERIFY;
    pSignSrv->keyHandle           = keyHandle;
    pSignSrv->inputLength         = inputLength;
    pSignSrv->pInput              = (HOST_ADDR)pInput;
    pSignSrv->bInputIsHashed      = bInputIsHashed;
    pSignSrv->sgtOption           = sgtOption;
	pSignSrv->pSignature[0] 	  = (HOST_ADDR)pSignature0; 	   // R
	pSignSrv->pSignatureLength[0] = (HOST_ADDR)pSignatureLength0; // R len
	
	pSignSrv->pSignature[1] 	  = (HOST_ADDR)pSignature1; 	   // S
	pSignSrv->pSignatureLength[1] = (HOST_ADDR)pSignatureLength1; // S len



    return _HSE_Send(muIf, muChannelIdx, txOptions, pHseSrvDesc);
}
 
 
 

 

Tags (2)
0 Kudos
Reply
2 Replies

982 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi

It’s caused by endianness, most likely. There’s a note in HSE Firmware reference manual rev. 2.7 on page 118 that keys on Ed29919 curve are processed by conversion to little-endian bit strings. But HSE expects the keys in big-endian format. It’s necessary to swap the keys and also the signature.

You can use function like this for keys and for the signature:

 

void SwapArrayBytes

(

                uint8_t *pu8Source,

                uint32_t u32ByteLen

)

{

                uint32_t u32Start = (uint32_t)0U;

    uint32_t u32End   = u32ByteLen - 1U ;

    uint8_t  u8Temp   = (uint8_t)0U;

 

    if ((NULL_PTR != pu8Source) && ((uint32_t)0U != u32ByteLen))

    {

        while (u32Start < u32End)

        {

            u8Temp              = pu8Source[u32Start];

            pu8Source[u32Start] = pu8Source[u32End];

            pu8Source[u32End]   = u8Temp;

            u32Start++;

            u32End--;

        }

    }

}

 

To test the result, you can use test vectors:

https://asecuritysite.com/ecc/eddsa4

 

Regards,

Lukas

0 Kudos
Reply

813 Views
cij45
Contributor II

That was the key point,
Thank you very much for your support!!

0 Kudos
Reply
%3CLINGO-SUB%20id%3D%22lingo-sub-2298523%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3EEd25519%20Signature%20verification%20in%20HSE%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2298523%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CDIV%3E%3CP%20class%3D%22%22%3E%3CSPAN%3EHello%2C%3C%2FSPAN%3E%3C%2FP%3E%3CP%20class%3D%22%22%3E%3CSPAN%3EI%20am%20currently%20using%20the%20S32K312.%3C%2FSPAN%3E%3C%2FP%3E%3CP%20class%3D%22%22%3E%3CSPAN%3EI%20imported%20a%20Ed25519%20public%20key%20in%20the%20HSE%20and%20am%20attempting%20to%20verify%20a%20signature%20that%20was%20generated%20externally.%20However%2C%20the%20verification%20consistently%20returns%20the%20error%20code%20%3C%2FSPAN%3E%3CSTRONG%3E%3CSPAN%3E0x55A5A164UL%3C%2FSPAN%3E%3C%2FSTRONG%3E%3CSPAN%3E.%3C%2FSPAN%3E%3C%2FP%3E%3CP%20class%3D%22%22%3E%3CSPAN%3ECould%20you%20please%20let%20me%20know%20if%20there%20is%20any%20issue%20with%20the%20parameters%20I%20am%20using%20for%20the%20Ed25519%20verification%20service%3F%3C%2FSPAN%3E%3C%2FP%3E%3CP%20class%3D%22%22%3E%3CSPAN%3E*%20If%20possible%2C%20I%20would%20also%20appreciate%20it%20if%20you%20could%20share%20a%20%3C%2FSPAN%3E%3CSTRONG%3E%3CSPAN%3Edemo%20code%20or%20reference%20example%3C%2FSPAN%3E%3C%2FSTRONG%3E%3CSPAN%3E%20for%20performing%20Ed25519%20signature%20verification%20using%20the%20HSE%20on%20S32K312.%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%3CSPAN%3EThank%20you%20for%20your%20support%3C%2FSPAN%3E%3CSPAN%3E!%3C%2FSPAN%3E%3C%2FP%3E%3CBR%20%2F%3E%3C%2FDIV%3E%3CPRE%20class%3D%22lia-code-sample%20language-c%22%3E%3CCODE%3Econst%20uint8_t%20eccPubKey%5B32%5D%20%3D%20%7BEd25519%20public%20key%7D%3B%0A%0AImportEccKeyReq(NVM_ECC_SECUREBOOT_HANDLE%2C%20HSE_KEY_TYPE_ECC_PUB%2C%20HSE_KF_USAGE_VERIFY%20%7C%20HSE_KF_USAGE_AUTHORIZATION%2C%09%09%09%09%09%20%20%20%09%09%09%09HSE_EC_25519_ED25519%2C%20256%2C%20(HOST_ADDR)eccPubKey%2C%20NULL)%3B%0A%0Auint8_t%20demo_plain%5B16%5D%3D%20%7Binput%20value%20not%20hashed%20%7D%3B%0Auint8_t%20rsignature%5B32%5D%3D%20%7BFirst%2032%20signature%7D%3B%0Auint8_t%20ssignature%5B32%5D%3D%20%7BLast%2032%20signature%7D%3B%0Auint32_t%20demo_sigsize%5B1%5D%20%3D%20%7B32%7D%3B%0A%09%20%0AEddsaVerify(NVM_ECC_SECUREBOOT_HANDLE%2C%20FALSE%2C%2016%2C%20(uint8_t*)demo_plain%2C%20FALSE%2C%200%2C%200%2C%20demo_sigsize%2C%20rsignature%2C%20demo_sigsize%2C%20ssignature)%3B%0A%0A%3C%2FCODE%3E%3C%2FPRE%3E%3CBR%20%2F%3E%3CPRE%20class%3D%22lia-code-sample%20language-c%22%3E%3CCODE%3EhseSrvResponse_t%20EddsaVerify(hseKeyHandle_t%20keyHandle%2C%20bool_t%20bHashEddsa%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20uint32_t%20inputLength%2C%20const%20uint8_t*%20pInput%2C%20bool_t%20bInputIsHashed%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20uint8_t%20userContextLength%2C%20const%20uint8_t*%20pUserContext%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20uint32_t*%20pRLen%2C%20const%20uint8_t*%20pR%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20uint32_t*%20pSLen%2C%20const%20uint8_t*%20pS)%0A%7B%0A%20%20%20%20hseSignScheme_t%20signScheme%3B%0A%0A%20%20%20%20signScheme.signSch%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20HSE_SIGN_EDDSA%3B%0A%20%20%20%20signScheme.sch.eddsa.bHashEddsa%20%20%20%20%3D%20bHashEddsa%3B%0A%20%20%20%20signScheme.sch.eddsa.contextLength%20%3D%20userContextLength%3B%0A%20%20%20%20signScheme.sch.eddsa.pContext%20%20%20%20%20%20%3D%20(HOST_ADDR)pUserContext%3B%0A%0A%20%20%20%20return%20VerReq(HSE_ACCESS_MODE_ONE_PASS%2C%20signScheme%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20keyHandle%2C%20muIf%2C%20muChannelIdx%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20inputLength%2C%20pInput%2C%20bInputIsHashed%2C%200%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pRLen%2C%20pR%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20pSLen%2C%20pS%2C%20gSyncTxOption)%3B%0A%7D%0A%0A%0Astatic%20hseSrvResponse_t%20VerReq(hseAccessMode_t%20accessMode%2C%20hseSignScheme_t%20signScheme%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hseKeyHandle_t%20keyHandle%2C%20const%20uint8_t%20muIf%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20uint8_t%20muChannelIdx%2C%20uint32_t%20inputLength%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20uint8_t*%20pInput%2C%20bool_t%20bInputIsHashed%2C%20hseSGTOption_t%20sgtOption%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20uint32_t*%20pSignatureLength0%2C%20const%20uint8_t*%20pSignature0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20const%20uint32_t*%20pSignatureLength1%2C%20const%20uint8_t*%20pSignature1%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20hseTxOptions_t%20txOptions)%0A%7B%0A%20%20%20%20hseSrvDescriptor_t*%20pHseSrvDesc%20%3D%20%26amp%3BgHseSrvDesc%5BmuIf%5D%5BmuChannelIdx%5D%3B%0A%20%20%20%20hseSignSrv_t*%20pSignSrv%3B%0A%20%20%20%20memset(pHseSrvDesc%2C%200%2C%20sizeof(hseSrvDescriptor_t))%3B%0A%0A%20%20%20%20pHseSrvDesc-%26gt%3BsrvId%20%3D%20HSE_SRV_ID_SIGN%3B%0A%20%20%20%20pSignSrv%20%3D%20%26amp%3B(pHseSrvDesc-%26gt%3BhseSrv.signReq)%3B%0A%0A%20%20%20%20pSignSrv-%26gt%3BaccessMode%20%20%20%20%20%20%20%20%20%20%3D%20accessMode%3B%0A%20%20%20%20pSignSrv-%26gt%3BsignScheme%20%20%20%20%20%20%20%20%20%20%3D%20signScheme%3B%0A%20%20%20%20pSignSrv-%26gt%3BauthDir%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20HSE_AUTH_DIR_VERIFY%3B%0A%20%20%20%20pSignSrv-%26gt%3BkeyHandle%20%20%20%20%20%20%20%20%20%20%20%3D%20keyHandle%3B%0A%20%20%20%20pSignSrv-%26gt%3BinputLength%20%20%20%20%20%20%20%20%20%3D%20inputLength%3B%0A%20%20%20%20pSignSrv-%26gt%3BpInput%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20(HOST_ADDR)pInput%3B%0A%20%20%20%20pSignSrv-%26gt%3BbInputIsHashed%20%20%20%20%20%20%3D%20bInputIsHashed%3B%0A%20%20%20%20pSignSrv-%26gt%3BsgtOption%20%20%20%20%20%20%20%20%20%20%20%3D%20sgtOption%3B%0A%09pSignSrv-%26gt%3BpSignature%5B0%5D%20%09%20%20%3D%20(HOST_ADDR)pSignature0%3B%20%09%20%20%20%2F%2F%20R%0A%09pSignSrv-%26gt%3BpSignatureLength%5B0%5D%20%3D%20(HOST_ADDR)pSignatureLength0%3B%20%2F%2F%20R%20len%0A%09%0A%09pSignSrv-%26gt%3BpSignature%5B1%5D%20%09%20%20%3D%20(HOST_ADDR)pSignature1%3B%20%09%20%20%20%2F%2F%20S%0A%09pSignSrv-%26gt%3BpSignatureLength%5B1%5D%20%3D%20(HOST_ADDR)pSignatureLength1%3B%20%2F%2F%20S%20len%0A%0A%0A%0A%20%20%20%20return%20_HSE_Send(muIf%2C%20muChannelIdx%2C%20txOptions%2C%20pHseSrvDesc)%3B%0A%7D%3C%2FCODE%3E%3C%2FPRE%3E%3CDIV%3E%26nbsp%3B%3C%2FDIV%3E%3CDIV%3E%26nbsp%3B%3C%2FDIV%3E%3CDIV%3E%26nbsp%3B%3C%2FDIV%3E%3CBR%20%2F%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2299226%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%20translate%3D%22no%22%3ERe%3A%20Ed25519%20Signature%20verification%20in%20HSE%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2299226%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3EHi%3C%2FP%3E%0A%3CP%3EIt%E2%80%99s%20caused%20by%20endianness%2C%20most%20likely.%20There%E2%80%99s%20a%20note%20in%20HSE%20Firmware%20reference%20manual%20rev.%202.7%20on%20page%20118%20that%20keys%20on%20Ed29919%20curve%20are%20processed%20by%20conversion%20to%20little-endian%20bit%20strings.%20But%20HSE%20expects%20the%20keys%20in%20big-endian%20format.%20It%E2%80%99s%20necessary%20to%20swap%20the%20keys%20and%20also%20the%20signature.%3C%2FP%3E%0A%3CP%3EYou%20can%20use%20function%20like%20this%20for%20keys%20and%20for%20the%20signature%3A%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CP%3Evoid%20SwapArrayBytes%3C%2FP%3E%0A%3CP%3E(%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20uint8_t%20*pu8Source%2C%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20uint32_t%20u32ByteLen%3C%2FP%3E%0A%3CP%3E)%3C%2FP%3E%0A%3CP%3E%7B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20uint32_t%20u32Start%20%3D%20(uint32_t)0U%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20uint32_t%20u32End%26nbsp%3B%26nbsp%3B%20%3D%20u32ByteLen%20-%201U%20%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20uint8_t%26nbsp%3B%20u8Temp%26nbsp%3B%26nbsp%3B%20%3D%20(uint8_t)0U%3B%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20if%20((NULL_PTR%20!%3D%20pu8Source)%20%26amp%3B%26amp%3B%20((uint32_t)0U%20!%3D%20u32ByteLen))%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20%7B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20while%20(u32Start%20%26lt%3B%20u32End)%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20%7B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20u8Temp%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20%3D%20pu8Source%5Bu32Start%5D%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20pu8Source%5Bu32Start%5D%20%3D%20pu8Source%5Bu32End%5D%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20pu8Source%5Bu32End%5D%26nbsp%3B%26nbsp%3B%20%3D%20u8Temp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20u32Start%2B%2B%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20u32End--%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%26nbsp%3B%20%7D%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%26nbsp%3B%20%7D%3C%2FP%3E%0A%3CP%3E%7D%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CP%3ETo%20test%20the%20result%2C%20you%20can%20use%20test%20vectors%3A%3C%2FP%3E%0A%3CP%3E%3CA%20href%3D%22https%3A%2F%2Fasecuritysite.com%2Fecc%2Feddsa4%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Fasecuritysite.com%2Fecc%2Feddsa4%3C%2FA%3E%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CP%3ERegards%2C%3C%2FP%3E%0A%3CP%3ELukas%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-2300595%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%20translate%3D%22no%22%3ERe%3A%20Ed25519%20Signature%20verification%20in%20HSE%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2300595%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3E%3CP%3E%3CSPAN%3EThat%20was%20the%20key%20point%2C%3C%2FSPAN%3E%3CBR%20%2F%3EThank%20you%20very%20much%20for%20your%20support!!%3C%2FP%3E%3C%2FLINGO-BODY%3E