BnMod-BnDiv-求余运算

10 篇文章 0 订阅
该代码示例展示了如何在TPM(TrustedPlatformModule)中使用ECDSA创建主密钥,并进行大数除法操作来生成ECC私钥。通过TPM创建主密钥,然后利用大数除法计算余数,将余数加1得到ECC私钥,最终生成对应的公钥。验证了公私钥对的正确性。
摘要由CSDN通过智能技术生成

客户端代码:

 @Test
    public void doMyEccprimaryKey(){
// Do the same thing with an ECDSA key
        // Create an RSA signing public key in the owner hierarchy
        TPMT_PUBLIC eccTemplate = new TPMT_PUBLIC(TPM_ALG_ID.SHA256,
                new TPMA_OBJECT(TPMA_OBJECT.sign, TPMA_OBJECT.sensitiveDataOrigin, TPMA_OBJECT.userWithAuth), new byte[0],
                new TPMS_ECC_PARMS(new TPMT_SYM_DEF_OBJECT(TPM_ALG_ID.NULL,  0, TPM_ALG_ID.NULL),
                        new TPMS_SIG_SCHEME_ECDSA(TPM_ALG_ID.SHA256), TPM_ECC_CURVE.NIST_P256,
                        new TPMS_NULL_KDF_SCHEME()),
                new TPMS_ECC_POINT());

        // Tell the TPM to make a key with a non-null auth value.
//        TPMS_SENSITIVE_CREATE eccSens = new TPMS_SENSITIVE_CREATE(Helpers.RandomBytes(10), new byte[0]);
        TPMS_SENSITIVE_CREATE eccSens = new TPMS_SENSITIVE_CREATE();

        CreatePrimaryResponse eccPrimary = tpm.CreatePrimary(TPM_HANDLE.from(TPM_RH.OWNER), eccSens,
                eccTemplate, new byte[0], new TPMS_PCR_SELECTION[0]);

        System.out.println("ECC Primary Key: \n" + eccPrimary.toString());
        System.out.println("ecc EK: " + eccPrimary.outPublic.toString());
    }

 bnExtraBits: :
13189847BCABC9D22FF6849F94607792EB7D8D4B01ADB2E24A06BF9B44EEC0CC843A51A9A9CC7482
 order: :
512563FCC2CAB9F3849E17A7ADFAE6BCFFFFFFFFFFFFFFFF00000000FFFFFFFF
 nMinus1: :
502563FCC2CAB9F3849E17A7ADFAE6BCFFFFFFFFFFFFFFFF00000000FFFFFFFF


#define BnMod(a, b)     BnDiv(NULL, (a), (a), (b))


ECFieldElement dividend = ...; // the number to be divided
ECFieldElement divisor = ...; // the divisor
BigInteger modulus = ...; // the modulus
BigInteger result = dividend.toBigInteger().mod(divisor.toBigInteger()).mod(modulus);


LIB_EXPORT BOOL
BnDiv(
      bigNum               quotient,
      bigNum               remainder,
      bigConst             dividend,
      bigConst             divisor
      )
{
    OSSL_ENTER();
    BIGNUM              *bnQ = BN_NEW();
    BIGNUM              *bnR = BN_NEW();
    BOOL                 OK = TRUE;
    BIG_INITIALIZED(bnDend, dividend);
    BIG_INITIALIZED(bnSor, divisor);
    //
    if(BnEqualZero(divisor))
	FAIL(FATAL_ERROR_DIVIDE_ZERO);
    VERIFY(BN_div(bnQ, bnR, bnDend, bnSor, CTX));
    VERIFY(OsslToTpmBn(quotient, bnQ));
    VERIFY(OsslToTpmBn(remainder, bnR));
    DEBUG_PRINT("In BnDiv:\n");
    BIGNUM_PRINT("   bnDividend: ", bnDend, TRUE);
    BIGNUM_PRINT("    bnDivisor: ", bnSor, TRUE);
    BIGNUM_PRINT("   bnQuotient: ", bnQ, TRUE);
    BIGNUM_PRINT("  bnRemainder: ", bnR, TRUE);
    goto Exit;
 Error:
    OK = FALSE;
 Exit:
    OSSL_LEAVE();
    return OK;
}

当被除数和除数都是带符号的大整数时,除法函数为:

───────────────────────────────────────

int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor)

功能:    大数除法

输入:    num【被除数】,divisor【除数】

输出:    dv【商】,rm【余数】

返回:    1【正常】 or 0【出错】

出处:    bn_div.c

备注:    num ÷ dv = divisor …… rm

               商的符号←被除数的符号除数的符号,余数的符号←商的符号


执行   VERIFY(BN_div(bnQ, bnR, bnDend, bnSor, CTX)); 后:

被除数:

除数:

  String bnExtraBits = "8274cca9a9513a84ccc0ee449bbf064ae2b2ad014b8d7deb927760949f84f62fd2c9abbc47981813";
        String nMinus1 = "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550";


        BigInteger bigbnExtraBits = new BigInteger(bnExtraBits, 16);

        BigInteger bignMinus1 = new BigInteger(nMinus1, 16);


        BigInteger  mod = bigbnExtraBits.remainder(bignMinus1);
        System.out.println("remainder " + HexUtils.toHexString(mod.toByteArray()) );

余数 remainder =   761228C86FF8FF1D04E3FEB010580B6122B7624138B364663BD584B8EBE233B3

加1后作为 ECC私钥

 OK = OK && BnAddWord(dOut, bnExtraBits, 1); 后:

私钥:

761228C86FF8FF1D04E3FEB010580B6122B7624138B364663BD584B8EBE233B4

公钥:

725fe8766178727a130e508a639433c123f74483fc12bed2f1b17f738b86bc38
fa7fcc8801f4c426927487e51be492db8f508046d21df22a88d15a27f4a5f60d

X :

Y:

 

 

经验证公私钥对正确。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值