Electroneum
Loading...
Searching...
No Matches
rct Namespace Reference

Classes

struct  MultiexpData
struct  key
struct  ctkey
struct  multisig_kLRki
struct  multisig_out
struct  ecdhTuple
struct  boroSig
struct  geDsmp
struct  mgSig
struct  rangeSig
struct  Bulletproof
struct  RCTConfig
struct  rctSigBase
struct  rctSigPrunable
struct  rctSig

Typedefs

typedef unsigned char * Bytes
typedef std::vector< keykeyV
typedef std::vector< keyVkeyM
typedef std::vector< ctkeyctkeyV
typedef std::vector< ctkeyVctkeyM
typedef uint64_t etn_amount
typedef unsigned int bits[ATOMS]
typedef key key64[64]

Enumerations

enum  {
  RCTTypeNull = 0 , RCTTypeFull = 1 , RCTTypeSimple = 2 , RCTTypeBulletproof = 3 ,
  RCTTypeBulletproof2 = 4
}
enum  RangeProofType { RangeProofBorromean , RangeProofBulletproof , RangeProofMultiOutputBulletproof , RangeProofPaddedBulletproof }

Functions

Bulletproof bulletproof_PROVE (const rct::key &v, const rct::key &gamma)
Bulletproof bulletproof_PROVE (uint64_t v, const rct::key &gamma)
Bulletproof bulletproof_PROVE (const rct::keyV &v, const rct::keyV &gamma)
Bulletproof bulletproof_PROVE (const std::vector< uint64_t > &v, const rct::keyV &gamma)
bool bulletproof_VERIFY (const Bulletproof &proof)
bool bulletproof_VERIFY (const std::vector< const Bulletproof * > &proofs)
bool bulletproof_VERIFY (const std::vector< Bulletproof > &proofs)
rct::key bos_coster_heap_conv (std::vector< MultiexpData > data)
rct::key bos_coster_heap_conv_robust (std::vector< MultiexpData > data)
std::shared_ptr< straus_cached_data > straus_init_cache (const std::vector< MultiexpData > &data, size_t N=0)
size_t straus_get_cache_size (const std::shared_ptr< straus_cached_data > &cache)
rct::key straus (const std::vector< MultiexpData > &data, const std::shared_ptr< straus_cached_data > &cache=NULL, size_t STEP=0)
std::shared_ptr< pippenger_cached_data > pippenger_init_cache (const std::vector< MultiexpData > &data, size_t start_offset=0, size_t N=0)
size_t pippenger_get_cache_size (const std::shared_ptr< pippenger_cached_data > &cache)
size_t get_pippenger_c (size_t N)
rct::key pippenger (const std::vector< MultiexpData > &data, const std::shared_ptr< pippenger_cached_data > &cache=NULL, size_t cache_size=0, size_t c=0)
keyM keyMInit (size_t rows, size_t cols)
bool toPointCheckOrder (ge_p3 *P, const unsigned char *data)
void skGen (key &sk)
key skGen ()
keyV skvGen (size_t rows)
key pkGen ()
void skpkGen (key &sk, key &pk)
tuple< key, keyskpkGen ()
void genC (key &C, const key &a, etn_amount amount)
tuple< ctkey, ctkeyctskpkGen (etn_amount amount)
tuple< ctkey, ctkeyctskpkGen (const key &bH)
key zeroCommit (etn_amount amount)
key commit (etn_amount amount, const key &mask)
etn_amount randEtnAmount (etn_amount upperlimit)
void scalarmultBase (key &aG, const key &a)
key scalarmultBase (const key &a)
void scalarmultKey (key &aP, const key &P, const key &a)
key scalarmultKey (const key &P, const key &a)
key scalarmultH (const key &a)
key scalarmult8 (const key &P)
bool isInMainSubgroup (const key &A)
void addKeys (key &AB, const key &A, const key &B)
rct::key addKeys (const key &A, const key &B)
rct::key addKeys (const keyV &A)
void addKeys1 (key &aGB, const key &a, const key &B)
void addKeys2 (key &aGbB, const key &a, const key &b, const key &B)
void precomp (ge_dsmp rv, const key &B)
void addKeys3 (key &aAbB, const key &a, const key &A, const key &b, const ge_dsmp B)
void addKeys3 (key &aAbB, const key &a, const ge_dsmp A, const key &b, const ge_dsmp B)
void subKeys (key &AB, const key &A, const key &B)
bool equalKeys (const key &a, const key &b)
void cn_fast_hash (key &hash, const void *data, const std::size_t l)
void hash_to_scalar (key &hash, const void *data, const std::size_t l)
void cn_fast_hash (key &hash, const key &in)
void hash_to_scalar (key &hash, const key &in)
key cn_fast_hash (const key &in)
key hash_to_scalar (const key &in)
key cn_fast_hash128 (const void *in)
key hash_to_scalar128 (const void *in)
key cn_fast_hash (const ctkeyV &PC)
key hash_to_scalar (const ctkeyV &PC)
key cn_fast_hash (const keyV &keys)
key hash_to_scalar (const keyV &keys)
key cn_fast_hash (const key64 keys)
key hash_to_scalar (const key64 keys)
key hashToPointSimple (const key &hh)
key hashToPoint (const key &hh)
void hashToPoint (key &pointk, const key &hh)
void sumKeys (key &Csum, const keyV &Cis)
key genCommitmentMask (const key &sk)
void ecdhEncode (ecdhTuple &unmasked, const key &sharedSec, bool v2)
void ecdhDecode (ecdhTuple &masked, const key &sharedSec, bool v2)
key zero ()
void zero (key &z)
key identity ()
void identity (key &Id)
key curveOrder ()
void curveOrder (key &l)
void copy (key &AA, const key &A)
key copy (const key &A)
bool toPointCheckOrder (ge_p3 *P, const unsigned char *data)
void cn_fast_hash (key &hash, const void *data, const size_t l)
void hash_to_scalar (key &hash, const void *data, const size_t l)
void sumKeys (key &Csum, const key &Cis)
void ecdhEncode (ecdhTuple &unmasked, const key &sharedSec, bool v2)
void ecdhDecode (ecdhTuple &masked, const key &sharedSec, bool v2)
Bulletproof proveRangeBulletproof (keyV &C, keyV &masks, const std::vector< uint64_t > &amounts, epee::span< const key > sk, hw::device &hwdev)
bool verBulletproof (const Bulletproof &proof)
bool verBulletproof (const std::vector< const Bulletproof * > &proofs)
boroSig genBorromean (const key64 x, const key64 P1, const key64 P2, const bits indices)
bool verifyBorromean (const boroSig &bb, const ge_p3 P1[64], const ge_p3 P2[64])
bool verifyBorromean (const boroSig &bb, const key64 P1, const key64 P2)
mgSig MLSAG_Gen (const key &message, const keyM &pk, const keyV &xx, const multisig_kLRki *kLRki, key *mscout, const unsigned int index, size_t dsRows, hw::device &hwdev)
bool MLSAG_Ver (const key &message, const keyM &pk, const mgSig &rv, size_t dsRows)
rangeSig proveRange (key &C, key &mask, const etn_amount &amount)
bool verRange (const key &C, const rangeSig &as)
key get_pre_mlsag_hash (const rctSig &rv, hw::device &hwdev)
mgSig proveRctMG (const key &message, const ctkeyM &pubs, const ctkeyV &inSk, const ctkeyV &outSk, const ctkeyV &outPk, const multisig_kLRki *kLRki, key *mscout, unsigned int index, const key &txnFeeKey, hw::device &hwdev)
mgSig proveRctMGSimple (const key &message, const ctkeyV &pubs, const ctkey &inSk, const key &a, const key &Cout, const multisig_kLRki *kLRki, key *mscout, unsigned int index, hw::device &hwdev)
bool verRctMG (const mgSig &mg, const ctkeyM &pubs, const ctkeyV &outPk, const key &txnFeeKey, const key &message)
bool verRctMGSimple (const key &message, const mgSig &mg, const ctkeyV &pubs, const key &C)
void getKeyFromBlockchain (ctkey &a, size_t reference_index)
tuple< ctkeyM, etn_amountpopulateFromBlockchain (ctkeyV inPk, int mixin)
etn_amount populateFromBlockchainSimple (ctkeyV &mixRing, const ctkey &inPk, int mixin)
rctSig genRct (const key &message, const ctkeyV &inSk, const keyV &destinations, const vector< etn_amount > &amounts, const ctkeyM &mixRing, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, unsigned int index, ctkeyV &outSk, const RCTConfig &rct_config, hw::device &hwdev)
rctSig genRct (const key &message, const ctkeyV &inSk, const ctkeyV &inPk, const keyV &destinations, const vector< etn_amount > &amounts, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, const int mixin, const RCTConfig &rct_config, hw::device &hwdev)
rctSig genRctSimple (const key &message, const ctkeyV &inSk, const keyV &destinations, const vector< etn_amount > &inamounts, const vector< etn_amount > &outamounts, etn_amount txnFee, const ctkeyM &mixRing, const keyV &amount_keys, const std::vector< multisig_kLRki > *kLRki, multisig_out *msout, const std::vector< unsigned int > &index, ctkeyV &outSk, const RCTConfig &rct_config, hw::device &hwdev)
rctSig genRctSimple (const key &message, const ctkeyV &inSk, const ctkeyV &inPk, const keyV &destinations, const vector< etn_amount > &inamounts, const vector< etn_amount > &outamounts, const keyV &amount_keys, const std::vector< multisig_kLRki > *kLRki, multisig_out *msout, etn_amount txnFee, unsigned int mixin, const RCTConfig &rct_config, hw::device &hwdev)
bool verRct (const rctSig &rv, bool semantics)
bool verRctSemanticsSimple (const std::vector< const rctSig * > &rvv)
bool verRctSemanticsSimple (const rctSig &rv)
bool verRctNonSemanticsSimple (const rctSig &rv)
etn_amount decodeRct (const rctSig &rv, const key &sk, unsigned int i, key &mask, hw::device &hwdev)
etn_amount decodeRct (const rctSig &rv, const key &sk, unsigned int i, hw::device &hwdev)
etn_amount decodeRctSimple (const rctSig &rv, const key &sk, unsigned int i, key &mask, hw::device &hwdev)
etn_amount decodeRctSimple (const rctSig &rv, const key &sk, unsigned int i, hw::device &hwdev)
bool signMultisig (rctSig &rv, const std::vector< unsigned int > &indices, const keyV &k, const multisig_out &msout, const key &secret_key)
mgSig proveRctMG (const ctkeyM &pubs, const ctkeyV &inSk, const keyV &outMasks, const ctkeyV &outPk, const multisig_kLRki *kLRki, key *mscout, unsigned int index, const key &txnFee, const key &message, hw::device &hwdev)
bool verRct (const rctSig &rv, bool semantics)
void dp (key a)
void dp (bool a)
void dp (const char *a, int l)
void dp (keyV a)
void dp (keyM a)
void dp (etn_amount vali)
void dp (bits amountb)
void dp (const char *st)
void d2h (key &amounth, const etn_amount in)
key d2h (const etn_amount in)
void d2b (bits amountb, etn_amount val)
etn_amount h2d (const key &test)
void h2b (bits amountb2, const key &test)
void b2h (key &amountdh, const bits amountb2)
etn_amount b2d (bits amountb)
bool is_rct_simple (int type)
bool is_rct_bulletproof (int type)
bool is_rct_borromean (int type)
size_t n_bulletproof_amounts (const Bulletproof &proof)
size_t n_bulletproof_amounts (const std::vector< Bulletproof > &proofs)
size_t n_bulletproof_max_amounts (const Bulletproof &proof)
size_t n_bulletproof_max_amounts (const std::vector< Bulletproof > &proofs)
void dp (bool a)
std::ostream & operator<< (std::ostream &o, const rct::key &v)

Typedef Documentation

◆ bits

typedef unsigned int rct::bits[ATOMS]

Definition at line 136 of file rctTypes.h.

◆ Bytes

typedef unsigned char* rct::Bytes

Definition at line 72 of file rctTypes.h.

◆ ctkeyM

typedef std::vector<ctkeyV> rct::ctkeyM

Definition at line 101 of file rctTypes.h.

◆ ctkeyV

typedef std::vector<ctkey> rct::ctkeyV

Definition at line 100 of file rctTypes.h.

◆ etn_amount

Definition at line 135 of file rctTypes.h.

◆ key64

typedef key rct::key64[64]

Definition at line 137 of file rctTypes.h.

◆ keyM

typedef std::vector<keyV> rct::keyM

Definition at line 89 of file rctTypes.h.

◆ keyV

typedef std::vector<key> rct::keyV

Definition at line 88 of file rctTypes.h.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
RCTTypeNull 
RCTTypeFull 
RCTTypeSimple 
RCTTypeBulletproof 
RCTTypeBulletproof2 

Definition at line 228 of file rctTypes.h.

228 {
229 RCTTypeNull = 0,
230 RCTTypeFull = 1,
231 RCTTypeSimple = 2,
234 };
@ RCTTypeFull
Definition rctTypes.h:230
@ RCTTypeSimple
Definition rctTypes.h:231
@ RCTTypeBulletproof2
Definition rctTypes.h:233
@ RCTTypeBulletproof
Definition rctTypes.h:232
@ RCTTypeNull
Definition rctTypes.h:229

◆ RangeProofType

Enumerator
RangeProofBorromean 
RangeProofBulletproof 
RangeProofMultiOutputBulletproof 
RangeProofPaddedBulletproof 

Definition at line 235 of file rctTypes.h.

Function Documentation

◆ addKeys() [1/3]

rct::key rct::addKeys ( const key & A,
const key & B )

Definition at line 432 of file rctOps.cpp.

432 {
433 key k;
434 addKeys(k, A, B);
435 return k;
436 }
void addKeys(key &AB, const key &A, const key &B)
Definition rctOps.cpp:420
Here is the call graph for this function:

◆ addKeys() [2/3]

rct::key rct::addKeys ( const keyV & A)

Definition at line 438 of file rctOps.cpp.

