github.com/cloudflare/circl@v1.5.0/internal/nist/drbg.go (about) 1 // Package nist implements helpers to generate NIST's Known Answer Tests (KATs). 2 package nist 3 4 import ( 5 "crypto/aes" 6 ) 7 8 // See NIST's PQCgenKAT.c. 9 type DRBG struct { 10 key [32]byte 11 v [16]byte 12 } 13 14 func (g *DRBG) incV() { 15 for j := 15; j >= 0; j-- { 16 if g.v[j] == 255 { 17 g.v[j] = 0 18 } else { 19 g.v[j]++ 20 break 21 } 22 } 23 } 24 25 // AES256_CTR_DRBG_Update(pd, &g.key, &g.v). 26 func (g *DRBG) update(pd *[48]byte) { 27 var buf [48]byte 28 b, _ := aes.NewCipher(g.key[:]) 29 for i := 0; i < 3; i++ { 30 g.incV() 31 b.Encrypt(buf[i*16:(i+1)*16], g.v[:]) 32 } 33 if pd != nil { 34 for i := 0; i < 48; i++ { 35 buf[i] ^= pd[i] 36 } 37 } 38 copy(g.key[:], buf[:32]) 39 copy(g.v[:], buf[32:]) 40 } 41 42 // randombyte_init(seed, NULL, 256). 43 func NewDRBG(seed *[48]byte) (g DRBG) { 44 g.update(seed) 45 return 46 } 47 48 // randombytes. 49 func (g *DRBG) Fill(x []byte) { 50 var block [16]byte 51 52 b, _ := aes.NewCipher(g.key[:]) 53 for len(x) > 0 { 54 g.incV() 55 b.Encrypt(block[:], g.v[:]) 56 if len(x) < 16 { 57 copy(x[:], block[:len(x)]) 58 break 59 } 60 copy(x[:], block[:]) 61 x = x[16:] 62 } 63 g.update(nil) 64 }