package goproxy import ( "crypto/aes" "crypto/cipher" "crypto/rsa" "crypto/sha256" "crypto/x509" "errors" ) type CounterEncryptorRand struct { cipher cipher.Block counter []byte rand []byte ix int } func NewCounterEncryptorRandFromKey(key interface{}, seed []byte) (r CounterEncryptorRand, err error) { var keyBytes []byte switch key := key.(type) { case *rsa.PrivateKey: keyBytes = x509.MarshalPKCS1PrivateKey(key) default: err = errors.New("only RSA keys supported") return } h := sha256.New() if r.cipher, err = aes.NewCipher(h.Sum(keyBytes)[:aes.BlockSize]); err != nil { return } r.counter = make([]byte, r.cipher.BlockSize()) if seed != nil { copy(r.counter, h.Sum(seed)[:r.cipher.BlockSize()]) } r.rand = make([]byte, r.cipher.BlockSize()) r.ix = len(r.rand) return } func (c *CounterEncryptorRand) Seed(b []byte) { if len(b) != len(c.counter) { panic("SetCounter: wrong counter size") } copy(c.counter, b) } func (c *CounterEncryptorRand) refill() { c.cipher.Encrypt(c.rand, c.counter) for i := 0; i < len(c.counter); i++ { if c.counter[i]++; c.counter[i] != 0 { break } } c.ix = 0 } func (c *CounterEncryptorRand) Read(b []byte) (n int, err error) { if c.ix == len(c.rand) { c.refill() } if n = len(c.rand) - c.ix; n > len(b) { n = len(b) } copy(b, c.rand[c.ix:c.ix+n]) c.ix += n return }