438 {
439 if (A.empty())
440 return rct::identity();
441 ge_p3 p3, tmp;
442 CHECK_AND_ASSERT_THROW_MES_L1(ge_frombytes_vartime(&p3, A[0].bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
443 for (size_t i = 1; i < A.size(); ++i)
444 {
445 CHECK_AND_ASSERT_THROW_MES_L1(ge_frombytes_vartime(&tmp, A[i].bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
446 ge_cached p2;
447 ge_p3_to_cached(&p2, &tmp);
448 ge_p1p1 p1;
449 ge_add(&p1, &p3, &p2);
450 ge_p1p1_to_p3(&p3, &p1);
451 }
453 ge_p3_tobytes(res.bytes, &p3);
454 return res;
455 }
int ge_frombytes_vartime(ge_p3 *, const unsigned char *)
#define CHECK_AND_ASSERT_THROW_MES_L1(expr, message)
const char * res
key identity()
Definition rctOps.h:73
#define ge_p1p1_to_p3
Definition ge.h:63
#define ge_p3_tobytes
Definition ge.h:55
#define ge_p3_to_cached
Definition ge.h:61
#define ge_add
Definition ge.h:69
Here is the call graph for this function:

◆ addKeys() [3/3]

void rct::addKeys ( key & AB,
const key & A,
const key & B )

Definition at line 420 of file rctOps.cpp.

420 {
421 ge_p3 B2, A2;
422 CHECK_AND_ASSERT_THROW_MES_L1(ge_frombytes_vartime(&B2, B.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
423 CHECK_AND_ASSERT_THROW_MES_L1(ge_frombytes_vartime(&A2, A.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
424 ge_cached tmp2;
425 ge_p3_to_cached(&tmp2, &B2);
426 ge_p1p1 tmp3;
427 ge_add(&tmp3, &A2, &tmp2);
428 ge_p1p1_to_p3(&A2, &tmp3);
429 ge_p3_tobytes(AB.bytes, &A2);
430 }
unsigned char bytes[32]
Definition rctTypes.h:86
Here is the call graph for this function:
Here is the caller graph for this function:

◆ addKeys1()

void rct::addKeys1 ( key & aGB,
const key & a,
const key & B )

Definition at line 459 of file rctOps.cpp.

459 {
460 key aG = scalarmultBase(a);
461 addKeys(aGB, aG, B);
462 }
void scalarmultBase(key &aG, const key &a)
Definition rctOps.cpp:350
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1124
Here is the call graph for this function:
Here is the caller graph for this function:

◆ addKeys2()

void rct::addKeys2 ( key & aGbB,
const key & a,
const key & b,
const key & B )

Definition at line 466 of file rctOps.cpp.

466 {
467 ge_p2 rv;
468 ge_p3 B2;
469 CHECK_AND_ASSERT_THROW_MES_L1(ge_frombytes_vartime(&B2, B.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
470 ge_double_scalarmult_base_vartime(&rv, b.bytes, &B2, a.bytes);
471 ge_tobytes(aGbB.bytes, &rv);
472 }
void ge_double_scalarmult_base_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *)
#define ge_tobytes
Definition ge.h:54
Here is the call graph for this function:
Here is the caller graph for this function:

◆ addKeys3() [1/2]

void rct::addKeys3 ( key & aAbB,
const key & a,
const ge_dsmp A,
const key & b,
const ge_dsmp B )

Definition at line 496 of file rctOps.cpp.

496 {
497 ge_p2 rv;
499 ge_tobytes(aAbB.bytes, &rv);
500 }
void ge_double_scalarmult_precomp_vartime2(ge_p2 *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp)
Here is the call graph for this function:

◆ addKeys3() [2/2]

void rct::addKeys3 ( key & aAbB,
const key & a,
const key & A,
const key & b,
const ge_dsmp B )

Definition at line 485 of file rctOps.cpp.

485 {
486 ge_p2 rv;
487 ge_p3 A2;
488 CHECK_AND_ASSERT_THROW_MES_L1(ge_frombytes_vartime(&A2, A.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
489 ge_double_scalarmult_precomp_vartime(&rv, a.bytes, &A2, b.bytes, B);
490 ge_tobytes(aAbB.bytes, &rv);
491 }
void ge_double_scalarmult_precomp_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *, const ge_dsmp)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ b2d()

etn_amount rct::b2d ( bits amountb)

Definition at line 205 of file rctTypes.cpp.

205 {
206 etn_amount vali = 0;
207 int j = 0;
208 for (j = 63; j >= 0; j--) {
209 vali = (etn_amount)(vali * 2 + amountb[j]);
210 }
211 return vali;
212 }
uint64_t etn_amount
Definition rctTypes.h:135
Here is the caller graph for this function:

◆ b2h()

void rct::b2h ( key & amountdh,
const bits amountb2 )

Definition at line 189 of file rctTypes.cpp.

189 {
190 int byte, i, j;
191 for (j = 0; j < 8; j++) {
192 byte = 0;
193 i = 8 * j;
194 for (i = 7; i > -1; i--) {
195 byte = byte * 2 + amountb2[8 * j + i];
196 }
197 amountdh[j] = (unsigned char)byte;
198 }
199 for (j = 8; j < 32; j++) {
200 amountdh[j] = (unsigned char)(0x00);
201 }
202 }
Here is the caller graph for this function:

◆ bos_coster_heap_conv()

rct::key rct::bos_coster_heap_conv ( std::vector< MultiexpData > data)

◆ bos_coster_heap_conv_robust()

rct::key rct::bos_coster_heap_conv_robust ( std::vector< MultiexpData > data)

◆ bulletproof_PROVE() [1/4]

Bulletproof rct::bulletproof_PROVE ( const rct::key & v,
const rct::key & gamma )
Here is the caller graph for this function:

◆ bulletproof_PROVE() [2/4]

Bulletproof rct::bulletproof_PROVE ( const rct::keyV & v,
const rct::keyV & gamma )

◆ bulletproof_PROVE() [3/4]

Bulletproof rct::bulletproof_PROVE ( const std::vector< uint64_t > & v,
const rct::keyV & gamma )

◆ bulletproof_PROVE() [4/4]

Bulletproof rct::bulletproof_PROVE ( uint64_t v,
const rct::key & gamma )

◆ bulletproof_VERIFY() [1/3]

bool rct::bulletproof_VERIFY ( const Bulletproof & proof)
Here is the caller graph for this function:

◆ bulletproof_VERIFY() [2/3]

bool rct::bulletproof_VERIFY ( const std::vector< Bulletproof > & proofs)

◆ bulletproof_VERIFY() [3/3]

bool rct::bulletproof_VERIFY ( const std::vector< const Bulletproof * > & proofs)

◆ cn_fast_hash() [1/7]

key rct::cn_fast_hash ( const ctkeyV & PC)

Definition at line 580 of file rctOps.cpp.

580 {
581 if (PC.empty()) return rct::hash2rct(crypto::cn_fast_hash("", 0));
582 key rv;
583 cn_fast_hash(rv, &PC[0], 64*PC.size());
584 return rv;
585 }
void cn_fast_hash(const void *data, size_t length, char *hash)
void cn_fast_hash(key &hash, const void *data, const std::size_t l)
Definition rctOps.cpp:532
Here is the call graph for this function:

◆ cn_fast_hash() [2/7]

key rct::cn_fast_hash ( const key & in)

Definition at line 552 of file rctOps.cpp.

552 {
553 key hash;
554 keccak((const uint8_t *)in.bytes, 32, hash.bytes, 32);
555 return hash;
556 }
void keccak(const uint8_t *in, size_t inlen, uint8_t *md, int mdlen)
POD_CLASS hash
Definition hash.h:50
unsigned char uint8_t
Definition stdint.h:124
Here is the call graph for this function:

◆ cn_fast_hash() [3/7]

key rct::cn_fast_hash ( const key64 keys)

Definition at line 611 of file rctOps.cpp.

611 {
612 key rv;
613 cn_fast_hash(rv, &keys[0], 64 * sizeof(keys[0]));
614 //dp(rv);
615 return rv;
616 }
Here is the call graph for this function:

◆ cn_fast_hash() [4/7]

key rct::cn_fast_hash ( const keyV & keys)

Definition at line 597 of file rctOps.cpp.

597 {
598 if (keys.empty()) return rct::hash2rct(crypto::cn_fast_hash("", 0));
599 key rv;
600 cn_fast_hash(rv, &keys[0], keys.size() * sizeof(keys[0]));
601 //dp(rv);
602 return rv;
603 }
Here is the call graph for this function:

◆ cn_fast_hash() [5/7]

void rct::cn_fast_hash ( key & hash,
const key & in )

Definition at line 542 of file rctOps.cpp.

542 {
543 keccak((const uint8_t *)in.bytes, 32, hash.bytes, 32);
544 }
Here is the call graph for this function:

◆ cn_fast_hash() [6/7]

void rct::cn_fast_hash ( key & hash,
const void * data,
const size_t l )

◆ cn_fast_hash() [7/7]

void rct::cn_fast_hash ( key & hash,
const void * data,
const std::size_t l )

Definition at line 532 of file rctOps.cpp.

532 {
533 keccak((const uint8_t *)data, l, hash.bytes, 32);
534 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cn_fast_hash128()

key rct::cn_fast_hash128 ( const void * in)

Definition at line 565 of file rctOps.cpp.

565 {
566 key hash;
567 keccak((const uint8_t *)in, 128, hash.bytes, 32);
568 return hash;
569 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ commit()

key rct::commit ( etn_amount amount,
const key & mask )

Definition at line 336 of file rctOps.cpp.

336 {
337 key c;
338 genC(c, mask, amount);
339 return c;
340 }
void genC(key &C, const key &a, etn_amount amount)
Definition rctOps.cpp:297
Here is the call graph for this function:
Here is the caller graph for this function:

◆ copy() [1/2]

key rct::copy ( const key & A)
inline

Definition at line 80 of file rctOps.h.

80{ key AA; memcpy(&AA, &A, 32); return AA; }
void * memcpy(void *a, const void *b, size_t c)
Here is the call graph for this function:

◆ copy() [2/2]

void rct::copy ( key & AA,
const key & A )
inline

Definition at line 79 of file rctOps.h.

79{ memcpy(&AA, &A, 32); }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ctskpkGen() [1/2]

std::tuple< ctkey, ctkey > rct::ctskpkGen ( const key & bH)

Definition at line 314 of file rctOps.cpp.

314 {
315 ctkey sk, pk;
316 skpkGen(sk.dest, pk.dest);
317 skpkGen(sk.mask, pk.mask);
318 addKeys(pk.mask, pk.mask, bH);
319 return make_tuple(sk, pk);
320 }
tuple< key, key > skpkGen()
Definition rctOps.cpp:290
Here is the call graph for this function:

◆ ctskpkGen() [2/2]

std::tuple< ctkey, ctkey > rct::ctskpkGen ( etn_amount amount)

Definition at line 302 of file rctOps.cpp.

302 {
303 ctkey sk, pk;
304 skpkGen(sk.dest, pk.dest);
305 skpkGen(sk.mask, pk.mask);
306 key am = d2h(amount);
307 key bH = scalarmultH(am);
308 addKeys(pk.mask, pk.mask, bH);
309 return make_tuple(sk, pk);
310 }
key scalarmultH(const key &a)
Definition rctOps.cpp:389
void d2h(key &amounth, const etn_amount in)
Definition rctTypes.cpp:119
Here is the call graph for this function:
Here is the caller graph for this function:

◆ curveOrder() [1/2]

key rct::curveOrder ( )
inline

Definition at line 76 of file rctOps.h.

76{ return L; }
Here is the caller graph for this function:

◆ curveOrder() [2/2]

void rct::curveOrder ( key & l)
inline

Definition at line 77 of file rctOps.h.

77{ l = L; }

◆ d2b()

void rct::d2b ( bits amountb,
etn_amount val )

Definition at line 145 of file rctTypes.cpp.

145 {
146 int i = 0;
147 while (val != 0) {
148 amountb[i] = val & 1;
149 i++;
150 val >>= 1;
151 }
152 while (i < 64) {
153 amountb[i] = 0;
154 i++;
155 }
156 }
Here is the caller graph for this function:

◆ d2h() [1/2]

key rct::d2h ( const etn_amount in)

Definition at line 131 of file rctTypes.cpp.

131 {
132 key amounth;
133 sc_0(amounth.bytes);
134 etn_amount val = in;
135 int i = 0;
136 while (val != 0) {
137 amounth[i] = (unsigned char)(val & 0xFF);
138 i++;
139 val /= (etn_amount)256;
140 }
141 return amounth;
142 }
void sc_0(unsigned char *)
Here is the call graph for this function:

◆ d2h() [2/2]

void rct::d2h ( key & amounth,
const etn_amount in )

Definition at line 119 of file rctTypes.cpp.

119 {
120 sc_0(amounth.bytes);
121 etn_amount val = in;
122 int i = 0;
123 while (val != 0) {
124 amounth[i] = (unsigned char)(val & 0xFF);
125 i++;
126 val /= (etn_amount)256;
127 }
128 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ decodeRct() [1/2]

etn_amount rct::decodeRct ( const rctSig & rv,
const key & sk,
unsigned int i,
hw::device & hwdev )

Definition at line 1175 of file rctSigs.cpp.

1175 {
1176 key mask;
1177 return decodeRct(rv, sk, i, mask, hwdev);
1178 }
etn_amount decodeRct(const rctSig &rv, const key &sk, unsigned int i, key &mask, hw::device &hwdev)
Definition rctSigs.cpp:1150
Here is the call graph for this function:

◆ decodeRct() [2/2]

etn_amount rct::decodeRct ( const rctSig & rv,
const key & sk,
unsigned int i,
key & mask,
hw::device & hwdev )

Definition at line 1150 of file rctSigs.cpp.

1150 {
1151 CHECK_AND_ASSERT_MES(rv.type == RCTTypeFull, false, "decodeRct called on non-full rctSig");
1152 CHECK_AND_ASSERT_THROW_MES(i < rv.ecdhInfo.size(), "Bad index");
1153 CHECK_AND_ASSERT_THROW_MES(rv.outPk.size() == rv.ecdhInfo.size(), "Mismatched sizes of rv.outPk and rv.ecdhInfo");
1154
1155 //mask amount and mask
1156 ecdhTuple ecdh_info = rv.ecdhInfo[i];
1157 hwdev.ecdhDecode(ecdh_info, sk, rv.type == RCTTypeBulletproof2);
1158 mask = ecdh_info.mask;
1159 key amount = ecdh_info.amount;
1160 key C = rv.outPk[i].mask;
1161 DP("C");
1162 DP(C);
1163 key Ctmp;
1164 CHECK_AND_ASSERT_THROW_MES(sc_check(mask.bytes) == 0, "warning, bad ECDH mask");
1165 CHECK_AND_ASSERT_THROW_MES(sc_check(amount.bytes) == 0, "warning, bad ECDH amount");
1166 addKeys2(Ctmp, mask, amount, H);
1167 DP("Ctmp");
1168 DP(Ctmp);
1169 if (equalKeys(C, Ctmp) == false) {
1170 CHECK_AND_ASSERT_THROW_MES(false, "warning, amount decoded incorrectly, will be unable to spend");
1171 }
1172 return h2d(amount);
1173 }
virtual bool ecdhDecode(rct::ecdhTuple &masked, const rct::key &sharedSec, bool short_amount)=0
int sc_check(const unsigned char *)
#define CHECK_AND_ASSERT_MES(expr, fail_ret_val, message)
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
etn_amount h2d(const key &test)
Definition rctTypes.cpp:161
void addKeys2(key &aGbB, const key &a, const key &b, const key &B)
Definition rctOps.cpp:466
bool equalKeys(const key &a, const key &b)
Definition rctOps.cpp:519
#define DP(x)
Definition rctOps.h:55
std::vector< ecdhTuple > ecdhInfo
Definition rctTypes.h:246
Here is the call graph for this function:
Here is the caller graph for this function:

◆ decodeRctSimple() [1/2]

etn_amount rct::decodeRctSimple ( const rctSig & rv,
const key & sk,
unsigned int i,
hw::device & hwdev )

Definition at line 1205 of file rctSigs.cpp.

1205 {
1206 key mask;
1207 return decodeRctSimple(rv, sk, i, mask, hwdev);
1208 }
etn_amount decodeRctSimple(const rctSig &rv, const key &sk, unsigned int i, key &mask, hw::device &hwdev)
Definition rctSigs.cpp:1180
Here is the call graph for this function:

◆ decodeRctSimple() [2/2]

etn_amount rct::decodeRctSimple ( const rctSig & rv,
const key & sk,
unsigned int i,
key & mask,
hw::device & hwdev )

Definition at line 1180 of file rctSigs.cpp.

1180 {
1181 CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2, false, "decodeRct called on non simple rctSig");
1182 CHECK_AND_ASSERT_THROW_MES(i < rv.ecdhInfo.size(), "Bad index");
1183 CHECK_AND_ASSERT_THROW_MES(rv.outPk.size() == rv.ecdhInfo.size(), "Mismatched sizes of rv.outPk and rv.ecdhInfo");
1184
1185 //mask amount and mask
1186 ecdhTuple ecdh_info = rv.ecdhInfo[i];
1187 hwdev.ecdhDecode(ecdh_info, sk, rv.type == RCTTypeBulletproof2);
1188 mask = ecdh_info.mask;
1189 key amount = ecdh_info.amount;
1190 key C = rv.outPk[i].mask;
1191 DP("C");
1192 DP(C);
1193 key Ctmp;
1194 CHECK_AND_ASSERT_THROW_MES(sc_check(mask.bytes) == 0, "warning, bad ECDH mask");
1195 CHECK_AND_ASSERT_THROW_MES(sc_check(amount.bytes) == 0, "warning, bad ECDH amount");
1196 addKeys2(Ctmp, mask, amount, H);
1197 DP("Ctmp");
1198 DP(Ctmp);
1199 if (equalKeys(C, Ctmp) == false) {
1200 CHECK_AND_ASSERT_THROW_MES(false, "warning, amount decoded incorrectly, will be unable to spend");
1201 }
1202 return h2d(amount);
1203 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ dp() [1/9]

void rct::dp ( bits amountb)

Definition at line 104 of file rctTypes.cpp.

104 {
105 for (int i = 0; i < 64; i++) {
106 printf("%d", amountb[i]);
107 }
108 printf("\n");
109
110 }

◆ dp() [2/9]

void rct::dp ( bool a)

Definition at line 56 of file rctTypes.cpp.

56 {
57 printf(" ... %s ... ", a ? "true" : "false");
58 printf("\n");
59 }

◆ dp() [3/9]

void rct::dp ( bool a)
Here is the call graph for this function:

◆ dp() [4/9]

void rct::dp ( const char * a,
int l )

Definition at line 61 of file rctTypes.cpp.

61 {
62 int j = 0;
63 printf("\"");
64 for (j = 0; j < l; j++) {
65 printf("%02x", (unsigned char)a[j]);
66 }
67 printf("\"");
68 printf("\n");
69 }

◆ dp() [5/9]

void rct::dp ( const char * st)

Definition at line 112 of file rctTypes.cpp.

112 {
113 printf("%s\n", st);
114 }

◆ dp() [6/9]

void rct::dp ( etn_amount vali)

Definition at line 94 of file rctTypes.cpp.

94 {
95 printf("x: ");
96 std::cout << vali;
97 printf("\n\n");
98 }

◆ dp() [7/9]

void rct::dp ( key a)

Definition at line 46 of file rctTypes.cpp.

46 {
47 int j = 0;
48 printf("\"");
49 for (j = 0; j < 32; j++) {
50 printf("%02x", (unsigned char)a.bytes[j]);
51 }
52 printf("\"");
53 printf("\n");
54 }
Here is the caller graph for this function:

◆ dp() [8/9]

void rct::dp ( keyM a)

Definition at line 82 of file rctTypes.cpp.

82 {
83 size_t j = 0;
84 printf("[");
85 for (j = 0; j < a.size(); j++) {
86 dp(a[j]);
87 if (j < a.size() - 1) {
88 printf(",");
89 }
90 }
91 printf("]");
92 printf("\n");
93 }
void dp(key a)
Definition rctTypes.cpp:46
Here is the call graph for this function:

◆ dp() [9/9]

void rct::dp ( keyV a)

Definition at line 70 of file rctTypes.cpp.

70 {
71 size_t j = 0;
72 printf("[");
73 for (j = 0; j < a.size(); j++) {
74 dp(a[j]);
75 if (j < a.size() - 1) {
76 printf(",");
77 }
78 }
79 printf("]");
80 printf("\n");
81 }
Here is the call graph for this function:

◆ ecdhDecode() [1/2]

void rct::ecdhDecode ( ecdhTuple & masked,
const key & sharedSec,
bool v2 )

Definition at line 712 of file rctOps.cpp.

712 {
713 //decode
714 if (v2)
715 {
716 masked.mask = genCommitmentMask(sharedSec);
717 xor8(masked.amount, ecdhHash(sharedSec));
718 }
719 else
720 {
721 key sharedSec1 = hash_to_scalar(sharedSec);
722 key sharedSec2 = hash_to_scalar(sharedSec1);
723 sc_sub(masked.mask.bytes, masked.mask.bytes, sharedSec1.bytes);
724 sc_sub(masked.amount.bytes, masked.amount.bytes, sharedSec2.bytes);
725 }
726 }
void sc_sub(unsigned char *, const unsigned char *, const unsigned char *)
const char * key
void hash_to_scalar(key &hash, const void *data, const std::size_t l)
Definition rctOps.cpp:536
key genCommitmentMask(const key &sk)
Definition rctOps.cpp:687
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ecdhDecode() [2/2]

void rct::ecdhDecode ( ecdhTuple & masked,
const key & sharedSec,
bool v2 )

◆ ecdhEncode() [1/2]

void rct::ecdhEncode ( ecdhTuple & unmasked,
const key & sharedSec,
bool v2 )

Definition at line 697 of file rctOps.cpp.

697 {
698 //encode
699 if (v2)
700 {
701 unmasked.mask = zero();
702 xor8(unmasked.amount, ecdhHash(sharedSec));
703 }
704 else
705 {
706 key sharedSec1 = hash_to_scalar(sharedSec);
707 key sharedSec2 = hash_to_scalar(sharedSec1);
708 sc_add(unmasked.mask.bytes, unmasked.mask.bytes, sharedSec1.bytes);
709 sc_add(unmasked.amount.bytes, unmasked.amount.bytes, sharedSec2.bytes);
710 }
711 }
void sc_add(unsigned char *, const unsigned char *, const unsigned char *)
key zero()
Definition rctOps.h:70
Here is the call graph for this function:

◆ ecdhEncode() [2/2]

void rct::ecdhEncode ( ecdhTuple & unmasked,
const key & sharedSec,
bool v2 )

◆ equalKeys()

bool rct::equalKeys ( const key & a,
const key & b )

Definition at line 519 of file rctOps.cpp.

519 {
520 bool rv = true;
521 for (int i = 0; i < 32; ++i) {
522 if (a.bytes[i] != b.bytes[i]) {
523 rv = false;
524 }
525 }
526 return rv;
527 }
Here is the caller graph for this function:

◆ genBorromean()

boroSig rct::genBorromean ( const key64 x,
const key64 P1,
const key64 P2,
const bits indices )

Definition at line 109 of file rctSigs.cpp.

109 {
110 key64 L[2], alpha;
111 key c;
112 int naught = 0, prime = 0, ii = 0, jj=0;
113 boroSig bb;
114 for (ii = 0 ; ii < 64 ; ii++) {
115 naught = indices[ii]; prime = (indices[ii] + 1) % 2;
116 skGen(alpha[ii]);
117 scalarmultBase(L[naught][ii], alpha[ii]);
118 if (naught == 0) {
119 skGen(bb.s1[ii]);
120 c = hash_to_scalar(L[naught][ii]);
121 addKeys2(L[prime][ii], bb.s1[ii], c, P2[ii]);
122 }
123 }
124 bb.ee = hash_to_scalar(L[1]); //or L[1]..
125 key LL, cc;
126 for (jj = 0 ; jj < 64 ; jj++) {
127 if (!indices[jj]) {
128 sc_mulsub(bb.s0[jj].bytes, x[jj].bytes, bb.ee.bytes, alpha[jj].bytes);
129 } else {
130 skGen(bb.s0[jj]);
131 addKeys2(LL, bb.s0[jj], bb.ee, P1[jj]); //different L0
132 cc = hash_to_scalar(LL);
133 sc_mulsub(bb.s1[jj].bytes, x[jj].bytes, cc.bytes, alpha[jj].bytes);
134 }
135 }
136 return bb;
137 }
void sc_mulsub(unsigned char *, const unsigned char *, const unsigned char *, const unsigned char *)
key skGen()
Definition rctOps.cpp:258
key key64[64]
Definition rctTypes.h:137
Here is the call graph for this function:
Here is the caller graph for this function:

◆ genC()

void rct::genC ( key & C,
const key & a,
etn_amount amount )

Definition at line 297 of file rctOps.cpp.

297 {
298 addKeys2(C, a, d2h(amount), rct::H);
299 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ genCommitmentMask()

key rct::genCommitmentMask ( const key & sk)

Definition at line 687 of file rctOps.cpp.

688 {
689 char data[15 + sizeof(key)];
690 memcpy(data, "commitment_mask", 15);
691 memcpy(data + 15, &sk, sizeof(sk));
692 key scalar;
693 hash_to_scalar(scalar, data, sizeof(data));
694 return scalar;
695 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ genRct() [1/2]

rctSig rct::genRct ( const key & message,
const ctkeyV & inSk,
const ctkeyV & inPk,
const keyV & destinations,
const vector< etn_amount > & amounts,
const keyV & amount_keys,
const multisig_kLRki * kLRki,
multisig_out * msout,
const int mixin,
const RCTConfig & rct_config,
hw::device & hwdev )

Definition at line 742 of file rctSigs.cpp.

742 {
743 unsigned int index;
744 ctkeyM mixRing;
745 ctkeyV outSk;
746 tie(mixRing, index) = populateFromBlockchain(inPk, mixin);
747 return genRct(message, inSk, destinations, amounts, mixRing, amount_keys, kLRki, msout, index, outSk, rct_config, hwdev);
748 }
std::string message("Message requiring signing")
tuple< ctkeyM, etn_amount > populateFromBlockchain(ctkeyV inPk, int mixin)
Definition rctSigs.cpp:645
std::vector< ctkeyV > ctkeyM
Definition rctTypes.h:101
rctSig genRct(const key &message, const ctkeyV &inSk, const keyV &destinations, const vector< etn_amount > &amounts, const ctkeyM &mixRing, const keyV &amount_keys, const multisig_kLRki *kLRki, multisig_out *msout, unsigned int index, ctkeyV &outSk, const RCTConfig &rct_config, hw::device &hwdev)
Definition rctSigs.cpp:690
std::vector< ctkey > ctkeyV
Definition rctTypes.h:100
Here is the call graph for this function:

◆ genRct() [2/2]

rctSig rct::genRct ( const key & message,
const ctkeyV & inSk,
const keyV & destinations,
const vector< etn_amount > & amounts,
const ctkeyM & mixRing,
const keyV & amount_keys,
const multisig_kLRki * kLRki,
multisig_out * msout,
unsigned int index,
ctkeyV & outSk,
const RCTConfig & rct_config,
hw::device & hwdev )

Definition at line 690 of file rctSigs.cpp.

690 {
691 CHECK_AND_ASSERT_THROW_MES(amounts.size() == destinations.size() || amounts.size() == destinations.size() + 1, "Different number of amounts/destinations");
692 CHECK_AND_ASSERT_THROW_MES(amount_keys.size() == destinations.size(), "Different number of amount_keys/destinations");
693 CHECK_AND_ASSERT_THROW_MES(index < mixRing.size(), "Bad index into mixRing");
694 for (size_t n = 0; n < mixRing.size(); ++n) {
695 CHECK_AND_ASSERT_THROW_MES(mixRing[n].size() == inSk.size(), "Bad mixRing size");
696 }
697 CHECK_AND_ASSERT_THROW_MES((kLRki && msout) || (!kLRki && !msout), "Only one of kLRki/msout is present");
698 CHECK_AND_ASSERT_THROW_MES(inSk.size() < 2, "genRct is not suitable for 2+ rings");
699
700 rctSig rv;
701 rv.type = RCTTypeFull;
702 rv.message = message;
703 rv.outPk.resize(destinations.size());
704 rv.p.rangeSigs.resize(destinations.size());
705 rv.ecdhInfo.resize(destinations.size());
706
707 size_t i = 0;
708 keyV masks(destinations.size()); //sk mask..
709 outSk.resize(destinations.size());
710 for (i = 0; i < destinations.size(); i++) {
711 //add destination to sig
712 rv.outPk[i].dest = copy(destinations[i]);
713 //compute range proof
714 rv.p.rangeSigs[i] = proveRange(rv.outPk[i].mask, outSk[i].mask, amounts[i]);
715 #ifdef DBG
716 CHECK_AND_ASSERT_THROW_MES(verRange(rv.outPk[i].mask, rv.p.rangeSigs[i]), "verRange failed on newly created proof");
717 #endif
718 //mask amount and mask
719 rv.ecdhInfo[i].mask = copy(outSk[i].mask);
720 rv.ecdhInfo[i].amount = d2h(amounts[i]);
721 hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i], rv.type == RCTTypeBulletproof2);
722 }
723
724 //set txn fee
725 if (amounts.size() > destinations.size())
726 {
727 rv.txnFee = amounts[destinations.size()];
728 }
729 else
730 {
731 rv.txnFee = 0;
732 }
733 key txnFeeKey = scalarmultH(d2h(rv.txnFee));
734
735 rv.mixRing = mixRing;
736 if (msout)
737 msout->c.resize(1);
738 rv.p.MGs.push_back(proveRctMG(get_pre_mlsag_hash(rv, hwdev), rv.mixRing, inSk, outSk, rv.outPk, kLRki, msout ? &msout->c[0] : NULL, index, txnFeeKey,hwdev));
739 return rv;
740 }
virtual bool ecdhEncode(rct::ecdhTuple &unmasked, const rct::key &sharedSec, bool short_amount)=0
std::vector< key > keyV
Definition rctTypes.h:88
bool verRange(const key &C, const rangeSig &as)
Definition rctSigs.cpp:368
key get_pre_mlsag_hash(const rctSig &rv, hw::device &hwdev)
Definition rctSigs.cpp:403
mgSig proveRctMG(const key &message, const ctkeyM &pubs, const ctkeyV &inSk, const ctkeyV &outSk, const ctkeyV &outPk, const multisig_kLRki *kLRki, key *mscout, unsigned int index, const key &txnFeeKey, hw::device &hwdev)
Definition rctSigs.cpp:471
void copy(key &AA, const key &A)
Definition rctOps.h:79
rangeSig proveRange(key &C, key &mask, const etn_amount &amount)
Definition rctSigs.cpp:336
std::vector< key > c
Definition rctTypes.h:112
Here is the call graph for this function:
Here is the caller graph for this function:

◆ genRctSimple() [1/2]

rctSig rct::genRctSimple ( const key & message,
const ctkeyV & inSk,
const ctkeyV & inPk,
const keyV & destinations,
const vector< etn_amount > & inamounts,
const vector< etn_amount > & outamounts,
const keyV & amount_keys,
const std::vector< multisig_kLRki > * kLRki,
multisig_out * msout,
etn_amount txnFee,
unsigned int mixin,
const RCTConfig & rct_config,
hw::device & hwdev )

Definition at line 890 of file rctSigs.cpp.

890 {
891 std::vector<unsigned int> index;
892 index.resize(inPk.size());
893 ctkeyM mixRing;
894 ctkeyV outSk;
895 mixRing.resize(inPk.size());
896 for (size_t i = 0; i < inPk.size(); ++i) {
897 mixRing[i].resize(mixin+1);
898 index[i] = populateFromBlockchainSimple(mixRing[i], inPk[i], mixin);
899 }
900 return genRctSimple(message, inSk, destinations, inamounts, outamounts, txnFee, mixRing, amount_keys, kLRki, msout, index, outSk, rct_config, hwdev);
901 }
etn_amount populateFromBlockchainSimple(ctkeyV &mixRing, const ctkey &inPk, int mixin)
Definition rctSigs.cpp:665
rctSig genRctSimple(const key &message, const ctkeyV &inSk, const keyV &destinations, const vector< etn_amount > &inamounts, const vector< etn_amount > &outamounts, etn_amount txnFee, const ctkeyM &mixRing, const keyV &amount_keys, const std::vector< multisig_kLRki > *kLRki, multisig_out *msout, const std::vector< unsigned int > &index, ctkeyV &outSk, const RCTConfig &rct_config, hw::device &hwdev)
Definition rctSigs.cpp:752
Here is the call graph for this function:

◆ genRctSimple() [2/2]

rctSig rct::genRctSimple ( const key & message,
const ctkeyV & inSk,
const keyV & destinations,
const vector< etn_amount > & inamounts,
const vector< etn_amount > & outamounts,
etn_amount txnFee,
const ctkeyM & mixRing,
const keyV & amount_keys,
const std::vector< multisig_kLRki > * kLRki,
multisig_out * msout,
const std::vector< unsigned int > & index,
ctkeyV & outSk,
const RCTConfig & rct_config,
hw::device & hwdev )

Definition at line 752 of file rctSigs.cpp.

752 {
753 const bool bulletproof = rct_config.range_proof_type != RangeProofBorromean;
754 CHECK_AND_ASSERT_THROW_MES(inamounts.size() > 0, "Empty inamounts");
755 CHECK_AND_ASSERT_THROW_MES(inamounts.size() == inSk.size(), "Different number of inamounts/inSk");
756 CHECK_AND_ASSERT_THROW_MES(outamounts.size() == destinations.size(), "Different number of amounts/destinations");
757 CHECK_AND_ASSERT_THROW_MES(amount_keys.size() == destinations.size(), "Different number of amount_keys/destinations");
758 CHECK_AND_ASSERT_THROW_MES(index.size() == inSk.size(), "Different number of index/inSk");
759 CHECK_AND_ASSERT_THROW_MES(mixRing.size() == inSk.size(), "Different number of mixRing/inSk");
760 for (size_t n = 0; n < mixRing.size(); ++n) {
761 CHECK_AND_ASSERT_THROW_MES(index[n] < mixRing[n].size(), "Bad index into mixRing");
762 }
763 CHECK_AND_ASSERT_THROW_MES((kLRki && msout) || (!kLRki && !msout), "Only one of kLRki/msout is present");
764 if (kLRki && msout) {
765 CHECK_AND_ASSERT_THROW_MES(kLRki->size() == inamounts.size(), "Mismatched kLRki/inamounts sizes");
766 }
767
768 rctSig rv;
769 rv.type = bulletproof ? (rct_config.bp_version == 0 || rct_config.bp_version >= 2 ? RCTTypeBulletproof2 : RCTTypeBulletproof) : RCTTypeSimple;
770 rv.message = message;
771 rv.outPk.resize(destinations.size());
772 if (!bulletproof)
773 rv.p.rangeSigs.resize(destinations.size());
774 rv.ecdhInfo.resize(destinations.size());
775
776 size_t i;
777 keyV masks(destinations.size()); //sk mask..
778 outSk.resize(destinations.size());
779 for (i = 0; i < destinations.size(); i++) {
780
781 //add destination to sig
782 rv.outPk[i].dest = copy(destinations[i]);
783 //compute range proof
784 if (!bulletproof)
785 rv.p.rangeSigs[i] = proveRange(rv.outPk[i].mask, outSk[i].mask, outamounts[i]);
786 #ifdef DBG
787 if (!bulletproof)
788 CHECK_AND_ASSERT_THROW_MES(verRange(rv.outPk[i].mask, rv.p.rangeSigs[i]), "verRange failed on newly created proof");
789 #endif
790 }
791
792 rv.p.bulletproofs.clear();
793 if (bulletproof)
794 {
795 size_t n_amounts = outamounts.size();
796 size_t amounts_proved = 0;
798 {
799 rct::keyV C, masks;
801 {
802 // use a fake bulletproof for speed
803 rv.p.bulletproofs.push_back(make_dummy_bulletproof(outamounts, C, masks));
804 }
805 else
806 {
807 const epee::span<const key> keys{&amount_keys[0], amount_keys.size()};
808 rv.p.bulletproofs.push_back(proveRangeBulletproof(C, masks, outamounts, keys, hwdev));
809 #ifdef DBG
810 CHECK_AND_ASSERT_THROW_MES(verBulletproof(rv.p.bulletproofs.back()), "verBulletproof failed on newly created proof");
811 #endif
812 }
813 for (i = 0; i < outamounts.size(); ++i)
814 {
815 rv.outPk[i].mask = rct::scalarmult8(C[i]);
816 outSk[i].mask = masks[i];
817 }
818 }
819 else while (amounts_proved < n_amounts)
820 {
821 size_t batch_size = 1;
823 while (batch_size * 2 + amounts_proved <= n_amounts && batch_size * 2 <= BULLETPROOF_MAX_OUTPUTS)
824 batch_size *= 2;
825 rct::keyV C, masks;
826 std::vector<uint64_t> batch_amounts(batch_size);
827 for (i = 0; i < batch_size; ++i)
828 batch_amounts[i] = outamounts[i + amounts_proved];
830 {
831 // use a fake bulletproof for speed
832 rv.p.bulletproofs.push_back(make_dummy_bulletproof(batch_amounts, C, masks));
833 }
834 else
835 {
836 const epee::span<const key> keys{&amount_keys[amounts_proved], batch_size};
837 rv.p.bulletproofs.push_back(proveRangeBulletproof(C, masks, batch_amounts, keys, hwdev));
838 #ifdef DBG
839 CHECK_AND_ASSERT_THROW_MES(verBulletproof(rv.p.bulletproofs.back()), "verBulletproof failed on newly created proof");
840 #endif
841 }
842 for (i = 0; i < batch_size; ++i)
843 {
844 rv.outPk[i + amounts_proved].mask = rct::scalarmult8(C[i]);
845 outSk[i + amounts_proved].mask = masks[i];
846 }
847 amounts_proved += batch_size;
848 }
849 }
850
851 key sumout = zero();
852 for (i = 0; i < outSk.size(); ++i)
853 {
854 sc_add(sumout.bytes, outSk[i].mask.bytes, sumout.bytes);
855
856 //mask amount and mask
857 rv.ecdhInfo[i].mask = copy(outSk[i].mask);
858 rv.ecdhInfo[i].amount = d2h(outamounts[i]);
859 hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i], rv.type == RCTTypeBulletproof2);
860 }
861
862 //set txn fee
863 rv.txnFee = txnFee;
864// TODO: unused ??
865// key txnFeeKey = scalarmultH(d2h(rv.txnFee));
866 rv.mixRing = mixRing;
867 keyV &pseudoOuts = bulletproof ? rv.p.pseudoOuts : rv.pseudoOuts;
868 pseudoOuts.resize(inamounts.size());
869 rv.p.MGs.resize(inamounts.size());
870 key sumpouts = zero(); //sum pseudoOut masks
871 keyV a(inamounts.size());
872 for (i = 0 ; i < inamounts.size() - 1; i++) {
873 skGen(a[i]);
874 sc_add(sumpouts.bytes, a[i].bytes, sumpouts.bytes);
875 genC(pseudoOuts[i], a[i], inamounts[i]);
876 }
877 sc_sub(a[i].bytes, sumout.bytes, sumpouts.bytes);
878 genC(pseudoOuts[i], a[i], inamounts[i]);
879 DP(pseudoOuts[i]);
880
881 key full_message = get_pre_mlsag_hash(rv,hwdev);
882 if (msout)
883 msout->c.resize(inamounts.size());
884 for (i = 0 ; i < inamounts.size(); i++) {
885 rv.p.MGs[i] = proveRctMGSimple(full_message, rv.mixRing[i], inSk[i], a[i], pseudoOuts[i], kLRki ? &(*kLRki)[i]: NULL, msout ? &msout->c[i] : NULL, index[i], hwdev);
886 }
887 return rv;
888 }
@ TRANSACTION_CREATE_FAKE
Definition device.hpp:101
virtual device_mode get_mode() const
Definition device.hpp:131
#define BULLETPROOF_MAX_OUTPUTS
key scalarmult8(const key &P)
Definition rctOps.cpp:398
Bulletproof proveRangeBulletproof(keyV &C, keyV &masks, const std::vector< uint64_t > &amounts, epee::span< const key > sk, hw::device &hwdev)
Definition rctSigs.cpp:82
bool verBulletproof(const Bulletproof &proof)
Definition rctSigs.cpp:94
mgSig proveRctMGSimple(const key &message, const ctkeyV &pubs, const ctkey &inSk, const key &a, const key &Cout, const multisig_kLRki *kLRki, key *mscout, unsigned int index, hw::device &hwdev)
Definition rctSigs.cpp:528
RangeProofType range_proof_type
Definition rctTypes.h:237
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_pippenger_c()

size_t rct::get_pippenger_c ( size_t N)

◆ get_pre_mlsag_hash()

key rct::get_pre_mlsag_hash ( const rctSig & rv,
hw::device & hwdev )

Definition at line 403 of file rctSigs.cpp.

404 {
405 keyV hashes;
406 hashes.reserve(3);
407 hashes.push_back(rv.message);
408 crypto::hash h;
409
410 std::stringstream ss;
412 CHECK_AND_ASSERT_THROW_MES(!rv.mixRing.empty(), "Empty mixRing");
413 const size_t inputs = is_rct_simple(rv.type) ? rv.mixRing.size() : rv.mixRing[0].size();
414 const size_t outputs = rv.ecdhInfo.size();
415 key prehash;
416 CHECK_AND_ASSERT_THROW_MES(const_cast<rctSig&>(rv).serialize_rctsig_base(ba, inputs, outputs),
417 "Failed to serialize rctSigBase");
418 cryptonote::get_blob_hash(ss.str(), h);
419 hashes.push_back(hash2rct(h));
420
421 keyV kv;
423 {
424 kv.reserve((6*2+9) * rv.p.bulletproofs.size());
425 for (const auto &p: rv.p.bulletproofs)
426 {
427 // V are not hashed as they're expanded from outPk.mask
428 // (and thus hashed as part of rctSigBase above)
429 kv.push_back(p.A);
430 kv.push_back(p.S);
431 kv.push_back(p.T1);
432 kv.push_back(p.T2);
433 kv.push_back(p.taux);
434 kv.push_back(p.mu);
435 for (size_t n = 0; n < p.L.size(); ++n)
436 kv.push_back(p.L[n]);
437 for (size_t n = 0; n < p.R.size(); ++n)
438 kv.push_back(p.R[n]);
439 kv.push_back(p.a);
440 kv.push_back(p.b);
441 kv.push_back(p.t);
442 }
443 }
444 else
445 {
446 kv.reserve((64*3+1) * rv.p.rangeSigs.size());
447 for (const auto &r: rv.p.rangeSigs)
448 {
449 for (size_t n = 0; n < 64; ++n)
450 kv.push_back(r.asig.s0[n]);
451 for (size_t n = 0; n < 64; ++n)
452 kv.push_back(r.asig.s1[n]);
453 kv.push_back(r.asig.ee);
454 for (size_t n = 0; n < 64; ++n)
455 kv.push_back(r.Ci[n]);
456 }
457 }
458 hashes.push_back(cn_fast_hash(kv));
459 hwdev.mlsag_prehash(ss.str(), inputs, outputs, hashes, rv.outPk, prehash);
460 return prehash;
461 }
virtual bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash)=0
void get_blob_hash(const epee::span< const char > &blob, crypto::hash &res)
bool is_rct_simple(int type)
Definition rctTypes.cpp:214
rctSigPrunable p
Definition rctTypes.h:437
std::vector< rangeSig > rangeSigs
Definition rctTypes.h:319
std::vector< Bulletproof > bulletproofs
Definition rctTypes.h:320
struct hash_func hashes[]
Here is the call graph for this function:
Here is the caller graph for this function:

◆ getKeyFromBlockchain()

void rct::getKeyFromBlockchain ( ctkey & a,
size_t reference_index )

Definition at line 635 of file rctSigs.cpp.

635 {
636 a.mask = pkGen();
637 a.dest = pkGen();
638 }
key pkGen()
Definition rctOps.cpp:277
Here is the call graph for this function:
Here is the caller graph for this function:

◆ h2b()

void rct::h2b ( bits amountb2,
const key & test )

Definition at line 171 of file rctTypes.cpp.

171 {
172 int val = 0, i = 0, j = 0;
173 for (j = 0; j < 8; j++) {
174 val = (unsigned char)test.bytes[j];
175 i = 8 * j;
176 while (val != 0) {
177 amountb2[i] = val & 1;
178 i++;
179 val >>= 1;
180 }
181 while (i < 8 * (j + 1)) {
182 amountb2[i] = 0;
183 i++;
184 }
185 }
186 }
Here is the caller graph for this function:

◆ h2d()

etn_amount rct::h2d ( const key & test)

Definition at line 161 of file rctTypes.cpp.

161 {
162 etn_amount vali = 0;
163 int j = 0;
164 for (j = 7; j >= 0; j--) {
165 vali = (etn_amount)(vali * 256 + (unsigned char)test.bytes[j]);
166 }
167 return vali;
168 }
Here is the caller graph for this function:

◆ hash_to_scalar() [1/7]

key rct::hash_to_scalar ( const ctkeyV & PC)

Definition at line 587 of file rctOps.cpp.

587 {
588 key rv = cn_fast_hash(PC);
589 sc_reduce32(rv.bytes);
590 return rv;
591 }
void sc_reduce32(unsigned char *)
Here is the call graph for this function:

◆ hash_to_scalar() [2/7]

key rct::hash_to_scalar ( const key & in)

Definition at line 558 of file rctOps.cpp.

558 {
559 key hash = cn_fast_hash(in);
560 sc_reduce32(hash.bytes);
561 return hash;
562 }
Here is the call graph for this function:

◆ hash_to_scalar() [3/7]

key rct::hash_to_scalar ( const key64 keys)

Definition at line 618 of file rctOps.cpp.

618 {
619 key rv = cn_fast_hash(keys);
620 sc_reduce32(rv.bytes);
621 return rv;
622 }
Here is the call graph for this function:

◆ hash_to_scalar() [4/7]

key rct::hash_to_scalar ( const keyV & keys)

Definition at line 605 of file rctOps.cpp.

605 {
606 key rv = cn_fast_hash(keys);
607 sc_reduce32(rv.bytes);
608 return rv;
609 }
Here is the call graph for this function:

◆ hash_to_scalar() [5/7]

void rct::hash_to_scalar ( key & hash,
const key & in )

Definition at line 546 of file rctOps.cpp.

546 {
547 cn_fast_hash(hash, in);
548 sc_reduce32(hash.bytes);
549 }
Here is the call graph for this function:

◆ hash_to_scalar() [6/7]

void rct::hash_to_scalar ( key & hash,
const void * data,
const size_t l )

◆ hash_to_scalar() [7/7]

void rct::hash_to_scalar ( key & hash,
const void * data,
const std::size_t l )

Definition at line 536 of file rctOps.cpp.

536 {
537 cn_fast_hash(hash, data, l);
538 sc_reduce32(hash.bytes);
539 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hash_to_scalar128()

key rct::hash_to_scalar128 ( const void * in)

Definition at line 571 of file rctOps.cpp.

571 {
573 sc_reduce32(hash.bytes);
574 return hash;
575 }
key cn_fast_hash128(const void *in)
Definition rctOps.cpp:565
Here is the call graph for this function:

◆ hashToPoint() [1/2]

key rct::hashToPoint ( const key & hh)

Definition at line 638 of file rctOps.cpp.

638 {
639 key pointk;
640 ge_p2 point;
641 ge_p1p1 point2;
642 ge_p3 res;
643 key h = cn_fast_hash(hh);
645 ge_mul8(&point2, &point);
646 ge_p1p1_to_p3(&res, &point2);
647 ge_p3_tobytes(pointk.bytes, &res);
648 return pointk;
649 }
void ge_mul8(ge_p1p1 *, const ge_p2 *)
void ge_fromfe_frombytes_vartime(ge_p2 *, const unsigned char *)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hashToPoint() [2/2]

void rct::hashToPoint ( key & pointk,
const key & hh )

Definition at line 651 of file rctOps.cpp.

651 {
652 ge_p2 point;
653 ge_p1p1 point2;
654 ge_p3 res;
655 key h = cn_fast_hash(hh);
657 ge_mul8(&point2, &point);
658 ge_p1p1_to_p3(&res, &point2);
659 ge_p3_tobytes(pointk.bytes, &res);
660 }
Here is the call graph for this function:

◆ hashToPointSimple()

key rct::hashToPointSimple ( const key & hh)

Definition at line 624 of file rctOps.cpp.

624 {
625 key pointk;
626 ge_p1p1 point2;
627 ge_p2 point;
628 ge_p3 res;
629 key h = cn_fast_hash(hh);
630 CHECK_AND_ASSERT_THROW_MES_L1(ge_frombytes_vartime(&res, h.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
631 ge_p3_to_p2(&point, &res);
632 ge_mul8(&point2, &point);
633 ge_p1p1_to_p3(&res, &point2);
634 ge_p3_tobytes(pointk.bytes, &res);
635 return pointk;
636 }
#define ge_p3_to_p2
Definition ge.h:60
Here is the call graph for this function:
Here is the caller graph for this function:

◆ identity() [1/2]

key rct::identity ( )
inline

Definition at line 73 of file rctOps.h.

73{ return I; }
Here is the caller graph for this function:

◆ identity() [2/2]

void rct::identity ( key & Id)
inline

Definition at line 74 of file rctOps.h.

74{ memcpy(&Id, &I, 32); }
Here is the call graph for this function:

◆ is_rct_borromean()

bool rct::is_rct_borromean ( int type)

Definition at line 239 of file rctTypes.cpp.

240 {
241 switch (type)
242 {
243 case RCTTypeSimple:
244 case RCTTypeFull:
245 return true;
246 default:
247 return false;
248 }
249 }
Here is the caller graph for this function:

◆ is_rct_bulletproof()

bool rct::is_rct_bulletproof ( int type)

Definition at line 227 of file rctTypes.cpp.

228 {
229 switch (type)
230 {
233 return true;
234 default:
235 return false;
236 }
237 }
Here is the caller graph for this function:

◆ is_rct_simple()

bool rct::is_rct_simple ( int type)

Definition at line 214 of file rctTypes.cpp.

215 {
216 switch (type)
217 {
218 case RCTTypeSimple:
221 return true;
222 default:
223 return false;
224 }
225 }
Here is the caller graph for this function:

◆ isInMainSubgroup()

bool rct::isInMainSubgroup ( const key & A)

Definition at line 412 of file rctOps.cpp.

412 {
413 ge_p3 p3;
414 return toPointCheckOrder(&p3, A.bytes);
415 }
bool toPointCheckOrder(ge_p3 *P, const unsigned char *data)
Definition rctOps.cpp:241
Here is the call graph for this function:
Here is the caller graph for this function:

◆ keyMInit()

keyM rct::keyMInit ( size_t rows,
size_t cols )

Definition at line 227 of file rctOps.cpp.

227 {
228 keyM rv(cols);
229 size_t i = 0;
230 for (i = 0 ; i < cols ; i++) {
231 rv[i] = keyV(rows);
232 }
233 return rv;
234 }
int rows
Definition crypto.h:86
std::vector< keyV > keyM
Definition rctTypes.h:89
Here is the caller graph for this function:

◆ MLSAG_Gen()

mgSig rct::MLSAG_Gen ( const key & message,
const keyM & pk,
const keyV & xx,
const multisig_kLRki * kLRki,
key * mscout,
const unsigned int index,
size_t dsRows,
hw::device & hwdev )

Definition at line 174 of file rctSigs.cpp.

174 {
175 mgSig rv;
176 size_t cols = pk.size();
177 CHECK_AND_ASSERT_THROW_MES(cols >= 2, "Error! What is c if cols = 1!");
178 CHECK_AND_ASSERT_THROW_MES(index < cols, "Index out of range");
179 size_t rows = pk[0].size();
180 CHECK_AND_ASSERT_THROW_MES(rows >= 1, "Empty pk");
181 for (size_t i = 1; i < cols; ++i) {
182 CHECK_AND_ASSERT_THROW_MES(pk[i].size() == rows, "pk is not rectangular");
183 }
184 CHECK_AND_ASSERT_THROW_MES(xx.size() == rows, "Bad xx size");
185 CHECK_AND_ASSERT_THROW_MES(dsRows <= rows, "Bad dsRows size");
186 CHECK_AND_ASSERT_THROW_MES((kLRki && mscout) || (!kLRki && !mscout), "Only one of kLRki/mscout is present");
187 CHECK_AND_ASSERT_THROW_MES(!kLRki || dsRows == 1, "Multisig requires exactly 1 dsRows");
188
189 size_t i = 0, j = 0, ii = 0;
190 key c, c_old, L, R, Hi;
191 sc_0(c_old.bytes);
192 vector<geDsmp> Ip(dsRows);
193 rv.II = keyV(dsRows);
194 keyV alpha(rows);
195 keyV aG(rows);
196 rv.ss = keyM(cols, aG);
197 keyV aHP(dsRows);
198 keyV toHash(1 + 3 * dsRows + 2 * (rows - dsRows));
199 toHash[0] = message;
200 DP("here1");
201 for (i = 0; i < dsRows; i++) {
202 toHash[3 * i + 1] = pk[index][i];
203 if (kLRki) {
204 // multisig
205 alpha[i] = kLRki->k;
206 toHash[3 * i + 2] = kLRki->L;
207 toHash[3 * i + 3] = kLRki->R;
208 rv.II[i] = kLRki->ki;
209 }
210 else {
211 Hi = hashToPoint(pk[index][i]);
212 hwdev.mlsag_prepare(Hi, xx[i], alpha[i] , aG[i] , aHP[i] , rv.II[i]);
213 toHash[3 * i + 2] = aG[i];
214 toHash[3 * i + 3] = aHP[i];
215 }
216 precomp(Ip[i].k, rv.II[i]);
217 }
218 size_t ndsRows = 3 * dsRows; //non Double Spendable Rows (see identity chains paper)
219 for (i = dsRows, ii = 0 ; i < rows ; i++, ii++) {
220 skpkGen(alpha[i], aG[i]); //need to save alphas for later..
221 toHash[ndsRows + 2 * ii + 1] = pk[index][i];
222 toHash[ndsRows + 2 * ii + 2] = aG[i];
223 }
224
225 hwdev.mlsag_hash(toHash, c_old);
226
227
228 i = (index + 1) % cols;
229 if (i == 0) {
230 copy(rv.cc, c_old);
231 }
232 while (i != index) {
233
234 rv.ss[i] = skvGen(rows);
235 sc_0(c.bytes);
236 for (j = 0; j < dsRows; j++) {
237 addKeys2(L, rv.ss[i][j], c_old, pk[i][j]);
238 hashToPoint(Hi, pk[i][j]);
239 addKeys3(R, rv.ss[i][j], Hi, c_old, Ip[j].k);
240 toHash[3 * j + 1] = pk[i][j];
241 toHash[3 * j + 2] = L;
242 toHash[3 * j + 3] = R;
243 }
244 for (j = dsRows, ii = 0; j < rows; j++, ii++) {
245 addKeys2(L, rv.ss[i][j], c_old, pk[i][j]);
246 toHash[ndsRows + 2 * ii + 1] = pk[i][j];
247 toHash[ndsRows + 2 * ii + 2] = L;
248 }
249 hwdev.mlsag_hash(toHash, c);
250 copy(c_old, c);
251 i = (i + 1) % cols;
252
253 if (i == 0) {
254 copy(rv.cc, c_old);
255 }
256 }
257 hwdev.mlsag_sign(c, xx, alpha, rows, dsRows, rv.ss[index]);
258 if (mscout)
259 *mscout = c;
260 return rv;
261 }
virtual bool mlsag_sign(const rct::key &c, const rct::keyV &xx, const rct::keyV &alpha, const size_t rows, const size_t dsRows, rct::keyV &ss)=0
virtual bool mlsag_hash(const rct::keyV &long_message, rct::key &c)=0
virtual bool mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &rvII)=0
keyV skvGen(size_t rows)
Definition rctOps.cpp:266
key hashToPoint(const key &hh)
Definition rctOps.cpp:638
void precomp(ge_dsmp rv, const key &B)
Definition rctOps.cpp:476
void addKeys3(key &aAbB, const key &a, const key &A, const key &b, const ge_dsmp B)
Definition rctOps.cpp:485
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MLSAG_Ver()

bool rct::MLSAG_Ver ( const key & message,
const keyM & pk,
const mgSig & rv,
size_t dsRows )

Definition at line 271 of file rctSigs.cpp.

271 {
272
273 size_t cols = pk.size();
274 CHECK_AND_ASSERT_MES(cols >= 2, false, "Error! What is c if cols = 1!");
275 size_t rows = pk[0].size();
276 CHECK_AND_ASSERT_MES(rows >= 1, false, "Empty pk");
277 for (size_t i = 1; i < cols; ++i) {
278 CHECK_AND_ASSERT_MES(pk[i].size() == rows, false, "pk is not rectangular");
279 }
280 CHECK_AND_ASSERT_MES(rv.II.size() == dsRows, false, "Bad II size");
281 CHECK_AND_ASSERT_MES(rv.ss.size() == cols, false, "Bad rv.ss size");
282 for (size_t i = 0; i < cols; ++i) {
283 CHECK_AND_ASSERT_MES(rv.ss[i].size() == rows, false, "rv.ss is not rectangular");
284 }
285 CHECK_AND_ASSERT_MES(dsRows <= rows, false, "Bad dsRows value");
286
287 for (size_t i = 0; i < rv.ss.size(); ++i)
288 for (size_t j = 0; j < rv.ss[i].size(); ++j)
289 CHECK_AND_ASSERT_MES(sc_check(rv.ss[i][j].bytes) == 0, false, "Bad ss slot");
290 CHECK_AND_ASSERT_MES(sc_check(rv.cc.bytes) == 0, false, "Bad cc");
291
292 size_t i = 0, j = 0, ii = 0;
293 key c, L, R, Hi;
294 key c_old = copy(rv.cc);
295 vector<geDsmp> Ip(dsRows);
296 for (i = 0 ; i < dsRows ; i++) {
297 precomp(Ip[i].k, rv.II[i]);
298 }
299 size_t ndsRows = 3 * dsRows; //non Double Spendable Rows (see identity chains paper
300 keyV toHash(1 + 3 * dsRows + 2 * (rows - dsRows));
301 toHash[0] = message;
302 i = 0;
303 while (i < cols) {
304 sc_0(c.bytes);
305 for (j = 0; j < dsRows; j++) {
306 addKeys2(L, rv.ss[i][j], c_old, pk[i][j]);
307 hashToPoint(Hi, pk[i][j]);
308 CHECK_AND_ASSERT_MES(!(Hi == rct::identity()), false, "Data hashed to point at infinity");
309 addKeys3(R, rv.ss[i][j], Hi, c_old, Ip[j].k);
310 toHash[3 * j + 1] = pk[i][j];
311 toHash[3 * j + 2] = L;
312 toHash[3 * j + 3] = R;
313 }
314 for (j = dsRows, ii = 0 ; j < rows ; j++, ii++) {
315 addKeys2(L, rv.ss[i][j], c_old, pk[i][j]);
316 toHash[ndsRows + 2 * ii + 1] = pk[i][j];
317 toHash[ndsRows + 2 * ii + 2] = L;
318 }
319 c = hash_to_scalar(toHash);
320 copy(c_old, c);
321 i = (i + 1);
322 }
323 sc_sub(c.bytes, c_old.bytes, rv.cc.bytes);
324 return sc_isnonzero(c.bytes) == 0;
325 }
int sc_isnonzero(const unsigned char *)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ n_bulletproof_amounts() [1/2]

size_t rct::n_bulletproof_amounts ( const Bulletproof & proof)

Definition at line 251 of file rctTypes.cpp.

252 {
253 CHECK_AND_ASSERT_MES(proof.L.size() >= 6, 0, "Invalid bulletproof L size");
254 CHECK_AND_ASSERT_MES(proof.L.size() == proof.R.size(), 0, "Mismatched bulletproof L/R size");
255 static const size_t extra_bits = 4;
256 static_assert((1 << extra_bits) == BULLETPROOF_MAX_OUTPUTS, "log2(BULLETPROOF_MAX_OUTPUTS) is out of date");
257 CHECK_AND_ASSERT_MES(proof.L.size() <= 6 + extra_bits, 0, "Invalid bulletproof L size");
258 CHECK_AND_ASSERT_MES(proof.V.size() <= (1u<<(proof.L.size()-6)), 0, "Invalid bulletproof V/L");
259 CHECK_AND_ASSERT_MES(proof.V.size() * 2 > (1u<<(proof.L.size()-6)), 0, "Invalid bulletproof V/L");
260 CHECK_AND_ASSERT_MES(proof.V.size() > 0, 0, "Empty bulletproof");
261 return proof.V.size();
262 }
rct::keyV L
Definition rctTypes.h:184
rct::keyV V
Definition rctTypes.h:181
rct::keyV R
Definition rctTypes.h:184
Here is the caller graph for this function:

◆ n_bulletproof_amounts() [2/2]

size_t rct::n_bulletproof_amounts ( const std::vector< Bulletproof > & proofs)

Definition at line 264 of file rctTypes.cpp.

265 {
266 size_t n = 0;
267 for (const Bulletproof &proof: proofs)
268 {
269 size_t n2 = n_bulletproof_amounts(proof);
270 CHECK_AND_ASSERT_MES(n2 < std::numeric_limits<uint32_t>::max() - n, 0, "Invalid number of bulletproofs");
271 if (n2 == 0)
272 return 0;
273 n += n2;
274 }
275 return n;
276 }
size_t n_bulletproof_amounts(const Bulletproof &proof)
Definition rctTypes.cpp:251
Here is the call graph for this function:

◆ n_bulletproof_max_amounts() [1/2]

size_t rct::n_bulletproof_max_amounts ( const Bulletproof & proof)

Definition at line 278 of file rctTypes.cpp.

279 {
280 CHECK_AND_ASSERT_MES(proof.L.size() >= 6, 0, "Invalid bulletproof L size");
281 CHECK_AND_ASSERT_MES(proof.L.size() == proof.R.size(), 0, "Mismatched bulletproof L/R size");
282 static const size_t extra_bits = 4;
283 static_assert((1 << extra_bits) == BULLETPROOF_MAX_OUTPUTS, "log2(BULLETPROOF_MAX_OUTPUTS) is out of date");
284 CHECK_AND_ASSERT_MES(proof.L.size() <= 6 + extra_bits, 0, "Invalid bulletproof L size");
285 return 1 << (proof.L.size() - 6);
286 }
Here is the caller graph for this function:

◆ n_bulletproof_max_amounts() [2/2]

size_t rct::n_bulletproof_max_amounts ( const std::vector< Bulletproof > & proofs)

Definition at line 288 of file rctTypes.cpp.

289 {
290 size_t n = 0;
291 for (const Bulletproof &proof: proofs)
292 {
293 size_t n2 = n_bulletproof_max_amounts(proof);
294 CHECK_AND_ASSERT_MES(n2 < std::numeric_limits<uint32_t>::max() - n, 0, "Invalid number of bulletproofs");
295 if (n2 == 0)
296 return 0;
297 n += n2;
298 }
299 return n;
300 }
size_t n_bulletproof_max_amounts(const Bulletproof &proof)
Definition rctTypes.cpp:278
Here is the call graph for this function:

◆ operator<<()

std::ostream & rct::operator<< ( std::ostream & o,
const rct::key & v )
inline

Definition at line 576 of file rctTypes.h.

576 {
578}
span< const std::uint8_t > as_byte_span(const T &src) noexcept
Definition span.h:153
static void formatted(std::ostream &out, const span< const std::uint8_t > src)
Append < + src + > as hex to out.
Definition hex.cpp:76
Here is the call graph for this function:

◆ pippenger()

rct::key rct::pippenger ( const std::vector< MultiexpData > & data,
const std::shared_ptr< pippenger_cached_data > & cache = NULL,
size_t cache_size = 0,
size_t c = 0 )

◆ pippenger_get_cache_size()

size_t rct::pippenger_get_cache_size ( const std::shared_ptr< pippenger_cached_data > & cache)

◆ pippenger_init_cache()

std::shared_ptr< pippenger_cached_data > rct::pippenger_init_cache ( const std::vector< MultiexpData > & data,
size_t start_offset = 0,
size_t N = 0 )
Here is the caller graph for this function:

◆ pkGen()

key rct::pkGen ( )

Definition at line 277 of file rctOps.cpp.

277 {
278 key sk = skGen();
279 key pk = scalarmultBase(sk);
280 return pk;
281 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ populateFromBlockchain()

std::tuple< ctkeyM, etn_amount > rct::populateFromBlockchain ( ctkeyV inPk,
int mixin )

Definition at line 645 of file rctSigs.cpp.

645 {
646 int rows = inPk.size();
647 ctkeyM rv(mixin + 1, inPk);
648 int index = randEtnAmount(mixin);
649 int i = 0, j = 0;
650 for (i = 0; i <= mixin; i++) {
651 if (i != index) {
652 for (j = 0; j < rows; j++) {
653 getKeyFromBlockchain(rv[i][j], (size_t)randEtnAmount);
654 }
655 }
656 }
657 return make_tuple(rv, index);
658 }
void getKeyFromBlockchain(ctkey &a, size_t reference_index)
Definition rctSigs.cpp:635
etn_amount randEtnAmount(etn_amount upperlimit)
Definition rctOps.cpp:343
tuple make_tuple()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ populateFromBlockchainSimple()

etn_amount rct::populateFromBlockchainSimple ( ctkeyV & mixRing,
const ctkey & inPk,
int mixin )

Definition at line 665 of file rctSigs.cpp.

665 {
666 int index = randEtnAmount(mixin);
667 int i = 0;
668 for (i = 0; i <= mixin; i++) {
669 if (i != index) {
670 getKeyFromBlockchain(mixRing[i], (size_t)randEtnAmount(1000));
671 } else {
672 mixRing[i] = inPk;
673 }
674 }
675 return index;
676 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ precomp()

void rct::precomp ( ge_dsmp rv,
const key & B )

Definition at line 476 of file rctOps.cpp.

476 {
477 ge_p3 B2;
478 CHECK_AND_ASSERT_THROW_MES_L1(ge_frombytes_vartime(&B2, B.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
479 ge_dsm_precomp(rv, &B2);
480 }
void ge_dsm_precomp(ge_dsmp r, const ge_p3 *s)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ proveRange()

rangeSig rct::proveRange ( key & C,
key & mask,
const etn_amount & amount )

Definition at line 336 of file rctSigs.cpp.

336 {
337 sc_0(mask.bytes);
338 identity(C);
339 bits b;
340 d2b(b, amount);
341 rangeSig sig;
342 key64 ai;
343 key64 CiH;
344 int i = 0;
345 for (i = 0; i < ATOMS; i++) {
346 skGen(ai[i]);
347 if (b[i] == 0) {
348 scalarmultBase(sig.Ci[i], ai[i]);
349 }
350 if (b[i] == 1) {
351 addKeys1(sig.Ci[i], ai[i], H2[i]);
352 }
353 subKeys(CiH[i], sig.Ci[i], H2[i]);
354 sc_add(mask.bytes, mask.bytes, ai[i].bytes);
355 addKeys(C, C, sig.Ci[i]);
356 }
357 sig.asig = genBorromean(ai, sig.Ci, CiH, b);
358 return sig;
359 }
void subKeys(key &AB, const key &A, const key &B)
Definition rctOps.cpp:505
boroSig genBorromean(const key64 x, const key64 P1, const key64 P2, const bits indices)
Definition rctSigs.cpp:109
unsigned int bits[ATOMS]
Definition rctTypes.h:136
void addKeys1(key &aGB, const key &a, const key &B)
Definition rctOps.cpp:459
void d2b(bits amountb, etn_amount val)
Definition rctTypes.cpp:145
#define ATOMS
Definition rctTypes.h:65
boroSig asig
Definition rctTypes.h:170
Here is the call graph for this function:
Here is the caller graph for this function:

◆ proveRangeBulletproof()

Bulletproof rct::proveRangeBulletproof ( keyV & C,
keyV & masks,
const std::vector< uint64_t > & amounts,
epee::span< const key > sk,
hw::device & hwdev )

Definition at line 82 of file rctSigs.cpp.

83 {
84 CHECK_AND_ASSERT_THROW_MES(amounts.size() == sk.size(), "Invalid amounts/sk sizes");
85 masks.resize(amounts.size());
86 for (size_t i = 0; i < masks.size(); ++i)
87 masks[i] = hwdev.genCommitmentMask(sk[i]);
88 Bulletproof proof = bulletproof_PROVE(amounts, masks);
89 CHECK_AND_ASSERT_THROW_MES(proof.V.size() == amounts.size(), "V does not have the expected size");
90 C = proof.V;
91 return proof;
92 }
constexpr std::size_t size() const noexcept
Definition span.h:111
virtual rct::key genCommitmentMask(const rct::key &amount_key)=0
Bulletproof bulletproof_PROVE(const rct::key &v, const rct::key &gamma)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ proveRctMG() [1/2]

mgSig rct::proveRctMG ( const ctkeyM & pubs,
const ctkeyV & inSk,
const keyV & outMasks,
const ctkeyV & outPk,
const multisig_kLRki * kLRki,
key * mscout,
unsigned int index,
const key & txnFee,
const key & message,
hw::device & hwdev )
Here is the call graph for this function:

◆ proveRctMG() [2/2]

mgSig rct::proveRctMG ( const key & message,
const ctkeyM & pubs,
const ctkeyV & inSk,
const ctkeyV & outSk,
const ctkeyV & outPk,
const multisig_kLRki * kLRki,
key * mscout,
unsigned int index,
const key & txnFeeKey,
hw::device & hwdev )

Definition at line 471 of file rctSigs.cpp.

471 {
472 //setup vars
473 size_t cols = pubs.size();
474 CHECK_AND_ASSERT_THROW_MES(cols >= 1, "Empty pubs");
475 size_t rows = pubs[0].size();
476 CHECK_AND_ASSERT_THROW_MES(rows >= 1, "Empty pubs");
477 for (size_t i = 1; i < cols; ++i) {
478 CHECK_AND_ASSERT_THROW_MES(pubs[i].size() == rows, "pubs is not rectangular");
479 }
480 CHECK_AND_ASSERT_THROW_MES(inSk.size() == rows, "Bad inSk size");
481 CHECK_AND_ASSERT_THROW_MES(outSk.size() == outPk.size(), "Bad outSk/outPk size");
482 CHECK_AND_ASSERT_THROW_MES((kLRki && mscout) || (!kLRki && !mscout), "Only one of kLRki/mscout is present");
483
484 keyV sk(rows + 1);
485 keyV tmp(rows + 1);
486 size_t i = 0, j = 0;
487 for (i = 0; i < rows + 1; i++) {
488 sc_0(sk[i].bytes);
489 identity(tmp[i]);
490 }
491 keyM M(cols, tmp);
492 //create the matrix to mg sig
493 for (i = 0; i < cols; i++) {
494 M[i][rows] = identity();
495 for (j = 0; j < rows; j++) {
496 M[i][j] = pubs[i][j].dest;
497 addKeys(M[i][rows], M[i][rows], pubs[i][j].mask); //add input commitments in last row
498 }
499 }
500 sc_0(sk[rows].bytes);
501 for (j = 0; j < rows; j++) {
502 sk[j] = copy(inSk[j].dest);
503 sc_add(sk[rows].bytes, sk[rows].bytes, inSk[j].mask.bytes); //add masks in last row
504 }
505 for (i = 0; i < cols; i++) {
506 for (size_t j = 0; j < outPk.size(); j++) {
507 subKeys(M[i][rows], M[i][rows], outPk[j].mask); //subtract output Ci's in last row
508 }
509 //subtract txn fee output in last row
510 subKeys(M[i][rows], M[i][rows], txnFeeKey);
511 }
512 for (size_t j = 0; j < outPk.size(); j++) {
513 sc_sub(sk[rows].bytes, sk[rows].bytes, outSk[j].mask.bytes); //subtract output masks in last row..
514 }
515 mgSig result = MLSAG_Gen(message, M, sk, kLRki, mscout, index, rows, hwdev);
516 memwipe(sk.data(), sk.size() * sizeof(key));
517 return result;
518 }
void * memwipe(void *src, size_t n)
mgSig MLSAG_Gen(const key &message, const keyM &pk, const keyV &xx, const multisig_kLRki *kLRki, key *mscout, const unsigned int index, size_t dsRows, hw::device &hwdev)
Definition rctSigs.cpp:174
CXA_THROW_INFO_T void(* dest)(void *))
Here is the call graph for this function:
Here is the caller graph for this function:

◆ proveRctMGSimple()

mgSig rct::proveRctMGSimple ( const key & message,
const ctkeyV & pubs,
const ctkey & inSk,
const key & a,
const key & Cout,
const multisig_kLRki * kLRki,
key * mscout,
unsigned int index,
hw::device & hwdev )

Definition at line 528 of file rctSigs.cpp.

528 {
529 //setup vars
530 size_t rows = 1;
531 size_t cols = pubs.size();
532 CHECK_AND_ASSERT_THROW_MES(cols >= 1, "Empty pubs");
533 CHECK_AND_ASSERT_THROW_MES((kLRki && mscout) || (!kLRki && !mscout), "Only one of kLRki/mscout is present");
534 keyV tmp(rows + 1);
535 keyV sk(rows + 1);
536 size_t i;
537 keyM M(cols, tmp);
538
539 sk[0] = copy(inSk.dest);
540 sc_sub(sk[1].bytes, inSk.mask.bytes, a.bytes);
541 for (i = 0; i < cols; i++) {
542 M[i][0] = pubs[i].dest;
543 subKeys(M[i][1], pubs[i].mask, Cout);
544 }
545 mgSig result = MLSAG_Gen(message, M, sk, kLRki, mscout, index, rows, hwdev);
546 memwipe(&sk[0], sizeof(key));
547 return result;
548 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ randEtnAmount()

etn_amount rct::randEtnAmount ( etn_amount upperlimit)

Definition at line 343 of file rctOps.cpp.

343 {
344 return h2d(skGen()) % (upperlimit);
345 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ scalarmult8()

key rct::scalarmult8 ( const key & P)

Definition at line 398 of file rctOps.cpp.

398 {
399 ge_p3 p3;
400 CHECK_AND_ASSERT_THROW_MES_L1(ge_frombytes_vartime(&p3, P.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
401 ge_p2 p2;
402 ge_p3_to_p2(&p2, &p3);
403 ge_p1p1 p1;
404 ge_mul8(&p1, &p2);
405 ge_p1p1_to_p2(&p2, &p1);
407 ge_tobytes(res.bytes, &p2);
408 return res;
409 }
#define ge_p1p1_to_p2
Definition ge.h:62
Here is the call graph for this function:
Here is the caller graph for this function:

◆ scalarmultBase() [1/2]

key rct::scalarmultBase ( const key & a)

Definition at line 358 of file rctOps.cpp.

358 {
359 ge_p3 point;
360 key aG;
361 sc_reduce32copy(aG.bytes, a.bytes); //do this beforehand
362 ge_scalarmult_base(&point, aG.bytes);
363 ge_p3_tobytes(aG.bytes, &point);
364 return aG;
365 }
void sc_reduce32copy(unsigned char *scopy, const unsigned char *s)
#define ge_scalarmult_base
Definition ge.h:71
Here is the call graph for this function:

◆ scalarmultBase() [2/2]

void rct::scalarmultBase ( key & aG,
const key & a )

Definition at line 350 of file rctOps.cpp.

350 {
351 ge_p3 point;
352 sc_reduce32copy(aG.bytes, a.bytes); //do this beforehand!
353 ge_scalarmult_base(&point, aG.bytes);
354 ge_p3_tobytes(aG.bytes, &point);
355 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ scalarmultH()

key rct::scalarmultH ( const key & a)

Definition at line 389 of file rctOps.cpp.

389 {
390 ge_p2 R;
391 ge_scalarmult(&R, a.bytes, &ge_p3_H);
392 key aP;
393 ge_tobytes(aP.bytes, &R);
394 return aP;
395 }
void ge_scalarmult(ge_p2 *, const unsigned char *, const ge_p3 *)
const ge_p3 ge_p3_H
Here is the call graph for this function:
Here is the caller graph for this function:

◆ scalarmultKey() [1/2]

key rct::scalarmultKey ( const key & P,
const key & a )

Definition at line 377 of file rctOps.cpp.

377 {
378 ge_p3 A;
379 ge_p2 R;
380 CHECK_AND_ASSERT_THROW_MES_L1(ge_frombytes_vartime(&A, P.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
381 ge_scalarmult(&R, a.bytes, &A);
382 key aP;
383 ge_tobytes(aP.bytes, &R);
384 return aP;
385 }
Here is the call graph for this function:

◆ scalarmultKey() [2/2]

void rct::scalarmultKey ( key & aP,
const key & P,
const key & a )

Definition at line 368 of file rctOps.cpp.

368 {
369 ge_p3 A;
370 ge_p2 R;
371 CHECK_AND_ASSERT_THROW_MES_L1(ge_frombytes_vartime(&A, P.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
372 ge_scalarmult(&R, a.bytes, &A);
373 ge_tobytes(aP.bytes, &R);
374 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ signMultisig()

bool rct::signMultisig ( rctSig & rv,
const std::vector< unsigned int > & indices,
const keyV & k,
const multisig_out & msout,
const key & secret_key )

Definition at line 1210 of file rctSigs.cpp.

1210 {
1212 false, "unsupported rct type");
1213 CHECK_AND_ASSERT_MES(indices.size() == k.size(), false, "Mismatched k/indices sizes");
1214 CHECK_AND_ASSERT_MES(k.size() == rv.p.MGs.size(), false, "Mismatched k/MGs size");
1215 CHECK_AND_ASSERT_MES(k.size() == msout.c.size(), false, "Mismatched k/msout.c size");
1216 if (rv.type == RCTTypeFull)
1217 {
1218 CHECK_AND_ASSERT_MES(rv.p.MGs.size() == 1, false, "MGs not a single element");
1219 }
1220 for (size_t n = 0; n < indices.size(); ++n) {
1221 CHECK_AND_ASSERT_MES(indices[n] < rv.p.MGs[n].ss.size(), false, "Index out of range");
1222 CHECK_AND_ASSERT_MES(!rv.p.MGs[n].ss[indices[n]].empty(), false, "empty ss line");
1223 }
1224
1225 for (size_t n = 0; n < indices.size(); ++n) {
1226 rct::key diff;
1227 sc_mulsub(diff.bytes, msout.c[n].bytes, secret_key.bytes, k[n].bytes);
1228 sc_add(rv.p.MGs[n].ss[indices[n]][0].bytes, rv.p.MGs[n].ss[indices[n]][0].bytes, diff.bytes);
1229 }
1230 return true;
1231 }
epee::mlocked< tools::scrubbed< ec_scalar > > secret_key
Definition crypto.h:82
std::vector< mgSig > MGs
Definition rctTypes.h:321
Here is the call graph for this function:
Here is the caller graph for this function:

◆ skGen() [1/2]

key rct::skGen ( )

Definition at line 258 of file rctOps.cpp.

258 {
259 key sk;
260 skGen(sk);
261 return sk;
262 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ skGen() [2/2]

void rct::skGen ( key & sk)

Definition at line 253 of file rctOps.cpp.

253 {
255 }
void random32_unbiased(unsigned char *bytes)
Definition crypto.cpp:110
Here is the call graph for this function:
Here is the caller graph for this function:

◆ skpkGen() [1/2]

std::tuple< key, key > rct::skpkGen ( )

Definition at line 290 of file rctOps.cpp.

290 {
291 key sk = skGen();
292 key pk = scalarmultBase(sk);
293 return make_tuple(sk, pk);
294 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ skpkGen() [2/2]

void rct::skpkGen ( key & sk,
key & pk )

Definition at line 284 of file rctOps.cpp.

284 {
285 skGen(sk);
286 scalarmultBase(pk, sk);
287 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ skvGen()

keyV rct::skvGen ( size_t rows)

Definition at line 266 of file rctOps.cpp.

266 {
267 CHECK_AND_ASSERT_THROW_MES(rows > 0, "0 keys requested");
268 keyV rv(rows);
269 size_t i = 0;
270 for (i = 0 ; i < rows ; i++) {
271 skGen(rv[i]);
272 }
273 return rv;
274 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ straus()

rct::key rct::straus ( const std::vector< MultiexpData > & data,
const std::shared_ptr< straus_cached_data > & cache = NULL,
size_t STEP = 0 )

◆ straus_get_cache_size()

size_t rct::straus_get_cache_size ( const std::shared_ptr< straus_cached_data > & cache)

◆ straus_init_cache()

std::shared_ptr< straus_cached_data > rct::straus_init_cache ( const std::vector< MultiexpData > & data,
size_t N = 0 )
Here is the caller graph for this function:

◆ subKeys()

void rct::subKeys ( key & AB,
const key & A,
const key & B )

Definition at line 505 of file rctOps.cpp.

505 {
506 ge_p3 B2, A2;
507 CHECK_AND_ASSERT_THROW_MES_L1(ge_frombytes_vartime(&B2, B.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
508 CHECK_AND_ASSERT_THROW_MES_L1(ge_frombytes_vartime(&A2, A.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__));
509 ge_cached tmp2;
510 ge_p3_to_cached(&tmp2, &B2);
511 ge_p1p1 tmp3;
512 ge_sub(&tmp3, &A2, &tmp2);
513 ge_p1p1_to_p3(&A2, &tmp3);
514 ge_p3_tobytes(AB.bytes, &A2);
515 }
#define ge_sub
Definition ge.h:70
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sumKeys() [1/2]

void rct::sumKeys ( key & Csum,
const key & Cis )

◆ sumKeys() [2/2]

void rct::sumKeys ( key & Csum,
const keyV & Cis )

Definition at line 663 of file rctOps.cpp.

663 {
664 identity(Csum);
665 size_t i = 0;
666 for (i = 0; i < Cis.size(); i++) {
667 addKeys(Csum, Csum, Cis[i]);
668 }
669 }
Here is the call graph for this function:

◆ toPointCheckOrder() [1/2]

bool rct::toPointCheckOrder ( ge_p3 * P,
const unsigned char * data )

Definition at line 241 of file rctOps.cpp.

242 {
243 if (ge_frombytes_vartime(P, data))
244 return false;
245 ge_p2 R;
246 ge_scalarmult(&R, curveOrder().bytes, P);
247 key tmp;
248 ge_tobytes(tmp.bytes, &R);
249 return tmp == identity();
250 }
key curveOrder()
Definition rctOps.h:76
Here is the call graph for this function:
Here is the caller graph for this function:

◆ toPointCheckOrder() [2/2]

bool rct::toPointCheckOrder ( ge_p3 * P,
const unsigned char * data )
Here is the call graph for this function:

◆ verBulletproof() [1/2]

bool rct::verBulletproof ( const Bulletproof & proof)

Definition at line 94 of file rctSigs.cpp.

95 {
96 try { return bulletproof_VERIFY(proof); }
97 // we can get deep throws from ge_frombytes_vartime if input isn't valid
98 catch (...) { return false; }
99 }
bool bulletproof_VERIFY(const Bulletproof &proof)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ verBulletproof() [2/2]

bool rct::verBulletproof ( const std::vector< const Bulletproof * > & proofs)

Definition at line 101 of file rctSigs.cpp.

102 {
103 try { return bulletproof_VERIFY(proofs); }
104 // we can get deep throws from ge_frombytes_vartime if input isn't valid
105 catch (...) { return false; }
106 }
Here is the call graph for this function:

◆ verifyBorromean() [1/2]

bool rct::verifyBorromean ( const boroSig & bb,
const ge_p3 P1[64],
const ge_p3 P2[64] )

Definition at line 140 of file rctSigs.cpp.

140 {
141 key64 Lv1; key chash, LL;
142 int ii = 0;
143 ge_p2 p2;
144 for (ii = 0 ; ii < 64 ; ii++) {
145 // equivalent of: addKeys2(LL, bb.s0[ii], bb.ee, P1[ii]);
146 ge_double_scalarmult_base_vartime(&p2, bb.ee.bytes, &P1[ii], bb.s0[ii].bytes);
147 ge_tobytes(LL.bytes, &p2);
148 chash = hash_to_scalar(LL);
149 // equivalent of: addKeys2(Lv1[ii], bb.s1[ii], chash, P2[ii]);
150 ge_double_scalarmult_base_vartime(&p2, chash.bytes, &P2[ii], bb.s1[ii].bytes);
151 ge_tobytes(Lv1[ii].bytes, &p2);
152 }
153 key eeComputed = hash_to_scalar(Lv1); //hash function fine
154 return equalKeys(eeComputed, bb.ee);
155 }
crypto::hash chash
Definition main.cpp:47
Here is the call graph for this function:
Here is the caller graph for this function:

◆ verifyBorromean() [2/2]

bool rct::verifyBorromean ( const boroSig & bb,
const key64 P1,
const key64 P2 )

Definition at line 157 of file rctSigs.cpp.

157 {
158 ge_p3 P1_p3[64], P2_p3[64];
159 for (size_t i = 0 ; i < 64 ; ++i) {
160 CHECK_AND_ASSERT_MES_L1(ge_frombytes_vartime(&P1_p3[i], P1[i].bytes) == 0, false, "point conv failed");
161 CHECK_AND_ASSERT_MES_L1(ge_frombytes_vartime(&P2_p3[i], P2[i].bytes) == 0, false, "point conv failed");
162 }
163 return verifyBorromean(bb, P1_p3, P2_p3);
164 }
bool verifyBorromean(const boroSig &bb, const ge_p3 P1[64], const ge_p3 P2[64])
Definition rctSigs.cpp:140
#define CHECK_AND_ASSERT_MES_L1(expr, ret, message)
Definition rctSigs.cpp:45
Here is the call graph for this function:

◆ verRange()

bool rct::verRange ( const key & C,
const rangeSig & as )

Definition at line 368 of file rctSigs.cpp.

368 {
369 try
370 {
372 ge_p3 CiH[64], asCi[64];
373 int i = 0;
374 ge_p3 Ctmp_p3 = ge_p3_identity;
375 for (i = 0; i < 64; i++) {
376 // faster equivalent of:
377 // subKeys(CiH[i], as.Ci[i], H2[i]);
378 // addKeys(Ctmp, Ctmp, as.Ci[i]);
379 ge_cached cached;
380 ge_p3 p3;
381 ge_p1p1 p1;
382 CHECK_AND_ASSERT_MES_L1(ge_frombytes_vartime(&p3, H2[i].bytes) == 0, false, "point conv failed");
383 ge_p3_to_cached(&cached, &p3);
384 CHECK_AND_ASSERT_MES_L1(ge_frombytes_vartime(&asCi[i], as.Ci[i].bytes) == 0, false, "point conv failed");
385 ge_sub(&p1, &asCi[i], &cached);
386 ge_p3_to_cached(&cached, &asCi[i]);
387 ge_p1p1_to_p3(&CiH[i], &p1);
388 ge_add(&p1, &Ctmp_p3, &cached);
389 ge_p1p1_to_p3(&Ctmp_p3, &p1);
390 }
391 key Ctmp;
392 ge_p3_tobytes(Ctmp.bytes, &Ctmp_p3);
393 if (!equalKeys(C, Ctmp))
394 return false;
395 if (!verifyBorromean(as.asig, asCi, CiH))
396 return false;
397 return true;
398 }
399 // we can get deep throws from ge_frombytes_vartime if input isn't valid
400 catch (...) { return false; }
401 }
const ge_p3 ge_p3_identity
#define PERF_TIMER(name)
Definition perf_timer.h:82
Here is the call graph for this function:
Here is the caller graph for this function:

◆ verRct() [1/2]

bool rct::verRct ( const rctSig & rv,
bool semantics )

Definition at line 913 of file rctSigs.cpp.

913 {
915 CHECK_AND_ASSERT_MES(rv.type == RCTTypeFull, false, "verRct called on non-full rctSig");
916 if (semantics)
917 {
918 CHECK_AND_ASSERT_MES(rv.outPk.size() == rv.p.rangeSigs.size(), false, "Mismatched sizes of outPk and rv.p.rangeSigs");
919 CHECK_AND_ASSERT_MES(rv.outPk.size() == rv.ecdhInfo.size(), false, "Mismatched sizes of outPk and rv.ecdhInfo");
920 CHECK_AND_ASSERT_MES(rv.p.MGs.size() == 1, false, "full rctSig has not one MG");
921 }
922 else
923 {
924 // semantics check is early, we don't have the MGs resolved yet
925 }
926
927 // some rct ops can throw
928 try
929 {
930 if (semantics) {
931 tools::threadpool& tpool = tools::threadpool::getInstance();
932 tools::threadpool::waiter waiter;
933 std::deque<bool> results(rv.outPk.size(), false);
934 DP("range proofs verified?");
935 for (size_t i = 0; i < rv.outPk.size(); i++)
936 tpool.submit(&waiter, [&, i] { results[i] = verRange(rv.outPk[i].mask, rv.p.rangeSigs[i]); });
937 waiter.wait(&tpool);
938
939 for (size_t i = 0; i < results.size(); ++i) {
940 if (!results[i]) {
941 LOG_PRINT_L1("Range proof verified failed for proof " << i);
942 return false;
943 }
944 }
945 }
946
947 if (!semantics) {
948 //compute txn fee
949 key txnFeeKey = scalarmultH(d2h(rv.txnFee));
950 bool mgVerd = verRctMG(rv.p.MGs[0], rv.mixRing, rv.outPk, txnFeeKey, get_pre_mlsag_hash(rv, hw::get_device("default")));
951 DP("mg sig verified?");
952 DP(mgVerd);
953 if (!mgVerd) {
954 LOG_PRINT_L1("MG signature verification failed");
955 return false;
956 }
957 }
958
959 return true;
960 }
961 catch (const std::exception &e)
962 {
963 LOG_PRINT_L1("Error in verRct: " << e.what());
964 return false;
965 }
966 catch (...)
967 {
968 LOG_PRINT_L1("Error in verRct, but not an actual exception");
969 return false;
970 }
971 }
void wait(threadpool *tpool)
void submit(waiter *waiter, std::function< void()> f, bool leaf=false)
static threadpool & getInstance()
Definition threadpool.h:46
#define LOG_PRINT_L1(x)
device & get_device(const std::string &device_descriptor)
Definition device.cpp:95
bool verRct(const rctSig &rv, bool semantics)
Definition rctSigs.cpp:913
bool verRctMG(const mgSig &mg, const ctkeyM &pubs, const ctkeyV &outPk, const key &txnFeeKey, const key &message)
Definition rctSigs.cpp:559
etn_amount txnFee
Definition rctTypes.h:248
Here is the call graph for this function:
Here is the caller graph for this function:

◆ verRct() [2/2]

bool rct::verRct ( const rctSig & rv,
bool semantics )

◆ verRctMG()

bool rct::verRctMG ( const mgSig & mg,
const ctkeyM & pubs,
const ctkeyV & outPk,
const key & txnFeeKey,
const key & message )

Definition at line 559 of file rctSigs.cpp.

559 {
561 //setup vars
562 size_t cols = pubs.size();
563 CHECK_AND_ASSERT_MES(cols >= 1, false, "Empty pubs");
564 size_t rows = pubs[0].size();
565 CHECK_AND_ASSERT_MES(rows >= 1, false, "Empty pubs");
566 for (size_t i = 1; i < cols; ++i) {
567 CHECK_AND_ASSERT_MES(pubs[i].size() == rows, false, "pubs is not rectangular");
568 }
569
570 keyV tmp(rows + 1);
571 size_t i = 0, j = 0;
572 for (i = 0; i < rows + 1; i++) {
573 identity(tmp[i]);
574 }
575 keyM M(cols, tmp);
576
577 //create the matrix to mg sig
578 for (j = 0; j < rows; j++) {
579 for (i = 0; i < cols; i++) {
580 M[i][j] = pubs[i][j].dest;
581 addKeys(M[i][rows], M[i][rows], pubs[i][j].mask); //add Ci in last row
582 }
583 }
584 for (i = 0; i < cols; i++) {
585 for (j = 0; j < outPk.size(); j++) {
586 subKeys(M[i][rows], M[i][rows], outPk[j].mask); //subtract output Ci's in last row
587 }
588 //subtract txn fee output in last row
589 subKeys(M[i][rows], M[i][rows], txnFeeKey);
590 }
591 return MLSAG_Ver(message, M, mg, rows);
592 }
bool MLSAG_Ver(const key &message, const keyM &pk, const mgSig &rv, size_t dsRows)
Definition rctSigs.cpp:271
Here is the call graph for this function:
Here is the caller graph for this function:

◆ verRctMGSimple()

bool rct::verRctMGSimple ( const key & message,
const mgSig & mg,
const ctkeyV & pubs,
const key & C )

Definition at line 598 of file rctSigs.cpp.

598 {
599 try
600 {
602 //setup vars
603 size_t rows = 1;
604 size_t cols = pubs.size();
605 CHECK_AND_ASSERT_MES(cols >= 1, false, "Empty pubs");
606 keyV tmp(rows + 1);
607 size_t i;
608 keyM M(cols, tmp);
609 ge_p3 Cp3;
610 CHECK_AND_ASSERT_MES_L1(ge_frombytes_vartime(&Cp3, C.bytes) == 0, false, "point conv failed");
611 ge_cached Ccached;
612 ge_p3_to_cached(&Ccached, &Cp3);
613 ge_p1p1 p1;
614 //create the matrix to mg sig
615 for (i = 0; i < cols; i++) {
616 M[i][0] = pubs[i].dest;
617 ge_p3 p3;
618 CHECK_AND_ASSERT_MES_L1(ge_frombytes_vartime(&p3, pubs[i].mask.bytes) == 0, false, "point conv failed");
619 ge_sub(&p1, &p3, &Ccached);
620 ge_p1p1_to_p3(&p3, &p1);
621 ge_p3_tobytes(M[i][1].bytes, &p3);
622 }
623 //DP(C);
624 return MLSAG_Ver(message, M, mg, rows);
625 }
626 catch (...) { return false; }
627 }
bool verRctMGSimple(const key &message, const mgSig &mg, const ctkeyV &pubs, const key &C)
Definition rctSigs.cpp:598
Here is the call graph for this function:
Here is the caller graph for this function:

◆ verRctNonSemanticsSimple()

bool rct::verRctNonSemanticsSimple ( const rctSig & rv)

Definition at line 1085 of file rctSigs.cpp.

1085 {
1086 try
1087 {
1089
1091 false, "verRctNonSemanticsSimple called on non simple rctSig");
1092 const bool bulletproof = is_rct_bulletproof(rv.type);
1093 // semantics check is early, and mixRing/MGs aren't resolved yet
1094 if (bulletproof)
1095 CHECK_AND_ASSERT_MES(rv.p.pseudoOuts.size() == rv.mixRing.size(), false, "Mismatched sizes of rv.p.pseudoOuts and mixRing");
1096 else
1097 CHECK_AND_ASSERT_MES(rv.pseudoOuts.size() == rv.mixRing.size(), false, "Mismatched sizes of rv.pseudoOuts and mixRing");
1098
1099 const size_t threads = std::max(rv.outPk.size(), rv.mixRing.size());
1100
1101 std::deque<bool> results(threads);
1104
1105 const keyV &pseudoOuts = bulletproof ? rv.p.pseudoOuts : rv.pseudoOuts;
1106
1107 const key message = get_pre_mlsag_hash(rv, hw::get_device("default"));
1108
1109 results.clear();
1110 results.resize(rv.mixRing.size());
1111 for (size_t i = 0 ; i < rv.mixRing.size() ; i++) {
1112 tpool.submit(&waiter, [&, i] {
1113 results[i] = verRctMGSimple(message, rv.p.MGs[i], rv.mixRing[i], pseudoOuts[i]);
1114 });
1115 }
1116 waiter.wait(&tpool);
1117
1118 for (size_t i = 0; i < results.size(); ++i) {
1119 if (!results[i]) {
1120 LOG_PRINT_L1("verRctMGSimple failed for input " << i);
1121 return false;
1122 }
1123 }
1124
1125 return true;
1126 }
1127 // we can get deep throws from ge_frombytes_vartime if input isn't valid
1128 catch (const std::exception &e)
1129 {
1130 LOG_PRINT_L1("Error in verRctNonSemanticsSimple: " << e.what());
1131 return false;
1132 }
1133 catch (...)
1134 {
1135 LOG_PRINT_L1("Error in verRctNonSemanticsSimple, but not an actual exception");
1136 return false;
1137 }
1138 }
A global thread pool.
Definition threadpool.h:44
bool is_rct_bulletproof(int type)
Definition rctTypes.cpp:227
bool verRctNonSemanticsSimple(const rctSig &rv)
Definition rctSigs.cpp:1085
Here is the call graph for this function:
Here is the caller graph for this function:

◆ verRctSemanticsSimple() [1/2]

bool rct::verRctSemanticsSimple ( const rctSig & rv)

Definition at line 1078 of file rctSigs.cpp.

1079 {
1080 return verRctSemanticsSimple(std::vector<const rctSig*>(1, &rv));
1081 }
bool verRctSemanticsSimple(const std::vector< const rctSig * > &rvv)
Definition rctSigs.cpp:975
Here is the call graph for this function:

◆ verRctSemanticsSimple() [2/2]

bool rct::verRctSemanticsSimple ( const std::vector< const rctSig * > & rvv)

Definition at line 975 of file rctSigs.cpp.

975 {
976 try
977 {
979
982 std::deque<bool> results;
983 std::vector<const Bulletproof*> proofs;
984 size_t max_non_bp_proofs = 0, offset = 0;
985
986 for (const rctSig *rvp: rvv)
987 {
988 CHECK_AND_ASSERT_MES(rvp, false, "rctSig pointer is NULL");
989 const rctSig &rv = *rvp;
991 false, "verRctSemanticsSimple called on non simple rctSig");
992 const bool bulletproof = is_rct_bulletproof(rv.type);
993 if (bulletproof)
994 {
995 CHECK_AND_ASSERT_MES(rv.outPk.size() == n_bulletproof_amounts(rv.p.bulletproofs), false, "Mismatched sizes of outPk and bulletproofs");
996 CHECK_AND_ASSERT_MES(rv.p.pseudoOuts.size() == rv.p.MGs.size(), false, "Mismatched sizes of rv.p.pseudoOuts and rv.p.MGs");
997 CHECK_AND_ASSERT_MES(rv.pseudoOuts.empty(), false, "rv.pseudoOuts is not empty");
998 }
999 else
1000 {
1001 CHECK_AND_ASSERT_MES(rv.outPk.size() == rv.p.rangeSigs.size(), false, "Mismatched sizes of outPk and rv.p.rangeSigs");
1002 CHECK_AND_ASSERT_MES(rv.pseudoOuts.size() == rv.p.MGs.size(), false, "Mismatched sizes of rv.pseudoOuts and rv.p.MGs");
1003 CHECK_AND_ASSERT_MES(rv.p.pseudoOuts.empty(), false, "rv.p.pseudoOuts is not empty");
1004 }
1005 CHECK_AND_ASSERT_MES(rv.outPk.size() == rv.ecdhInfo.size(), false, "Mismatched sizes of outPk and rv.ecdhInfo");
1006
1007 if (!bulletproof)
1008 max_non_bp_proofs += rv.p.rangeSigs.size();
1009 }
1010
1011 results.resize(max_non_bp_proofs);
1012 for (const rctSig *rvp: rvv)
1013 {
1014 const rctSig &rv = *rvp;
1015
1016 const bool bulletproof = is_rct_bulletproof(rv.type);
1017 const keyV &pseudoOuts = bulletproof ? rv.p.pseudoOuts : rv.pseudoOuts;
1018
1019 rct::keyV masks(rv.outPk.size());
1020 for (size_t i = 0; i < rv.outPk.size(); i++) {
1021 masks[i] = rv.outPk[i].mask;
1022 }
1023 key sumOutpks = addKeys(masks);
1024 DP(sumOutpks);
1025 const key txnFeeKey = scalarmultH(d2h(rv.txnFee));
1026 addKeys(sumOutpks, txnFeeKey, sumOutpks);
1027
1028 key sumPseudoOuts = addKeys(pseudoOuts);
1029 DP(sumPseudoOuts);
1030
1031 //check pseudoOuts vs Outs..
1032 if (!equalKeys(sumPseudoOuts, sumOutpks)) {
1033 LOG_PRINT_L1("Sum check failed");
1034 return false;
1035 }
1036
1037 if (bulletproof)
1038 {
1039 for (size_t i = 0; i < rv.p.bulletproofs.size(); i++)
1040 proofs.push_back(&rv.p.bulletproofs[i]);
1041 }
1042 else
1043 {
1044 for (size_t i = 0; i < rv.p.rangeSigs.size(); i++)
1045 tpool.submit(&waiter, [&, i, offset] { results[i+offset] = verRange(rv.outPk[i].mask, rv.p.rangeSigs[i]); });
1046 offset += rv.p.rangeSigs.size();
1047 }
1048 }
1049 if (!proofs.empty() && !verBulletproof(proofs))
1050 {
1051 LOG_PRINT_L1("Aggregate range proof verified failed");
1052 return false;
1053 }
1054
1055 waiter.wait(&tpool);
1056 for (size_t i = 0; i < results.size(); ++i) {
1057 if (!results[i]) {
1058 LOG_PRINT_L1("Range proof verified failed for proof " << i);
1059 return false;
1060 }
1061 }
1062
1063 return true;
1064 }
1065 // we can get deep throws from ge_frombytes_vartime if input isn't valid
1066 catch (const std::exception &e)
1067 {
1068 LOG_PRINT_L1("Error in verRctSemanticsSimple: " << e.what());
1069 return false;
1070 }
1071 catch (...)
1072 {
1073 LOG_PRINT_L1("Error in verRctSemanticsSimple, but not an actual exception");
1074 return false;
1075 }
1076 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ zero() [1/2]

key rct::zero ( )
inline

Definition at line 70 of file rctOps.h.

70{ return Z; }
Here is the caller graph for this function:

◆ zero() [2/2]

void rct::zero ( key & z)
inline

Definition at line 71 of file rctOps.h.

71{ memset(&z, 0, 32); }

◆ zeroCommit()

key rct::zeroCommit ( etn_amount amount)

Definition at line 322 of file rctOps.cpp.

322 {
323 const zero_commitment *begin = zero_commitments;
324 const zero_commitment *end = zero_commitments + sizeof(zero_commitments) / sizeof(zero_commitments[0]);
325 const zero_commitment value{amount, rct::zero()};
326 const auto it = std::lower_bound(begin, end, value, [](const zero_commitment &e0, const zero_commitment &e1){ return e0.amount < e1.amount; });
327 if (it != end && it->amount == amount)
328 {
329 return it->commitment;
330 }
331 key am = d2h(amount);
332 key bH = scalarmultH(am);
333 return addKeys(G, bH);
334 }
const GenericPointer< typename T::ValueType > T2 value
Definition pointer.h:1225
uint64_t amount
Definition rctOps.cpp:43
Here is the call graph for this function:
Here is the caller graph for this function: