u64bit encrypt_number(u64bit cc_number, int length, const std::string& key_str, const std::string& tweak){ BigInt n = 1; for(int j=0; j<length; ++j){ n = n * 10; } u64bit cc_ranked = cc_rank(cc_number); SymmetricKey key = sha1(key_str); BigInt c = FPE::fe1_encrypt(n, cc_ranked, key, sha1(tweak)); if(c.bits() > 50) throw std::runtime_error("FPE produced a number too large"); u64bit enc_cc = 0; for(u32bit i = 0; i != 7; ++i) enc_cc = (enc_cc << 8) | c.byte_at(6-i); return cc_derank(enc_cc); }
PointGFp operator*(const BigInt& scalar, const PointGFp& point) { //BOTAN_ASSERT(point.on_the_curve(), "Input is on the curve"); const CurveGFp& curve = point.get_curve(); const size_t scalar_bits = scalar.bits(); std::vector<BigInt> ws(9); if(scalar_bits <= 2) { const byte abs_val = scalar.byte_at(0); if(abs_val == 0) return PointGFp::zero_of(curve); PointGFp result = point; if(abs_val == 2) result.mult2(ws); if(scalar.is_negative()) result.negate(); return result; } PointGFp R[2] = { PointGFp(curve), point }; for(size_t i = scalar_bits; i > 0; i--) { const size_t b = scalar.get_bit(i - 1); R[b ^ 1].add(R[b], ws); R[b].mult2(ws); } if(scalar.is_negative()) R[0].negate(); //BOTAN_ASSERT(R[0].on_the_curve(), "Output is on the curve"); return R[0]; }