2022-07-15 16:42:39 +08:00
package sm9
import (
2025-03-13 13:46:14 +08:00
"bytes"
2022-07-15 16:42:39 +08:00
"crypto/rand"
"encoding/hex"
"testing"
)
func TestSignASN1 ( t * testing . T ) {
masterKey , err := GenerateSignMasterKey ( rand . Reader )
hashed := [ ] byte ( "Chinese IBS standard" )
uid := [ ] byte ( "emmansun" )
hid := byte ( 0x01 )
if err != nil {
t . Fatal ( err )
}
userKey , err := masterKey . GenerateUserKey ( uid , hid )
if err != nil {
t . Fatal ( err )
}
2022-11-28 10:55:23 +08:00
sig , err := userKey . Sign ( rand . Reader , hashed , nil )
2022-07-15 16:42:39 +08:00
if err != nil {
t . Fatal ( err )
}
2022-11-28 10:55:23 +08:00
if ! masterKey . Public ( ) . Verify ( uid , hid , hashed , sig ) {
2022-07-15 16:42:39 +08:00
t . Errorf ( "Verify failed" )
}
2022-12-02 15:49:48 +08:00
sig [ 0 ] = 0xff
if masterKey . Public ( ) . Verify ( uid , hid , hashed , sig ) {
t . Errorf ( "Verify with invalid asn1 format successed" )
}
}
func TestParseInvalidASN1 ( t * testing . T ) {
tests := [ ] struct {
name string
sigHex string
} {
// TODO: Add test cases.
{ "invalid point format" , "30660420723a8b38dd2441c2aa1c3ec092eaa34996c53bf9ca7515272395c012ab6e6e070342000C389fc45b711d9dfd9d91958f64d89d3528cf577c6dc2bc792c2969188e76865e16c2d85419f8f923a0e77c7f269c0eeb97b6c4d7e2735189180ec719a380fe1d" } ,
{ "invalid point encoding length" , "30660420723a8b38dd2441c2aa1c3ec092eaa34996c53bf9ca7515272395c012ab6e6e0703420004389fc45b711d9dfd9d91958f64d89d3528cf577c6dc2bc792c2969188e76865e16c2d85419f8f923a0e77c7f269c0eeb97b6c4d7e2735189180ec719a380fe" } ,
}
for _ , tt := range tests {
sig , err := hex . DecodeString ( tt . sigHex )
if err != nil {
t . Fatal ( err )
}
_ , _ , err = parseSignature ( sig )
if err == nil {
t . Errorf ( "%s should be failed" , tt . name )
}
}
2022-07-15 16:42:39 +08:00
}
2025-03-13 13:46:14 +08:00
func TestWrapKey ( t * testing . T ) {
masterKey , err := GenerateEncryptMasterKey ( rand . Reader )
2022-07-15 16:42:39 +08:00
hid := byte ( 0x01 )
2025-03-13 13:46:14 +08:00
uid := [ ] byte ( "emmansun" )
2022-11-25 10:11:46 +08:00
if err != nil {
t . Fatal ( err )
}
2022-07-15 16:42:39 +08:00
userKey , err := masterKey . GenerateUserKey ( uid , hid )
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
key , cipher , err := masterKey . Public ( ) . WrapKey ( rand . Reader , uid , hid , 16 )
2022-11-25 10:11:46 +08:00
if err != nil {
t . Fatal ( err )
}
2022-07-15 16:42:39 +08:00
2025-03-13 13:46:14 +08:00
key2 , err := userKey . UnwrapKey ( uid , cipher , 16 )
2022-11-25 10:11:46 +08:00
if err != nil {
t . Fatal ( err )
}
2022-07-15 16:42:39 +08:00
2025-03-13 13:46:14 +08:00
if ! bytes . Equal ( key , key2 ) {
t . Errorf ( "expected %x, got %x" , key , key2 )
2022-07-15 16:42:39 +08:00
}
}
2025-03-13 13:46:14 +08:00
func TestWrapKeyASN1 ( t * testing . T ) {
2022-08-03 16:31:02 +08:00
masterKey , err := GenerateEncryptMasterKey ( rand . Reader )
2025-03-13 13:46:14 +08:00
hid := byte ( 0x01 )
uid := [ ] byte ( "emmansun" )
2022-08-03 16:31:02 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
userKey , err := masterKey . GenerateUserKey ( uid , hid )
2022-08-03 16:31:02 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
keyPackage , err := masterKey . Public ( ) . WrapKeyASN1 ( rand . Reader , uid , hid , 16 )
2022-08-03 16:31:02 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
key1 , cipher , err := UnmarshalSM9KeyPackage ( keyPackage )
2022-08-03 16:31:02 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
key2 , err := UnwrapKey ( userKey , uid , cipher , 16 )
2022-08-03 16:31:02 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
if ! bytes . Equal ( key1 , key2 ) {
t . Errorf ( "expected %x, got %x" , key1 , key2 )
2022-08-03 16:31:02 +08:00
}
}
2025-03-13 13:46:14 +08:00
func TestEncryptDecrypt ( t * testing . T ) {
plaintext := [ ] byte ( "Chinese IBE standard" )
2022-08-17 11:36:50 +08:00
masterKey , err := GenerateEncryptMasterKey ( rand . Reader )
2025-03-13 13:46:14 +08:00
hid := byte ( 0x01 )
uid := [ ] byte ( "emmansun" )
2022-08-17 11:36:50 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
userKey , err := masterKey . GenerateUserKey ( uid , hid )
2022-08-17 11:36:50 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
encTypes := [ ] EncrypterOpts {
DefaultEncrypterOpts , SM4ECBEncrypterOpts , SM4CBCEncrypterOpts , SM4CFBEncrypterOpts , SM4OFBEncrypterOpts ,
2022-08-17 11:36:50 +08:00
}
2025-03-13 13:46:14 +08:00
for _ , opts := range encTypes {
cipher , err := Encrypt ( rand . Reader , masterKey . Public ( ) , uid , hid , plaintext , opts )
if err != nil {
t . Fatal ( err )
}
2022-08-17 11:36:50 +08:00
2025-03-13 13:46:14 +08:00
got , err := Decrypt ( userKey , uid , cipher , opts )
if err != nil {
t . Fatal ( err )
}
if string ( got ) != string ( plaintext ) {
t . Errorf ( "expected %v, got %v\n" , string ( plaintext ) , string ( got ) )
}
2022-08-17 11:36:50 +08:00
2025-03-13 13:46:14 +08:00
got , err = userKey . Decrypt ( uid , cipher , opts )
if err != nil {
t . Fatalf ( "encType %v, first byte %x, %v" , opts . GetEncryptType ( ) , cipher [ 0 ] , err )
}
2022-08-24 15:15:58 +08:00
2025-03-13 13:46:14 +08:00
if string ( got ) != string ( plaintext ) {
t . Errorf ( "expected %v, got %v\n" , string ( plaintext ) , string ( got ) )
}
2022-08-17 11:36:50 +08:00
}
}
2025-03-13 13:46:14 +08:00
func TestEncryptEmptyPlaintext ( t * testing . T ) {
2022-07-15 16:42:39 +08:00
masterKey , err := GenerateEncryptMasterKey ( rand . Reader )
hid := byte ( 0x01 )
uid := [ ] byte ( "emmansun" )
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
encTypes := [ ] EncrypterOpts {
DefaultEncrypterOpts , SM4ECBEncrypterOpts , SM4CBCEncrypterOpts , SM4CFBEncrypterOpts , SM4OFBEncrypterOpts ,
2022-07-15 16:42:39 +08:00
}
2025-03-13 13:46:14 +08:00
for _ , opts := range encTypes {
_ , err := Encrypt ( rand . Reader , masterKey . Public ( ) , uid , hid , nil , opts )
if err != ErrEmptyPlaintext {
t . Fatalf ( "should be ErrEmptyPlaintext" )
}
2022-07-15 16:42:39 +08:00
}
}
2025-03-13 13:46:14 +08:00
func TestEncryptDecryptASN1 ( t * testing . T ) {
plaintext := [ ] byte ( "Chinese IBE standard" )
2022-07-15 16:42:39 +08:00
masterKey , err := GenerateEncryptMasterKey ( rand . Reader )
hid := byte ( 0x01 )
uid := [ ] byte ( "emmansun" )
if err != nil {
t . Fatal ( err )
}
userKey , err := masterKey . GenerateUserKey ( uid , hid )
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
encTypes := [ ] EncrypterOpts {
DefaultEncrypterOpts , SM4ECBEncrypterOpts , SM4CBCEncrypterOpts , SM4CFBEncrypterOpts , SM4OFBEncrypterOpts ,
2022-07-15 16:42:39 +08:00
}
2025-03-13 13:46:14 +08:00
for _ , opts := range encTypes {
cipher , err := EncryptASN1 ( rand . Reader , masterKey . Public ( ) , uid , hid , plaintext , opts )
if err != nil {
t . Fatal ( err )
}
2022-07-15 16:42:39 +08:00
2025-03-13 13:46:14 +08:00
got , err := DecryptASN1 ( userKey , uid , cipher )
if err != nil {
t . Fatal ( err )
}
2022-07-15 16:42:39 +08:00
2025-03-13 13:46:14 +08:00
if string ( got ) != string ( plaintext ) {
t . Errorf ( "expected %v, got %v\n" , string ( plaintext ) , string ( got ) )
}
2023-02-03 15:13:02 +08:00
2025-03-13 13:46:14 +08:00
got , err = userKey . DecryptASN1 ( uid , cipher )
if err != nil {
t . Fatal ( err )
}
if string ( got ) != string ( plaintext ) {
t . Errorf ( "expected %v, got %v\n" , string ( plaintext ) , string ( got ) )
}
2022-07-15 16:42:39 +08:00
}
}
func TestUnmarshalSM9KeyPackage ( t * testing . T ) {
masterKey , err := GenerateEncryptMasterKey ( rand . Reader )
hid := byte ( 0x01 )
uid := [ ] byte ( "emmansun" )
if err != nil {
t . Fatal ( err )
}
userKey , err := masterKey . GenerateUserKey ( uid , hid )
if err != nil {
t . Fatal ( err )
}
p , err := masterKey . Public ( ) . WrapKeyASN1 ( rand . Reader , uid , hid , 16 )
if err != nil {
t . Fatal ( err )
}
key , cipher , err := UnmarshalSM9KeyPackage ( p )
if err != nil {
t . Fatal ( err )
}
key2 , err := UnwrapKey ( userKey , uid , cipher , 16 )
if err != nil {
t . Fatal ( err )
}
if hex . EncodeToString ( key ) != hex . EncodeToString ( key2 ) {
t . Errorf ( "expected %v, got %v\n" , hex . EncodeToString ( key ) , hex . EncodeToString ( key2 ) )
}
}
2025-03-13 13:46:14 +08:00
func TestKeyExchange ( t * testing . T ) {
hid := byte ( 0x02 )
userA := [ ] byte ( "Alice" )
userB := [ ] byte ( "Bob" )
masterKey , err := GenerateEncryptMasterKey ( rand . Reader )
2022-11-25 10:11:46 +08:00
if err != nil {
t . Fatal ( err )
}
2022-07-15 16:42:39 +08:00
2025-03-13 13:46:14 +08:00
userKey , err := masterKey . GenerateUserKey ( userA , hid )
2022-07-15 16:42:39 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
initiator := userKey . NewKeyExchange ( userA , userB , 16 , true )
2022-07-15 16:42:39 +08:00
2025-03-13 13:46:14 +08:00
userKey , err = masterKey . GenerateUserKey ( userB , hid )
2022-11-25 10:11:46 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
responder := userKey . NewKeyExchange ( userB , userA , 16 , true )
defer func ( ) {
initiator . Destroy ( )
responder . Destroy ( )
} ( )
// A1-A4
rA , err := initiator . InitKeyExchange ( rand . Reader , hid )
2022-07-15 16:42:39 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
// B1 - B7
rB , sigB , err := responder . RespondKeyExchange ( rand . Reader , hid , rA )
2022-11-25 10:11:46 +08:00
if err != nil {
t . Fatal ( err )
}
2022-07-15 16:42:39 +08:00
2025-03-13 13:46:14 +08:00
// A5 -A8
key1 , sigA , err := initiator . ConfirmResponder ( rB , sigB )
2022-07-15 16:42:39 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
// B8
key2 , err := responder . ConfirmInitiator ( sigA )
2022-11-25 10:11:46 +08:00
if err != nil {
t . Fatal ( err )
}
2022-07-15 16:42:39 +08:00
2025-03-13 13:46:14 +08:00
if hex . EncodeToString ( key1 ) != hex . EncodeToString ( key2 ) {
t . Errorf ( "got different key" )
2022-07-15 16:42:39 +08:00
}
}
2025-03-13 13:46:14 +08:00
func TestKeyExchangeWithoutSignature ( t * testing . T ) {
hid := byte ( 0x02 )
userA := [ ] byte ( "Alice" )
userB := [ ] byte ( "Bob" )
masterKey , err := GenerateEncryptMasterKey ( rand . Reader )
2023-02-13 14:36:34 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
userKey , err := masterKey . GenerateUserKey ( userA , hid )
2023-02-13 14:36:34 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
initiator := userKey . NewKeyExchange ( userA , userB , 16 , false )
2023-02-13 14:36:34 +08:00
2025-03-13 13:46:14 +08:00
userKey , err = masterKey . GenerateUserKey ( userB , hid )
2023-02-13 14:36:34 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
responder := userKey . NewKeyExchange ( userB , userA , 16 , false )
defer func ( ) {
initiator . Destroy ( )
responder . Destroy ( )
} ( )
// A1-A4
rA , err := initiator . InitKeyExchange ( rand . Reader , hid )
2023-02-13 14:36:34 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
// B1 - B7
rB , sigB , err := responder . RespondKeyExchange ( rand . Reader , hid , rA )
2022-07-15 16:42:39 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
if len ( sigB ) != 0 {
t . Errorf ( "should no signature" )
2022-07-15 16:42:39 +08:00
}
2025-03-13 13:46:14 +08:00
// A5 -A8
key1 , sigA , err := initiator . ConfirmResponder ( rB , sigB )
2023-02-14 10:45:02 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
if len ( sigA ) != 0 {
t . Errorf ( "should no signature" )
2023-02-14 10:45:02 +08:00
}
2025-03-13 13:46:14 +08:00
key2 , err := responder . ConfirmInitiator ( nil )
2022-07-15 16:42:39 +08:00
if err != nil {
t . Fatal ( err )
}
2025-03-13 13:46:14 +08:00
if hex . EncodeToString ( key1 ) != hex . EncodeToString ( key2 ) {
t . Errorf ( "got different key" )
2022-07-15 16:42:39 +08:00
}
}
func BenchmarkSign ( b * testing . B ) {
hashed := [ ] byte ( "Chinese IBS standard" )
uid := [ ] byte ( "emmansun" )
hid := byte ( 0x01 )
masterKey , err := GenerateSignMasterKey ( rand . Reader )
if err != nil {
b . Fatal ( err )
}
userKey , err := masterKey . GenerateUserKey ( uid , hid )
if err != nil {
b . Fatal ( err )
}
SignASN1 ( rand . Reader , userKey , hashed ) // fire precompute
b . ReportAllocs ( )
b . ResetTimer ( )
for i := 0 ; i < b . N ; i ++ {
sig , err := SignASN1 ( rand . Reader , userKey , hashed )
if err != nil {
b . Fatal ( err )
}
// Prevent the compiler from optimizing out the operation.
hashed [ 0 ] = sig [ 0 ]
}
}
func BenchmarkVerify ( b * testing . B ) {
hashed := [ ] byte ( "Chinese IBS standard" )
uid := [ ] byte ( "emmansun" )
hid := byte ( 0x01 )
masterKey , err := GenerateSignMasterKey ( rand . Reader )
if err != nil {
b . Fatal ( err )
}
userKey , err := masterKey . GenerateUserKey ( uid , hid )
if err != nil {
b . Fatal ( err )
}
sig , err := SignASN1 ( rand . Reader , userKey , hashed )
if err != nil {
b . Fatal ( err )
}
b . ReportAllocs ( )
b . ResetTimer ( )
for i := 0 ; i < b . N ; i ++ {
if ! VerifyASN1 ( masterKey . Public ( ) , uid , hid , hashed , sig ) {
b . Fatal ( "verify failed" )
}
}
}
func BenchmarkEncrypt ( b * testing . B ) {
plaintext := [ ] byte ( "Chinese IBE standard" )
masterKey , err := GenerateEncryptMasterKey ( rand . Reader )
hid := byte ( 0x01 )
uid := [ ] byte ( "emmansun" )
if err != nil {
b . Fatal ( err )
}
b . ReportAllocs ( )
b . ResetTimer ( )
for i := 0 ; i < b . N ; i ++ {
2023-02-10 17:19:50 +08:00
cipher , err := Encrypt ( rand . Reader , masterKey . Public ( ) , uid , hid , plaintext , nil )
2022-07-15 16:42:39 +08:00
if err != nil {
b . Fatal ( err )
}
// Prevent the compiler from optimizing out the operation.
plaintext [ 0 ] = cipher [ 0 ]
}
}
func BenchmarkDecrypt ( b * testing . B ) {
plaintext := [ ] byte ( "Chinese IBE standard" )
masterKey , err := GenerateEncryptMasterKey ( rand . Reader )
hid := byte ( 0x01 )
uid := [ ] byte ( "emmansun" )
if err != nil {
b . Fatal ( err )
}
userKey , err := masterKey . GenerateUserKey ( uid , hid )
if err != nil {
b . Fatal ( err )
}
2023-02-10 17:19:50 +08:00
cipher , err := Encrypt ( rand . Reader , masterKey . Public ( ) , uid , hid , plaintext , nil )
2022-07-15 16:42:39 +08:00
if err != nil {
b . Fatal ( err )
}
b . ReportAllocs ( )
b . ResetTimer ( )
for i := 0 ; i < b . N ; i ++ {
2023-02-10 17:19:50 +08:00
got , err := Decrypt ( userKey , uid , cipher , nil )
2022-07-15 16:42:39 +08:00
if err != nil {
b . Fatal ( err )
}
if string ( got ) != string ( plaintext ) {
b . Errorf ( "expected %v, got %v\n" , string ( plaintext ) , string ( got ) )
}
}
}
func BenchmarkDecryptASN1 ( b * testing . B ) {
plaintext := [ ] byte ( "Chinese IBE standard" )
masterKey , err := GenerateEncryptMasterKey ( rand . Reader )
hid := byte ( 0x01 )
uid := [ ] byte ( "emmansun" )
if err != nil {
b . Fatal ( err )
}
userKey , err := masterKey . GenerateUserKey ( uid , hid )
if err != nil {
b . Fatal ( err )
}
2023-02-10 17:19:50 +08:00
cipher , err := EncryptASN1 ( rand . Reader , masterKey . Public ( ) , uid , hid , plaintext , nil )
2022-07-15 16:42:39 +08:00
if err != nil {
b . Fatal ( err )
}
b . ReportAllocs ( )
b . ResetTimer ( )
for i := 0 ; i < b . N ; i ++ {
got , err := DecryptASN1 ( userKey , uid , cipher )
if err != nil {
b . Fatal ( err )
}
if string ( got ) != string ( plaintext ) {
b . Errorf ( "expected %v, got %v\n" , string ( plaintext ) , string ( got ) )
}
}
}