void sm2_z ( unsigned char *id, unsigned int ilen, point_affn_ptr G, point_affn_ptr sG, unsigned char *hash ) { sm3_context ctx; #ifndef MUL_BITS unsigned char xt[FIELD_SIZE_IN_BYTES*2]; #else unsigned char xt[32*2]; #endif unsigned short nlen = ilen*8; int tlen; sm3_starts( &ctx ); #ifdef LT_ENDIAN xt[0]= ((unsigned char *)&nlen)[1]; xt[1]= ((unsigned char *)&nlen)[0]; #else xt[0]= ((unsigned char *)&nlen)[0]; xt[1]= ((unsigned char *)&nlen)[1]; #endif sm3_update( &ctx, xt, 2 ); // dump_mem(xt, 2, "idlen"); if(id && ilen) sm3_update( &ctx, id, ilen ); // dump_mem(id, ilen, "id"); tlen = FIELD_SIZE_IN_BYTES; I2OSP(xt, tlen, COA); sm3_update( &ctx, xt, tlen ); // dump_mem(xt, tlen, "a"); tlen = FIELD_SIZE_IN_BYTES; I2OSP(xt, tlen, COB); sm3_update( &ctx, xt, tlen ); // dump_mem(xt, tlen, "b"); tlen = sizeof(xt); EC2OSP_XY(xt, &tlen, G); sm3_update( &ctx, xt, tlen ); // dump_mem(xt, tlen, "G"); tlen = sizeof(xt); EC2OSP_XY(xt, &tlen, sG); sm3_update( &ctx, xt, tlen ); // dump_mem(xt, tlen, "sG"); sm3_finish( &ctx, hash ); memset( &ctx, 0, sizeof( sm3_context ) ); }
/* * RSA private key encrypt using the straightforward but less * efficient algorithm: * * c = (m**d) mod n * * where * c = ciphertext * m = cleartext message * d = private exponent * n = public modulus * * In the common usage, the cleartext message is a digest (SHA1 or SHA256) * padded to keysize as specified by EMSA-PKCS1-v1_5. */ void CSL_ComputeRsaSig(CSLOSRsaSig result, CSLOSRsaMsg paddedmessage, CSLOSRsaPublicKey certpublickey, CSLOSRsaSecretExp secretexponent, u32 keysize) { u32 dDigits, nDigits; #ifdef __KERNEL__ bigint_digit *_big = kmalloc(4 * sizeof(bigint_digit) * MAX_BIGINT_DIGITS, GFP_KERNEL); bigint_digit *bign = _big; bigint_digit *bigm = bign + MAX_BIGINT_DIGITS; bigint_digit *bigd = bigm + MAX_BIGINT_DIGITS; /* secret exp */ bigint_digit *bigc = bigd + MAX_BIGINT_DIGITS; #else bigint_digit bign[MAX_BIGINT_DIGITS]; bigint_digit bigm[MAX_BIGINT_DIGITS]; bigint_digit bigd[MAX_BIGINT_DIGITS]; /* secret exp */ bigint_digit bigc[MAX_BIGINT_DIGITS]; #endif int outlen; nDigits = keysize/BIGINT_DIGIT_BYTES; dDigits = keysize/BIGINT_DIGIT_BYTES; OS2IP (bign, nDigits, certpublickey, keysize); OS2IP (bigm, nDigits, paddedmessage, keysize); OS2IP (bigd, dDigits, secretexponent, keysize); bigint_mod_exp(bigc, bigm, bigd, dDigits, bign, nDigits); outlen = ((keysize * 8) + 7)/8; I2OSP(result, outlen, bigc, nDigits); #ifdef __KERNEL__ kfree(_big); #endif }
DigitalSignature sign(const ManagedBlob & data, const DataInputPolicy * dip = NULL) { if (! _isPrivateKeyLoaded) throw std::exception(); const ZZ k = OS2IP(_PRNG()) % _Curve.getOrder(); Octet P; do { _Curve.enter_mod_context(EC_Dscr::aEC::FIELD_CONTEXT); const typename EC_Dscr::aECP PP = toAffine(_BasePoint * k); _Curve.leave_mod_context(); if (PP.isZero()) continue; P = EC2OSP(PP, EC_Dscr::aEC::EC2OSP_COMPRESSED); break; } while(1); /* FIX IT */ const DSSDataInput SignData = dip == NULL ? _ECNR_Data.createInput(data, P) : TDataInput<ECNR_Input>(*dip).createInput(data, P); _Curve.enter_mod_context(EC_Dscr::aEC::ORDER_CONTEXT); const ZZ_p pi = InMod(OS2IP(P)); const ZZ_p d = InMod(OS2IP(SignData.d)); const ZZ_p r = (d + pi); const ZZ_p s = (InMod(k) - InMod(_privateKey)*r); _Curve.leave_mod_context(); const ByteSeq R = I2OSP(r,_Ln); const ByteSeq S = I2OSP(s,_Ln); return DigitalSignature(R, S, SignData.M_clr); }
VerificationVerdict verify(const DigitalSignature & data, const DataInputPolicy * dip = NULL) { if ( ! _isPublicKeyLoaded ) throw std::exception(); ZZ t = OS2IP(data.R); ZZ s = OS2IP(data.S); if ((L(t) > _Ln || (IsZero(t))) || (s > _Curve.getOrder())) return VerificationVerdict(); t %= _Curve.getOrder(); _Curve.enter_mod_context(EC_Dscr::aEC::FIELD_CONTEXT); typename EC_Dscr::aECP R = toAffine(_publicKey * t + _BasePoint * s); _Curve.leave_mod_context(); const Octet P = EC2OSP(R, EC_Dscr::aEC::EC2OSP_COMPRESSED); const ZZ d = (t - OS2IP(P)) % _Curve.getOrder(); Octet vdata = I2OSP(d); /* MAKE CHECKS */ const DSSDataOutput vmsg = dip == NULL ? _ECNR_Data.createOutput(vdata) : TDataInput<ECNR_Input>(*dip).createOutput(vdata); ManagedBlob M = vmsg.M_rec || data.M_clr; const DSSDataInput vsign = dip == NULL ? _ECNR_Data.createInput(M, P) : TDataInput<ECNR_Input>(*dip).createInput(M, P); if (vsign.d == vmsg.d_pad) { return VerificationVerdict(M); } else { return VerificationVerdict(); } }
/* * RSA Sign using Garners algorithm and Chinese Remainder theorem. * See the derivation on page 613 in handbook of applied cryptography * use factors dp and dq of secret exponent d and p and q of public * exponent n, and qinv */ void CSL_ComputeRsaSigFast(u8 *result, u32 *message, u32 *certpublickey, u32 *certp, u32 *certq, u32 *dmp, u32 *dmq, u32 *qinv, int num_bits) { u32 pDigits, qDigits, cDigits, nDigits; bigint_digit bigp[MAX_BIGINT_DIGITS]; bigint_digit bigq[MAX_BIGINT_DIGITS]; bigint_digit bigc[MAX_BIGINT_DIGITS]; bigint_digit bigdmp[MAX_BIGINT_DIGITS]; bigint_digit bigdmq[MAX_BIGINT_DIGITS]; bigint_digit bigqinv[MAX_BIGINT_DIGITS]; bigint_digit bign[MAX_BIGINT_DIGITS]; bigint_digit cP[MAX_BIGINT_DIGITS]; bigint_digit cQ[MAX_BIGINT_DIGITS]; bigint_digit mP[MAX_BIGINT_DIGITS]; bigint_digit mQ[MAX_BIGINT_DIGITS]; bigint_digit temp[MAX_BIGINT_DIGITS]; int outlen; int i; int num_words = num_bits/BIGINT_DIGIT_BITS; bigint_zero(bigp, MAX_BIGINT_DIGITS); bigint_zero(bigq, MAX_BIGINT_DIGITS); bigint_zero(bigdmp, MAX_BIGINT_DIGITS); bigint_zero(bigdmq, MAX_BIGINT_DIGITS); bigint_zero(bigqinv, MAX_BIGINT_DIGITS); bigint_zero(bigc, MAX_BIGINT_DIGITS); for (i = 0; i < num_words/2; i++) { bigp[num_words/2 - 1 - i] = certp[i]; bigq[num_words/2 - 1 - i] = certq[i]; bigdmp[num_words/2 - 1 - i] = dmp[i]; bigdmq[num_words/2 - 1 - i] = dmq[i]; bigqinv[num_words/2 - 1 - i] = qinv[i]; } for (i = 0; i < num_words; i++) { bigc[num_words - 1 - i] = message[i]; bign[num_words - 1 - i] = certpublickey[i]; } cDigits = bigint_digits(bigc, MAX_BIGINT_DIGITS); pDigits = bigint_digits(bigp, MAX_BIGINT_DIGITS); qDigits = bigint_digits(bigq, MAX_BIGINT_DIGITS); nDigits = bigint_digits(bign, MAX_BIGINT_DIGITS); /* * compute cP and cQ */ bigint_mod(cP, bigc, cDigits, bigp, pDigits); bigint_mod(cQ, bigc, cDigits, bigq, qDigits); /* * Compute mP = cP^dP mod p and mQ = cQ^dQ mod q. */ bigint_mod_exp(mP, cP, bigdmp, pDigits, bigp, pDigits); bigint_zero(mQ, nDigits); bigint_mod_exp(mQ, cQ, bigdmq, pDigits, bigq, pDigits); /* * do CRT * m = ((((mP - mQ) mod p)*qinv) mod p) *q + mQ */ if (bigint_cmp(mP, mQ, pDigits) >= 0) { bigint_sub(temp, mP, mQ, pDigits); } else { bigint_sub(temp, mQ, mP, pDigits); bigint_sub(temp, bigp, temp, pDigits); } bigint_mod_mult(temp, temp, bigqinv, bigp, pDigits); bigint_mult(temp, temp, bigq, pDigits); bigint_add(temp, temp, mQ, nDigits); outlen = (num_bits + 7)/8; I2OSP(result, outlen, temp, nDigits); }
int sm2_sign ( sm2_prvkey *prvkey, unsigned char *id, unsigned int ilen, unsigned char *message, unsigned int mlen, unsigned char *signature, unsigned int *slen ) { #ifndef MUL_BITS unsigned char xt[FIELD_SIZE_IN_BYTES*2]; #else unsigned char xt[32*2]; #endif mpz_t e, k, s; point_affn_t kG; //unsigned int xlen = sizeof(xt); if( !signature ) { *slen = FIELD_SIZE_IN_BYTES*2; return 0; } if(*slen < (unsigned int)(FIELD_SIZE_IN_BYTES*2)) return 1; sm2_z(id, ilen, GENERATOR, prvkey->sG, xt); // dump_mem(z, sizeof(z), "z"); sm2_hash(xt, SM3_HASH_LEN, message, mlen, NULL, 0, xt); // dump_mem(h, sizeof(h), "h"); mpz_init(e); OS2IP(e, xt, SM3_HASH_LEN); //e NN_BarrettSetBuf(&pXbufSubgrpOrder); mpz_mod(e, e, SUBGRP_ORDER); mpz_init(k); random_limit(k, SUBGRP_ORDER); NN_BarrettSetBuf(&pXbufFieldPrime); #ifdef USE_ECC_256 //mpz_set_str(k, "6CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F", 16); #else //mpz_set_str(k, "ADB6F4FE3E8B1D9E0DA8C0D40FC962195DFAE76F5656460", 16); #endif point_affn_init(kG); point_affn_mul(kG, GENERATOR, k); // dump_point(kG, "kG"); // gmp_printf("x: %Zx\n", x); mpz_BarrettSetBuf(&pXbufSubgrpOrder); //mpz_mod_BarrettInit(SUBGRP_ORDER, &pXbuf); zp_add_mod_p(e, e, kG->x, SUBGRP_ORDER); I2OSP(signature, FIELD_SIZE_IN_BYTES, e); point_affn_clear(kG); mpz_init(s); mpz_add_ui(s, prvkey->s, 1); //1+d_A mpz_invert(s, s, SUBGRP_ORDER); //(1+d_A)^-1 zp_mul_mod_p(e, e, prvkey->s, SUBGRP_ORDER); zp_sub_mod_p(k, k, e, SUBGRP_ORDER); zp_mul_mod_p(s, s, k, SUBGRP_ORDER); //mpz_mod_BarrettInit(FIELD_P, &pXbuf); mpz_BarrettSetBuf(&pXbufFieldPrime); I2OSP(signature+FIELD_SIZE_IN_BYTES, FIELD_SIZE_IN_BYTES, s); *slen = FIELD_SIZE_IN_BYTES*2; mpz_clear(e); mpz_clear(k); mpz_clear(s); return 0; }