init: v1.0.0
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
///
|
||||
/// Copyright (c) 2018 xdx. All rights reserved.
|
||||
///
|
||||
/// \file: enc_impl.go
|
||||
///
|
||||
/// \brief: sm9加密辅助函数
|
||||
///
|
||||
/// \author: xdx
|
||||
///
|
||||
|
||||
package sm9
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"math/big"
|
||||
|
||||
"xdx.jelly/xgcl/gerrors"
|
||||
"xdx.jelly/xgcl/sm/sm4"
|
||||
"xdx.jelly/xgcl/sm/sm9/errors"
|
||||
)
|
||||
|
||||
type encReader struct {
|
||||
E encoder
|
||||
R io.Reader
|
||||
}
|
||||
|
||||
func (er *encReader) Read(dst []byte) (n int, err error) {
|
||||
n, err = er.R.Read(dst)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
dst, err = er.E.encode(dst, dst)
|
||||
return len(dst), nil
|
||||
}
|
||||
|
||||
type encoder interface {
|
||||
encode(dst, src []byte) ([]byte, error)
|
||||
}
|
||||
|
||||
type encFunc func(dst, iv, key, src []byte) ([]byte, error)
|
||||
type worker struct {
|
||||
key []byte
|
||||
iv []byte
|
||||
f encFunc
|
||||
}
|
||||
|
||||
func (o *worker) encode(dst, src []byte) ([]byte, error) {
|
||||
return o.f(dst, o.iv, o.key, src)
|
||||
}
|
||||
|
||||
func DecryptParams(c *Cipher) (int, func(dst, iv, key, src []byte) ([]byte, error), error) {
|
||||
switch c.EncType {
|
||||
case EncTypeKDF:
|
||||
return len(c.C) + macKeySize, xor, nil
|
||||
case EncTypeSM4ECB:
|
||||
return sm4.BlockSize + macKeySize, decEcb, nil
|
||||
case EncTypeSM4CBC:
|
||||
return sm4.BlockSize + macKeySize, decCbc, nil
|
||||
case EncTypeSM4CFB:
|
||||
return sm4.BlockSize + macKeySize, decCfb, nil
|
||||
case EncTypeSM4OFB:
|
||||
return sm4.BlockSize + macKeySize, decOfb, nil
|
||||
default:
|
||||
return 0, nil, errors.ErrEncUnsupportedMode
|
||||
}
|
||||
}
|
||||
|
||||
var DecryptFunc = map[EncType]func(dst, iv, key, src []byte) ([]byte, error){
|
||||
EncTypeKDF: xor,
|
||||
EncTypeSM4ECB: decEcb,
|
||||
EncTypeSM4CBC: decCbc,
|
||||
EncTypeSM4CFB: decCfb,
|
||||
EncTypeSM4OFB: decOfb,
|
||||
}
|
||||
|
||||
func xor(dst, iv, key, src []byte) ([]byte, error) {
|
||||
for i := range src {
|
||||
dst[i] = key[i] ^ src[i]
|
||||
}
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
func encEcb(dst, iv, key, src []byte) ([]byte, error) {
|
||||
return sm4.ECBEncrypt(dst, key, src)
|
||||
}
|
||||
|
||||
func decEcb(dst, iv, key, src []byte) ([]byte, error) {
|
||||
return sm4.ECBDecrypt(dst, key, src)
|
||||
}
|
||||
|
||||
func encCbc(dst, iv, key, src []byte) ([]byte, error) {
|
||||
return sm4.CBCEncrypt(dst, iv, key, src)
|
||||
}
|
||||
func decCbc(dst, iv, key, src []byte) ([]byte, error) {
|
||||
return sm4.CBCDecrypt(dst, iv, key, src)
|
||||
}
|
||||
|
||||
func encCfb(dst, iv, key, src []byte) ([]byte, error) {
|
||||
return sm4.CFBEncrypt(dst, iv, key, src)
|
||||
}
|
||||
|
||||
func decCfb(dst, iv, key, src []byte) ([]byte, error) {
|
||||
return sm4.CFBDecrypt(dst, iv, key, src)
|
||||
}
|
||||
|
||||
func encOfb(dst, iv, key, src []byte) ([]byte, error) {
|
||||
return sm4.OFBEncrypt(dst, iv, key, src)
|
||||
}
|
||||
|
||||
func decOfb(dst, iv, key, src []byte) ([]byte, error) {
|
||||
return sm4.OFBDecrypt(dst, iv, key, src)
|
||||
}
|
||||
|
||||
// assume plain is padding and n blocks, iv is set of 16 bytes if cbc
|
||||
func encryption(id, plain []byte, pube *MastEncPublicKey, iv, rnd []byte, keylen int, f encFunc, encType EncType) *Cipher {
|
||||
c := new(Cipher)
|
||||
c.C = make([]byte, len(plain))
|
||||
r := new(big.Int).SetBytes(rnd)
|
||||
// c.X, c.Y = genKeyPackage(id, pube, rnd)
|
||||
c.C1.Set(hashToG1(id, &pube.G1, hidEncryption))
|
||||
c.C1.ScalarMult(&c.C1, r)
|
||||
c.EncType = encType
|
||||
copy(c.IV[:], iv)
|
||||
|
||||
key := make([]byte, keylen)
|
||||
|
||||
// genKey(key, id, &c.C1, &pube.G1, g2Gen, r)
|
||||
w := >{}
|
||||
if pube.e != nil {
|
||||
w.ScalarMult(pube.e, r)
|
||||
} else {
|
||||
pairing(w, &pube.G1, g2Gen)
|
||||
w.ScalarMult(w, r)
|
||||
}
|
||||
genKey(key, id, &c.C1, w)
|
||||
|
||||
reader := &encReader{
|
||||
E: &worker{key[:len(key)-macKeySize], iv, f},
|
||||
R: bytes.NewReader(plain),
|
||||
}
|
||||
_, _ = reader.Read(c.C)
|
||||
copy(c.H[:], mac(key[len(key)-macKeySize:], c.C))
|
||||
return c
|
||||
}
|
||||
|
||||
// decryptions, encType are not used
|
||||
func decryption(id []byte, c *Cipher, de *UserEncKey, keylen int, f encFunc) ([]byte, error) {
|
||||
if !c.C1.IsValid() {
|
||||
return nil, gerrors.WithAnnotating(errors.ErrDecFailed, "C1 is not a valid point on curve")
|
||||
}
|
||||
|
||||
w := >{}
|
||||
pairing(w, &c.C1, &de.G2)
|
||||
|
||||
key := make([]byte, keylen)
|
||||
genKey(key, id, &c.C1, w)
|
||||
return decodeCipher(c, key, f)
|
||||
}
|
||||
|
||||
// DecodeCipher export decodeCipher for tpc package.
|
||||
// Do not use this function unless you know what you are doing.
|
||||
var DecodeCipher = decodeCipher
|
||||
|
||||
func decodeCipher(c *Cipher, key []byte, f encFunc) ([]byte, error) {
|
||||
keylen := len(key)
|
||||
|
||||
m := mac(key[keylen-macKeySize:], c.C)
|
||||
if !bytes.Equal(c.H[:], m[:]) {
|
||||
return nil, gerrors.WithAnnotating(errors.ErrDecFailed, "check C3 failed")
|
||||
}
|
||||
|
||||
reader := &encReader{
|
||||
E: &worker{key[:keylen-macKeySize], c.IV[:], f},
|
||||
R: bytes.NewReader(c.C),
|
||||
}
|
||||
plain := make([]byte, len(c.C))
|
||||
_, _ = reader.Read(plain)
|
||||
|
||||
return plain, nil
|
||||
}
|
||||
Reference in New Issue
Block a user