init: v1.0.0
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
// package drng implements the SM3Rng and SM4Rng which specified in GM/T 0115.
|
||||
//
|
||||
// ctrrng and hashrng implements the low-level Drng interface.
|
||||
// Combine entropy(pool) and xxxrng we got the Drng as a ReadWriter.
|
||||
// The Read method generates random bits, and the Write method
|
||||
// add outter entropy into the Drng.
|
||||
//
|
||||
// Use drng.SM3Rng as an ordinary io.Reader to generate random bits.
|
||||
// If necessary, it could add extra entropy into the Drng.
|
||||
// For example, add user's scratch points on mobile, get random bits
|
||||
// from the cryptography server, etc..
|
||||
package drng
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"xdx.jelly/xgcl/grand/drng/ctrrng"
|
||||
"xdx.jelly/xgcl/grand/drng/entropy"
|
||||
"xdx.jelly/xgcl/grand/drng/hashrng"
|
||||
"xdx.jelly/xgcl/grand/drng/internal"
|
||||
"xdx.jelly/xgcl/sm"
|
||||
)
|
||||
|
||||
// PERSONALIZATIONSTRING = "粤信签协同签名软件Android客户端密码模块YXQXTQM-Y"
|
||||
var PERSONALIZATIONSTRING = []byte("xdx")
|
||||
|
||||
// SM3Rng implements the io.ReadWriter interface.
|
||||
//
|
||||
// SM3Rng.Read reads random bytes from the DRNG.
|
||||
// SM3rng.Write add extra entropy to the DRNG.
|
||||
var SM3Rng io.ReadWriter
|
||||
var SM4Rng io.ReadWriter
|
||||
|
||||
func init() {
|
||||
raw, _ := hashrng.NewHashDrng(sm.SM3, hashrng.Config(internal.SecureLevel2))
|
||||
rng, _ := raw.Instantiate(PERSONALIZATIONSTRING, internal.Nonce(), entropy.GetEntropyPool())
|
||||
SM3Rng = &DrngUtil{
|
||||
Drng: rng,
|
||||
ReseedSource: entropy.GetEntropyPool(),
|
||||
}
|
||||
|
||||
raw, _ = ctrrng.NewCtrDrng(ctrrng.SM4BlockNewer{}, ctrrng.Config(internal.SecureLevel2))
|
||||
rng, _ = raw.Instantiate(PERSONALIZATIONSTRING, internal.Nonce(), entropy.GetEntropyPool())
|
||||
SM4Rng = &DrngUtil{
|
||||
Drng: rng,
|
||||
ReseedSource: entropy.GetEntropyPool(),
|
||||
}
|
||||
}
|
||||
|
||||
// DrngUtil implements the io.Reader interface
|
||||
type DrngUtil struct {
|
||||
mu sync.Mutex
|
||||
internal.Drng
|
||||
ReseedSource io.Reader // 重播种熵源
|
||||
|
||||
additionalInput io.Reader // TODO: 额外输入, 可为空
|
||||
}
|
||||
|
||||
// Write implements io.ReadWriter.
|
||||
// The returns can be ignored.
|
||||
func (du *DrngUtil) Write(p []byte) (n int, err error) {
|
||||
du.mu.Lock()
|
||||
defer du.mu.Unlock()
|
||||
|
||||
du.Drng.Reseed(p, nil)
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// Read implements io.Reader
|
||||
func (du *DrngUtil) Read(p []byte) (n int, err error) {
|
||||
du.mu.Lock()
|
||||
defer du.mu.Unlock()
|
||||
|
||||
outlen := du.OutLen()
|
||||
for len(p) > 0 {
|
||||
generateLen := len(p)
|
||||
if generateLen > outlen {
|
||||
generateLen = outlen
|
||||
}
|
||||
err := du.Generate(p[:generateLen], nil)
|
||||
if err != nil {
|
||||
// 需要重播种
|
||||
config := du.Config()
|
||||
entropyInput := make([]byte, config.MinEntropy)
|
||||
n, err := du.ReseedSource.Read(entropyInput)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
du.Drng.Reseed(entropyInput[:n], nil)
|
||||
err = du.Generate(p[:generateLen], nil)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
n += generateLen
|
||||
p = p[generateLen:]
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
Reference in New Issue
Block a user