@@ -4,7 +4,7 @@ use ckb_hash::blake2b_256;
44use ckb_jsonrpc_types as json_types;
55use ckb_jsonrpc_types:: Either ;
66use ckb_sdk:: rpc:: CkbRpcClient ;
7- use ckb_sphincs_utils:: SphincsPlus ;
7+ use ckb_sphincs_utils:: sphincsplus :: * ;
88use ckb_types:: {
99 bytes:: Bytes ,
1010 core:: { Capacity , DepType , ScriptHashType , TransactionBuilder , TransactionView } ,
@@ -126,13 +126,18 @@ pub fn sign_tx_by_input_group(
126126 . build ( )
127127}
128128
129- pub fn sign_tx_sphincs_plus ( tx : TransactionView , key : & SphincsPlus ) -> TransactionView {
129+ pub fn sign_tx_sphincs_plus (
130+ tx : TransactionView ,
131+ inputs : & [ ( CellOutput , Bytes ) ] ,
132+ key : & SphincsPlus ,
133+ ) -> TransactionView {
130134 let witnesses_len = tx. witnesses ( ) . len ( ) ;
131- sign_tx_by_input_group_sphincs_plus ( tx, key, 0 , witnesses_len)
135+ sign_tx_by_input_group_sphincs_plus ( tx, inputs , key, 0 , witnesses_len)
132136}
133137
134138pub fn sign_tx_by_input_group_sphincs_plus (
135139 tx : TransactionView ,
140+ inputs : & [ ( CellOutput , Bytes ) ] ,
136141 key : & SphincsPlus ,
137142 begin_index : usize ,
138143 len : usize ,
@@ -144,21 +149,35 @@ pub fn sign_tx_by_input_group_sphincs_plus(
144149 . enumerate ( )
145150 . map ( |( i, _) | {
146151 if i == begin_index {
147- let mut blake2b = ckb_hash:: new_blake2b ( ) ;
152+ let mut blake2b = ckb_hash:: Blake2bBuilder :: new ( 32 )
153+ . personal ( b"ckb-sphincs+-msg" )
154+ . build ( ) ;
148155 let mut message = [ 0u8 ; 32 ] ;
156+ // CKB_TX_MESSAGE_ALL process, see: https://github.com/nervosnetwork/rfcs/pull/446
149157 blake2b. update ( & tx_hash. raw_data ( ) ) ;
158+ // digest input cells
159+ for ( cell_output, cell_data) in inputs {
160+ blake2b. update ( cell_output. as_slice ( ) ) ;
161+
162+ blake2b. update ( & ( cell_data. len ( ) as u32 ) . to_le_bytes ( ) ) ;
163+ blake2b. update ( cell_data) ;
164+ }
150165 // digest the first witness
151166 let witness = WitnessArgs :: new_unchecked ( tx. witnesses ( ) . get ( i) . unwrap ( ) . unpack ( ) ) ;
152- let zero_lock: Bytes = vec ! [ 0 ; key. get_sign_len( ) + key. get_pk_len( ) ] . into ( ) ;
167+ let zero_lock: Bytes = vec ! [ 0 ; 5 + key. get_sign_len( ) + key. get_pk_len( ) ] . into ( ) ;
153168
154169 let witness_for_digest = witness
155170 . clone ( )
156171 . as_builder ( )
157172 . lock ( Some ( zero_lock) . pack ( ) )
158173 . build ( ) ;
159- let witness_len = witness_for_digest. as_bytes ( ) . len ( ) as u64 ;
160- blake2b. update ( & witness_len. to_le_bytes ( ) ) ;
161- blake2b. update ( & witness_for_digest. as_bytes ( ) ) ;
174+
175+ // digest the first witness
176+ blake2b. update ( & witness_for_digest. as_slice ( ) [ 0 ..16 ] ) ;
177+ blake2b. update ( witness_for_digest. input_type ( ) . as_slice ( ) ) ;
178+ blake2b. update ( witness_for_digest. output_type ( ) . as_slice ( ) ) ;
179+
180+ // digest the remaining witnesses
162181 ( ( i + 1 ) ..( i + len) ) . for_each ( |n| {
163182 let witness = tx. witnesses ( ) . get ( n) . unwrap ( ) ;
164183 let witness_len = witness. raw_data ( ) . len ( ) as u64 ;
@@ -169,10 +188,11 @@ pub fn sign_tx_by_input_group_sphincs_plus(
169188 let message = H256 :: from ( message) ;
170189
171190 let witness_data = {
172- let mut data = vec ! [ 0 ; key. get_sign_len( ) + key. get_pk_len( ) ] ;
191+ let mut data = vec ! [ 0 ; 5 + key. get_sign_len( ) + key. get_pk_len( ) ] ;
173192
174- data[ ..key. get_sign_len ( ) ] . copy_from_slice ( & key. sign ( message. as_bytes ( ) ) ) ;
175- data[ key. get_sign_len ( ) ..] . copy_from_slice ( & key. pk ) ;
193+ data[ 0 ..5 ] . copy_from_slice ( & single_sign_witness_prefix ( ) . unwrap ( ) ) ;
194+ data[ 5 ..key. get_sign_len ( ) + 5 ] . copy_from_slice ( & key. pk ) ;
195+ data[ key. get_sign_len ( ) + 5 ..] . copy_from_slice ( & key. sign ( message. as_bytes ( ) ) ) ;
176196
177197 Bytes :: from ( data)
178198 } ;
@@ -253,8 +273,18 @@ pub fn cc_to_sphincsplus(
253273 . witness ( witness_args. as_bytes ( ) . pack ( ) ) ;
254274
255275 // output cell
276+ let sphincs_args: Bytes = {
277+ let mut hasher = ckb_hash:: Blake2bBuilder :: new ( 32 )
278+ . personal ( b"ckb-sphincs+-sct" )
279+ . build ( ) ;
280+ hasher. update ( & single_sign_script_args_prefix ( ) . expect ( "prefix" ) ) ;
281+ hasher. update ( & key. pk ) ;
282+ let mut result = [ 0u8 ; 32 ] ;
283+ hasher. finalize ( & mut result) ;
284+ result. to_vec ( ) . into ( )
285+ } ;
256286 let output_script = Script :: new_builder ( )
257- . args ( Bytes :: from ( blake2b_256 ( & key . pk ) . to_vec ( ) ) . pack ( ) )
287+ . args ( sphincs_args . pack ( ) )
258288 . code_hash ( Byte32 :: from_slice ( & get_sphincsplus_code_hash ( ) ) . unwrap ( ) )
259289 . hash_type ( ScriptHashType :: Data1 . into ( ) )
260290 . build ( ) ;
@@ -310,15 +340,24 @@ pub fn cc_to_def_lock_script(
310340 . transaction
311341 . expect ( "input transaction is empty" ) ;
312342
313- let input_cell = {
343+ let ( input_cell, input_cell_data ) = {
314344 let tx = input_tx. inner ;
315345 match tx {
316- Either :: Left ( tx_view) => tx_view
317- . inner
318- . outputs
319- . get ( tx_index as usize )
320- . expect ( "input index invade" )
321- . clone ( ) ,
346+ Either :: Left ( tx_view) => (
347+ tx_view
348+ . inner
349+ . outputs
350+ . get ( tx_index as usize )
351+ . expect ( "input index invade" )
352+ . clone ( ) ,
353+ tx_view
354+ . inner
355+ . outputs_data
356+ . get ( tx_index as usize )
357+ . expect ( "input index invade" )
358+ . clone ( )
359+ . into_bytes ( ) ,
360+ ) ,
322361 Either :: Right ( _json_byte) => {
323362 panic ! ( "unsupport" )
324363 }
@@ -383,7 +422,7 @@ pub fn cc_to_def_lock_script(
383422 . output_data ( Bytes :: new ( ) . pack ( ) ) ;
384423
385424 let tx = tx_builder. build ( ) ;
386- let tx = sign_tx_sphincs_plus ( tx, & key) ;
425+ let tx = sign_tx_sphincs_plus ( tx, & [ ( input_cell . into ( ) , input_cell_data ) ] , & key) ;
387426
388427 println ! ( "tx hash: {:?}" , tx. hash( ) ) ;
389428 let outputs_validator = Some ( json_types:: OutputsValidator :: Passthrough ) ;
0 commit comments