Add MLSAG_ver and tests for MLSAG_gen

pull/29/head
HenryNguyen5 6 years ago
parent e4d6954c0e
commit 0ef04dad25

@ -87,7 +87,13 @@ var cnUtil = function(currencyConfig) {
var l = JSBigInt(
"7237005577332262213973186563042994240857116359379907606001950938285454250989",
); //curve order (not RCT specific)
var I = "0100000000000000000000000000000000000000000000000000000000000000"; //identity element
this.I = I;
this.identity = function() {
return I;
};
var Z = "0000000000000000000000000000000000000000000000000000000000000000"; //zero scalar
//H2 object to speed up some operations
var H2 = [
@ -520,6 +526,8 @@ var cnUtil = function(currencyConfig) {
return this.sc_reduce32(this.rand_32());
};
// alias
this.skGen = random_scalar;
/* no longer used
this.keccak = function(hex, inlen, outlen) {
var input = hextobin(hex);
@ -875,6 +883,7 @@ var cnUtil = function(currencyConfig) {
CNCrypto._free(res2_m);
return bintohex(res);
};
this.hashToPoint = hash_to_ec_2;
this.generate_key_image_2 = function(pub, sec) {
if (!pub || !sec || pub.length !== 64 || sec.length !== 64) {
@ -1448,13 +1457,16 @@ var cnUtil = function(currencyConfig) {
// because we don't want to force same secret column for all inputs
this.MLSAG_Gen = function(message, pk, xx, kimg, index) {
var cols = pk.length; //ring size
// secret index
if (index >= cols) {
throw "index out of range";
}
var rows = pk[0].length; //number of signature rows (always 2)
// [pub, com] = 2
if (rows !== 2) {
throw "wrong row count";
}
// check all are len 2
for (var i = 0; i < cols; i++) {
if (pk[i].length !== rows) {
throw "pk is not rectangular";
@ -1478,9 +1490,14 @@ var cnUtil = function(currencyConfig) {
toHash[0] = message;
//secret index (pubkey section)
alpha[0] = random_scalar(); //need to save alphas for later
toHash[1] = pk[index][0]; //secret index pubkey
toHash[2] = ge_scalarmult_base(alpha[0]); //dsRow L
// this is the keyimg anyway const H1 = this.hashToPoint(pk[index][0]) // Hp(K_in)
// rv.II[0] = this.ge_scalarmult(H1, xx[0]) // k_in.Hp(K_in)
toHash[2] = ge_scalarmult_base(alpha[0]); //dsRow L, a.G
toHash[3] = generate_key_image_2(pk[index][0], alpha[0]); //dsRow R (key image check)
//secret index (commitment section)
alpha[1] = random_scalar();
@ -1529,6 +1546,51 @@ var cnUtil = function(currencyConfig) {
return rv;
};
this.MLSAG_ver = function(message, pk, rv, kimg) {
// we assume that col, row, rectangular checks are already done correctly
// in MLSAG_gen
const cols = pk.length;
let c_old = rv.cc;
console.log(`cols ${cols}`);
let i = 0;
let toHash = [];
toHash[0] = message;
while (i < cols) {
//!secret index (pubkey section)
toHash[1] = pk[i][0];
toHash[2] = ge_double_scalarmult_base_vartime(
c_old,
pk[i][0],
rv.ss[i][0],
);
toHash[3] = ge_double_scalarmult_postcomp_vartime(
rv.ss[i][0],
pk[i][0],
c_old,
kimg,
);
//!secret index (commitment section)
toHash[4] = pk[i][1];
toHash[5] = ge_double_scalarmult_base_vartime(
c_old,
pk[i][1],
rv.ss[i][1],
);
c_old = array_hash_to_scalar(toHash);
i = i + 1;
}
const c = this.sc_sub(c_old, rv.cc);
console.log(`
c_old: ${c_old}
rc.cc: ${rv.cc}
c: ${c}`);
return c;
};
//prepares for MLSAG_Gen
this.proveRctMG = function(message, pubs, inSk, kimg, mask, Cout, index) {
var cols = pubs.length;

@ -37,7 +37,7 @@ describe("cryptonote_utils tests", function() {
for (let j = 0; j < N; j++) {
indi[j] = randomBit();
xv[j] = monero_utils.random_scalar();
xv[j] = monero_utils.skGen();
if (+indi[j] === 0) {
P1v[j] = monero_utils.ge_scalarmult_base(xv[j]);
@ -87,8 +87,8 @@ describe("cryptonote_utils tests", function() {
];
for (const amount of test_amounts) {
const k = monero_utils.random_scalar();
const scalar = monero_utils.random_scalar(); /*?*/
const k = monero_utils.skGen();
const scalar = monero_utils.skGen(); /*?*/
const amt = monero_utils.d2s(amount.toString());
const t0 = {
mask: scalar,
@ -106,6 +106,91 @@ describe("cryptonote_utils tests", function() {
}
});
it("MG_sigs", () => {
function skvGen(len) {
let skVec = [];
for (let i = 0; i < len; i++) {
skVec.push(monero_utils.skGen());
}
return skVec;
}
//initializes a key matrix;
//first parameter is rows,
//second is columns
function keyMInit(rows, cols) {
let rv = [];
for (let i = 0; i < cols; i++) {
rv.push([]);
}
return rv;
}
let j = 0;
//Tests for MG Sigs
//#MG sig: true one
let N = 3; // cols
let R = 2; // rows
let xtmp = skvGen(R);
let xm = keyMInit(R, N); // = [[None]*N] #just used to generate test public keys
let sk = skvGen(R);
// [
// [pubkey1, commitment1],
// [pubkey2, commitment2],
// ...
// [pubkeyn, commitmentn]]
// // 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
let P = keyMInit(R, N); // = keyM[[None]*N] #stores the public keys;
let ind = 2;
let i = 0;
for (j = 0; j < R; j++) {
for (i = 0; i < N; i++) {
xm[i][j] = monero_utils.skGen();
P[i][j] = monero_utils.ge_scalarmult_base(xm[i][j]); // generate fake [pubkey, commit]
}
}
for (j = 0; j < R; j++) {
// our secret vector of [onetimesec, z]
sk[j] = xm[ind][j];
}
let message = monero_utils.identity();
let kimg = monero_utils.ge_scalarmult(
monero_utils.hashToPoint(P[ind][0]),
sk[0],
);
let rv = monero_utils.MLSAG_Gen(message, P, sk, kimg, ind);
let c = monero_utils.MLSAG_ver(message, P, rv, kimg);
expect(Number(c)).toEqual(0);
xtmp = skvGen(R);
xm = keyMInit(R, N); // = [[None]*N] #just used to generate test public keys
sk = skvGen(R);
for (j = 0; j < R; j++) {
for (i = 0; i < N; i++) {
xm[i][j] = monero_utils.skGen();
P[i][j] = monero_utils.ge_scalarmult_base(xm[i][j]); // generate fake [pubkey, commit]
}
}
sk[1] = skGen(); //assume we don't know one of the private keys..
kimg = monero_utils.ge_scalarmult(
monero_utils.hashToPoint(P[ind][0]),
sk[0],
);
rv = monero_utils.MLSAG_Gen(message, P, sk, kimg, ind);
c = monero_utils.MLSAG_ver(message, P, rv, kimg);
expect(Number(c)).toBeFalsy();
});
describe("old_tests", () => {
it("is valid hex", function() {
var valid = mymonero.monero_utils.valid_hex(private_key);

Loading…
Cancel
Save