Monero
sig_clsag.h
Go to the documentation of this file.
1 // Copyright (c) 2014-2022, The Monero Project
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are
6 // permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice, this list of
9 // conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 // of conditions and the following disclaimer in the documentation and/or other
13 // materials provided with the distribution.
14 //
15 // 3. Neither the name of the copyright holder nor the names of its contributors may be
16 // used to endorse or promote products derived from this software without specific
17 // prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //
29 // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
30 
31 #pragma once
32 
33 #include "ringct/rctSigs.h"
34 #include "ringct/rctTypes.h"
35 #include "device/device.hpp"
36 
37 using namespace rct;
38 
39 template<size_t a_N, size_t a_T, size_t a_w>
41 {
42  public:
43  static const size_t loop_count = 1000;
44  static const size_t N = a_N;
45  static const size_t T = a_T;
46  static const size_t w = a_w;
47 
48  bool init()
49  {
50  pubs.reserve(N);
51  pubs.resize(N);
52 
53  r = keyV(w); // M[l[u]] = Com(0,r[u])
54 
55  a = keyV(w); // P[l[u]] = Com(a[u],s[u])
56  s = keyV(w);
57 
58  Q = keyV(T); // Q[j] = Com(b[j],t[j])
59  b = keyV(T);
60  t = keyV(T);
61 
62  // Random keys
63  key temp;
64  for (size_t k = 0; k < N; k++)
65  {
66  skpkGen(temp,pubs[k].dest);
67  skpkGen(temp,pubs[k].mask);
68  }
69 
70  // Signing and commitment keys (assumes fixed signing indices 0,1,...,w-1 for this test)
71  // TODO: random signing indices
72  C_offsets = keyV(w); // P[l[u]] - C_offsets[u] = Com(0,s[u]-s1[u])
73  s1 = keyV(w);
74  key a_sum = zero();
75  key s1_sum = zero();
76  messages = keyV(w);
77  for (size_t u = 0; u < w; u++)
78  {
79  skpkGen(r[u],pubs[u].dest); // M[u] = Com(0,r[u])
80 
81  a[u] = skGen(); // P[u] = Com(a[u],s[u])
82  s[u] = skGen();
83  addKeys2(pubs[u].mask,s[u],a[u],H);
84 
85  s1[u] = skGen(); // C_offsets[u] = Com(a[u],s1[u])
86  addKeys2(C_offsets[u],s1[u],a[u],H);
87 
88  sc_add(a_sum.bytes,a_sum.bytes,a[u].bytes);
89  sc_add(s1_sum.bytes,s1_sum.bytes,s1[u].bytes);
90 
91  messages[u] = skGen();
92  }
93 
94  // Outputs
95  key b_sum = zero();
96  key t_sum = zero();
97  for (size_t j = 0; j < T-1; j++)
98  {
99  b[j] = skGen(); // Q[j] = Com(b[j],t[j])
100  t[j] = skGen();
101  addKeys2(Q[j],t[j],b[j],H);
102 
103  sc_add(b_sum.bytes,b_sum.bytes,b[j].bytes);
104  sc_add(t_sum.bytes,t_sum.bytes,t[j].bytes);
105  }
106  // Value/mask balance for Q[T-1]
107  sc_sub(b[T-1].bytes,a_sum.bytes,b_sum.bytes);
108  sc_sub(t[T-1].bytes,s1_sum.bytes,t_sum.bytes);
109  addKeys2(Q[T-1],t[T-1],b[T-1],H);
110 
111  // Build proofs
112  sigs.reserve(w);
113  sigs.resize(0);
114  ctkey sk;
115  for (size_t u = 0; u < w; u++)
116  {
117  sk.dest = r[u];
118  sk.mask = s[u];
119 
120  sigs.push_back(proveRctCLSAGSimple(messages[u],pubs,sk,s1[u],C_offsets[u],u,hw::get_device("default")));
121  }
122 
123  return true;
124  }
125 
126  bool test()
127  {
128  for (size_t u = 0; u < w; u++)
129  {
130  if (!verRctCLSAGSimple(messages[u],sigs[u],pubs,C_offsets[u]))
131  {
132  return false;
133  }
134  }
135 
136  // Check balanace
137  std::vector<MultiexpData> balance;
138  balance.reserve(w + T);
139  balance.resize(0);
140  key ZERO = zero();
141  key ONE = identity();
142  key MINUS_ONE;
144  for (size_t u = 0; u < w; u++)
145  {
146  balance.push_back({ONE,C_offsets[u]});
147  }
148  for (size_t j = 0; j < T; j++)
149  {
150  balance.push_back({MINUS_ONE,Q[j]});
151  }
152  if (!(straus(balance) == ONE)) // group identity
153  {
154  return false;
155  }
156 
157  return true;
158  }
159 
160  private:
171  std::vector<clsag> sigs;
172 };
keyV C_offsets
Definition: sig_clsag.h:169
const uint32_t T[512]
Definition: groestl_tables.h:36
static const key H
Definition: rctTypes.h:633
static const constexpr rct::key ZERO
Definition: bulletproofs_plus.cc:76
std::vector< clsag > sigs
Definition: sig_clsag.h:171
u
Definition: pymoduletest.py:20
keyV messages
Definition: sig_clsag.h:170
CXA_THROW_INFO_T void(* dest)(void *))
Definition: stack_trace.cpp:91
Definition: rctTypes.h:97
t
Definition: console.py:33
clsag proveRctCLSAGSimple(const key &message, const ctkeyV &pubs, const ctkey &inSk, const key &a, const key &Cout, unsigned int index, hw::device &hwdev)
Definition: rctSigs.cpp:764
static const constexpr rct::key MINUS_ONE
Definition: bulletproofs.cc:77
const char * s
Definition: minissdp.c:596
Definition: bulletproofs.cc:63
ctkeyV pubs
Definition: sig_clsag.h:161
key dest
Definition: rctTypes.h:98
std::vector< key > keyV
Definition: rctTypes.h:89
bool verRctCLSAGSimple(const key &message, const clsag &sig, const ctkeyV &pubs, const key &C_offset)
Definition: rctSigs.cpp:872
keyV s1
Definition: sig_clsag.h:165
keyV t
Definition: sig_clsag.h:166
keyV r
Definition: sig_clsag.h:163
bool init()
Definition: sig_clsag.h:48
device & get_device(const std::string &device_descriptor)
Definition: device.cpp:95
void sc_add(unsigned char *s, const unsigned char *a, const unsigned char *b)
Definition: crypto-ops.c:2548
std::vector< ctkey > ctkeyV
Definition: rctTypes.h:109
Definition: rctTypes.h:79
keyV Q
Definition: sig_clsag.h:162
void sc_sub(unsigned char *s, const unsigned char *a, const unsigned char *b)
Definition: crypto-ops.c:2687
bool test()
Definition: sig_clsag.h:126
void skGen(key &sk)
Definition: rctOps.cpp:253
keyV a
Definition: sig_clsag.h:167
keyV s
Definition: sig_clsag.h:164
static const constexpr rct::key ONE
Definition: bulletproofs_plus.cc:77
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124
r
Definition: testupnpigd.py:61
unsigned char bytes[32]
Definition: rctTypes.h:87
key identity()
Definition: rctOps.h:73
void addKeys2(key &aGbB, const key &a, const key &b, const key &B)
Definition: rctOps.cpp:478
void skpkGen(key &sk, key &pk)
Definition: rctOps.cpp:284
Definition: sig_clsag.h:40
key mask
Definition: rctTypes.h:99
key zero()
Definition: rctOps.h:70
rct::key straus(const std::vector< MultiexpData > &data, const std::shared_ptr< straus_cached_data > &cache, size_t STEP)
Definition: multiexp.cc:446
cryptonote::block b
Definition: block.cpp:40
keyV b
Definition: sig_clsag.h:168