9
9
#include "../../../include/secp256k1.h"
10
10
#include "../../../include/secp256k1_extrakeys.h"
11
11
#include "../../../include/secp256k1_silentpayments.h"
12
+ #include "dleq_impl.h"
12
13
13
14
/** Sort an array of silent payment recipients. This is used to group recipients by scan pubkey to
14
15
* ensure the correct values of k are used when creating multiple outputs for a recipient. */
@@ -64,15 +65,46 @@ static void secp256k1_silentpayments_calculate_input_hash(unsigned char *input_h
64
65
secp256k1_sha256_finalize (& hash , input_hash );
65
66
}
66
67
67
- static void secp256k1_silentpayments_create_shared_secret ( unsigned char * shared_secret33 , const secp256k1_scalar * secret_component , const secp256k1_ge * public_component ) {
68
+ static int secp256k1_silentpayments_create_shared_secret_with_proof ( const secp256k1_context * ctx , unsigned char * proof64 , secp256k1_ge * shared_secret , const secp256k1_scalar * secret_component , secp256k1_ge * public_component ) {
68
69
secp256k1_gej ss_j ;
69
- secp256k1_ge ss ;
70
- size_t len ;
71
- int ret ;
70
+ int ret = 1 ;
72
71
73
72
/* Compute shared_secret = tweaked_secret_component * Public_component */
74
73
secp256k1_ecmult_const (& ss_j , public_component , secret_component );
75
- secp256k1_ge_set_gej (& ss , & ss_j );
74
+ secp256k1_ge_set_gej (shared_secret , & ss_j );
75
+
76
+ if (proof64 != NULL ) {
77
+ secp256k1_scalar s ;
78
+ secp256k1_scalar e ;
79
+ secp256k1_ge ge_secret_component ;
80
+ secp256k1_gej gej_secret_component ;
81
+
82
+ secp256k1_ecmult_gen (& ctx -> ecmult_gen_ctx , & gej_secret_component , secret_component );
83
+ secp256k1_ge_set_gej (& ge_secret_component , & gej_secret_component );
84
+
85
+ ret &= secp256k1_dleq_prove (ctx , & s , & e , secret_component , public_component , & ge_secret_component , shared_secret ,
86
+ NULL , NULL ); /*todo: how to pass auxrand*/
87
+ /* sanity check*/
88
+ ret &= secp256k1_dleq_verify (& s , & e , & ge_secret_component , public_component , shared_secret , NULL );
89
+
90
+ secp256k1_scalar_get_b32 (proof64 , & s );
91
+ secp256k1_scalar_get_b32 (proof64 + 32 , & e );
92
+ }
93
+ /* While not technically "secret" data, explicitly clear the shared secret since leaking this would allow an attacker
94
+ * to identify the resulting transaction as a silent payments transaction and potentially link the transaction
95
+ * back to the silent payment address
96
+ */
97
+ secp256k1_gej_clear (& ss_j );
98
+ return ret ;
99
+ }
100
+
101
+ static void secp256k1_silentpayments_create_shared_secret (const secp256k1_context * ctx , unsigned char * shared_secret33 , const secp256k1_scalar * secret_component , secp256k1_ge * public_component ) {
102
+ size_t len ;
103
+ int ret ;
104
+ secp256k1_ge ss ;
105
+
106
+ ret = secp256k1_silentpayments_create_shared_secret_with_proof (ctx , NULL , & ss , secret_component , public_component );
107
+ VERIFY_CHECK (ret );
76
108
/* This can only fail if the shared secret is the point at infinity, which should be
77
109
* impossible at this point, considering we have already validated the public key and
78
110
* the secret key being used
@@ -85,7 +117,6 @@ static void secp256k1_silentpayments_create_shared_secret(unsigned char *shared_
85
117
* back to the silent payment address
86
118
*/
87
119
secp256k1_ge_clear (& ss );
88
- secp256k1_gej_clear (& ss_j );
89
120
}
90
121
91
122
/** Set hash state to the BIP340 tagged hash midstate for "BIP0352/SharedSecret". */
@@ -233,7 +264,7 @@ int secp256k1_silentpayments_sender_create_outputs(
233
264
secp256k1_ge pk ;
234
265
ret &= secp256k1_pubkey_load (ctx , & pk , & recipients [i ]-> scan_pubkey );
235
266
if (!ret ) break ;
236
- secp256k1_silentpayments_create_shared_secret (shared_secret , & a_sum_scalar , & pk );
267
+ secp256k1_silentpayments_create_shared_secret (ctx , shared_secret , & a_sum_scalar , & pk );
237
268
k = 0 ;
238
269
}
239
270
ret &= secp256k1_silentpayments_create_output_pubkey (ctx , generated_outputs [recipients [i ]-> index ], shared_secret , & recipients [i ]-> spend_pubkey , k );
@@ -490,7 +521,7 @@ int secp256k1_silentpayments_recipient_scan_outputs(
490
521
secp256k1_scalar_mul (& rsk_scalar , & rsk_scalar , & input_hash_scalar );
491
522
ret &= !overflow ;
492
523
}
493
- secp256k1_silentpayments_create_shared_secret (shared_secret , & rsk_scalar , & A_sum_ge );
524
+ secp256k1_silentpayments_create_shared_secret (ctx , shared_secret , & rsk_scalar , & A_sum_ge );
494
525
495
526
found_idx = 0 ;
496
527
n_found = 0 ;
@@ -609,7 +640,7 @@ int secp256k1_silentpayments_recipient_create_shared_secret(const secp256k1_cont
609
640
if (!ret ) {
610
641
return 0 ;
611
642
}
612
- secp256k1_silentpayments_create_shared_secret (shared_secret33 , & rsk , & A_tweaked_ge );
643
+ secp256k1_silentpayments_create_shared_secret (ctx , shared_secret33 , & rsk , & A_tweaked_ge );
613
644
614
645
/* Explicitly clear secrets */
615
646
secp256k1_scalar_clear (& rsk );
0 commit comments