diff options
author | amjuarez <amjuarez@users.noreply.github.com> | 2013-11-15 02:28:17 +0400 |
---|---|---|
committer | amjuarez <amjuarez@users.noreply.github.com> | 2013-11-15 02:28:17 +0400 |
commit | 175d06e75e05aa4a42269dd048516e13b5bd585e (patch) | |
tree | 6828038a2d86174c6041f65187d7521c719606b3 /src/crypto/crypto.h | |
parent | Initial commit (diff) | |
download | monero-175d06e75e05aa4a42269dd048516e13b5bd585e.tar.xz |
crypto lib
Diffstat (limited to '')
-rw-r--r-- | src/crypto/crypto.h | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h new file mode 100644 index 000000000..2dd2085ce --- /dev/null +++ b/src/crypto/crypto.h @@ -0,0 +1,166 @@ +#pragma once + +#include <cstddef> +#include <cstring> + +namespace crypto { + +#pragma pack(push, 1) + class hash { + char data[32]; + }; + + class ec_point { + char data[32]; + }; + + class ec_scalar { + char data[32]; + }; + + class public_key: ec_point { + friend class crypto_ops; + }; + + class secret_key: ec_scalar { + friend class crypto_ops; + }; + + class key_image: ec_point { + friend class crypto_ops; + }; + + class signature { + ec_scalar c, r; + friend class crypto_ops; + }; +#pragma pack(pop) + + static_assert(sizeof(hash) == 32 && sizeof(ec_point) == 32 && + sizeof(ec_scalar) == 32 && sizeof(public_key) == 32 && + sizeof(secret_key) == 32 && sizeof(key_image) == 32 && + sizeof(signature) == 64, "Invalid structure size"); + + extern "C" { + void keccak(const void *data, std::size_t length, char *hash); + } + + inline void keccak(const void *data, std::size_t length, hash &hash) { + keccak(data, length, reinterpret_cast<char *>(&hash)); + } + + inline bool operator==(const hash &a, const hash &b) { + return std::memcmp(&a, &b, sizeof(struct hash)) == 0; + } + + inline bool operator==(const public_key &a, const public_key &b) { + return std::memcmp(&a, &b, sizeof(struct public_key)) == 0; + } + + inline bool operator==(const key_image &a, const key_image &b) { + return std::memcmp(&a, &b, sizeof(struct key_image)) == 0; + } + + class crypto_ops { + crypto_ops(); + crypto_ops(const crypto_ops &); + void operator=(const crypto_ops &); + ~crypto_ops(); + + static void generate_keys(public_key &, secret_key &); + friend void generate_keys(public_key &, secret_key &); + static bool check_key(const public_key &); + friend bool check_key(const public_key &); + static void generate_signature(const hash &, const public_key &, const secret_key &, signature &); + friend void generate_signature(const hash &, const public_key &, const secret_key &, signature &); + static bool check_signature(const hash &, const public_key &, const signature &); + friend bool check_signature(const hash &, const public_key &, const signature &); + static void generate_key_image(const public_key &, const secret_key &, key_image &); + friend void generate_key_image(const public_key &, const secret_key &, key_image &); + static void generate_ring_signature(const hash &, const key_image &, + const public_key *const *, std::size_t, const secret_key &, std::size_t, signature *); + friend void generate_ring_signature(const hash &, const key_image &, + const public_key *const *, std::size_t, const secret_key &, std::size_t, signature *); + static bool check_ring_signature(const hash &, const key_image &, + const public_key *const *, std::size_t, const signature *); + friend bool check_ring_signature(const hash &, const key_image &, + const public_key *const *, std::size_t, const signature *); + }; + + /* Generate a new key pair. + * pub: a newly generated public key. + * sec: a newly generated secret key. + */ + inline void generate_keys(public_key &pub, secret_key &sec) { + crypto_ops::generate_keys(pub, sec); + } + + /* Check a public key. + * key: a key to check. + * returns: true if the key is valid, false otherwise. + */ + inline bool check_key(const public_key &key) { + return crypto_ops::check_key(key); + } + + /* Sign a message. + * message_hash: hash of a message. + * pub: public key used for signing. Assumed to be valid. + * sec: secret key used for signing. Assumed to correspond to pub. + * sig: the resulting signature. + */ + inline void generate_signature(const hash &message_hash, const public_key &pub, const secret_key &sec, signature &sig) { + crypto_ops::generate_signature(message_hash, pub, sec, sig); + } + + /* Verify a signature. + * message_hash: hash of a message. + * pub: public key used for signing. Assumed to be valid, use check_key to check it first. + * sig: a signature. + * returns: true if the signature is valid, false otherwise. + */ + inline bool check_signature(const hash &message_hash, const public_key &pub, const signature &sig) { + return crypto_ops::check_signature(message_hash, pub, sig); + } + + /* Generate the image of a key. + * pub: public key used for signing. Assumed to be valid. + * sec: secret key used for signing. Assumed to correspond to pub. + * image: the resulting key image. + */ + inline void generate_key_image(const public_key &pub, const secret_key &sec, key_image &image) { + crypto_ops::generate_key_image(pub, sec, image); + } + + /* Sign a message using linkable ring signature. + * message_hash: hash of a message. + * image: image of the key used for signing. Use generate_key_image to create it. Assumed to correspond to the key used for signing. + * pubs: pointer to an array of pointers to public keys of a ring. All keys are assumed to be valid, use check_key to check them first. + * pubs_count: number of keys in a ring. + * sec: secret key used for signing. + * sec_index: index of the key used for signing in pubs. It is assumed that 0 <= sec_index < pubs_count and that sec corresponds to *pubs[sec_index]. + * sig: the resulting signature (occupies pubs_count elements). To verify it, image of the key is also necessary. + */ + inline void generate_ring_signature(const hash &message_hash, const key_image &image, + const public_key *const *pubs, std::size_t pubs_count, + const secret_key &sec, std::size_t sec_index, + signature *sig) { + crypto_ops::generate_ring_signature(message_hash, image, pubs, pubs_count, sec, sec_index, sig); + } + + /* Verify a linkable ring signature. + * message_hash: hash of a message. + * image: image of the key used for signing. + * pubs: pointer to an array of pointers to public keys of a ring. All keys are assumed to be valid, use check_key to check them first. + * pubs_count: number of keys in a ring. + * sig: a signature (occupies pubs_count elements). + * returns: true if the signature is valid, false otherwise. + */ + inline bool check_ring_signature(const hash &message_hash, const key_image &image, + const public_key *const *pubs, std::size_t pubs_count, + const signature *sig) { + return crypto_ops::check_ring_signature(message_hash, image, pubs, pubs_count, sig); + } + + /* To check whether two signatures are linked, compare their key images. */ +}
\ No newline at end of file |