1
1
//! Shared RISC-V intrinsics
2
+ mod p;
3
+
4
+ pub use p:: * ;
2
5
3
6
use crate :: arch:: asm;
4
7
@@ -602,12 +605,10 @@ pub unsafe fn hinval_gvma_all() {
602
605
/// According to RISC-V Cryptography Extensions, Volume I, the execution latency of
603
606
/// this instruction must always be independent from the data it operates on.
604
607
#[ inline]
608
+ #[ target_feature( enable = "zksh" ) ]
605
609
pub fn sm3p0 ( x : u32 ) -> u32 {
606
610
let ans: u32 ;
607
- unsafe {
608
- // asm!("sm3p0 {}, {}", out(reg) ans, in(reg) x, options(nomem, nostack))
609
- asm ! ( ".insn i 0x13, 0x1, {}, {}, 0x108" , out( reg) ans, in( reg) x, options( nomem, nostack) )
610
- } ;
611
+ unsafe { asm ! ( "sm3p0 {}, {}" , lateout( reg) ans, in( reg) x, options( pure, nomem, nostack) ) } ;
611
612
ans
612
613
}
613
614
@@ -634,12 +635,10 @@ pub fn sm3p0(x: u32) -> u32 {
634
635
/// According to RISC-V Cryptography Extensions, Volume I, the execution latency of
635
636
/// this instruction must always be independent from the data it operates on.
636
637
#[ inline]
638
+ #[ target_feature( enable = "zksh" ) ]
637
639
pub fn sm3p1 ( x : u32 ) -> u32 {
638
640
let ans: u32 ;
639
- unsafe {
640
- // asm!("sm3p1 {}, {}", out(reg) ans, in(reg) x, options(nomem, nostack))
641
- asm ! ( ".insn i 0x13, 0x1, {}, {}, 0x109" , out( reg) ans, in( reg) x, options( nomem, nostack) )
642
- } ;
641
+ unsafe { asm ! ( "sm3p1 {}, {}" , lateout( reg) ans, in( reg) x, options( pure, nomem, nostack) ) } ;
643
642
ans
644
643
}
645
644
@@ -674,33 +673,28 @@ pub fn sm3p1(x: u32) -> u32 {
674
673
/// It can be implemented by `sm4ed` instruction like:
675
674
///
676
675
/// ```no_run
676
+ /// # #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
677
+ /// # fn round_function(x0: u32, x1: u32, x2: u32, x3: u32, rk: u32) -> u32 {
678
+ /// # #[cfg(target_arch = "riscv32")] use core::arch::riscv32::sm4ed;
679
+ /// # #[cfg(target_arch = "riscv64")] use core::arch::riscv64::sm4ed;
677
680
/// let a = x1 ^ x2 ^ x3 ^ rk;
678
681
/// let c0 = sm4ed::<0>(x0, a);
679
682
/// let c1 = sm4ed::<1>(c0, a); // c1 represents c[0..=1], etc.
680
683
/// let c2 = sm4ed::<2>(c1, a);
681
684
/// let c3 = sm4ed::<3>(c2, a);
682
685
/// return c3; // c3 represents c[0..=3]
686
+ /// # }
683
687
/// ```
684
688
///
685
689
/// According to RISC-V Cryptography Extensions, Volume I, the execution latency of
686
690
/// this instruction must always be independent from the data it operates on.
691
+ #[ inline]
692
+ #[ target_feature( enable = "zksed" ) ]
687
693
pub fn sm4ed < const BS : u8 > ( x : u32 , a : u32 ) -> u32 {
688
694
static_assert ! ( BS : u8 where BS <= 3 ) ;
689
695
let ans: u32 ;
690
- match BS {
691
- 0 => unsafe {
692
- asm ! ( ".insn r 0x33, 0, 0x18, {}, {}, {}" , out( reg) ans, in( reg) x, in( reg) a, options( nomem, nostack) )
693
- } ,
694
- 1 => unsafe {
695
- asm ! ( ".insn r 0x33, 0, 0x38, {}, {}, {}" , out( reg) ans, in( reg) x, in( reg) a, options( nomem, nostack) )
696
- } ,
697
- 2 => unsafe {
698
- asm ! ( ".insn r 0x33, 0, 0x58, {}, {}, {}" , out( reg) ans, in( reg) x, in( reg) a, options( nomem, nostack) )
699
- } ,
700
- 3 => unsafe {
701
- asm ! ( ".insn r 0x33, 0, 0x78, {}, {}, {}" , out( reg) ans, in( reg) x, in( reg) a, options( nomem, nostack) )
702
- } ,
703
- _ => unreachable ! ( ) ,
696
+ unsafe {
697
+ asm ! ( "sm4ed {}, {}, {}, {}" , lateout( reg) ans, in( reg) x, in( reg) k, const BS , options( pure, nomem, nostack) )
704
698
} ;
705
699
ans
706
700
}
@@ -739,33 +733,28 @@ pub fn sm4ed<const BS: u8>(x: u32, a: u32) -> u32 {
739
733
/// Hence, the key schedule operation can be implemented by `sm4ks` instruction like:
740
734
///
741
735
/// ```no_run
736
+ /// # #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
737
+ /// # fn key_schedule(k0: u32, k1: u32, k2: u32, k3: u32, ck_i: u32) -> u32 {
738
+ /// # #[cfg(target_arch = "riscv32")] use core::arch::riscv32::sm4ks;
739
+ /// # #[cfg(target_arch = "riscv64")] use core::arch::riscv64::sm4ks;
742
740
/// let k = k1 ^ k2 ^ k3 ^ ck_i;
743
741
/// let c0 = sm4ks::<0>(k0, k);
744
742
/// let c1 = sm4ks::<1>(c0, k); // c1 represents c[0..=1], etc.
745
743
/// let c2 = sm4ks::<2>(c1, k);
746
744
/// let c3 = sm4ks::<3>(c2, k);
747
745
/// return c3; // c3 represents c[0..=3]
746
+ /// # }
748
747
/// ```
749
748
///
750
749
/// According to RISC-V Cryptography Extensions, Volume I, the execution latency of
751
750
/// this instruction must always be independent from the data it operates on.
751
+ #[ inline]
752
+ #[ target_feature( enable = "zksed" ) ]
752
753
pub fn sm4ks < const BS : u8 > ( x : u32 , k : u32 ) -> u32 {
753
754
static_assert ! ( BS : u8 where BS <= 3 ) ;
754
755
let ans: u32 ;
755
- match BS {
756
- 0 => unsafe {
757
- asm ! ( ".insn r 0x33, 0, 0x1A, {}, {}, {}" , out( reg) ans, in( reg) x, in( reg) k, options( nomem, nostack) )
758
- } ,
759
- 1 => unsafe {
760
- asm ! ( ".insn r 0x33, 0, 0x3A, {}, {}, {}" , out( reg) ans, in( reg) x, in( reg) k, options( nomem, nostack) )
761
- } ,
762
- 2 => unsafe {
763
- asm ! ( ".insn r 0x33, 0, 0x5A, {}, {}, {}" , out( reg) ans, in( reg) x, in( reg) k, options( nomem, nostack) )
764
- } ,
765
- 3 => unsafe {
766
- asm ! ( ".insn r 0x33, 0, 0x7A, {}, {}, {}" , out( reg) ans, in( reg) x, in( reg) k, options( nomem, nostack) )
767
- } ,
768
- _ => unreachable ! ( ) ,
756
+ unsafe {
757
+ asm ! ( "sm4ks {}, {}, {}, {}" , lateout( reg) ans, in( reg) x, in( reg) k, const BS , options( pure, nomem, nostack) )
769
758
} ;
770
759
ans
771
760
}
0 commit comments