@@ -456,24 +456,163 @@ fn test_omnilock_owner_lock_tranfer(cobuild: bool) {
456456 ctx. verify ( tx, FEE_RATE ) . unwrap ( ) ;
457457}
458458
459+ #[ cfg( unix) ]
460+ mod rsa_dl_test {
461+ use super :: test_omnilock_dl_exec;
462+ use crate :: {
463+ tests:: build_rsa_script_dl,
464+ traits:: { Signer , SignerError } ,
465+ unlock:: omni_lock:: { ExecDlConfig , Preimage } ,
466+ util:: blake160,
467+ } ;
468+
469+ use ckb_types:: core:: TransactionView ;
470+ use openssl:: {
471+ hash:: MessageDigest ,
472+ pkey:: { PKey , Private , Public } ,
473+ rsa:: Rsa ,
474+ sign:: Signer as RSASigner ,
475+ } ;
476+
477+ #[ derive( Clone ) ]
478+ struct RSASinger {
479+ key : PKey < Private > ,
480+ }
481+
482+ impl Signer for RSASinger {
483+ fn match_id ( & self , id : & [ u8 ] ) -> bool {
484+ let rsa_script = build_rsa_script_dl ( ) ;
485+ let public_key_pem: Vec < u8 > = self . key . public_key_to_pem ( ) . unwrap ( ) ;
486+ let rsa_pubkey = PKey :: public_key_from_pem ( & public_key_pem) . unwrap ( ) ;
487+ let signning_pubkey = rsa_signning_prepare_pubkey ( & rsa_pubkey) ;
488+
489+ let preimage = Preimage :: new_with_dl ( rsa_script, blake160 ( & signning_pubkey) ) ;
490+ id. len ( ) == 20 && id == preimage. auth ( ) . as_bytes ( )
491+ }
492+
493+ fn sign (
494+ & self ,
495+ id : & [ u8 ] ,
496+ message : & [ u8 ] ,
497+ _recoverable : bool ,
498+ _tx : & TransactionView ,
499+ ) -> Result < bytes:: Bytes , SignerError > {
500+ if !self . match_id ( id) {
501+ return Err ( SignerError :: IdNotFound ) ;
502+ }
503+ Ok ( bytes:: Bytes :: from ( rsa_sign ( message, & self . key ) ) )
504+ }
505+ }
506+
507+ fn rsa_signning_prepare_pubkey ( pubkey : & PKey < Public > ) -> Vec < u8 > {
508+ let mut sig = vec ! [
509+ 1 , // algorithm id
510+ 1 , // key size, 1024
511+ 0 , // padding, PKCS# 1.5
512+ 6 , // hash type SHA256
513+ ] ;
514+
515+ let pubkey2 = pubkey. rsa ( ) . unwrap ( ) ;
516+ let mut e = pubkey2. e ( ) . to_vec ( ) ;
517+ let mut n = pubkey2. n ( ) . to_vec ( ) ;
518+ e. reverse ( ) ;
519+ n. reverse ( ) ;
520+
521+ while e. len ( ) < 4 {
522+ e. push ( 0 ) ;
523+ }
524+ while n. len ( ) < 128 {
525+ n. push ( 0 ) ;
526+ }
527+ sig. append ( & mut e) ; // 4 bytes E
528+ sig. append ( & mut n) ; // N
529+
530+ sig
531+ }
532+
533+ pub fn rsa_sign ( msg : & [ u8 ] , key : & PKey < Private > ) -> Vec < u8 > {
534+ let pem: Vec < u8 > = key. public_key_to_pem ( ) . unwrap ( ) ;
535+ let pubkey = PKey :: public_key_from_pem ( & pem) . unwrap ( ) ;
536+
537+ let mut sig = rsa_signning_prepare_pubkey ( & pubkey) ;
538+
539+ let mut signer = RSASigner :: new ( MessageDigest :: sha256 ( ) , key) . unwrap ( ) ;
540+ signer. update ( msg) . unwrap ( ) ;
541+ sig. extend ( signer. sign_to_vec ( ) . unwrap ( ) ) ; // sig
542+
543+ sig
544+ }
545+
546+ #[ test]
547+ fn test_omnilock_dl ( ) {
548+ let rsa_script = build_rsa_script_dl ( ) ;
549+ let bits = 1024 ;
550+ let rsa = Rsa :: generate ( bits) . unwrap ( ) ;
551+ let rsa_private_key = PKey :: from_rsa ( rsa) . unwrap ( ) ;
552+ let public_key_pem: Vec < u8 > = rsa_private_key. public_key_to_pem ( ) . unwrap ( ) ;
553+ let rsa_pubkey = PKey :: public_key_from_pem ( & public_key_pem) . unwrap ( ) ;
554+ let signning_pubkey = rsa_signning_prepare_pubkey ( & rsa_pubkey) ;
555+
556+ let preimage = Preimage :: new_with_dl ( rsa_script, blake160 ( & signning_pubkey) ) ;
557+ let config = ExecDlConfig :: new ( preimage, 264 ) ;
558+ let signer = RSASinger {
559+ key : rsa_private_key,
560+ } ;
561+ test_omnilock_dl_exec ( config. clone ( ) , signer. clone ( ) , false ) ;
562+ test_omnilock_dl_exec ( config, signer. clone ( ) , true ) ;
563+ }
564+ }
565+
459566#[ derive( Clone ) ]
460567struct DummySinger { }
461568
462569impl Signer for DummySinger {
463570 fn match_id ( & self , id : & [ u8 ] ) -> bool {
464- let always_success_script = build_always_success_script ( ) ;
465- let preimage =
466- Preimage :: new_with_exec ( always_success_script, 0 , [ 0 ; 8 ] , blake160 ( & [ 0u8 ; 20 ] ) ) ;
467- id. len ( ) == 20 && id == preimage. auth ( ) . as_bytes ( )
571+ let ( preimage, preimage_dl) = if cfg ! ( unix) {
572+ let always_success_script = build_always_success_script ( ) ;
573+
574+ (
575+ Preimage :: new_with_exec (
576+ always_success_script. clone ( ) ,
577+ 0 ,
578+ [ 0 ; 8 ] ,
579+ blake160 ( & [ 0u8 ; 20 ] ) ,
580+ ) ,
581+ Preimage :: new_with_exec ( always_success_script, 0 , [ 0 ; 8 ] , blake160 ( & [ 0u8 ; 20 ] ) ) ,
582+ )
583+ } else {
584+ #[ cfg( not( unix) ) ]
585+ {
586+ use crate :: tests:: build_always_success_dl_script;
587+ let always_success_script_dl = build_always_success_dl_script ( ) ;
588+ let always_success_script = build_always_success_script ( ) ;
589+ (
590+ Preimage :: new_with_exec (
591+ always_success_script. clone ( ) ,
592+ 0 ,
593+ [ 0 ; 8 ] ,
594+ blake160 ( & [ 0u8 ; 20 ] ) ,
595+ ) ,
596+ Preimage :: new_with_dl ( always_success_script_dl, H160 :: from ( [ 0u8 ; 20 ] ) ) ,
597+ )
598+ }
599+ #[ cfg( unix) ]
600+ unreachable ! ( )
601+ } ;
602+
603+ id. len ( ) == 20 && ( id == preimage. auth ( ) . as_bytes ( ) || id == preimage_dl. auth ( ) . as_bytes ( ) )
468604 }
469605
470606 fn sign (
471607 & self ,
472- _id : & [ u8 ] ,
608+ id : & [ u8 ] ,
473609 _message : & [ u8 ] ,
474610 _recoverable : bool ,
475611 _tx : & TransactionView ,
476612 ) -> Result < bytes:: Bytes , SignerError > {
613+ if !self . match_id ( id) {
614+ return Err ( SignerError :: IdNotFound ) ;
615+ }
477616 Ok ( bytes:: Bytes :: from ( vec ! [ 0 ; 65 ] ) )
478617 }
479618}
@@ -484,34 +623,63 @@ fn test_omnilock_exec() {
484623 let preimage = Preimage :: new_with_exec ( always_success_script, 0 , [ 0 ; 8 ] , blake160 ( & [ 0u8 ; 20 ] ) ) ;
485624 let config = ExecDlConfig :: new ( preimage, 65 ) ;
486625
487- test_omnilock_dl_exec ( config. clone ( ) , false ) ;
488- test_omnilock_dl_exec ( config, true )
626+ test_omnilock_dl_exec ( config. clone ( ) , DummySinger { } , false ) ;
627+ test_omnilock_dl_exec ( config, DummySinger { } , true )
489628}
490629
491- #[ ignore ]
630+ #[ cfg ( not ( unix ) ) ]
492631#[ test]
493632fn test_omnilock_dl ( ) {
494- // let always_success_script = build_always_success_script_dl();
495- // let preimage = Preimage::new_with_dl(always_success_script, blake160(&[0u8; 20]));
496- // test_omnilock_dl_exec(preimage)
633+ use crate :: tests:: build_always_success_dl_script;
634+ let always_success_script = build_always_success_dl_script ( ) ;
635+ let preimage = Preimage :: new_with_dl ( always_success_script, H160 :: from ( [ 0u8 ; 20 ] ) ) ;
636+ let config = ExecDlConfig :: new ( preimage, 65 ) ;
637+
638+ test_omnilock_dl_exec ( config. clone ( ) , DummySinger { } , false ) ;
639+ test_omnilock_dl_exec ( config, DummySinger { } , true )
497640}
498641
499- fn test_omnilock_dl_exec ( config : ExecDlConfig , cobuild : bool ) {
642+ #[ cfg( unix) ]
643+ fn dl_exec_cfg ( config : ExecDlConfig ) -> ( OmniLockConfig , & ' static [ u8 ] ) {
644+ use crate :: tests:: RSA_DL_BIN ;
645+ if config. preimage ( ) . len ( ) == 32 + 1 + 1 + 8 + 20 {
646+ (
647+ OmniLockConfig :: new_with_exec_preimage ( config) ,
648+ ALWAYS_SUCCESS_BIN ,
649+ )
650+ } else {
651+ ( OmniLockConfig :: new_with_dl_preimage ( config) , RSA_DL_BIN )
652+ }
653+ }
654+
655+ #[ cfg( not( unix) ) ]
656+ fn dl_exec_cfg ( config : ExecDlConfig ) -> ( OmniLockConfig , & ' static [ u8 ] ) {
657+ use crate :: tests:: ALWAYS_SUCCESS_DL_BIN ;
658+ if config. preimage ( ) . len ( ) == 32 + 1 + 1 + 8 + 20 {
659+ (
660+ OmniLockConfig :: new_with_exec_preimage ( config) ,
661+ ALWAYS_SUCCESS_BIN ,
662+ )
663+ } else {
664+ (
665+ OmniLockConfig :: new_with_dl_preimage ( config) ,
666+ ALWAYS_SUCCESS_DL_BIN ,
667+ )
668+ }
669+ }
670+
671+ fn test_omnilock_dl_exec < T : Signer + ' static > ( config : ExecDlConfig , signer : T , cobuild : bool ) {
500672 let network_info = NetworkInfo :: testnet ( ) ;
501673 let receiver = build_sighash_script ( ACCOUNT2_ARG ) ;
502674
503- let mut cfg = if config. preimage ( ) . len ( ) == 32 + 1 + 1 + 8 + 20 {
504- OmniLockConfig :: new_with_exec_preimage ( config)
505- } else {
506- OmniLockConfig :: new_with_dl_preimage ( config)
507- } ;
675+ let ( mut cfg, bin) = dl_exec_cfg ( config) ;
508676
509677 cfg. enable_cobuild ( cobuild) ;
510678 let sender = build_omnilock_script ( & cfg) ;
511- let sign_context = SignContexts :: new_omnilock_exec_dl_custom ( DummySinger { } , cfg. clone ( ) ) ;
679+ let sign_context = SignContexts :: new_omnilock_exec_dl_custom ( signer , cfg. clone ( ) ) ;
512680
513681 let ( ctx, outpoints) = init_context (
514- vec ! [ ( OMNILOCK_BIN , true ) , ( ALWAYS_SUCCESS_BIN , true ) ] ,
682+ vec ! [ ( OMNILOCK_BIN , true ) , ( bin , true ) ] ,
515683 vec ! [ ( sender. clone( ) , Some ( 300 * ONE_CKB ) ) ] ,
516684 ) ;
517685
0 commit comments