38 #include <boost/thread/mutex.hpp>
39 #include <boost/thread/lock_guard.hpp>
40 #include <boost/shared_ptr.hpp>
47 static void local_abort(
const char *msg)
49 fprintf(stderr,
"%s\n", msg);
75 static inline unsigned char *operator &(
ec_point &point) {
76 return &
reinterpret_cast<unsigned char &
>(point);
79 static inline const unsigned char *operator &(
const ec_point &point) {
80 return &
reinterpret_cast<const unsigned char &
>(point);
83 static inline unsigned char *operator &(
ec_scalar &scalar) {
84 return &
reinterpret_cast<unsigned char &
>(scalar);
87 static inline const unsigned char *operator &(
const ec_scalar &scalar) {
88 return &
reinterpret_cast<const unsigned char &
>(scalar);
93 static boost::mutex random_lock;
94 boost::lock_guard<boost::mutex> lock(random_lock);
98 static inline bool less32(
const unsigned char *k0,
const unsigned char *k1)
100 for (
int n = 31; n >= 0; --n)
114 static const unsigned char limit[32] = { 0xe3, 0x6a, 0x67, 0x72, 0x8b, 0xce, 0x13, 0x29, 0x8f, 0x30, 0x82, 0x8c, 0x0b, 0xa4, 0x10, 0x39, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0 };
118 }
while (!
sc_isnonzero(bytes) && !less32(bytes, limit));
193 char *end =
buf.output_index;
194 buf.derivation = derivation;
196 assert(end <=
buf.output_index +
sizeof buf.output_index);
214 ge_add(&point4, &point1, &point3);
241 ge_sub(&point4, &point1, &point3);
285 if (((
const uint32_t*)(&k))[7] == 0)
302 assert(check_key(pub));
313 static const ec_point infinity = {{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
314 if (memcmp(&
buf.comm, &infinity, 32) == 0)
328 if (
ge_frombytes_vartime(&A_p3, &
A) != 0)
throw std::runtime_error(
"recipient view pubkey is invalid");
329 if (B &&
ge_frombytes_vartime(&B_p3, &*B) != 0)
throw std::runtime_error(
"recipient spend pubkey is invalid");
330 if (
ge_frombytes_vartime(&D_p3, &D) != 0)
throw std::runtime_error(
"key derivation is invalid");
363 buf.msg = prefix_hash;
427 ge_add(&X_p1p1, &cR_p3, &rB_cached);
436 ge_add(&X_p1p1, &cR_p3, &rG_cached);
461 ge_add(&Y_p1p1, &cD_p3, &rA_cached);
467 buf.msg = prefix_hash;
512 secret_key sec = addSecretKeys(sec_view, sec_spend);
530 if (((
const uint32_t*)(&k))[7] == 0)
544 public_key pub = addKeys(pub_view, pub_spend);
550 assert(check_key(pub));
562 static const ec_point infinity = {{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
563 if (memcmp(&
buf.comm, &infinity, 32) == 0)
578 ge_add(&tmp3, &A2, &tmp2);
594 void crypto_ops::generate_ring_signature(
const hash &prefix_hash,
const key_image &image,
595 const public_key *
const *pubs,
size_t pubs_count,
602 boost::shared_ptr<rs_comm>
buf(
reinterpret_cast<rs_comm *
>(malloc(
rs_comm_size(pubs_count))), free);
604 local_abort(
"malloc failure");
605 assert(sec_index < pubs_count);
614 assert(*pubs[sec_index] ==
t2);
615 generate_key_image(*pubs[sec_index], sec,
t3);
617 for (i = 0; i < pubs_count; i++) {
618 assert(check_key(*pubs[i]));
623 local_abort(
"invalid key image");
627 buf->h = prefix_hash;
628 for (i = 0; i < pubs_count; i++) {
632 if (i == sec_index) {
651 local_abort(
"invalid pubkey");
663 sc_add(&sum, &sum, &sig[i].c);
669 sc_sub(&sig[sec_index].c, &h, &sum);
675 bool crypto_ops::check_ring_signature(
const hash &prefix_hash,
const key_image &image,
676 const public_key *
const *pubs,
size_t pubs_count,
682 boost::shared_ptr<rs_comm>
buf(
reinterpret_cast<rs_comm *
>(malloc(
rs_comm_size(pubs_count))), free);
687 for (i = 0; i < pubs_count; i++) {
688 assert(check_key(*pubs[i]));
696 buf->h = prefix_hash;
697 for (i = 0; i < pubs_count; i++) {
711 sc_add(&sum, &sum, &sig[i].c);
758 std::vector<std::string> crypto_ops::create_ed25519_keypair() {
764 std::vector<std::string> result = {
765 boost::algorithm::hex(
std::string(
reinterpret_cast<char const*
>(sk), 32)),
766 boost::algorithm::hex(
std::string(
reinterpret_cast<char const*
>(pk), 32))
void ge_double_scalarmult_precomp_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *, const ge_dsmp)
void sc_0(unsigned char *)
void sc_reduce32(unsigned char *)
void ge_dsm_precomp(ge_dsmp r, const ge_p3 *s)
int ge_frombytes_vartime(ge_p3 *, const unsigned char *)
void sc_sub(unsigned char *, const unsigned char *, const unsigned char *)
void sc_mulsub(unsigned char *, const unsigned char *, const unsigned char *, const unsigned char *)
void ge_mul8(ge_p1p1 *, const ge_p2 *)
int sc_check(const unsigned char *)
void ge_double_scalarmult_base_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *)
int sc_isnonzero(const unsigned char *)
void sc_add(unsigned char *, const unsigned char *, const unsigned char *)
void ge_fromfe_frombytes_vartime(ge_p2 *, const unsigned char *)
void ge_scalarmult(ge_p2 *, const unsigned char *, const ge_p3 *)
std::string message("Message requiring signing")
void ED25519_FN() ed25519_randombytes_unsafe(void *p, size_t len)
int ed25519_sign_open(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS)
unsigned char ed25519_signature[64]
unsigned char ed25519_secret_key[32]
void ed25519_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS)
unsigned char ed25519_public_key[32]
void ed25519_publickey(const ed25519_secret_key sk, ed25519_public_key pk)
const crypto::public_key null_pkey
void cn_fast_hash(const void *data, std::size_t length, hash &hash)
void generate_random_bytes_thread_safe(size_t N, uint8_t *bytes)
void hash_to_ec(const public_key &key, ge_p3 &res)
const crypto::secret_key null_skey
epee::mlocked< tools::scrubbed< ec_scalar > > secret_key
size_t rs_comm_size(size_t pubs_count)
void random32_unbiased(unsigned char *bytes)
void hash_to_scalar(const void *data, size_t length, ec_scalar &res)
void random_scalar(ec_scalar &res)
T & unwrap(mlocked< T > &src)
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
#define ge_scalarmult_base
void generate_random_bytes_not_thread_safe(size_t n, void *result)
unsigned __int64 uint64_t
provides the implementation of varint's