mirror of
https://github.com/monero-project/research-lab.git
synced 2025-03-12 09:37:25 +00:00
Updated rct code with ring multisig and fixing key image bug I found last night
This commit is contained in:
parent
bfb18a0eed
commit
b215a98a74
11 changed files with 267 additions and 207 deletions
|
@ -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
|
|
|
@ -1,4 +0,0 @@
|
||||||
gtags.exe
|
|
||||||
mingw32-make.exe clean
|
|
||||||
mingw32-make.exe
|
|
||||||
a.exe > .results
|
|
|
@ -1,4 +0,0 @@
|
||||||
gtags.exe
|
|
||||||
make clean
|
|
||||||
make
|
|
||||||
./a.exe
|
|
|
@ -1,3 +0,0 @@
|
||||||
rm.exe a.exe
|
|
||||||
g++ bits.cpp
|
|
||||||
./a.exe
|
|
|
@ -1 +0,0 @@
|
||||||
%1
|
|
|
@ -34,4 +34,74 @@ using namespace std;
|
||||||
|
|
||||||
namespace rct {
|
namespace rct {
|
||||||
|
|
||||||
|
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<key, key, key, key> 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<ge_dsmp> 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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -50,6 +50,7 @@
|
||||||
|
|
||||||
#include "rctTypes.h"
|
#include "rctTypes.h"
|
||||||
#include "rctOps.h"
|
#include "rctOps.h"
|
||||||
|
#include "rctSigs.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,11 +59,8 @@ using namespace std;
|
||||||
using namespace crypto;
|
using namespace crypto;
|
||||||
|
|
||||||
namespace rct {
|
namespace rct {
|
||||||
|
tuple<key, key, key, key> InitiateRMS(key x);
|
||||||
int i;
|
key rmsMgSigStart(const keyM & pk, mgSig & rv, keyV aG, keyV aHP, const int index);
|
||||||
//rctSig genRMS(ctkeyV & inSk, ctkeyV & inPk, const keyV & destinations, const vector<xmr_amount> amounts, const int mixin);
|
key rmsSign(key a, key c, key x) ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -353,14 +353,41 @@ namespace rct {
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns cn_fast_hash(input) * G where G is the basepoint
|
//cn_fast_hash for a 96 byte unsigned char
|
||||||
key hashToPoint(const key & in) {
|
key cn_fast_hash96(const void * in) {
|
||||||
return scalarmultBase(cn_fast_hash(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
|
key hashToPoint(const key & hh) {
|
||||||
void hashToPoint(key & out, const key & in) {
|
key pointk;
|
||||||
scalarmultBase(out, cn_fast_hash(in));
|
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)
|
//sums a vector of curve points (for scalars use sc_add)
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
|
|
||||||
#include "rctTypes.h"
|
#include "rctTypes.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace crypto;
|
using namespace crypto;
|
||||||
|
|
||||||
|
@ -128,6 +129,8 @@ namespace rct {
|
||||||
void cn_fast_hash(key &hash, const key &in);
|
void cn_fast_hash(key &hash, const key &in);
|
||||||
//cn_fast_hash for a 32 byte key
|
//cn_fast_hash for a 32 byte key
|
||||||
key cn_fast_hash(const key &in);
|
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
|
//returns cn_fast_hash(input) * G where G is the basepoint
|
||||||
key hashToPoint(const key &in);
|
key hashToPoint(const key &in);
|
||||||
|
|
|
@ -134,18 +134,10 @@ namespace rct {
|
||||||
return II;
|
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)
|
//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
|
//These are aka MG signatutes in earlier drafts of the ring ct paper
|
||||||
// c.f. http://eprint.iacr.org/2015/1098 section 2.
|
// c.f. http://eprint.iacr.org/2015/1098 section 2.
|
||||||
// keyImageV just does I[i] = xx[i] * Hash(xx[i] * G) for each i
|
// keyImageV just does I[i] = xx[i] * Hash(xx[i] * G) for each i
|
||||||
|
@ -153,7 +145,6 @@ namespace rct {
|
||||||
// the signer knows a secret key for each row in that column
|
// the signer knows a secret key for each row in that column
|
||||||
// Ver verifies that the MG sig was created correctly
|
// Ver verifies that the MG sig was created correctly
|
||||||
mgSig MLSAG_Gen(const keyM & pk, const keyV & xx, const int index) {
|
mgSig MLSAG_Gen(const keyM & pk, const keyV & xx, const int index) {
|
||||||
|
|
||||||
mgSig rv;
|
mgSig rv;
|
||||||
int rows = pk[0].size();
|
int rows = pk[0].size();
|
||||||
int cols = pk.size();
|
int cols = pk.size();
|
||||||
|
@ -161,118 +152,117 @@ namespace rct {
|
||||||
printf("Error! What is c if cols = 1!");
|
printf("Error! What is c if cols = 1!");
|
||||||
}
|
}
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
|
key c, c_old, L, R, Hi;
|
||||||
keyV c(cols);
|
sc_0(c_old.bytes);
|
||||||
keyV alpha = skvGen(rows);
|
|
||||||
rv.II = keyImageV(xx);
|
|
||||||
DP(rv.II);
|
|
||||||
vector<ge_dsmp> Ip(rows);
|
vector<ge_dsmp> Ip(rows);
|
||||||
keyM L(cols, rv.II);
|
rv.II = keyV(rows);
|
||||||
keyM R(cols, rv.II);
|
|
||||||
rv.ss = keyM(cols, rv.II);
|
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++) {
|
for (i = 0; i < rows; i++) {
|
||||||
L[index][i] = scalarmultBase(alpha[i]);
|
skpkGen(alpha[i], aG[i]); //need to save alphas for later..
|
||||||
hashToPoint(Hi[i], pk[index][i]);
|
Hi = hashToPoint(pk[index][i]);
|
||||||
R[index][i] = scalarmultKey(Hi[i], alpha[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]);
|
precomp(Ip[i], rv.II[i]);
|
||||||
}
|
m2hash = cn_fast_hash96(m2);
|
||||||
char * m1 = (char *)malloc(32 * rows * (cols + 2));
|
sc_add(c_old.bytes, c_old.bytes, m2hash.bytes);
|
||||||
//vector<char> 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;
|
int oldi = index;
|
||||||
|
|
||||||
i = (index + 1) % cols;
|
i = (index + 1) % cols;
|
||||||
for (j = 0; j < rows; j++) {
|
if (i == 0) {
|
||||||
memcpy(m1 + rows * 32 * cols + (32 * j), L[oldi][j].bytes, 32);
|
copy(rv.cc, c_old);
|
||||||
memcpy(m1 + rows * 32 * (cols + 1) + (32 * j), R[oldi][j].bytes, 32);
|
|
||||||
}
|
}
|
||||||
while (i != index) {
|
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++) {
|
for (j = 0; j < rows; j++) {
|
||||||
addKeys2(L[i][j], rv.ss[i][j], c[i], pk[i][j]);
|
addKeys2(L, rv.ss[i][j], c_old, pk[i][j]);
|
||||||
hashToPoint(Hi[j], pk[i][j]);
|
hashToPoint(Hi, pk[i][j]);
|
||||||
addKeys3(R[i][j], rv.ss[i][j], Hi[j], c[i], Ip[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;
|
oldi = i;
|
||||||
i = (i + 1) % cols;
|
i = (i + 1) % cols;
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
copy(rv.cc, c_old);
|
||||||
|
}
|
||||||
|
}
|
||||||
for (j = 0; j < rows; j++) {
|
for (j = 0; j < rows; j++) {
|
||||||
memcpy(m1 + rows * 32 * cols + (32 * j), L[oldi][j].bytes, 32);
|
sc_mulsub(rv.ss[index][j].bytes, c.bytes, xx[j].bytes, alpha[j].bytes);
|
||||||
memcpy(m1 + rows * 32 * (cols + 1) + (32 * j), R[oldi][j].bytes, 32);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
cn_fast_hash(c[index], m1, 32 * rows * (cols + 2));
|
|
||||||
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);
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Multilayered Spontaneous Anonymous Group Signatures (MLSAG signatures)
|
//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
|
//These are aka MG signatutes in earlier drafts of the ring ct paper
|
||||||
// c.f. http://eprint.iacr.org/2015/1098 section 2.
|
// c.f. http://eprint.iacr.org/2015/1098 section 2.
|
||||||
// keyImageV just does I[i] = xx[i] * Hash(xx[i] * G) for each i
|
// 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"
|
// 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
|
// the signer knows a secret key for each row in that column
|
||||||
// Ver verifies that the MG sig was created correctly
|
// Ver verifies that the MG sig was created correctly
|
||||||
bool MLSAG_Ver(keyM &pk, mgSig &sig) {
|
bool MLSAG_Ver(keyM & pk, mgSig & rv) {
|
||||||
|
|
||||||
int rows = pk[0].size();
|
int rows = pk[0].size();
|
||||||
int cols = pk.size();
|
int cols = pk.size();
|
||||||
if (cols < 2) {
|
if (cols < 2) {
|
||||||
printf("Error! What is c if cols = 1!");
|
printf("Error! What is c if cols = 1!");
|
||||||
|
|
||||||
}
|
}
|
||||||
DP("Verifying MG sig");
|
int i = 0, j = 0;
|
||||||
keyV c(cols + 1);
|
key c, L, R, Hi;
|
||||||
memcpy(c[0].bytes, sig.cc.bytes, 32);
|
key c_old = copy(rv.cc);
|
||||||
vector<ge_dsmp> Ip(rows);
|
vector<ge_dsmp> Ip(rows);
|
||||||
keyM L(cols, pk[0]);
|
|
||||||
keyM R(cols, pk[0]);
|
|
||||||
|
|
||||||
int i = 0, oldi = 0, j = 0;
|
|
||||||
keyV Hi(rows);
|
|
||||||
for (i= 0 ; i< rows ; i++) {
|
for (i= 0 ; i< rows ; i++) {
|
||||||
precomp(Ip[i], sig.II[i]);
|
precomp(Ip[i], rv.II[i]);
|
||||||
}
|
|
||||||
i = 0;
|
|
||||||
char * m1 = (char *)malloc(32 * rows * (cols + 2));
|
|
||||||
//vector<char> 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
unsigned char m2[96];
|
||||||
|
key m2hash;
|
||||||
|
|
||||||
|
int oldi = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < cols) {
|
while (i < cols) {
|
||||||
|
sc_0(c.bytes);
|
||||||
for (j = 0; j < rows; j++) {
|
for (j = 0; j < rows; j++) {
|
||||||
addKeys2(L[i][j], sig.ss[i][j], c[i], pk[i][j]);
|
addKeys2(L, rv.ss[i][j], c_old, pk[i][j]);
|
||||||
hashToPoint(Hi[j], pk[i][j]);
|
hashToPoint(Hi, pk[i][j]);
|
||||||
addKeys3(R[i][j], sig.ss[i][j], Hi[j], c[i], Ip[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;
|
oldi = i;
|
||||||
i = (i + 1);
|
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));
|
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;
|
||||||
}
|
}
|
||||||
key cc;
|
|
||||||
|
|
||||||
sc_sub(cc.bytes, c[0].bytes, c[cols].bytes);
|
|
||||||
free(m1);
|
|
||||||
return sc_isnonzero(cc.bytes) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//proveRange and verRange
|
//proveRange and verRange
|
||||||
//proveRange gives C, and mask such that \sumCi = C
|
//proveRange gives C, and mask such that \sumCi = C
|
||||||
|
|
|
@ -78,13 +78,14 @@ namespace rct {
|
||||||
//Multilayered Spontaneous Anonymous Group Signatures (MLSAG signatures)
|
//Multilayered Spontaneous Anonymous Group Signatures (MLSAG signatures)
|
||||||
//These are aka MG signatutes in earlier drafts of the ring ct paper
|
//These are aka MG signatutes in earlier drafts of the ring ct paper
|
||||||
// c.f. http://eprint.iacr.org/2015/1098 section 2.
|
// c.f. http://eprint.iacr.org/2015/1098 section 2.
|
||||||
// keyImageV just does I[i] = xx[i] * Hash(xx[i] * G) for each i
|
// 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"
|
// 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
|
// the signer knows a secret key for each row in that column
|
||||||
// Ver verifies that the MG sig was created correctly
|
// Ver verifies that the MG sig was created correctly
|
||||||
keyV keyImageV(const keyV &xx);
|
keyV keyImageV(const keyV &xx);
|
||||||
mgSig MLSAG_Gen(const keyM & pk, const keyV & xx, const int index);
|
mgSig MLSAG_Gen(const keyM & pk, const keyV & xx, const int index);
|
||||||
bool MLSAG_Ver(keyM &pk, mgSig &sig);
|
bool MLSAG_Ver(keyM &pk, mgSig &sig);
|
||||||
|
//mgSig MLSAG_Gen_Old(const keyM & pk, const keyV & xx, const int index);
|
||||||
|
|
||||||
//proveRange and verRange
|
//proveRange and verRange
|
||||||
//proveRange gives C, and mask such that \sumCi = C
|
//proveRange gives C, and mask such that \sumCi = C
|
||||||
|
|
Loading…
Reference in a new issue