Ed25519 Signature verification in HSE

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

Ed25519 Signature verification in HSE

1,166 次查看
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);
}
 
 
 

 

标记 (2)
0 项奖励
回复
2 回复数

1,106 次查看
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 项奖励
回复

937 次查看
cij45
Contributor II

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

0 项奖励
回复
%3CLINGO-SUB%20id%3D%22lingo-sub-2298523%22%20slang%3D%22en-US%22%20mode%3D%22CREATE%22%3EEd25519%20HSE%20%E4%B8%AD%E7%9A%84%E7%AD%BE%E5%90%8D%E9%AA%8C%E8%AF%81%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%3E%E4%BD%A0%E5%A5%BD%3C%2FSPAN%3E%3C%2FP%3E%3CP%20class%3D%22%22%3E%3CSPAN%3E%E6%88%91%E7%9B%AE%E5%89%8D%E4%BD%BF%E7%94%A8%E7%9A%84%E6%98%AF%20S32K312%E3%80%82%3C%2FSPAN%3E%3C%2FP%3E%3CP%20class%3D%22%22%3E%3CSPAN%3E%E6%88%91%E5%9C%A8%20HSE%20%E4%B8%AD%E5%AF%BC%E5%85%A5%E4%BA%86%20Ed25519%20%E5%85%AC%E9%92%A5%EF%BC%8C%E5%B9%B6%E5%B0%9D%E8%AF%95%E9%AA%8C%E8%AF%81%E5%A4%96%E9%83%A8%E7%94%9F%E6%88%90%E7%9A%84%E7%AD%BE%E5%90%8D%E3%80%82%E4%BD%86%E6%98%AF%EF%BC%8C%E9%AA%8C%E8%AF%81%E5%A7%8B%E7%BB%88%E8%BF%94%E5%9B%9E%E9%94%99%E8%AF%AF%E4%BB%A3%E7%A0%81%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%3E%E8%AF%B7%E5%91%8A%E8%AF%89%E6%88%91%20Ed25519%20%E9%AA%8C%E8%AF%81%E6%9C%8D%E5%8A%A1%E4%BD%BF%E7%94%A8%E7%9A%84%E5%8F%82%E6%95%B0%E6%98%AF%E5%90%A6%E6%9C%89%E9%97%AE%E9%A2%98%EF%BC%9F%3C%2FSPAN%3E%3C%2FP%3E%3CP%20class%3D%22%22%3E%3CSPAN%3E*%20%E5%A6%82%E6%9E%9C%E5%8F%AF%E8%83%BD%E7%9A%84%E8%AF%9D%EF%BC%8C%E5%A6%82%E6%9E%9C%E4%BD%A0%E8%83%BD%E5%88%86%E4%BA%AB%E5%9C%A8%3C%2FSPAN%3E%3CSPAN%3E%20S32K312%20%E4%B8%8A%20%E4%BD%BF%E7%94%A8%20HSE%20%E6%89%A7%E8%A1%8C%20Ed25519%20%E7%AD%BE%E5%90%8D%E9%AA%8C%E8%AF%81%3C%2FSPAN%3E%3CSTRONG%3E%3CSPAN%3E%20%E7%9A%84%20%E6%BC%94%E7%A4%BA%E4%BB%A3%E7%A0%81%E6%88%96%E5%8F%82%E8%80%83%E7%A4%BA%E4%BE%8B%20%EF%BC%8C%E6%88%91%E4%B9%9F%E5%B0%86%E4%B8%8D%E8%83%9C%E6%84%9F%E6%BF%80%20%E3%80%82%3C%2FSPAN%3E%3C%2FSTRONG%3E%3C%2FP%3E%3CP%3E%3CSPAN%3E%E6%84%9F%E8%B0%A2%E6%82%A8%E7%9A%84%E6%94%AF%E6%8C%81%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%20translate%3D%22no%22%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%20translate%3D%22no%22%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%3E%E8%BF%99%E5%BE%88%E5%8F%AF%E8%83%BD%E6%98%AF%E7%94%B1%E5%AD%97%E8%8A%82%E5%BA%8F%E9%80%A0%E6%88%90%E7%9A%84%E3%80%82HSE%20%E5%9B%BA%E4%BB%B6%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C%E4%BF%AE%E8%AE%A2%E7%89%88%E4%B8%AD%E6%9C%89%E6%B3%A8%E9%87%8A2.7%20%E7%AC%AC%20118%20%E9%A1%B5%EF%BC%8CEd29919%20%E6%9B%B2%E7%BA%BF%E4%B8%8A%E7%9A%84%E9%94%AE%E6%98%AF%E9%80%9A%E8%BF%87%E8%BD%AC%E6%8D%A2%E4%B8%BA%E5%B0%8F%E6%95%B0%E4%BD%8D%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%9D%A5%E5%A4%84%E7%90%86%E7%9A%84%E3%80%82%E4%BD%86%20HSE%20%E5%B8%8C%E6%9C%9B%E9%94%AE%E5%80%BC%E6%98%AF%E5%A4%A7%E4%BA%8C%E8%BF%9B%E5%88%B6%E6%A0%BC%E5%BC%8F%E3%80%82%E6%9C%89%E5%BF%85%E8%A6%81%E4%BA%A4%E6%8D%A2%E5%AF%86%E9%92%A5%E5%92%8C%E7%AD%BE%E5%90%8D%E3%80%82%3C%2FP%3E%0A%3CP%3E%E6%82%A8%E5%8F%AF%E4%BB%A5%E5%B0%86%E8%BF%99%E6%A0%B7%E7%9A%84%E5%87%BD%E6%95%B0%E7%94%A8%E4%BA%8E%E9%94%AE%E5%92%8C%E7%AD%BE%E5%90%8D%EF%BC%9A%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CP%3Evoid%20SwapArrayBytes%3C%2FP%3E%0A%3CP%3E%EF%BC%88%3C%2FP%3E%0A%3CP%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20uint8_t%20*pu8Source%E3%80%81%3C%2FP%3E%0A%3CP%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20uint32_t%20u32ByteLen%3C%2FP%3E%0A%3CP%3E%EF%BC%89%3C%2FP%3E%0A%3CP%3E%7B%3C%2FP%3E%0A%3CP%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20uint32_t%20u32Start%20%3D%20(uint32_t)0U%EF%BC%9B%3C%2FP%3E%0A%3CP%3E%20%20%20%20uint32_t%20u32End%20%3D%20u32ByteLen%20-%201U%20%EF%BC%9B%3C%2FP%3E%0A%3CP%3E%20%20%20%20uint8_t%20u8Temp%20%3D%20(uint8_t)0U%EF%BC%9B%3C%2FP%3E%0A%3CBR%20%2F%3E%0A%3CP%3E%20%20%20%20if%20((NULL_PTR%20!%3D%20pu8Source)%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%20%20%20%20%20%20%20%20while%20(u32Start%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%20%20%20%20%20%20%20%20%20%20%20%20u8Temp%20%3D%20pu8Source%5Bu32Start%5D%EF%BC%9B%3C%2FP%3E%0A%3CP%3E%20%20%20%20%20%20%20%20%20%20%20%20pu8Source%5Bu32Start%5D%20%3D%20pu8Source%5Bu32End%5D%EF%BC%9B%3C%2FP%3E%0A%3CP%3E%20%20%20%20%20%20%20%20%20%20%20%20pu8Source%5Bu32End%5D%20%3D%20u8Temp%EF%BC%9B%3C%2FP%3E%0A%3CP%3E%20%20%20%20%20%20%20%20%20%20%20%20u32Start%2B%2B%EF%BC%9B%3C%2FP%3E%0A%3CP%3E%20%20%20%20%20%20%20%20%20%20%20%20u32End--%EF%BC%9B%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%3E%E8%A6%81%E6%B5%8B%E8%AF%95%E7%BB%93%E6%9E%9C%EF%BC%8C%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%E6%B5%8B%E8%AF%95%E5%90%91%E9%87%8F%EF%BC%9A%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%3E%E6%AD%A4%E8%87%B4%EF%BC%8C%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%3E%E8%BF%99%E5%B0%B1%E6%98%AF%E5%85%B3%E9%94%AE%E6%89%80%E5%9C%A8%EF%BC%8C%3C%2FSPAN%3E%3CBR%20%2F%3E%EF%BC%8C%E9%9D%9E%E5%B8%B8%E6%84%9F%E8%B0%A2%E4%BD%A0%E4%BB%AC%E7%9A%84%E6%94%AF%E6%8C%81%EF%BC%81%3C%2FP%3E%3C%2FLINGO-BODY%3E