aboutsummaryrefslogtreecommitdiff
path: root/src/crypto/crypto.h
diff options
context:
space:
mode:
authoramjuarez <amjuarez@users.noreply.github.com>2013-11-15 02:28:17 +0400
committeramjuarez <amjuarez@users.noreply.github.com>2013-11-15 02:28:17 +0400
commit175d06e75e05aa4a42269dd048516e13b5bd585e (patch)
tree6828038a2d86174c6041f65187d7521c719606b3 /src/crypto/crypto.h
parentInitial commit (diff)
downloadmonero-175d06e75e05aa4a42269dd048516e13b5bd585e.tar.xz
crypto lib
Diffstat (limited to 'src/crypto/crypto.h')
-rw-r--r--src/crypto/crypto.h166
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