11extern crate config as exconfig;
22
33use bdk:: bitcoin:: secp256k1:: { All , Secp256k1 , SecretKey } ;
4- use bdk:: bitcoin:: { Address , PublicKey } ;
4+ use bdk:: bitcoin:: { secp256k1 , Address , PublicKey } ;
55use bdk:: bitcoincore_rpc:: Client as BitcoinClient ;
66use bdk:: blockchain:: RpcBlockchain as BitcoinWalletClient ;
77use bdk:: database:: MemoryDatabase ;
88use ethers:: prelude:: Http ;
99use ethers:: providers:: Provider as EthereumClient ;
1010use ethers:: signers:: { LocalWallet as EthereumWallet , Signer } ;
1111use ethers:: types:: Address as EthereumAddress ;
12- use eyre:: { Context , Result } ;
13- use num:: { bigint:: Sign , BigInt , ToPrimitive , Zero } ;
12+ use eyre:: { eyre , Context , Result } ;
13+ use num:: { bigint:: Sign , BigInt , One , ToPrimitive , Zero } ;
1414use rand:: rngs:: ThreadRng ;
1515use rapidsnark:: { groth16_prover, groth16_verifier} ;
1616use std:: collections:: HashMap ;
1717use std:: env;
1818use std:: fs:: File ;
1919use std:: io:: Read ;
20- use std:: ops:: Div ;
20+ use std:: ops:: { Add , Div , Mul } ;
2121use std:: path:: PathBuf ;
22+ use std:: str:: FromStr ;
2223use witness_calculator:: WitnessCalculator ;
2324
2425mod config;
@@ -83,22 +84,27 @@ impl SwapParticipant {
8384 } )
8485 }
8586
86- pub fn new_atomic_swap ( & self , rng : & mut ThreadRng ) -> Result < ( String , String ) > {
87+ pub fn new_atomic_swap (
88+ & self ,
89+ rng : & mut ThreadRng ,
90+ secp_ctx : & Secp256k1 < All > ,
91+ ) -> Result < ( String , String ) > {
8792 println ! ( "\n {} starts atomic-swap" , self . name) ;
8893
8994 let swap_secret = SecretKey :: new ( rng) ;
9095
91- println ! ( "Swap secret: {}" , swap_secret. display_secret( ) ) ;
96+ println ! ( "Swap k secret: {}" , swap_secret. display_secret( ) ) ;
97+ println ! ( "Swap k public: {}" , swap_secret. public_key( secp_ctx) ) ;
9298
9399 let swap_secret_bigint = BigInt :: from_bytes_be ( Sign :: Plus , & swap_secret. secret_bytes ( ) ) ;
94- let broken_swap_secret_bigint = u256_to_u64array ( swap_secret_bigint)
100+ let swap_secret_u64array = u256_to_u64array ( swap_secret_bigint)
95101 . expect ( "Secret is always lseq than u256" )
96102 . iter ( )
97103 . map ( |val| BigInt :: from ( * val) )
98104 . collect ( ) ;
99105
100106 let mut prover_inputs = HashMap :: new ( ) ;
101- prover_inputs. insert ( "secret" . to_string ( ) , broken_swap_secret_bigint ) ;
107+ prover_inputs. insert ( "secret" . to_string ( ) , swap_secret_u64array ) ;
102108
103109 println ! ( "Loading wasm..." ) ;
104110
@@ -129,7 +135,7 @@ impl SwapParticipant {
129135 Ok ( proof)
130136 }
131137
132- pub fn accept_atomic_swap ( & self , proof : String , public_inputs : String ) -> Result < bool > {
138+ pub fn accept_atomic_swap ( & self , proof : String , public_inputs_json : String ) -> Result < ( ) > {
133139 println ! ( "\n {} accepts atomic-swap" , self . name) ;
134140 println ! ( "Loading verification key..." ) ;
135141
@@ -145,16 +151,19 @@ impl SwapParticipant {
145151 let is_proof_valid = groth16_verifier (
146152 & verification_key,
147153 proof. as_bytes ( ) ,
148- public_inputs . as_bytes ( ) ,
154+ public_inputs_json . as_bytes ( ) ,
149155 )
150156 . wrap_err ( "failed to verify proof" ) ?;
151157
152158 if !is_proof_valid {
153- println ! ( "Proof is invalid" ) ;
159+ return Err ( eyre ! ( "invalid atomic-swap proof" ) ) ;
154160 }
155161
156- println ! ( ) ;
157- Ok ( is_proof_valid)
162+ let public_inputs: Vec < String > = serde_json:: from_str ( public_inputs_json. as_str ( ) ) ?;
163+ let swap_pubkey = parse_pubkey_from_pub_signals ( public_inputs) ?;
164+ println ! ( "{}" , swap_pubkey. to_string( ) ) ;
165+
166+ Ok ( ( ) )
158167 }
159168}
160169
@@ -183,20 +192,44 @@ fn main() -> Result<()> {
183192 let bob = SwapParticipant :: from_config ( "Bob" . to_string ( ) , & cfg, & cfg. bob_config , & secp_ctx)
184193 . wrap_err ( "failed to initialize Bob" ) ?;
185194
186- let ( proof, public_inputs) = alice. new_atomic_swap ( rng) ?;
195+ let ( proof, public_inputs) = alice. new_atomic_swap ( rng, & secp_ctx ) ?;
187196
188- let is_proof_valid = bob. accept_atomic_swap ( proof, public_inputs) ?;
189- if !is_proof_valid {
190- println ! ( "Atomic-swap failed" ) ;
191- }
197+ bob. accept_atomic_swap ( proof, public_inputs) ?;
192198
193199 Ok ( ( ) )
194200}
195201
202+ fn parse_pubkey_from_pub_signals ( pubsignals : Vec < String > ) -> Result < secp256k1:: PublicKey > {
203+ let key_x = parse_scalar_from_vec_str ( pubsignals[ 0 ..4 ] . to_vec ( ) ) ?;
204+ let key_y = parse_scalar_from_vec_str ( pubsignals[ 4 ..8 ] . to_vec ( ) ) ?;
205+
206+ // Public key prefix 0x04
207+ let mut key_raw = vec ! [ 0x4 ] ;
208+ key_raw. append ( & mut key_x. to_bytes_be ( ) . 1 . to_vec ( ) ) ;
209+ key_raw. append ( & mut key_y. to_bytes_be ( ) . 1 . to_vec ( ) ) ;
210+
211+ Ok ( secp256k1:: PublicKey :: from_str (
212+ hex:: encode ( key_raw. as_slice ( ) ) . as_str ( ) ,
213+ ) ?)
214+ }
215+
216+ fn parse_scalar_from_vec_str ( scalar_raw : Vec < String > ) -> Result < BigInt > {
217+ if scalar_raw. len ( ) != 4 {
218+ return Err ( eyre ! ( "invalid number of scalar parts to parse" ) ) ;
219+ }
220+
221+ let mut scalar_u64_array = [ 0u64 ; 4 ] ;
222+ for i in 0 ..4 {
223+ scalar_u64_array[ i] = u64:: from_str ( scalar_raw[ i] . as_str ( ) ) ?
224+ }
225+
226+ Ok ( u64array_to_u256 ( scalar_u64_array) )
227+ }
228+
196229fn u256_to_u64array ( mut input : BigInt ) -> Option < [ u64 ; 4 ] > {
197230 let mut result = [ 0u64 ; 4 ] ;
198231
199- let u64_max = BigInt :: from ( u64:: MAX ) ;
232+ let u64_max = BigInt :: from ( u64:: MAX ) + BigInt :: one ( ) ;
200233
201234 for x in result. iter_mut ( ) {
202235 let rem = input. clone ( ) % u64_max. clone ( ) ;
@@ -211,9 +244,22 @@ fn u256_to_u64array(mut input: BigInt) -> Option<[u64; 4]> {
211244 Some ( result)
212245}
213246
247+ fn u64array_to_u256 ( input : [ u64 ; 4 ] ) -> BigInt {
248+ let mut result = BigInt :: from ( input[ 3 ] ) ;
249+
250+ let u64_max = BigInt :: from ( u64:: MAX ) + BigInt :: one ( ) ;
251+
252+ for i in ( 0 ..=2 ) . rev ( ) {
253+ result = result. mul ( u64_max. clone ( ) ) ;
254+ result = result. add ( BigInt :: from ( input[ i] ) ) ;
255+ }
256+
257+ result
258+ }
259+
214260#[ cfg( test) ]
215261mod test {
216- use crate :: u256_to_u64array;
262+ use crate :: { u256_to_u64array, u64array_to_u256 } ;
217263 use num:: BigInt ;
218264 use std:: str:: FromStr ;
219265
@@ -225,28 +271,32 @@ mod test {
225271 )
226272 . unwrap ( ) ,
227273 vec ! [
228- 1015469868109144153 ,
229- 7042290186432306956 ,
230- 10826996139724932949 ,
231- 17982017980625340072 ,
274+ 5264901914485981690 ,
275+ 2440863701439358041 ,
276+ 12221174418977567583 ,
277+ 17982017980625340069 ,
232278 ] ,
233279 ) ;
234280 do_test_u256_to_u64array ( BigInt :: from_str ( "1" ) . unwrap ( ) , vec ! [ 1 , 0 , 0 , 0 ] ) ;
235281 do_test_u256_to_u64array ( BigInt :: from_str ( "0" ) . unwrap ( ) , vec ! [ 0 , 0 , 0 , 0 ] ) ;
236282 do_test_u256_to_u64array (
237283 BigInt :: from_str ( "9134136032198266807219851950679215" ) . unwrap ( ) ,
238- vec ! [ 5858704018890565205 , 495162506494374 , 0 , 0 ] ,
284+ vec ! [ 5858208856384070831 , 495162506494374 , 0 , 0 ] ,
239285 ) ;
240286 }
241287
242- fn do_test_u256_to_u64array ( input : BigInt , expect : Vec < u64 > ) {
243- assert_eq ! ( expect. len( ) , 4 ) ;
288+ fn do_test_u256_to_u64array ( expected_u256 : BigInt , expected_u64array : Vec < u64 > ) {
289+ assert_eq ! ( expected_u64array. len( ) , 4 ) ;
290+
291+ let u64array = u256_to_u64array ( expected_u256. clone ( ) ) . unwrap ( ) ;
292+
293+ assert_eq ! ( u64array[ 0 ] , expected_u64array[ 0 ] ) ;
294+ assert_eq ! ( u64array[ 1 ] , expected_u64array[ 1 ] ) ;
295+ assert_eq ! ( u64array[ 2 ] , expected_u64array[ 2 ] ) ;
296+ assert_eq ! ( u64array[ 3 ] , expected_u64array[ 3 ] ) ;
244297
245- let result = u256_to_u64array ( input ) . unwrap ( ) ;
298+ let u256 = u64array_to_u256 ( u64array ) ;
246299
247- assert_eq ! ( result[ 0 ] , expect[ 0 ] ) ;
248- assert_eq ! ( result[ 1 ] , expect[ 1 ] ) ;
249- assert_eq ! ( result[ 2 ] , expect[ 2 ] ) ;
250- assert_eq ! ( result[ 3 ] , expect[ 3 ] ) ;
300+ assert_eq ! ( u256, expected_u256) ;
251301 }
252302}
0 commit comments