// 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 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "rctMSig.h" using namespace crypto; using namespace std; 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 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; } }