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
import (

View File

@ -1,3 +1,4 @@
// Package drbg implements Random Number Generation Using Deterministic Random Bit Generators.
package drbg
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
import (

View File

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

View File

@ -1,3 +1,4 @@
// Package padding implements some padding schemes for padding octets at the trailing end.
package padding
// 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
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
// Further references:

View File

@ -9,7 +9,9 @@ import (
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"io"
"log"
"math/big"
"reflect"
"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) {
priv, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
tests := []struct {
@ -583,30 +600,31 @@ func TestEqual(t *testing.T) {
}
}
// a sample method to get frist ASN1 SEQUENCE data
func getFirstASN1Sequence(ciphertext []byte) ([]byte, []byte, error) {
input := cryptobyte.String(ciphertext)
var inner cryptobyte.String
if !input.ReadASN1(&inner, asn1.SEQUENCE) {
return nil, nil, errors.New("there are no sequence tag")
// 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
getFirstASN1Sequence := func(ciphertext []byte) ([]byte, []byte, error) {
input := cryptobyte.String(ciphertext)
var inner cryptobyte.String
if !input.ReadASN1(&inner, asn1.SEQUENCE) {
return nil, nil, errors.New("there are no sequence tag")
}
if len(input) == 0 {
return ciphertext, nil, nil
}
return ciphertext[:len(ciphertext)-len(input)], input, nil
}
if len(input) == 0 {
return ciphertext, nil, nil
}
return ciphertext[:len(ciphertext)-len(input)], input, nil
}
func TestCipherASN1WithInvalidBytes(t *testing.T) {
ciphertext, _ := hex.DecodeString("3081980220298ED52AE2A0EBA8B7567D54DF41C5F9B310EDFA4A8E15ECCB44EDA94F9F1FC20220116BE33B0833C95D8E5FF9483CD2D7EFF7033C92FE5DEAB6197D809FF1EEE05F042097A90979A6FCEBDE883C2E07E9C286818E694EDE37C3CDAA70E4CD481BE883E00430D62160BB179CB20CE3B5ECA0F5A535BEB6E221566C78FEA92105F71BD37F3F850AD2F86F2D1E35F15E9356557DAC026A")
_, rest, err := getFirstASN1Sequence(ciphertext)
if err != nil || len(rest) != 0 {
t.FailNow()
log.Fatalf("can't get a complete ASN1 sequence")
}
ciphertext, _ = hex.DecodeString("3081980220298ED52AE2A0EBA8B7567D54DF41C5F9B310EDFA4A8E15ECCB44EDA94F9F1FC20220116BE33B0833C95D8E5FF9483CD2D7EFF7033C92FE5DEAB6197D809FF1EEE05F042097A90979A6FCEBDE883C2E07E9C286818E694EDE37C3CDAA70E4CD481BE883E00430D62160BB179CB20CE3B5ECA0F5A535BEB6E221566C78FEA92105F71BD37F3F850AD2F86F2D1E35F15E9356557DAC026A0000")
seq, rest, err := getFirstASN1Sequence(ciphertext)
if err != nil || len(rest) != 2 {
t.FailNow()
log.Fatalf("can't get a complete ASN1 sequence")
}
var (
@ -623,7 +641,7 @@ func TestCipherASN1WithInvalidBytes(t *testing.T) {
!inner.ReadASN1Bytes(&c3, asn1.OCTET_STRING) ||
!inner.ReadASN1Bytes(&c2, asn1.OCTET_STRING) ||
!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
// (see RFC 5280, Section 4.1).
func TestCreateKeysFromRawValue(t *testing.T) {
func Example_createKeysFromRawValue() {
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
@ -689,7 +707,7 @@ func TestCreateKeysFromRawValue(t *testing.T) {
keyCopy.D = d
keyCopy.PublicKey.X, keyCopy.PublicKey.Y = keyCopy.ScalarBaseMult(keyCopy.D.Bytes())
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)
@ -698,7 +716,7 @@ func TestCreateKeysFromRawValue(t *testing.T) {
publicKeyCopy.Curve = P256()
publicKeyCopy.X, publicKeyCopy.Y = elliptic.Unmarshal(publicKeyCopy.Curve, pointBytes)
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
import (

View File

@ -1,4 +1,4 @@
// Package sm3 handle shangmi sm3 hash algorithm
// Package sm3 implements ShangMi(SM) sm3 hash algorithm.
package sm3
// [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
import (

View File

@ -1,3 +1,4 @@
// Package bn256 defines/implements ShangMi(SM) sm9's curves and pairing.
package bn256
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
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
import (