Skip to content

Commit 0d711b5

Browse files
committed
1 parent bba6aa5 commit 0d711b5

File tree

4 files changed

+172
-1
lines changed

4 files changed

+172
-1
lines changed

src/crypto/crypto.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "warnings.h"
4343
#include "crypto.h"
4444
#include "hash.h"
45+
#include "blake2b.h"
4546

4647
#include "cryptonote_config.h"
4748

@@ -608,7 +609,7 @@ namespace crypto {
608609
return sc_isnonzero(&c2) == 0;
609610
}
610611

611-
static void hash_to_ec(const public_key &key, ge_p3 &res) {
612+
static void biased_hash_to_ec(const public_key &key, ge_p3 &res) {
612613
hash h;
613614
ge_p2 point;
614615
ge_p1p1 point2;
@@ -618,6 +619,39 @@ namespace crypto {
618619
ge_p1p1_to_p3(&res, &point2);
619620
}
620621

622+
void crypto_ops::unbiased_hash_to_ec(const unsigned char *preimage, const size_t length, ec_point &res) {
623+
uint8_t hash[64];
624+
blake2b(std::addressof(hash), 64, preimage, length, NULL, 0);
625+
626+
ge_p2 first;
627+
ge_fromfe_frombytes_vartime(&first, reinterpret_cast<const unsigned char *>(&hash));
628+
ge_p1p1 first_p1p1;
629+
ge_mul8(&first_p1p1, &first);
630+
ge_p3 first_p3;
631+
ge_p1p1_to_p3(&first_p3, &first_p1p1);
632+
633+
ge_p2 second;
634+
ge_fromfe_frombytes_vartime(&second, reinterpret_cast<const unsigned char *>(&hash) + 32);
635+
ge_p1p1 second_p1p1;
636+
ge_mul8(&second_p1p1, &second);
637+
ge_p3 second_p3;
638+
ge_p1p1_to_p3(&second_p3, &second_p1p1);
639+
ge_cached second_cached;
640+
ge_p3_to_cached(&second_cached, &second_p3);
641+
642+
ge_p1p1 point;
643+
ge_add(&point, &first_p3, &second_cached);
644+
645+
ge_p3 res_ge_p3;
646+
ge_p1p1_to_p3(&res_ge_p3, &point);
647+
ge_p3_tobytes(&res, &res_ge_p3);
648+
}
649+
650+
// TODO @jeffro256
651+
static void hash_to_ec(const public_key &key, ge_p3 &res) {
652+
return biased_hash_to_ec(key, res);
653+
}
654+
621655
void crypto_ops::generate_key_image(const public_key &pub, const secret_key &sec, key_image &image) {
622656
ge_p3 point;
623657
ge_p2 point2;

src/crypto/crypto.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ namespace crypto {
141141
const public_key *const *, std::size_t, const signature *);
142142
static void derive_view_tag(const key_derivation &, std::size_t, view_tag &);
143143
friend void derive_view_tag(const key_derivation &, std::size_t, view_tag &);
144+
static void unbiased_hash_to_ec(const unsigned char *, const size_t, ec_point &);
145+
friend void unbiased_hash_to_ec(const unsigned char *, const size_t, ec_point &);
144146
};
145147

146148
void generate_random_bytes_thread_safe(size_t N, uint8_t *bytes);
@@ -297,6 +299,10 @@ namespace crypto {
297299
crypto_ops::derive_view_tag(derivation, output_index, vt);
298300
}
299301

302+
inline void unbiased_hash_to_ec(const unsigned char *preimage, const size_t length, ec_point &res) {
303+
crypto_ops::unbiased_hash_to_ec(preimage, length, res);
304+
}
305+
300306
inline std::ostream &operator <<(std::ostream &o, const crypto::public_key &v) {
301307
epee::to_hex::formatted(o, epee::as_byte_span(v)); return o;
302308
}

src/crypto/generators.cpp

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ extern "C"
3939
#include <cstddef>
4040
#include <cstdint>
4141
#include <mutex>
42+
#include <string_view>
4243

4344
namespace crypto
4445
{
@@ -68,14 +69,36 @@ constexpr public_key G = bytes_to<public_key>({ 0x58, 0x66, 0x66, 0x66, 0x66, 0x
6869
//pedersen commitment generator H: toPoint(cn_fast_hash(G))
6970
constexpr public_key H = bytes_to<public_key>({ 0x8b, 0x65, 0x59, 0x70, 0x15, 0x37, 0x99, 0xaf, 0x2a, 0xea, 0xdc, 0x9f, 0xf1,
7071
0xad, 0xd0, 0xea, 0x6c, 0x72, 0x51, 0xd5, 0x41, 0x54, 0xcf, 0xa9, 0x2c, 0x17, 0x3a, 0x0d, 0xd3, 0x9c, 0x1f, 0x94 });
72+
//FCMP++ generator T: unbiased_hash_to_ec(keccak("Monero Generator T"))
73+
constexpr public_key T = bytes_to<public_key>({ 97, 183, 54, 206, 147, 182, 42, 61, 55, 120, 171, 32, 77, 168, 93, 59, 76,
74+
220, 7, 37, 15, 93, 167, 227, 223, 38, 41, 146, 129, 52, 213, 38 });
75+
//FCMP++ generator U: unbiased_hash_to_ec(keccak("Monero FCMP++ Generator U"))
76+
constexpr public_key U = bytes_to<public_key>({ 80, 107, 35, 246, 214, 229, 48, 153, 122, 188, 172, 198, 253, 52, 119, 52,
77+
177, 76, 43, 215, 155, 234, 0, 238, 176, 72, 87, 232, 234, 221, 26, 138 });
78+
//FCMP++ generator V: unbiased_hash_to_ec(keccak("Monero FCMP++ Generator V"))
79+
constexpr public_key V = bytes_to<public_key>({ 105, 53, 244, 19, 248, 49, 9, 19, 138, 122, 20, 180, 9, 85, 45, 59, 118,
80+
216, 143, 202, 129, 187, 89, 39, 233, 161, 225, 48, 205, 254, 41, 249 });
7181
static ge_p3 G_p3;
7282
static ge_p3 H_p3;
83+
static ge_p3 T_p3;
84+
static ge_p3 U_p3;
85+
static ge_p3 V_p3;
7386
static ge_cached G_cached;
7487
static ge_cached H_cached;
88+
static ge_cached T_cached;
89+
static ge_cached U_cached;
90+
static ge_cached V_cached;
7591

7692
// misc
7793
static std::once_flag init_gens_once_flag;
7894

95+
//-------------------------------------------------------------------------------------------------------------------
96+
// hash-to-point: H_p(x) = unbiased_hash_to_ec(x)
97+
//-------------------------------------------------------------------------------------------------------------------
98+
static void hash_to_point(const crypto::hash &x, crypto::ec_point &point_out)
99+
{
100+
unbiased_hash_to_ec((const unsigned char*)x.data, sizeof(crypto::hash), point_out);
101+
}
79102
//-------------------------------------------------------------------------------------------------------------------
80103
//-------------------------------------------------------------------------------------------------------------------
81104
static public_key reproduce_generator_G()
@@ -120,6 +143,39 @@ static public_key reproduce_generator_H()
120143
return reproduced_H;
121144
}
122145
//-------------------------------------------------------------------------------------------------------------------
146+
//-------------------------------------------------------------------------------------------------------------------
147+
static public_key reproduce_generator_T()
148+
{
149+
// T = H_p(keccak("Monero Generator T"))
150+
const std::string_view T_seed{"Monero Generator T"};
151+
public_key reproduced_T;
152+
hash_to_point(cn_fast_hash(T_seed.data(), T_seed.size()), reproduced_T);
153+
154+
return reproduced_T;
155+
}
156+
//-------------------------------------------------------------------------------------------------------------------
157+
//-------------------------------------------------------------------------------------------------------------------
158+
static public_key reproduce_generator_U()
159+
{
160+
// U = H_p(keccak("Monero FCMP++ Generator U"))
161+
const std::string_view U_seed{"Monero FCMP++ Generator U"};
162+
public_key reproduced_U;
163+
hash_to_point(cn_fast_hash(U_seed.data(), U_seed.size()), reproduced_U);
164+
165+
return reproduced_U;
166+
}
167+
//-------------------------------------------------------------------------------------------------------------------
168+
//-------------------------------------------------------------------------------------------------------------------
169+
static public_key reproduce_generator_V()
170+
{
171+
// V = H_p(keccak("Monero FCMP++ Generator V"))
172+
const std::string_view V_seed{"Monero FCMP++ Generator V"};
173+
public_key reproduced_V;
174+
hash_to_point(cn_fast_hash(V_seed.data(), V_seed.size()), reproduced_V);
175+
176+
return reproduced_V;
177+
}
178+
//-------------------------------------------------------------------------------------------------------------------
123179
// Make generators, but only once
124180
//-------------------------------------------------------------------------------------------------------------------
125181
static void init_gens()
@@ -130,21 +186,36 @@ static void init_gens()
130186
// sanity check the generators
131187
static_assert(static_cast<unsigned char>(G.data[0]) == 0x58, "compile-time constant sanity check");
132188
static_assert(static_cast<unsigned char>(H.data[0]) == 0x8b, "compile-time constant sanity check");
189+
static_assert(static_cast<unsigned char>(T.data[0]) == 97, "compile-time constant sanity check");
190+
static_assert(static_cast<unsigned char>(U.data[0]) == 80, "compile-time constant sanity check");
191+
static_assert(static_cast<unsigned char>(V.data[0]) == 105, "compile-time constant sanity check");
133192

134193
// build ge_p3 representations of generators
135194
const int G_deserialize = ge_frombytes_vartime(&G_p3, to_bytes(G));
136195
const int H_deserialize = ge_frombytes_vartime(&H_p3, to_bytes(H));
196+
const int T_deserialize = ge_frombytes_vartime(&T_p3, to_bytes(T));
197+
const int U_deserialize = ge_frombytes_vartime(&U_p3, to_bytes(U));
198+
const int V_deserialize = ge_frombytes_vartime(&V_p3, to_bytes(V));
137199

138200
(void)G_deserialize; assert(G_deserialize == 0);
139201
(void)H_deserialize; assert(H_deserialize == 0);
202+
(void)T_deserialize; assert(T_deserialize == 0);
203+
(void)U_deserialize; assert(U_deserialize == 0);
204+
(void)V_deserialize; assert(V_deserialize == 0);
140205

141206
// get cached versions
142207
ge_p3_to_cached(&G_cached, &G_p3);
143208
ge_p3_to_cached(&H_cached, &H_p3);
209+
ge_p3_to_cached(&T_cached, &T_p3);
210+
ge_p3_to_cached(&U_cached, &U_p3);
211+
ge_p3_to_cached(&V_cached, &V_p3);
144212

145213
// in debug mode, check that generators are reproducible
146214
(void)reproduce_generator_G; assert(reproduce_generator_G() == G);
147215
(void)reproduce_generator_H; assert(reproduce_generator_H() == H);
216+
(void)reproduce_generator_T; assert(reproduce_generator_T() == T);
217+
(void)reproduce_generator_U; assert(reproduce_generator_U() == U);
218+
(void)reproduce_generator_V; assert(reproduce_generator_V() == V);
148219

149220
});
150221
}
@@ -159,6 +230,21 @@ public_key get_H()
159230
return H;
160231
}
161232
//-------------------------------------------------------------------------------------------------------------------
233+
public_key get_T()
234+
{
235+
return T;
236+
}
237+
//-------------------------------------------------------------------------------------------------------------------
238+
public_key get_U()
239+
{
240+
return U;
241+
}
242+
//-------------------------------------------------------------------------------------------------------------------
243+
public_key get_V()
244+
{
245+
return V;
246+
}
247+
//-------------------------------------------------------------------------------------------------------------------
162248
ge_p3 get_G_p3()
163249
{
164250
init_gens();
@@ -171,6 +257,24 @@ ge_p3 get_H_p3()
171257
return H_p3;
172258
}
173259
//-------------------------------------------------------------------------------------------------------------------
260+
ge_p3 get_T_p3()
261+
{
262+
init_gens();
263+
return T_p3;
264+
}
265+
//-------------------------------------------------------------------------------------------------------------------
266+
ge_p3 get_U_p3()
267+
{
268+
init_gens();
269+
return U_p3;
270+
}
271+
//-------------------------------------------------------------------------------------------------------------------
272+
ge_p3 get_V_p3()
273+
{
274+
init_gens();
275+
return V_p3;
276+
}
277+
//-------------------------------------------------------------------------------------------------------------------
174278
ge_cached get_G_cached()
175279
{
176280
init_gens();
@@ -183,4 +287,22 @@ ge_cached get_H_cached()
183287
return H_cached;
184288
}
185289
//-------------------------------------------------------------------------------------------------------------------
290+
ge_cached get_T_cached()
291+
{
292+
init_gens();
293+
return T_cached;
294+
}
295+
//-------------------------------------------------------------------------------------------------------------------
296+
ge_cached get_U_cached()
297+
{
298+
init_gens();
299+
return U_cached;
300+
}
301+
//-------------------------------------------------------------------------------------------------------------------
302+
ge_cached get_V_cached()
303+
{
304+
init_gens();
305+
return V_cached;
306+
}
307+
//-------------------------------------------------------------------------------------------------------------------
186308
} //namespace crypto

src/crypto/generators.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,18 @@ namespace crypto
3939

4040
public_key get_G();
4141
public_key get_H();
42+
public_key get_T();
43+
public_key get_U();
44+
public_key get_V();
4245
ge_p3 get_G_p3();
4346
ge_p3 get_H_p3();
47+
ge_p3 get_T_p3();
48+
ge_p3 get_U_p3();
49+
ge_p3 get_V_p3();
4450
ge_cached get_G_cached();
4551
ge_cached get_H_cached();
52+
ge_cached get_T_cached();
53+
ge_cached get_U_cached();
54+
ge_cached get_V_cached();
4655

4756
} //namespace crypto

0 commit comments

Comments
 (0)