diff options
| author | Riccardo Spagni <ric@spagni.net> | 2016-08-28 22:41:11 +0200 |
|---|---|---|
| committer | Riccardo Spagni <ric@spagni.net> | 2016-08-28 22:41:12 +0200 |
| commit | 8a5b766d17761f5fbdd3e30e638daa98a40a4c8a (patch) | |
| tree | ea05e3f0fd47fd1d8728e64d081292d337825cb9 /src/ringct/rctOps.cpp | |
| parent | a569b264bc4d4ca1a07c2eadcc24b5ab75fd0c84 (diff) | |
| parent | 887db9f93670da8c1eb28c9d53d6d4f055486e3b (diff) | |
| download | monzero-core-8a5b766d17761f5fbdd3e30e638daa98a40a4c8a.tar.gz monzero-core-8a5b766d17761f5fbdd3e30e638daa98a40a4c8a.tar.xz monzero-core-8a5b766d17761f5fbdd3e30e638daa98a40a4c8a.zip | |
Merge pull request #961
887db9f blockchain: testnet heights for v3, v4, and v5 (moneromooo-monero)
f24ab58 ringct: remove unused code (moneromooo-monero)
b38452b ringct: pass structure by const ref, not value (moneromooo-monero)
fd11271 ringct: use memcpy/memset instead of handwritten loop where appropriate (moneromooo-monero)
5d38206 ringct: remove spurious copies (moneromooo-monero)
16732a8 rct: faster Cryptonote/rct conversions (moneromooo-monero)
fbd7c35 wallet: fix some "may be used uninitialized" warnings (moneromooo-monero)
4a41dd4 wallet: do not generate 0 change (moneromooo-monero)
a0925e6 core: use full rct signatures if just one input (moneromooo-monero)
94fd881 rct: early out on failure on verRange (moneromooo-monero)
45349b6 wallet: do not ask for duplicate histograms (moneromooo-monero)
b951bc8 wallet: transfer_selected_rct now also selects fake outs (moneromooo-monero)
4f887de increase minimum mixin to 4 on hard fork 5 (moneromooo-monero)
0815c72 core: allow v1 txes after HF 5 when sweeping unmixable outputs (moneromooo-monero)
f782d45 tests: hard fork list must end with a 0 (moneromooo-monero)
074e602 ringct: use Cryptonote serialization to hash non prunable data (moneromooo-monero)
c3b3260 New "Halfway RingCT" outputs for coinbase transactions (moneromooo-monero)
6f526cd rct: log why verification fails (moneromooo-monero)
d4b8991 rct: serialize txnFee as varint (moneromooo-monero)
d4b62a1 rct amount key modified as per luigi1111's recommendations (moneromooo-monero)
93f5c62 rct: rework v2 txes into prunable and non prunable data (moneromooo-monero)
d93746b rct: rework the verification preparation process (moneromooo-monero)
3ab2ab3 rct: change the simple flag to a type (moneromooo-monero)
c5be4b0 rct: avoid the need for the last II element (Shen Noether)
a47ceee wallet: do not store signatures in the wallet cache (moneromooo-monero)
0263dd2 core: add some locking around pool use (moneromooo-monero)
2c9d951 wallet2: factor m_spent changes (moneromooo-monero)
1303cda wallet: always use new algorithm for RPC transfers (moneromooo-monero)
b337aea rct: do not serialize senderPk - it is not used anymore (moneromooo-monero)
e5a9a47 core_tests: fix a couple pre-rct tests using rct (moneromooo-monero)
230fca2 wallet: use the prefered rct case only when enough rct outs exist (moneromooo-monero)
c27194a wallet: do not try to use rct txes a few blocks before the fork (moneromooo-monero)
1bf0698 tx_pool: log why a transaction was rejected for version checks (moneromooo-monero)
37bdf6e change fork settings to allow pre-rct txes for one more fork cycle (moneromooo-monero)
cc85cc6 simplewallet: better check_tx_key feedback (moneromooo-monero)
9b70856 rct: make the amount key derivable by a third party with the tx key (moneromooo-monero)
cf33e1a rct: do not serialize public keys in outPk (moneromooo-monero)
83ab315 wallet2_api: zero amounts are now allowed with rct (moneromooo-monero)
096ac06 wallet2_api: update on_money_{received,spent} prototypes for rct changes (moneromooo-monero)
3cb2ede rpc: send global indices along with blocks/transacions on refresh (moneromooo-monero)
414b424 core: always use the new simple rct variant (moneromooo-monero)
ce5de8b tests: add tests for wallet output selection (moneromooo-monero)
84c82cd wallet: better tx input selection (moneromooo-monero)
1e21651 rct: use the already defined H where possible (moneromooo-monero)
07d353d wallet: handle 0 change properly (moneromooo-monero)
e81a2b2 port get_tx_key/check_tx_key to rct (moneromooo-monero)
e06faef tests: add basic tests for simple rct api (moneromooo-monero)
a4d4d61 integrate simple rct api (moneromooo-monero)
1e8d37e serialization: add override for serializing bool (moneromooo-monero)
dbb5f2d ringct: optimization/cleanup of hash functions (Shen Noether)
4fd01f2 ringct: "simple" ringct variant (Shen Noether)
37c895e wallet: rct specific output selection (moneromooo-monero)
1181c57 wallet: make sweep_all work with rct txes too (moneromooo-monero)
c2ec6d3 mixable transactions must be rct for v3 (moneromooo-monero)
1017a75 wallet: factor transfer_rct code with transfer code (moneromooo-monero)
f5465d8 Condition v2 txes on v3 hard fork (moneromooo-monero)
59a66e2 move the rct commitments to the output_amounts database (moneromooo-monero)
6d0e471 rct: add the tx prefix hash into the MLSAG (moneromooo-monero)
35dce5c ringct: fix size unit mismatch calling keccak (moneromooo-monero)
20e50ec ringct: do not serialize what can be reconstructed (moneromooo-monero)
106e3dc Add rct core tests (moneromooo-monero)
ada5275 Use the supplied hard fork version in validate_miner_transaction (moneromooo-monero)
acbe06d wallet: update spent status when an accepted tx disappears (moneromooo-monero)
089df4a wallet: reset output spent status on blockchain reorg (moneromooo-monero)
73d59f1 ringct: catch errors from ge_frombytes_vartime (moneromooo-monero)
161551e tests: test for ringct rctSig data sizes (moneromooo-monero)
359f469 ringct: add missing size check for ecdhInfo (moneromooo-monero)
229968e ringct: change asserts to return false for boolean functions (moneromooo-monero)
dc4aad7 add rct to the protocol (moneromooo-monero)
211d1db db_lmdb: update reset for recent db changes (moneromooo-monero)
dee42d6 ringct: add functions to commit to an amount (moneromooo-monero)
cc7f449 make rct tx serialization work (moneromooo-monero)
e70e8a6 crypto: error out where appropriate (moneromooo-monero)
54f7429 ringct: allow no outputs, and add tests for this and fees (moneromooo-monero)
e99904a ringct: make fee optional (moneromooo-monero)
f8c04ad ringct: txn fee stuff (Shen Noether)
66f9626 ringct: new {gen,decode}Rct APIs for convenience (moneromooo-monero)
789b2e2 ringct: add more convenience functions (moneromooo-monero)
9856443 core: link against libringct (moneromooo-monero)
4258dab core: new /getrandom_rctouts.bin binary RPC call (moneromooo-monero)
c3a2e14 ringct: add convenience functions to bridge ringct and cryptonote (moneromooo-monero)
eb56d0f blockchain_db: add functions for adding/removing/getting rct commitments (moneromooo-monero)
82072e7 ringct: restore verRange check in debug mode (moneromooo-monero)
63856ca ringct: add check for destinations/amount size being equal (moneromooo-monero)
e816a09 ringct: fix off by 1 in mixin usage (moneromooo-monero)
09c5ea4 ringct: simplify random key generation (moneromooo-monero)
53cdf4d tests: new ringct test for checking H2 values (Shen Noether)
56f6549 ringct: cosmetic fixes (Shen Noether)
55ff136 ringct: changes to hashToPointSimple to calcualte H2 values (Shen Noether)
63733b1 ringct: compare keys with bitwise equality, not crypto ops (Shen Noether)
98f4c6f ringct: fix size argument to cn_fast_hash (Shen Noether)
720ac85 tests: zero inputs/outputs are in fact supposed to be accepted (moneromooo-monero)
84948ea ringct: add a test for prooveRange being non deterministic (moneromooo-monero)
09fb9f4 Fix sc_0 to skGen in ProveRange (Shen Noether)
d37c1db ringct: add a few consts where appropriate (moneromooo-monero)
700248f tests: more ringct range proof tests (moneromooo-monero)
d02f999 rct: add serialization machinery to rct types (moneromooo-monero)
0ff8305 serialization: declare do_serialize specializations before use (moneromooo-monero)
8b135e7 Added note on generating H2 (Shen Noether)
4d639d9 Fixed missing last index H2 (Shen Noether)
9e82b69 remove original Cryptonote blockchain_storage blockchain format (moneromooo-monero)
86b4426 ringct: lock access to the PRNG (moneromooo-monero)
4d7f073 ringct: add simple input validation (moneromooo-monero)
57779ab tests: add some more ringct building block tests (moneromooo-monero)
b656001 ringct: add convenience operators to key (moneromooo-monero)
2d6303f tests: add Shen Noether's basic ringct tests (moneromooo-monero)
9b1afe5 ringct: import of Shen Noether's ring confidential transactions (moneromooo-monero)
Diffstat (limited to 'src/ringct/rctOps.cpp')
| -rw-r--r-- | src/ringct/rctOps.cpp | 475 |
1 files changed, 475 insertions, 0 deletions
diff --git a/src/ringct/rctOps.cpp b/src/ringct/rctOps.cpp new file mode 100644 index 000000000..488e47ca0 --- /dev/null +++ b/src/ringct/rctOps.cpp @@ -0,0 +1,475 @@ +// Copyright (c) 2016, Monero Research Labs +// +// Author: Shen Noether <shen.noether@gmx.com> +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "misc_log_ex.h" +#include "rctOps.h" +using namespace crypto; +using namespace std; + +namespace rct { + + //Various key initialization functions + + //Creates a zero scalar + void zero(key &zero) { + memset(&zero, 0, 32); + } + + //Creates a zero scalar + key zero() { + static const key z = { {0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 , 0x00, 0x00, 0x00,0x00 } }; + return z; + } + + //Creates a zero elliptic curve point + void identity(key &Id) { + Id[0] = (unsigned char)(0x01); + memset(Id.bytes+1, 0, 31); + } + + //Creates a zero elliptic curve point + key identity() { + key Id; + Id[0] = (unsigned char)(0x01); + memset(Id.bytes+1, 0, 31); + return Id; + } + + //copies a scalar or point + void copy(key &AA, const key &A) { + memcpy(&AA, &A, 32); + } + + //copies a scalar or point + key copy(const key &A) { + key AA; + memcpy(&AA, &A, 32); + return AA; + } + + + //initializes a key matrix; + //first parameter is rows, + //second is columns + keyM keyMInit(int rows, int cols) { + keyM rv(cols); + int i = 0; + for (i = 0 ; i < cols ; i++) { + rv[i] = keyV(rows); + } + return rv; + } + + + + + //Various key generation functions + + //generates a random scalar which can be used as a secret key or mask + void skGen(key &sk) { + sk = crypto::rand<key>(); + sc_reduce32(sk.bytes); + } + + //generates a random scalar which can be used as a secret key or mask + key skGen() { + key sk = crypto::rand<key>(); + sc_reduce32(sk.bytes); + return sk; + } + + //Generates a vector of secret key + //Mainly used in testing + keyV skvGen(int rows ) { + keyV rv(rows); + int i = 0; + for (i = 0 ; i < rows ; i++) { + skGen(rv[i]); + } + return rv; + } + + //generates a random curve point (for testing) + key pkGen() { + key sk = skGen(); + key pk = scalarmultBase(sk); + return pk; + } + + //generates a random secret and corresponding public key + void skpkGen(key &sk, key &pk) { + skGen(sk); + scalarmultBase(pk, sk); + } + + //generates a random secret and corresponding public key + tuple<key, key> skpkGen() { + key sk = skGen(); + key pk = scalarmultBase(sk); + return make_tuple(sk, pk); + } + + //generates C =aG + bH from b, a is given.. + void genC(key & C, const key & a, xmr_amount amount) { + key bH = scalarmultH(d2h(amount)); + addKeys1(C, a, bH); + } + + //generates a <secret , public> / Pedersen commitment to the amount + tuple<ctkey, ctkey> ctskpkGen(xmr_amount amount) { + ctkey sk, pk; + skpkGen(sk.dest, pk.dest); + skpkGen(sk.mask, pk.mask); + key am = d2h(amount); + key bH = scalarmultH(am); + addKeys(pk.mask, pk.mask, bH); + return make_tuple(sk, pk); + } + + + //generates a <secret , public> / Pedersen commitment but takes bH as input + tuple<ctkey, ctkey> ctskpkGen(key bH) { + ctkey sk, pk; + skpkGen(sk.dest, pk.dest); + skpkGen(sk.mask, pk.mask); + addKeys(pk.mask, pk.mask, bH); + return make_tuple(sk, pk); + } + + key zeroCommit(xmr_amount amount) { + key mask = identity(); + mask = scalarmultBase(mask); + key am = d2h(amount); + key bH = scalarmultH(am); + addKeys(mask, mask, bH); + return mask; + } + + key commit(xmr_amount amount, key mask) { + mask = scalarmultBase(mask); + key am = d2h(amount); + key bH = scalarmultH(am); + addKeys(mask, mask, bH); + return mask; + } + + //generates a random uint long long (for testing) + xmr_amount randXmrAmount(xmr_amount upperlimit) { + return h2d(skGen()) % (upperlimit); + } + + //Scalar multiplications of curve points + + //does a * G where a is a scalar and G is the curve basepoint + void scalarmultBase(key &aG,const key &a) { + ge_p3 point; + sc_reduce32copy(aG.bytes, a.bytes); //do this beforehand! + ge_scalarmult_base(&point, aG.bytes); + ge_p3_tobytes(aG.bytes, &point); + } + + //does a * G where a is a scalar and G is the curve basepoint + key scalarmultBase(const key & a) { + ge_p3 point; + key aG; + sc_reduce32copy(aG.bytes, a.bytes); //do this beforehand + ge_scalarmult_base(&point, aG.bytes); + ge_p3_tobytes(aG.bytes, &point); + return aG; + } + + //does a * P where a is a scalar and P is an arbitrary point + void scalarmultKey(key & aP, const key &P, const key &a) { + ge_p3 A; + ge_p2 R; + CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&A, P.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); + ge_scalarmult(&R, a.bytes, &A); + ge_tobytes(aP.bytes, &R); + } + + //does a * P where a is a scalar and P is an arbitrary point + key scalarmultKey(const key & P, const key & a) { + ge_p3 A; + ge_p2 R; + CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&A, P.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); + ge_scalarmult(&R, a.bytes, &A); + key aP; + ge_tobytes(aP.bytes, &R); + return aP; + } + + + //Computes aH where H= toPoint(cn_fast_hash(G)), G the basepoint + key scalarmultH(const key & a) { + ge_p3 A; + ge_p2 R; + CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&A, H.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); + ge_scalarmult(&R, a.bytes, &A); + key aP; + ge_tobytes(aP.bytes, &R); + return aP; + } + + //Curve addition / subtractions + + //for curve points: AB = A + B + void addKeys(key &AB, const key &A, const key &B) { + ge_p3 B2, A2; + CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&B2, B.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); + CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&A2, A.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); + ge_cached tmp2; + ge_p3_to_cached(&tmp2, &B2); + ge_p1p1 tmp3; + ge_add(&tmp3, &A2, &tmp2); + ge_p1p1_to_p3(&A2, &tmp3); + ge_p3_tobytes(AB.bytes, &A2); + } + + + //addKeys1 + //aGB = aG + B where a is a scalar, G is the basepoint, and B is a point + void addKeys1(key &aGB, const key &a, const key & B) { + key aG = scalarmultBase(a); + addKeys(aGB, aG, B); + } + + //addKeys2 + //aGbB = aG + bB where a, b are scalars, G is the basepoint and B is a point + void addKeys2(key &aGbB, const key &a, const key &b, const key & B) { + ge_p2 rv; + ge_p3 B2; + CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&B2, B.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); + ge_double_scalarmult_base_vartime(&rv, b.bytes, &B2, a.bytes); + ge_tobytes(aGbB.bytes, &rv); + } + + //Does some precomputation to make addKeys3 more efficient + // input B a curve point and output a ge_dsmp which has precomputation applied + void precomp(ge_dsmp rv, const key & B) { + ge_p3 B2; + CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&B2, B.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); + ge_dsm_precomp(rv, &B2); + } + + //addKeys3 + //aAbB = a*A + b*B where a, b are scalars, A, B are curve points + //B must be input after applying "precomp" + void addKeys3(key &aAbB, const key &a, const key &A, const key &b, const ge_dsmp B) { + ge_p2 rv; + ge_p3 A2; + CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&A2, A.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); + ge_double_scalarmult_precomp_vartime(&rv, a.bytes, &A2, b.bytes, B); + ge_tobytes(aAbB.bytes, &rv); + } + + + //subtract Keys (subtracts curve points) + //AB = A - B where A, B are curve points + void subKeys(key & AB, const key &A, const key &B) { + ge_p3 B2, A2; + CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&B2, B.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); + CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&A2, A.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); + ge_cached tmp2; + ge_p3_to_cached(&tmp2, &B2); + ge_p1p1 tmp3; + ge_sub(&tmp3, &A2, &tmp2); + ge_p1p1_to_p3(&A2, &tmp3); + ge_p3_tobytes(AB.bytes, &A2); + } + + //checks if A, B are equal as curve points + //without doing curve operations + bool equalKeys(const key & a, const key & b) { + bool rv = true; + for (int i = 0; i < 32; ++i) { + if (a.bytes[i] != b.bytes[i]) { + rv = false; + } + } + return rv; + } + + //Hashing - cn_fast_hash + //be careful these are also in crypto namespace + //cn_fast_hash for arbitrary multiples of 32 bytes + void cn_fast_hash(key &hash, const void * data, const std::size_t l) { + keccak((uint8_t *)data, l, hash.bytes, 32); + } + + void hash_to_scalar(key &hash, const void * data, const std::size_t l) { + cn_fast_hash(hash, data, l); + sc_reduce32(hash.bytes); + } + + //cn_fast_hash for a 32 byte key + void cn_fast_hash(key & hash, const key & in) { + keccak((uint8_t *)in.bytes, 32, hash.bytes, 32); + } + + void hash_to_scalar(key & hash, const key & in) { + cn_fast_hash(hash, in); + sc_reduce32(hash.bytes); + } + + //cn_fast_hash for a 32 byte key + key cn_fast_hash(const key & in) { + key hash; + keccak((uint8_t *)in.bytes, 32, hash.bytes, 32); + return hash; + } + + key hash_to_scalar(const key & in) { + key hash = cn_fast_hash(in); + sc_reduce32(hash.bytes); + return hash; + } + + //cn_fast_hash for a 128 byte unsigned char + key cn_fast_hash128(const void * in) { + key hash; + keccak((uint8_t *)in, 128, hash.bytes, 32); + return hash; + } + + key hash_to_scalar128(const void * in) { + key hash = cn_fast_hash128(in); + sc_reduce32(hash.bytes); + return hash; + } + + //cn_fast_hash for multisig purpose + //This takes the outputs and commitments + //and hashes them into a 32 byte sized key + key cn_fast_hash(ctkeyV PC) { + key rv = identity(); + std::size_t l = (std::size_t)PC.size(); + size_t i = 0, j = 0; + vector<char> m(l * 64); + for (i = 0 ; i < l ; i++) { + memcpy(&m[i * 64], &PC[i].dest, 32); + memcpy(&m[i * 64 + 32], &PC[i].mask, 32); + } + cn_fast_hash(rv, &m[0], 64*l); + return rv; + } + + key hash_to_scalar(ctkeyV PC) { + key rv = cn_fast_hash(PC); + sc_reduce32(rv.bytes); + return rv; + } + + //cn_fast_hash for a key-vector of arbitrary length + //this is useful since you take a number of keys + //put them in the key vector and it concatenates them + //and then hashes them + key cn_fast_hash(const keyV &keys) { + size_t l = keys.size(); + vector<unsigned char> m(l * 32); + size_t i; + for (i = 0 ; i < l ; i++) { + memcpy(&m[i * 32], keys[i].bytes, 32); + } + key rv; + cn_fast_hash(rv, &m[0], 32 * l); + //dp(rv); + return rv; + } + + key hash_to_scalar(const keyV &keys) { + key rv = cn_fast_hash(keys); + sc_reduce32(rv.bytes); + return rv; + } + + key hashToPointSimple(const key & hh) { + key pointk; + ge_p1p1 point2; + ge_p2 point; + ge_p3 res; + key h = cn_fast_hash(hh); + CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&res, h.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); + ge_p3_to_p2(&point, &res); + ge_mul8(&point2, &point); + ge_p1p1_to_p3(&res, &point2); + ge_p3_tobytes(pointk.bytes, &res); + return pointk; + } + + key hashToPoint(const key & hh) { + key pointk; + ge_p2 point; + ge_p1p1 point2; + ge_p3 res; + key h = cn_fast_hash(hh); + ge_fromfe_frombytes_vartime(&point, h.bytes); + ge_mul8(&point2, &point); + ge_p1p1_to_p3(&res, &point2); + ge_p3_tobytes(pointk.bytes, &res); + return pointk; + } + + void hashToPoint(key & pointk, const key & hh) { + ge_p2 point; + ge_p1p1 point2; + ge_p3 res; + key h = cn_fast_hash(hh); + ge_fromfe_frombytes_vartime(&point, h.bytes); + ge_mul8(&point2, &point); + ge_p1p1_to_p3(&res, &point2); + ge_p3_tobytes(pointk.bytes, &res); + } + + //sums a vector of curve points (for scalars use sc_add) + void sumKeys(key & Csum, const keyV & Cis) { + identity(Csum); + size_t i = 0; + for (i = 0; i < Cis.size(); i++) { + addKeys(Csum, Csum, Cis[i]); + } + } + + //Elliptic Curve Diffie Helman: encodes and decodes the amount b and mask a + // where C= aG + bH + void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec) { + key sharedSec1 = hash_to_scalar(sharedSec); + key sharedSec2 = hash_to_scalar(sharedSec1); + //encode + sc_add(unmasked.mask.bytes, unmasked.mask.bytes, sharedSec1.bytes); + sc_add(unmasked.amount.bytes, unmasked.amount.bytes, sharedSec2.bytes); + } + void ecdhDecode(ecdhTuple & masked, const key & sharedSec) { + key sharedSec1 = hash_to_scalar(sharedSec); + key sharedSec2 = hash_to_scalar(sharedSec1); + //decode + sc_sub(masked.mask.bytes, masked.mask.bytes, sharedSec1.bytes); + sc_sub(masked.amount.bytes, masked.amount.bytes, sharedSec2.bytes); + } +} |
