sm: improve docs and add examples

This commit is contained in:
Sun Yimin 2023-01-31 13:50:14 +08:00 committed by GitHub
parent 72bb569234
commit edfb4febdd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 49 additions and 26 deletions

View File

@ -1,3 +1,4 @@
// Package cipher provides several extra chipher modes.
package cipher package cipher
import ( import (

View File

@ -1,3 +1,4 @@
// Package drbg implements Random Number Generation Using Deterministic Random Bit Generators.
package drbg package drbg
import ( import (

View File

@ -1,3 +1,4 @@
// Package kdf implements ShangMi(SM) used Key Derivation Function, compliances with GB/T 32918.4-2016 5.4.3.
package kdf package kdf
import ( import (

View File

@ -1,4 +1,3 @@
// Package padding handle padding octets at the trailing end
package padding package padding
import ( import (

View File

@ -1,3 +1,4 @@
// Package padding implements some padding schemes for padding octets at the trailing end.
package padding package padding
// Padding interface represents a padding scheme // Padding interface represents a padding scheme

View File

@ -1,4 +1,4 @@
// Package pkcs8 implements functions to parse and convert private keys in PKCS#8 format, as defined in RFC5208 and RFC5958 // Package pkcs8 implements functions to parse and convert private keys in PKCS#8 format with ShangMi(SM) support, as defined in RFC5208 and RFC5958.
package pkcs8 package pkcs8
import ( import (

View File

@ -1,4 +1,4 @@
// Package sm2 handle shangmi sm2 digital signature and public key encryption algorithm and its curve implementation // Package sm2 implements ShangMi(SM) sm2 digital signature, public key encryption and key exchange algorithms.
package sm2 package sm2
// Further references: // Further references:

View File

@ -9,7 +9,9 @@ import (
"crypto/rand" "crypto/rand"
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt"
"io" "io"
"log"
"math/big" "math/big"
"reflect" "reflect"
"testing" "testing"
@ -369,6 +371,21 @@ func TestSignVerify(t *testing.T) {
} }
} }
// This is a reference method to force SM2 standard with SDK [crypto.Signer].
func ExamplePrivateKey_Sign_forceSM2() {
toSign := []byte("ShangMi SM2 Sign Standard")
priv, _ := GenerateKey(rand.Reader)
// force SM2 sign standard and use default UID
sig, err := priv.Sign(rand.Reader, toSign, NewSM2SignerOption(true, nil))
if err != nil {
log.Fatalf("%v", err)
}
// use default UID
ok := VerifyASN1WithSM2(&priv.PublicKey, nil, toSign, sig)
fmt.Printf("%v\n", ok)
// Output: true
}
func TestSignVerifyLegacy(t *testing.T) { func TestSignVerifyLegacy(t *testing.T) {
priv, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) priv, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
tests := []struct { tests := []struct {
@ -583,8 +600,10 @@ func TestEqual(t *testing.T) {
} }
} }
// This method provide a sample to handle ASN1 ciphertext ends with extra bytes.
func Example_parseCipherASN1EndsWithInvalidBytes() {
// a sample method to get frist ASN1 SEQUENCE data // a sample method to get frist ASN1 SEQUENCE data
func getFirstASN1Sequence(ciphertext []byte) ([]byte, []byte, error) { getFirstASN1Sequence := func(ciphertext []byte) ([]byte, []byte, error) {
input := cryptobyte.String(ciphertext) input := cryptobyte.String(ciphertext)
var inner cryptobyte.String var inner cryptobyte.String
if !input.ReadASN1(&inner, asn1.SEQUENCE) { if !input.ReadASN1(&inner, asn1.SEQUENCE) {
@ -596,17 +615,16 @@ func getFirstASN1Sequence(ciphertext []byte) ([]byte, []byte, error) {
return ciphertext[:len(ciphertext)-len(input)], input, nil return ciphertext[:len(ciphertext)-len(input)], input, nil
} }
func TestCipherASN1WithInvalidBytes(t *testing.T) {
ciphertext, _ := hex.DecodeString("3081980220298ED52AE2A0EBA8B7567D54DF41C5F9B310EDFA4A8E15ECCB44EDA94F9F1FC20220116BE33B0833C95D8E5FF9483CD2D7EFF7033C92FE5DEAB6197D809FF1EEE05F042097A90979A6FCEBDE883C2E07E9C286818E694EDE37C3CDAA70E4CD481BE883E00430D62160BB179CB20CE3B5ECA0F5A535BEB6E221566C78FEA92105F71BD37F3F850AD2F86F2D1E35F15E9356557DAC026A") ciphertext, _ := hex.DecodeString("3081980220298ED52AE2A0EBA8B7567D54DF41C5F9B310EDFA4A8E15ECCB44EDA94F9F1FC20220116BE33B0833C95D8E5FF9483CD2D7EFF7033C92FE5DEAB6197D809FF1EEE05F042097A90979A6FCEBDE883C2E07E9C286818E694EDE37C3CDAA70E4CD481BE883E00430D62160BB179CB20CE3B5ECA0F5A535BEB6E221566C78FEA92105F71BD37F3F850AD2F86F2D1E35F15E9356557DAC026A")
_, rest, err := getFirstASN1Sequence(ciphertext) _, rest, err := getFirstASN1Sequence(ciphertext)
if err != nil || len(rest) != 0 { if err != nil || len(rest) != 0 {
t.FailNow() log.Fatalf("can't get a complete ASN1 sequence")
} }
ciphertext, _ = hex.DecodeString("3081980220298ED52AE2A0EBA8B7567D54DF41C5F9B310EDFA4A8E15ECCB44EDA94F9F1FC20220116BE33B0833C95D8E5FF9483CD2D7EFF7033C92FE5DEAB6197D809FF1EEE05F042097A90979A6FCEBDE883C2E07E9C286818E694EDE37C3CDAA70E4CD481BE883E00430D62160BB179CB20CE3B5ECA0F5A535BEB6E221566C78FEA92105F71BD37F3F850AD2F86F2D1E35F15E9356557DAC026A0000") ciphertext, _ = hex.DecodeString("3081980220298ED52AE2A0EBA8B7567D54DF41C5F9B310EDFA4A8E15ECCB44EDA94F9F1FC20220116BE33B0833C95D8E5FF9483CD2D7EFF7033C92FE5DEAB6197D809FF1EEE05F042097A90979A6FCEBDE883C2E07E9C286818E694EDE37C3CDAA70E4CD481BE883E00430D62160BB179CB20CE3B5ECA0F5A535BEB6E221566C78FEA92105F71BD37F3F850AD2F86F2D1E35F15E9356557DAC026A0000")
seq, rest, err := getFirstASN1Sequence(ciphertext) seq, rest, err := getFirstASN1Sequence(ciphertext)
if err != nil || len(rest) != 2 { if err != nil || len(rest) != 2 {
t.FailNow() log.Fatalf("can't get a complete ASN1 sequence")
} }
var ( var (
@ -623,7 +641,7 @@ func TestCipherASN1WithInvalidBytes(t *testing.T) {
!inner.ReadASN1Bytes(&c3, asn1.OCTET_STRING) || !inner.ReadASN1Bytes(&c3, asn1.OCTET_STRING) ||
!inner.ReadASN1Bytes(&c2, asn1.OCTET_STRING) || !inner.ReadASN1Bytes(&c2, asn1.OCTET_STRING) ||
!inner.Empty() { !inner.Empty() {
t.Fatalf("invalid cipher text") log.Fatalf("invalid cipher text")
} }
} }
@ -676,10 +694,10 @@ func TestRandomPoint(t *testing.T) {
} }
} }
// This test method is just for reference, it's NOT a standard method for key transmission. // This example method is just for reference, it's NOT a standard method for key transmission.
// In general, private key will be encoded/formatted with PKCS8, public key will be encoded/formatted with a SubjectPublicKeyInfo structure // In general, private key will be encoded/formatted with PKCS8, public key will be encoded/formatted with a SubjectPublicKeyInfo structure
// (see RFC 5280, Section 4.1). // (see RFC 5280, Section 4.1).
func TestCreateKeysFromRawValue(t *testing.T) { func Example_createKeysFromRawValue() {
key, _ := GenerateKey(rand.Reader) key, _ := GenerateKey(rand.Reader)
d := new(big.Int).SetBytes(key.D.Bytes()) // here we do NOT check if the d is in (0, N) or not d := new(big.Int).SetBytes(key.D.Bytes()) // here we do NOT check if the d is in (0, N) or not
@ -689,7 +707,7 @@ func TestCreateKeysFromRawValue(t *testing.T) {
keyCopy.D = d keyCopy.D = d
keyCopy.PublicKey.X, keyCopy.PublicKey.Y = keyCopy.ScalarBaseMult(keyCopy.D.Bytes()) keyCopy.PublicKey.X, keyCopy.PublicKey.Y = keyCopy.ScalarBaseMult(keyCopy.D.Bytes())
if !key.Equal(keyCopy) { if !key.Equal(keyCopy) {
t.Fatalf("private key and copy should be equal") log.Fatalf("private key and copy should be equal")
} }
pointBytes := elliptic.Marshal(key.Curve, key.X, key.Y) pointBytes := elliptic.Marshal(key.Curve, key.X, key.Y)
@ -698,7 +716,7 @@ func TestCreateKeysFromRawValue(t *testing.T) {
publicKeyCopy.Curve = P256() publicKeyCopy.Curve = P256()
publicKeyCopy.X, publicKeyCopy.Y = elliptic.Unmarshal(publicKeyCopy.Curve, pointBytes) publicKeyCopy.X, publicKeyCopy.Y = elliptic.Unmarshal(publicKeyCopy.Curve, pointBytes)
if !key.PublicKey.Equal(publicKeyCopy) { if !key.PublicKey.Equal(publicKeyCopy) {
t.Fatalf("public key and copy should be equal") log.Fatalf("public key and copy should be equal")
} }
} }

View File

@ -1,3 +1,4 @@
// Package sm2ec defines/implements SM2 curve structure.
package sm2ec package sm2ec
import ( import (

View File

@ -1,4 +1,4 @@
// Package sm3 handle shangmi sm3 hash algorithm // Package sm3 implements ShangMi(SM) sm3 hash algorithm.
package sm3 package sm3
// [GM/T] SM3 GB/T 32905-2016 // [GM/T] SM3 GB/T 32905-2016

View File

@ -1,4 +1,4 @@
// Package sm4 handle shangmi sm4 symmetric encryption algorithm // Package sm4 implements ShangMi(SM) sm4 symmetric encryption algorithm.
package sm4 package sm4
import ( import (

View File

@ -1,3 +1,4 @@
// Package bn256 defines/implements ShangMi(SM) sm9's curves and pairing.
package bn256 package bn256
func lineFunctionAdd(r, p *twistPoint, q *curvePoint, r2 *gfP2) (a, b, c, d *gfP2, rOut *twistPoint) { func lineFunctionAdd(r, p *twistPoint, q *curvePoint, r2 *gfP2) (a, b, c, d *gfP2, rOut *twistPoint) {

View File

@ -1,4 +1,4 @@
// Package sm9 handle shangmi sm9 algorithm and its curves and pairing implementation // Package sm9 implements ShangMi(SM) sm9 digital signature, encryption and key exchange algorithms.
package sm9 package sm9
import ( import (

View File

@ -1,4 +1,4 @@
// Package zuc handle shangmi zuc stream cipher. // Package zuc implements ShangMi(SM) zuc stream cipher and integrity algorithm.
package zuc package zuc
import ( import (