/* * Encode two BigInt, with leading 0s if needed, and concatenate */ secure_vector<uint8_t> BigInt::encode_fixed_length_int_pair(const BigInt& n1, const BigInt& n2, size_t bytes) { if(n1.bytes() > bytes || n2.bytes() > bytes) throw Encoding_Error("encode_fixed_length_int_pair: values too large to encode properly"); secure_vector<uint8_t> output(2 * bytes); n1.binary_encode(output.data() , bytes); n2.binary_encode(output.data() + bytes, bytes); return output; }
/************************************************* * Encode a BigInt * *************************************************/ void BigInt::encode(byte output[], const BigInt& n, Base base) { if(base == Binary) n.binary_encode(output); #ifndef BOTAN_MINIMAL_BIGINT else if(base == Hexadecimal) { SecureVector<byte> binary(n.encoded_size(Binary)); n.binary_encode(binary); for(u32bit j = 0; j != binary.size(); ++j) Hex_Encoder::encode(binary[j], output + 2*j); } #endif else if(base == Octal) { BigInt copy = n; const u32bit output_size = n.encoded_size(Octal); for(u32bit j = 0; j != output_size; ++j) { output[output_size - 1 - j] = Charset::digit2char(copy % 8); copy /= 8; } } else if(base == Decimal) { BigInt copy = n; BigInt remainder; copy.set_sign(Positive); const u32bit output_size = n.encoded_size(Decimal); for(u32bit j = 0; j != output_size; ++j) { divide(copy, 10, copy, remainder); output[output_size - 1 - j] = Charset::digit2char(remainder.word_at(0)); if(copy.is_zero()) { if(j < output_size - 1) { int extra = output_size - 1 - j; memmove(output, output + extra, output_size - extra); memset(output + output_size - extra, 0, extra); } break; } } } else throw Invalid_Argument("Unknown BigInt encoding method"); }
/* * Default ElGamal Encrypt Operation */ SecureVector<byte> Default_ELG_Op::encrypt(const byte in[], u32bit length, const BigInt& k) const { BigInt m(in, length); if(m >= p) throw Invalid_Argument("Default_ELG_Op::encrypt: Input is too large"); BigInt a = powermod_g_p(k); BigInt b = mod_p.multiply(m, powermod_y_p(k)); SecureVector<byte> output(2*p.bytes()); a.binary_encode(output + (p.bytes() - a.bytes())); b.binary_encode(output + output.size() / 2 + (p.bytes() - b.bytes())); return output; }
//static void BigInt::encode_1363(uint8_t output[], size_t bytes, const BigInt& n) { if(n.bytes() > bytes) throw Encoding_Error("encode_1363: n is too large to encode properly"); n.binary_encode(output, bytes); }
SecureVector<byte> DSA_Signature_Operation::sign(const byte msg[], size_t msg_len, RandomNumberGenerator& rng) { rng.add_entropy(msg, msg_len); BigInt i(msg, msg_len); BigInt r = 0, s = 0; while(r == 0 || s == 0) { BigInt k; do k.randomize(rng, q.bits()); while(k >= q); r = mod_q.reduce(powermod_g_p(k)); s = mod_q.multiply(inverse_mod(k, q), mul_add(x, r, i)); } SecureVector<byte> output(2*q.bytes()); r.binary_encode(&output[output.size() / 2 - r.bytes()]); s.binary_encode(&output[output.size() - s.bytes()]); return output; }
SecureVector<byte> ECDSA_Signature_Operation::sign(const byte msg[], size_t msg_len, RandomNumberGenerator& rng) { rng.add_entropy(msg, msg_len); BigInt m(msg, msg_len); BigInt r = 0, s = 0; while(r == 0 || s == 0) { // This contortion is necessary for the tests BigInt k; k.randomize(rng, order.bits()); while(k >= order) k.randomize(rng, order.bits() - 1); PointGFp k_times_P = base_point * k; r = mod_order.reduce(k_times_P.get_affine_x()); s = mod_order.multiply(inverse_mod(k, order), mul_add(x, r, m)); } SecureVector<byte> output(2*order.bytes()); r.binary_encode(&output[output.size() / 2 - r.bytes()]); s.binary_encode(&output[output.size() - s.bytes()]); return output; }
/* * Encode a BigInt, with leading 0s if needed */ secure_vector<uint8_t> BigInt::encode_1363(const BigInt& n, size_t bytes) { if(n.bytes() > bytes) throw Encoding_Error("encode_1363: n is too large to encode properly"); secure_vector<uint8_t> output(bytes); n.binary_encode(output.data(), output.size()); return output; }
std::vector<byte> GOST_3410_PublicKey::x509_subject_public_key() const { const BigInt x = public_point().get_affine_x(); const BigInt y = public_point().get_affine_y(); size_t part_size = std::max(x.bytes(), y.bytes()); std::vector<byte> bits(2*part_size); x.binary_encode(&bits[part_size - x.bytes()]); y.binary_encode(&bits[2*part_size - y.bytes()]); // Keys are stored in little endian format (WTF) for(size_t i = 0; i != part_size / 2; ++i) { std::swap(bits[i], bits[part_size-1-i]); std::swap(bits[part_size+i], bits[2*part_size-1-i]); } return DER_Encoder().encode(bits, OCTET_STRING).get_contents_unlocked(); }