ByteSeq EC2OSP(const EC_Point & Point, EC::EC2OSP_COMPRESS_MODE mode) { const unsigned char tY = ((mode == EC::EC2OSP_COMPRESSED) || (mode == EC::EC2OSP_HYBRID)) ? EC_CPoint::compress_tY(Point) : 0; if (Point.isZero()) return ByteSeq(0); /* Pad - according to example of 2^m/ECNR. * Check this. Don't see much sense */ const long Pad = L(Point.getEC().getModulus()); const unsigned int U = ((mode == EC::EC2OSP_UNCOMPRESSED) || (mode == EC::EC2OSP_HYBRID)) ? 1 : 0; const unsigned int C = ((mode == EC::EC2OSP_COMPRESSED) || (mode == EC::EC2OSP_HYBRID)) ? 1 : 0; const ByteSeq X(FE2OSP(Point.getX(), Pad)); const ByteSeq H(FE2OSP(4*U+C*(2+tY))); if (U) return H || X || FE2OSP(Point.getY(), Pad); else return H || X; }
CSL_error CSL_GenerateEccSharedKey(CSLOSEccPrivateKey privateKey, CSLOSEccPublicKey publicKey, CSLOSEccSharedKey sharedKey, u32 numBytes){ field_2n pvtkey, sharedkey; point publickey; CSLOSEccSharedKey sharedKeyCopy; CSL_error error = CSL_OK; if(numBytes > sizeof(CSLOSEccSharedKey)){ return CSL_OVERFLOW; } poly_elliptic_init_233_bit(); OS2FEP(privateKey, &pvtkey); OS2ECP(publicKey, OCTET_STRING_LEN*2, &publickey); error = alg_generate_shared_key(&named_point, &named_curve, &publickey, &pvtkey, &sharedkey); /* collect the result into output */ #ifdef KDF1 post_process_key(&sharedkey, sharedKeyCopy); #else FE2OSP(sharedKeyCopy, &sharedkey); #endif /* convert to octet string of desired length */ memcpy(sharedKey, sharedKeyCopy, numBytes); return error; }
static void post_process_key(field_2n *sharedkey, CSLOSEccSharedKey sharedkeystr){ #ifdef HWCRYPTO IOSCHashContext sha; IOSCHash hash; FE2OSP(alignedKeyStr, sharedkey); __iosGenerateHash(sha, 0, 0, IOSC_HASH_FIRST, hash, -1, 0); __iosGenerateHash(sha, alignedKeyStr, OCTET_STRING_LEN, IOSC_HASH_LAST, hash, -1, 0); memcpy((unsigned char *)sharedkeystr, hash, sizeof(IOSCHash)); #else u8 inputkeystr[OCTET_STRING_LEN]; SHA1Context shactx; /* convert to octet string */ FE2OSP(inputkeystr, sharedkey); SHA1Reset(&shactx); SHA1Input(&shactx, inputkeystr, OCTET_STRING_LEN); SHA1Result(&shactx, (unsigned char *)sharedkeystr); #endif }
virtual Octet generatePublicKey() { if (! _isPrivateKeyLoaded) throw std::exception(); // Operation unaviable _Curve.enter_mod_context(EC_Dscr::aEC::FIELD_CONTEXT); _publicKey = _BasePoint * _privateKey; typename EC_Dscr::aECP _AffinePublicKey = toAffine(_publicKey); _Curve.leave_mod_context(); _isPublicKeyLoaded = true; setPublicKeyHook(); return FE2OSP(_AffinePublicKey.getX(), _Lcm) || FE2OSP(_AffinePublicKey.getY(), _Lcm); }
CSL_error CSL_GenerateEccKeyPair(CSLOSEccPrivateRand rand, CSLOSEccPrivateKey privateKey, CSLOSEccPublicKey publicKey){ field_2n pvtkey; OS2FEP(rand, &pvtkey); memset(privateKey, 0x0, sizeof(CSLOSEccPrivateKey)); FE2OSP(privateKey, &pvtkey); return CSL_GenerateEccPublicKey(privateKey, publicKey); }
ECIES::ECIES (OCTETSTR& M, ECPubKey& pk) { OCTETSTR P1, P2; // These are 0 ECPrivKey u (pk.dp); V = ECPubKey(u); F2M z = ECSVDP_DH (pk.dp, u.s, pk.W); OCTETSTR Z = FE2OSP (z); OCTETSTR K = KDF2_SURDOC (Z, 32, P1); // 256 bits OCTETSTR K1 (16); // 128 bit symmetric encryption key OCTETSTR K2 (16); // 128 bit MAC key for (int j=0; j<K1.size();j++) { K1[j] = K[j]; } for (int k=0; k<K2.size();k++) { K2[k] = K[k+K1.size()]; } C = AES_CBC_IV0_Encrypt (K1, M); T = MAC1 (K2, C||P2); }
CSL_error CSL_GenerateEccSharedKeyPre(CSLOSEccPrivateKey privateKey, CSLOSEccExpPublicKey publicKey, CSLOSEccSharedKey sharedKey, u32 numBytes){ field_2n pvtkey, sharedkey; CSLOSEccSharedKey sharedKeyCopy; CSL_error error = CSL_OK; int j; #ifdef __KERNEL__ point *precomputedpublickey = kmalloc(sizeof(point) * 16, GFP_KERNEL); if (!precomputedpublickey) return CSL_NO_MEMORY; #else point precomputedpublickey[16]; #endif poly_elliptic_init_233_bit(); OS2FEP(privateKey, &pvtkey); /* convert public key to point variable */ for(j=0; j< 16; j++){ OS2ECP((publicKey + (2*OCTET_STRING_LEN*j)), (2*OCTET_STRING_LEN), &(precomputedpublickey[j])); } error = alg_generate_shared_key_pre(&named_point, &named_curve, &precomputedpublickey[0], &pvtkey, &sharedkey); /* collect the result into output */ #ifdef KDF1 post_process_key(&sharedkey, sharedKeyCopy); #else FE2OSP(sharedKeyCopy, &sharedkey); #endif /* convert to octet string of desired length */ memcpy(sharedKey, sharedKeyCopy, numBytes); #ifdef __KERNEL__ kfree(precomputedpublickey); #endif return error; }
// Throws ECIES_Err if the tag is invalid OCTETSTR ECIES::decrypt (ECPrivKey& sk) { OCTETSTR P1, P2; // These are 0 F2M z = ECSVDP_DH (sk.dp, sk.s, V.W); OCTETSTR Z = FE2OSP (z); OCTETSTR K = KDF2_SURDOC (Z, 32, P1); // 256 bits OCTETSTR K1 (16); // 128 bit symmetric encryption key OCTETSTR K2 (16); // 128 bit MAC key for (int j=0; j<K1.size();j++) { K1[j] = K[j]; } for (int k=0; k<K2.size();k++) { K2[k] = K[k+K1.size()]; } OCTETSTR M = AES_CBC_IV0_Decrypt (K1, C); if (T != MAC1 (K2, C||P2)) { throw borzoiException ("ECIES: tag invalid"); } return M; }