From b215a98a749c452c0a0336ab4ee93b1d71df2e78 Mon Sep 17 00:00:00 2001 From: shnoe Date: Sun, 7 Feb 2016 08:42:01 -0700 Subject: [PATCH] Updated rct code with ring multisig and fixing key image bug I found last night --- source-code/MiniNero/brief/MakeClass.lua | 17 --- source-code/MiniNero/brief/runtest.bat | 4 - source-code/MiniNero/brief/runtest.sh | 4 - source-code/MiniNero/brief/runtest2.sh | 3 - source-code/MiniNero/brief/tasks.bat | 1 - source-code/RingCT/rctMSig.cpp | 72 ++++++++- source-code/RingCT/rctMSig.h | 10 +- source-code/RingCT/rctOps.cpp | 43 +++++- source-code/RingCT/rctOps.h | 3 + source-code/RingCT/rctSigs.cpp | 178 +++++++++++------------ source-code/RingCT/rctSigs.h | 139 +++++++++--------- 11 files changed, 267 insertions(+), 207 deletions(-) delete mode 100644 source-code/MiniNero/brief/MakeClass.lua delete mode 100644 source-code/MiniNero/brief/runtest.bat delete mode 100644 source-code/MiniNero/brief/runtest.sh delete mode 100644 source-code/MiniNero/brief/runtest2.sh delete mode 100644 source-code/MiniNero/brief/tasks.bat diff --git a/source-code/MiniNero/brief/MakeClass.lua b/source-code/MiniNero/brief/MakeClass.lua deleted file mode 100644 index fc0ff68..0000000 --- a/source-code/MiniNero/brief/MakeClass.lua +++ /dev/null @@ -1,17 +0,0 @@ ---for quick conversion of the MiniNero python code to c++ --- -if #arg > 0 then - class = string.lower(arg[1]) --asdf - object = arg[1] --Asdf - deff = string.upper(arg[1]) --ASDF - hfile = io.input("TemplateHead"):read("*a") - cppfile = io.input("TemplateBody"):read("*a") - hfile = string.gsub(hfile, "asdf", class) - hfile = string.gsub(hfile, "Asdf", object) - hfile = string.gsub(hfile, "ASDF", deff) - cppfile = string.gsub(cppfile, "asdf", class) - cppfile = string.gsub(cppfile, "Asdf", object) - cppfile = string.gsub(cppfile, "ASDF", deff) - io.output(object..".h"):write(hfile) - io.output(object..".cpp"):write(cppfile) -end diff --git a/source-code/MiniNero/brief/runtest.bat b/source-code/MiniNero/brief/runtest.bat deleted file mode 100644 index 39b5304..0000000 --- a/source-code/MiniNero/brief/runtest.bat +++ /dev/null @@ -1,4 +0,0 @@ -gtags.exe -mingw32-make.exe clean -mingw32-make.exe -a.exe > .results diff --git a/source-code/MiniNero/brief/runtest.sh b/source-code/MiniNero/brief/runtest.sh deleted file mode 100644 index a14ae31..0000000 --- a/source-code/MiniNero/brief/runtest.sh +++ /dev/null @@ -1,4 +0,0 @@ -gtags.exe -make clean -make -./a.exe diff --git a/source-code/MiniNero/brief/runtest2.sh b/source-code/MiniNero/brief/runtest2.sh deleted file mode 100644 index e4eb4bc..0000000 --- a/source-code/MiniNero/brief/runtest2.sh +++ /dev/null @@ -1,3 +0,0 @@ -rm.exe a.exe -g++ bits.cpp -./a.exe diff --git a/source-code/MiniNero/brief/tasks.bat b/source-code/MiniNero/brief/tasks.bat deleted file mode 100644 index 5fc782c..0000000 --- a/source-code/MiniNero/brief/tasks.bat +++ /dev/null @@ -1 +0,0 @@ -%1 diff --git a/source-code/RingCT/rctMSig.cpp b/source-code/RingCT/rctMSig.cpp index df51e4f..5433283 100644 --- a/source-code/RingCT/rctMSig.cpp +++ b/source-code/RingCT/rctMSig.cpp @@ -34,4 +34,74 @@ using namespace std; namespace rct { - } \ No newline at end of file + int i; + //Generate Signing Keys + //This function is called by each participant in + //A ring multisignature transaction. + //The participant will send the returned parameters + //to whomever is managing the transaction. + //returns a, aG, aHP and I + tuple InitiateRMS(key x) { + key I = scalarmultKey(hashToPoint(scalarmultBase(x)), x); + key a, aG; + skpkGen(a, aG); + key aHP = scalarmultKey(hashToPoint(scalarmultBase(x)), a); + return make_tuple(a, aG, aHP, I); + } + + //returns "c" which is the last index needed to get the last s-values + key rmsMgSigStart(const keyM & pk, mgSig & rv, keyV aG, keyV aHP, const int index) { + + int rows = pk[0].size(); + int cols = pk.size(); + if (cols < 2) { + printf("Error! What is c if cols = 1!"); + } + int i = 0, j = 0; + key c, c_old, c0, L, R, Hi; + sc_0(c_old.bytes); + vector Ip(rows); + rv.ss = keyM(cols, rv.II); + unsigned char m2[96]; + for (i = 0; i < rows; i++) { + memcpy(m2, pk[index][i].bytes, 32); + memcpy(m2 + 32, aG[i].bytes, 32); + memcpy(m2 + 64, aHP[i].bytes, 32); + precomp(Ip[i], rv.II[i]); + sc_add(c_old.bytes, c_old.bytes, cn_fast_hash96(m2).bytes); + } + + int oldi = index; + i = (index + 1) % cols; + while (i != index) { + + rv.ss[i] = skvGen(rows); + sc_0(c.bytes); + for (j = 0; j < rows; j++) { + addKeys2(L, rv.ss[i][j], c_old, pk[i][j]); + hashToPoint(Hi, pk[i][j]); + addKeys3(R, rv.ss[i][j], Hi, c_old, Ip[j]); + memcpy(m2, pk[i][j].bytes, 32); + memcpy(m2 + 32, L.bytes, 32); + memcpy(m2 + 64, R.bytes, 32); + sc_add(c.bytes, c.bytes, cn_fast_hash96(m2).bytes); + } + c_old = copy(c); + if (i == 0) { + c0 = copy(c); + } + oldi = i; + i = (i + 1) % cols; + } + return c; + } + + //have to return s = a - cx + //for each participant in the MG sig.. + key rmsSign(key a, key c, key x) { + key s; + sc_mulsub(s.bytes, c.bytes, x.bytes, a.bytes); + return s; + } + +} \ No newline at end of file diff --git a/source-code/RingCT/rctMSig.h b/source-code/RingCT/rctMSig.h index 681b761..4829724 100644 --- a/source-code/RingCT/rctMSig.h +++ b/source-code/RingCT/rctMSig.h @@ -50,6 +50,7 @@ #include "rctTypes.h" #include "rctOps.h" +#include "rctSigs.h" @@ -58,11 +59,8 @@ using namespace std; using namespace crypto; namespace rct { - - int i; - //rctSig genRMS(ctkeyV & inSk, ctkeyV & inPk, const keyV & destinations, const vector amounts, const int mixin); - - - + tuple InitiateRMS(key x); + key rmsMgSigStart(const keyM & pk, mgSig & rv, keyV aG, keyV aHP, const int index); + key rmsSign(key a, key c, key x) ; } #endif diff --git a/source-code/RingCT/rctOps.cpp b/source-code/RingCT/rctOps.cpp index 7c2c4ff..c7be5c4 100644 --- a/source-code/RingCT/rctOps.cpp +++ b/source-code/RingCT/rctOps.cpp @@ -352,16 +352,43 @@ namespace rct { sc_reduce32(hash.bytes); return hash; } - - //returns cn_fast_hash(input) * G where G is the basepoint - key hashToPoint(const key & in) { - return scalarmultBase(cn_fast_hash(in)); + + //cn_fast_hash for a 96 byte unsigned char + key cn_fast_hash96(const void * in) { + uint8_t md2[32]; + int j = 0; + key hash; + keccak((uint8_t *)in, 96, md2, 32); + for (j = 0; j < 32; j++) { + hash[j] = (unsigned char)md2[j]; + } + sc_reduce32(hash.bytes); + return hash; } - - //returns cn_fast_hash(input) * G where G is the basepoint - void hashToPoint(key & out, const key & in) { - scalarmultBase(out, cn_fast_hash(in)); + + key hashToPoint(const key & hh) { + key pointk; + ge_p2 point; + ge_p1p1 point2; + ge_p3 res; + key h = cn_fast_hash(hh); + ge_fromfe_frombytes_vartime(&point, h.bytes); + ge_mul8(&point2, &point); + ge_p1p1_to_p3(&res, &point2); + ge_p3_tobytes(pointk.bytes, &res); + return pointk; } + + void hashToPoint(key & pointk, const key & hh) { + ge_p2 point; + ge_p1p1 point2; + ge_p3 res; + key h = cn_fast_hash(hh); + ge_fromfe_frombytes_vartime(&point, h.bytes); + ge_mul8(&point2, &point); + ge_p1p1_to_p3(&res, &point2); + ge_p3_tobytes(pointk.bytes, &res); + } //sums a vector of curve points (for scalars use sc_add) void sumKeys(key & Csum, const keyV & Cis) { diff --git a/source-code/RingCT/rctOps.h b/source-code/RingCT/rctOps.h index 56568e0..7620165 100644 --- a/source-code/RingCT/rctOps.h +++ b/source-code/RingCT/rctOps.h @@ -48,6 +48,7 @@ #include "rctTypes.h" + using namespace std; using namespace crypto; @@ -128,6 +129,8 @@ namespace rct { void cn_fast_hash(key &hash, const key &in); //cn_fast_hash for a 32 byte key key cn_fast_hash(const key &in); + //for mg sigs + key cn_fast_hash96(const void * in); //returns cn_fast_hash(input) * G where G is the basepoint key hashToPoint(const key &in); diff --git a/source-code/RingCT/rctSigs.cpp b/source-code/RingCT/rctSigs.cpp index 323fc92..49a2119 100644 --- a/source-code/RingCT/rctSigs.cpp +++ b/source-code/RingCT/rctSigs.cpp @@ -129,150 +129,140 @@ namespace rct { keyV II(xx.size()); int i = 0; for (i = 0; i < xx.size(); i++) { - II[i] = scalarmultKey(hashToPoint(scalarmultBase(xx[i])), xx[i]); + II[i] = scalarmultKey(hashToPoint(scalarmultBase(xx[i])), xx[i]); } return II; } - -/* - keyV skvGen(int n) { - keyV rv(n); - int i = 0; - for (i = 0; i < n; i++) { - skGen(rv[i]); - } - return rv; - } - */ - + + //Multilayered Spontaneous Anonymous Group Signatures (MLSAG signatures) + //This is a just slghtly more efficient version than the ones described below + //(will be explained in more detail in Ring Multisig paper //These are aka MG signatutes in earlier drafts of the ring ct paper // c.f. http://eprint.iacr.org/2015/1098 section 2. // keyImageV just does I[i] = xx[i] * Hash(xx[i] * G) for each i // Gen creates a signature which proves that for some column in the keymatrix "pk" // the signer knows a secret key for each row in that column - // Ver verifies that the MG sig was created correctly - mgSig MLSAG_Gen(const keyM & pk, const keyV & xx, const int index) { - - mgSig rv; + // Ver verifies that the MG sig was created correctly + mgSig MLSAG_Gen(const keyM & pk, const keyV & xx, const int index) { + mgSig rv; int rows = pk[0].size(); int cols = pk.size(); if (cols < 2) { printf("Error! What is c if cols = 1!"); } int i = 0, j = 0; - - keyV c(cols); - keyV alpha = skvGen(rows); - rv.II = keyImageV(xx); - DP(rv.II); + key c, c_old, L, R, Hi; + sc_0(c_old.bytes); vector Ip(rows); - keyM L(cols, rv.II); - keyM R(cols, rv.II); + rv.II = keyV(rows); rv.ss = keyM(cols, rv.II); - keyV Hi(rows); + keyV alpha(rows); + keyV aG(rows); + keyV aHP(rows); + key m2hash; + unsigned char m2[96]; + DP("here1"); for (i = 0; i < rows; i++) { - L[index][i] = scalarmultBase(alpha[i]); - hashToPoint(Hi[i], pk[index][i]); - R[index][i] = scalarmultKey(Hi[i], alpha[i]); + skpkGen(alpha[i], aG[i]); //need to save alphas for later.. + Hi = hashToPoint(pk[index][i]); + aHP[i] = scalarmultKey(Hi, alpha[i]); + memcpy(m2, pk[index][i].bytes, 32); + memcpy(m2 + 32, aG[i].bytes, 32); + memcpy(m2 + 64, aHP[i].bytes, 32); + rv.II[i] = scalarmultKey(Hi, xx[i]); precomp(Ip[i], rv.II[i]); + m2hash = cn_fast_hash96(m2); + sc_add(c_old.bytes, c_old.bytes, m2hash.bytes); } - char * m1 = (char *)malloc(32 * rows * (cols + 2)); - //vector m1(32 * rows * (cols + 2)); - for (i = 0; i < cols; i++) { - for (j = 0; j < rows; j++) { - memcpy(m1 + rows * 32 * i + (32 * j), pk[i][j].bytes, 32); - } - } - + int oldi = index; + i = (index + 1) % cols; - for (j = 0; j < rows; j++) { - memcpy(m1 + rows * 32 * cols + (32 * j), L[oldi][j].bytes, 32); - memcpy(m1 + rows * 32 * (cols + 1) + (32 * j), R[oldi][j].bytes, 32); - } + if (i == 0) { + copy(rv.cc, c_old); + } while (i != index) { - cn_fast_hash(c[i], m1, 32 * rows * (cols + 2)); - - rv.ss[i] = skvGen(rows); + rv.ss[i] = skvGen(rows); + sc_0(c.bytes); for (j = 0; j < rows; j++) { - addKeys2(L[i][j], rv.ss[i][j], c[i], pk[i][j]); - hashToPoint(Hi[j], pk[i][j]); - addKeys3(R[i][j], rv.ss[i][j], Hi[j], c[i], Ip[j]); + addKeys2(L, rv.ss[i][j], c_old, pk[i][j]); + hashToPoint(Hi, pk[i][j]); + addKeys3(R, rv.ss[i][j], Hi, c_old, Ip[j]); + memcpy(m2, pk[i][j].bytes, 32); + memcpy(m2 + 32, L.bytes, 32); + memcpy(m2 + 64, R.bytes, 32); + m2hash = cn_fast_hash96(m2); + sc_add(c.bytes, c.bytes, m2hash.bytes); } + copy(c_old, c); oldi = i; - i = (i + 1) % cols; - for (j = 0; j < rows; j++) { - memcpy(m1 + rows * 32 * cols + (32 * j), L[oldi][j].bytes, 32); - memcpy(m1 + rows * 32 * (cols + 1) + (32 * j), R[oldi][j].bytes, 32); - } - } - cn_fast_hash(c[index], m1, 32 * rows * (cols + 2)); + i = (i + 1) % cols; + + if (i == 0) { + copy(rv.cc, c_old); + } + } for (j = 0; j < rows; j++) { - sc_mulsub(rv.ss[index][j].bytes, c[index].bytes, xx[j].bytes, alpha[j].bytes); - } - memcpy(rv.cc.bytes, c[0].bytes, 32); - free(m1); + sc_mulsub(rv.ss[index][j].bytes, c.bytes, xx[j].bytes, alpha[j].bytes); + } return rv; } - - + //Multilayered Spontaneous Anonymous Group Signatures (MLSAG signatures) + //This is a just slghtly more efficient version than the ones described below + //(will be explained in more detail in Ring Multisig paper //These are aka MG signatutes in earlier drafts of the ring ct paper // c.f. http://eprint.iacr.org/2015/1098 section 2. // keyImageV just does I[i] = xx[i] * Hash(xx[i] * G) for each i // Gen creates a signature which proves that for some column in the keymatrix "pk" // the signer knows a secret key for each row in that column - // Ver verifies that the MG sig was created correctly - bool MLSAG_Ver(keyM &pk, mgSig &sig) { + // Ver verifies that the MG sig was created correctly + bool MLSAG_Ver(keyM & pk, mgSig & rv) { + int rows = pk[0].size(); int cols = pk.size(); if (cols < 2) { printf("Error! What is c if cols = 1!"); - } - DP("Verifying MG sig"); - keyV c(cols + 1); - memcpy(c[0].bytes, sig.cc.bytes, 32); + int i = 0, j = 0; + key c, L, R, Hi; + key c_old = copy(rv.cc); vector Ip(rows); - keyM L(cols, pk[0]); - keyM R(cols, pk[0]); + for (i= 0 ; i< rows ; i++) { + precomp(Ip[i], rv.II[i]); + } + unsigned char m2[96]; + key m2hash; - int i = 0, oldi = 0, j = 0; - keyV Hi(rows); - for (i = 0; i < rows; i++) { - precomp(Ip[i], sig.II[i]); - } - i = 0; - char * m1 = (char *)malloc(32 * rows * (cols + 2)); - //vector m1(32 * rows * (cols + 2)); - for (i = 0; i < cols; i++) { - for (j = 0; j < rows; j++) { - memcpy(m1 + rows * 32 * i + (32 * j), pk[i][j].bytes, 32); - } - } - i = 0; + int oldi = 0; + i = 0; while (i < cols) { + sc_0(c.bytes); for (j = 0; j < rows; j++) { - addKeys2(L[i][j], sig.ss[i][j], c[i], pk[i][j]); - hashToPoint(Hi[j], pk[i][j]); - addKeys3(R[i][j], sig.ss[i][j], Hi[j], c[i], Ip[j]); + addKeys2(L, rv.ss[i][j], c_old, pk[i][j]); + hashToPoint(Hi, pk[i][j]); + addKeys3(R, rv.ss[i][j], Hi, c_old, Ip[j]); + memcpy(m2, pk[i][j].bytes, 32); + memcpy(m2 + 32, L.bytes, 32); + memcpy(m2 + 64, R.bytes, 32); + m2hash = cn_fast_hash96(m2); + sc_add(c.bytes, c.bytes, m2hash.bytes); } + copy(c_old, c); oldi = i; i = (i + 1); - for (j = 0; j < rows; j++) { - memcpy(m1 + rows * 32 * cols + (32 * j), L[oldi][j].bytes, 32); - memcpy(m1 + rows * 32 * (cols + 1) + (32 * j), R[oldi][j].bytes, 32); - } - cn_fast_hash(c[i], m1, 32 * rows * (cols + 2)); } - key cc; + DP("c0"); + DP(rv.cc); + DP("c_old"); + DP(c_old); + sc_sub(c.bytes, c_old.bytes, rv.cc.bytes); + return sc_isnonzero(c.bytes) == 0; + } + - sc_sub(cc.bytes, c[0].bytes, c[cols].bytes); - free(m1); - return sc_isnonzero(cc.bytes) == 0; - } //proveRange and verRange //proveRange gives C, and mask such that \sumCi = C diff --git a/source-code/RingCT/rctSigs.h b/source-code/RingCT/rctSigs.h index e1f9a4e..197031f 100644 --- a/source-code/RingCT/rctSigs.h +++ b/source-code/RingCT/rctSigs.h @@ -1,23 +1,23 @@ // Copyright (c) 2016, Monero Research Labs // // Author: Shen Noether -// +// // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are // permitted provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list // of conditions and the following disclaimer in the documentation and/or other // materials provided with the distribution. -// +// // 3. Neither the name of the copyright holder nor the names of its contributors may be // used to endorse or promote products derived from this software without specific // prior written permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL @@ -59,75 +59,76 @@ using namespace crypto; namespace rct { - //Schnorr Non-linkable - //Gen Gives a signature (L1, s1, s2) proving that the sender knows "x" such that xG = one of P1 or P2 - //Ver Verifies that signer knows an "x" such that xG = one of P1 or P2 - //These are called in the below ASNL sig generation - void GenSchnorrNonLinkable(key & L1, key & s1, key & s2, const key & x, const key & P1, const key & P2, int index); - bool VerSchnorrNonLinkable(const key & P1, const key & P2, const key & L1, const key & s1, const key & s2); + //Schnorr Non-linkable + //Gen Gives a signature (L1, s1, s2) proving that the sender knows "x" such that xG = one of P1 or P2 + //Ver Verifies that signer knows an "x" such that xG = one of P1 or P2 + //These are called in the below ASNL sig generation + void GenSchnorrNonLinkable(key & L1, key & s1, key & s2, const key & x, const key & P1, const key & P2, int index); + bool VerSchnorrNonLinkable(const key & P1, const key & P2, const key & L1, const key & s1, const key & s2); - //Aggregate Schnorr Non-linkable Ring Signature (ASNL) - // c.f. http://eprint.iacr.org/2015/1098 section 5. - // These are used in range proofs (alternatively Borromean could be used) - // Gen gives a signature which proves the signer knows, for each i, - // an x[i] such that x[i]G = one of P1[i] or P2[i] - // Ver Verifies the signer knows a key for one of P1[i], P2[i] at each i - asnlSig GenASNL(key64 x, key64 P1, key64 P2, bits indices); - bool VerASNL(key64 P1, key64 P2, asnlSig &as); + //Aggregate Schnorr Non-linkable Ring Signature (ASNL) + // c.f. http://eprint.iacr.org/2015/1098 section 5. + // These are used in range proofs (alternatively Borromean could be used) + // Gen gives a signature which proves the signer knows, for each i, + // an x[i] such that x[i]G = one of P1[i] or P2[i] + // Ver Verifies the signer knows a key for one of P1[i], P2[i] at each i + asnlSig GenASNL(key64 x, key64 P1, key64 P2, bits indices); + bool VerASNL(key64 P1, key64 P2, asnlSig &as); - //Multilayered Spontaneous Anonymous Group Signatures (MLSAG signatures) - //These are aka MG signatutes in earlier drafts of the ring ct paper - // c.f. http://eprint.iacr.org/2015/1098 section 2. - // keyImageV just does I[i] = xx[i] * Hash(xx[i] * G) for each i - // Gen creates a signature which proves that for some column in the keymatrix "pk" - // the signer knows a secret key for each row in that column - // Ver verifies that the MG sig was created correctly - keyV keyImageV(const keyV &xx); - mgSig MLSAG_Gen(const keyM &pk, const keyV &xx, const int index); - bool MLSAG_Ver(keyM &pk, mgSig &sig); + //Multilayered Spontaneous Anonymous Group Signatures (MLSAG signatures) + //These are aka MG signatutes in earlier drafts of the ring ct paper + // c.f. http://eprint.iacr.org/2015/1098 section 2. + // keyImageV just does I[i] = xx[i] * HashToPoint(xx[i] * G) for each i + // Gen creates a signature which proves that for some column in the keymatrix "pk" + // the signer knows a secret key for each row in that column + // Ver verifies that the MG sig was created correctly + keyV keyImageV(const keyV &xx); + mgSig MLSAG_Gen(const keyM & pk, const keyV & xx, const int index); + bool MLSAG_Ver(keyM &pk, mgSig &sig); + //mgSig MLSAG_Gen_Old(const keyM & pk, const keyV & xx, const int index); - //proveRange and verRange - //proveRange gives C, and mask such that \sumCi = C - // c.f. http://eprint.iacr.org/2015/1098 section 5.1 - // and Ci is a commitment to either 0 or 2^i, i=0,...,63 - // thus this proves that "amount" is in [0, 2^64] - // mask is a such that C = aG + bH, and b = amount - //verRange verifies that \sum Ci = C and that each Ci is a commitment to 0 or 2^i - rangeSig proveRange(key & C, key & mask, const xmr_amount & amount); - bool verRange(key & C, rangeSig & as); + //proveRange and verRange + //proveRange gives C, and mask such that \sumCi = C + // c.f. http://eprint.iacr.org/2015/1098 section 5.1 + // and Ci is a commitment to either 0 or 2^i, i=0,...,63 + // thus this proves that "amount" is in [0, 2^64] + // mask is a such that C = aG + bH, and b = amount + //verRange verifies that \sum Ci = C and that each Ci is a commitment to 0 or 2^i + rangeSig proveRange(key & C, key & mask, const xmr_amount & amount); + bool verRange(key & C, rangeSig & as); - //Ring-ct MG sigs - //Prove: - // c.f. http://eprint.iacr.org/2015/1098 section 4. definition 10. - // This does the MG sig on the "dest" part of the given key matrix, and - // the last row is the sum of input commitments from that column - sum output commitments - // this shows that sum inputs = sum outputs - //Ver: - // verifies the above sig is created corretly - mgSig proveRctMG(const ctkeyM & pubs, const ctkeyV & inSk, const keyV &outMasks, const ctkeyV & outPk, int index); - bool verRctMG(mgSig mg, ctkeyM & pubs, ctkeyV & outPk); + //Ring-ct MG sigs + //Prove: + // c.f. http://eprint.iacr.org/2015/1098 section 4. definition 10. + // This does the MG sig on the "dest" part of the given key matrix, and + // the last row is the sum of input commitments from that column - sum output commitments + // this shows that sum inputs = sum outputs + //Ver: + // verifies the above sig is created corretly + mgSig proveRctMG(const ctkeyM & pubs, const ctkeyV & inSk, const keyV &outMasks, const ctkeyV & outPk, int index); + bool verRctMG(mgSig mg, ctkeyM & pubs, ctkeyV & outPk); - //These functions get keys from blockchain - //replace these when connecting blockchain - //getKeyFromBlockchain grabs a key from the blockchain at "reference_index" to mix with - //populateFromBlockchain creates a keymatrix with "mixin" columns and one of the columns is inPk - // the return value are the key matrix, and the index where inPk was put (random). - void getKeyFromBlockchain(ctkey & a, size_t reference_index); - tuple populateFromBlockchain(ctkeyV inPk, int mixin); + //These functions get keys from blockchain + //replace these when connecting blockchain + //getKeyFromBlockchain grabs a key from the blockchain at "reference_index" to mix with + //populateFromBlockchain creates a keymatrix with "mixin" columns and one of the columns is inPk + // the return value are the key matrix, and the index where inPk was put (random). + void getKeyFromBlockchain(ctkey & a, size_t reference_index); + tuple populateFromBlockchain(ctkeyV inPk, int mixin); - //RingCT protocol - //genRct: - // creates an rctSig with all data necessary to verify the rangeProofs and that the signer owns one of the - // columns that are claimed as inputs, and that the sum of inputs = sum of outputs. - // Also contains masked "amount" and "mask" so the receiver can see how much they received - //verRct: - // verifies that all signatures (rangeProogs, MG sig, sum inputs = outputs) are correct - //decodeRct: (c.f. http://eprint.iacr.org/2015/1098 section 5.1.1) - // uses the attached ecdh info to find the amounts represented by each output commitment - // must know the destination private key to find the correct amount, else will return a random number - rctSig genRct(ctkeyV & inSk, ctkeyV & inPk, const keyV & destinations, const vector amounts, const int mixin); - bool verRct(rctSig & rv); - xmr_amount decodeRct(rctSig & rv, key & sk, int i); + //RingCT protocol + //genRct: + // creates an rctSig with all data necessary to verify the rangeProofs and that the signer owns one of the + // columns that are claimed as inputs, and that the sum of inputs = sum of outputs. + // Also contains masked "amount" and "mask" so the receiver can see how much they received + //verRct: + // verifies that all signatures (rangeProogs, MG sig, sum inputs = outputs) are correct + //decodeRct: (c.f. http://eprint.iacr.org/2015/1098 section 5.1.1) + // uses the attached ecdh info to find the amounts represented by each output commitment + // must know the destination private key to find the correct amount, else will return a random number + rctSig genRct(ctkeyV & inSk, ctkeyV & inPk, const keyV & destinations, const vector amounts, const int mixin); + bool verRct(rctSig & rv); + xmr_amount decodeRct(rctSig & rv, key & sk, int i);