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));
191 char output_index[(
sizeof(size_t) * 8 + 6) / 7];
193 char *end =
buf.output_index;
194 buf.derivation = derivation;
196 assert(end <=
buf.output_index +
sizeof buf.output_index);
200 bool crypto_ops::derive_public_key(
const key_derivation &derivation,
size_t output_index,
211 derivation_to_scalar(derivation, output_index, scalar);
214 ge_add(&point4, &point1, &point3);
220 void crypto_ops::derive_secret_key(
const key_derivation &derivation,
size_t output_index,
224 derivation_to_scalar(derivation, output_index, scalar);
238 derivation_to_scalar(derivation, output_index, scalar);
241 ge_sub(&point4, &point1, &point3);
285 if (((
const uint32_t*)(&k))[7] == 0)
292 sc_mulsub(&sig.r, &sig.c, &unwrap(sec), &k);
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;
518 secret_key sec = addSecretKeys(sec_view, sec_spend);
536 if (((
const uint32_t*)(&k))[7] == 0)
543 sc_mulsub(&sig.r, &sig.c, &unwrap(sec), &k);
550 public_key pub = addKeys(pub_view, pub_spend);
556 assert(check_key(pub));
568 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}};
569 if (memcmp(&
buf.comm, &infinity, 32) == 0)
582 local_abort(
"addKeys: issue converting a public key to a curve point");
588 ge_add(&tmp3, &A2, &tmp2);
604 void crypto_ops::generate_ring_signature(
const hash &prefix_hash,
const key_image &image,
605 const public_key *
const *pubs,
size_t pubs_count,
612 boost::shared_ptr<rs_comm>
buf(
reinterpret_cast<rs_comm *
>(malloc(
rs_comm_size(pubs_count))), free);
614 local_abort(
"malloc failure");
615 assert(sec_index < pubs_count);
624 assert(*pubs[sec_index] ==
t2);
625 generate_key_image(*pubs[sec_index], sec,
t3);
627 for (i = 0; i < pubs_count; i++) {
628 assert(check_key(*pubs[i]));
633 local_abort(
"invalid key image");
637 buf->h = prefix_hash;
638 for (i = 0; i < pubs_count; i++) {
642 if (i == sec_index) {
661 local_abort(
"invalid pubkey");
673 sc_add(&sum, &sum, &sig[i].c);
679 sc_sub(&sig[sec_index].c, &h, &sum);
685 bool crypto_ops::check_ring_signature(
const hash &prefix_hash,
const key_image &image,
686 const public_key *
const *pubs,
size_t pubs_count,
692 boost::shared_ptr<rs_comm>
buf(
reinterpret_cast<rs_comm *
>(malloc(
rs_comm_size(pubs_count))), free);
697 for (i = 0; i < pubs_count; i++) {
698 assert(check_key(*pubs[i]));
706 buf->h = prefix_hash;
707 for (i = 0; i < pubs_count; i++) {
721 sc_add(&sum, &sum, &sig[i].c);
728 std::string crypto_ops::sign_message(
const std::string &
message,
const std::string &
privateKey) {
731 return std::string(
"");
740 return std::string(
reinterpret_cast<char const*
>(
signature), 64);
743 bool crypto_ops::verify_signature(
const std::string &
message,
const std::string &
publicKey,
const std::string &
signature) {
751 bool crypto_ops::verify_signature(
const std::string &
message,
const std::vector<std::string>
publicKey,
const std::string &
signature) {
774 std::vector<std::string> result = {
775 boost::algorithm::hex(std::string(
reinterpret_cast<char const*
>(sk), 32)),
776 boost::algorithm::hex(std::string(
reinterpret_cast<char const*
>(pk), 32))
friend std::vector< std::string > create_ed25519_keypair()
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 ge_scalarmult(ge_p2 *, const unsigned char *, const ge_p3 *)
void generate_random_bytes_thread_safe(size_t N, uint8_t *bytes)
void hash_to_ec(const public_key &key, ge_p3 &res)
int ge_frombytes_vartime(ge_p3 *, const unsigned char *)
void ge_dsm_precomp(ge_dsmp r, const ge_p3 *s)
const crypto::secret_key null_skey
void sc_reduce32(unsigned char *)
epee::mlocked< tools::scrubbed< ec_scalar > > secret_key
void ge_double_scalarmult_precomp_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *, const ge_dsmp)
void ge_double_scalarmult_base_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *)
void cn_fast_hash(const void *data, size_t length, char *hash)
int sc_check(const unsigned char *)
int sc_isnonzero(const unsigned char *)
void generate_random_bytes_not_thread_safe(size_t n, void *result)
size_t rs_comm_size(size_t pubs_count)
void random32_unbiased(unsigned char *bytes)
void hash_to_point(const crypto::hash &h, crypto::ec_point &res)
void sc_add(unsigned char *, const unsigned char *, const unsigned char *)
void ge_fromfe_frombytes_vartime(ge_p2 *, const unsigned char *)
void ge_mul8(ge_p1p1 *, const ge_p2 *)
void sc_0(unsigned char *)
void sc_mulsub(unsigned char *, const unsigned char *, const unsigned char *, const unsigned char *)
void hash_to_scalar(const void *data, size_t length, ec_scalar &res)
void random_scalar(ec_scalar &res)
void sc_sub(unsigned char *, const unsigned char *, const unsigned char *)
T & unwrap(mlocked< T > &src)
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
#define ge_scalarmult_base
provides the implementation of varint's