From 80ada649b82f30495f7c1f46afd33ee502088a90 Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Fri, 31 Jul 2015 11:10:28 -0400 Subject: [PATCH] draft specs --- draft-docs/extensions/data.md | 62 +++++++++++++++++++ draft-docs/extensions/private_memo.md | 86 +++++++++++++++++++++++++++ draft-docs/extensions/public_memo.md | 16 +++++ 3 files changed, 164 insertions(+) create mode 100644 draft-docs/extensions/data.md create mode 100644 draft-docs/extensions/private_memo.md create mode 100644 draft-docs/extensions/public_memo.md diff --git a/draft-docs/extensions/data.md b/draft-docs/extensions/data.md new file mode 100644 index 00000000..fe7040fc --- /dev/null +++ b/draft-docs/extensions/data.md @@ -0,0 +1,62 @@ + +Status +------ + +This spec is a suggestion for a future improvement. It has not yet +been implemented and is not yet considered normative for wallets. + +data_extension specification +---------------------------- + +The `data_extension` is an extension (in `future_extensions`) with +the following semantics: + +- All `data_extension` are semantically no-ops as far as validation +and core consensus is concerned (of course they increase data tx fees +as dictated by their size). +- The `data_extension` semantics is determined by a GUID account +(described below) + +Data extension structure +------------------------ + + struct data_extension + { + account_id_type semantics_uid; + vector data; + }; + +UID accounts +------------ + +Many different `data_extension` will be created by different +applications. Each data extension will have its own semantics. The +semantics dictate how `data` is parsed: Imagine a (fairly typical) +application which only understands `data` formatted by other instances +of itself. The way it can *unambiguously tell* that the `data` was +created by an interoperable application is because `semantics_uid` +says it is compatible. + +Specifically, `semantics_uid` refers to an account whose name is +`ripemd160(sha256( spec ))`, where `spec` is the contents of +the specification in some format (usually English text). + +The hash of the specification can be viewed as a "magic number" +which is "assigned" in a decentralized way (because 160 bits of entropy +are included in the hash, two specifications will almost certainly be +"assigned" separate magic numbers). The `account_id_type` is simply a +shorthand way to refer to a magic number, and anyone with access to +the blockchain can convert back and forth between them. + +Note, it does not matter who registered or controls the account, or +what activity they do! All that matters is that the name-to-ID mapping +is bijective, immutable, and known to all chain participants. + +Genesis UID's +------------- + +UID accounts (for example, for the memo extension) may already exist, +or may even be created at genesis. Wallets *may* hard-code these ID's, +however for maximum compatibility with all Graphene-powered chains, +wallets are encouraged to look up the name-to-ID mapping to resolve +the UID instead. diff --git a/draft-docs/extensions/private_memo.md b/draft-docs/extensions/private_memo.md new file mode 100644 index 00000000..7741c140 --- /dev/null +++ b/draft-docs/extensions/private_memo.md @@ -0,0 +1,86 @@ + +Status +------ + +This spec is a suggestion for a future improvement. It has not yet +been implemented and is not yet considered normative for wallets. + +private_memo_data specification +------------------------------- + +The `private_memo_data` is a `data_extension` with the following +semantics: + +- Memo encrypted by ECDH shared secret used as AES key +- All wallets should support displaying and sending memos with accounts' +memo keys for `asset_issue_operation`, `transfer_operation`, +`override_transfer_operation` and `withdraw_permission_claim_operation`. + +Data extension structure +------------------------ + + /** + * @brief defines the keys used to derive the shared secret + * + * Because account authorities and keys can change at any time, each memo must + * capture the specific keys used to derive the shared secret. In order to read + * the cipher message you will need one of the two private keys. + * + * If @ref from == @ref to and @ref from == 0 then no encryption is used, the memo is public. + * If @ref from == @ref to and @ref from != 0 then invalid memo data + * + * The reason we include *both* keys is to allow the wallet to + * rebuild the data for any transfer, including the memo, from the + * user's private keys and the contents of the blockchain -- + * regardless of whether the user is the sender or receiver. + */ + struct memo_data + { + public_key_type from; + public_key_type to; + /** + * 64 bit nonce format: + * [ 8 bits | 56 bits ] + * [ entropy | timestamp ] + * Timestamp is number of microseconds since the epoch + * Entropy is a byte taken from the hash of a new private key + * + * This format is not mandated or verified; it is chosen to ensure uniqueness of key-IV pairs only. This should + * be unique with high probability as long as the generating host has a high-resolution clock OR a strong source + * of entropy for generating private keys. + */ + uint64_t nonce; + /** + * This field contains the AES encrypted packed @ref memo_message + */ + vector message; + }; + +Encrypting/decrypting +--------------------- + +TODO: write in words + +NB no public memo (this is separate extension) + + void memo_data::set_message(const fc::ecc::private_key& priv, const fc::ecc::public_key& pub, + const string& msg, uint64_t nonce) + { + from = priv.get_public_key(); + to = pub; + auto secret = priv.get_shared_secret(pub); + auto nonce_plus_secret = fc::sha512::hash(fc::to_string(nonce) + secret.str()); + string text = memo_message(digest_type::hash(msg)._hash[0], msg).serialize(); + message = fc::aes_encrypt( nonce_plus_secret, vector(text.begin(), text.end()) ); + } + + string memo_data::get_message(const fc::ecc::private_key& priv, + const fc::ecc::public_key& pub)const + { + auto secret = priv.get_shared_secret(pub); + auto nonce_plus_secret = fc::sha512::hash(fc::to_string(nonce) + secret.str()); + auto plain_text = fc::aes_decrypt( nonce_plus_secret, message ); + auto result = memo_message::deserialize(string(plain_text.begin(), plain_text.end())); + FC_ASSERT( result.checksum == uint32_t(digest_type::hash(result.text)._hash[0]) ); + return result.text; + } diff --git a/draft-docs/extensions/public_memo.md b/draft-docs/extensions/public_memo.md new file mode 100644 index 00000000..7c1192ff --- /dev/null +++ b/draft-docs/extensions/public_memo.md @@ -0,0 +1,16 @@ + +Status +------ + +This spec is a suggestion for a future improvement. It has not yet +been implemented and is not yet considered normative for wallets. + +public_memo_data specification +------------------------------ + +The `public_memo_data` is a `data_extension` which suggests to wallets +to display some text. + +- All wallets should support displaying and sending memos with accounts' +memo keys for `asset_issue_operation`, `transfer_operation`, +`override_transfer_operation` and `withdraw_permission_claim_operation`.