github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/machine_rp2040_rng.go (about) 1 //go:build rp2040 2 3 // Implementation based on code located here: 4 // https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/pico_lwip/random.c 5 6 package machine 7 8 import ( 9 "device/rp" 10 ) 11 12 const numberOfCycles = 32 13 14 // GetRNG returns 32 bits of semi-random data based on ring oscillator. 15 // 16 // Unlike some other implementations of GetRNG, these random numbers are not 17 // cryptographically secure and must not be used for cryptographic operations 18 // (nonces, etc). 19 func GetRNG() (uint32, error) { 20 var val uint32 21 for i := 0; i < 4; i++ { 22 val = (val << 8) | uint32(roscRandByte()) 23 } 24 return val, nil 25 } 26 27 var randomByte uint8 28 29 func roscRandByte() uint8 { 30 var poly uint8 31 for i := 0; i < numberOfCycles; i++ { 32 if randomByte&0x80 != 0 { 33 poly = 0x35 34 } else { 35 poly = 0 36 } 37 randomByte = ((randomByte << 1) | uint8(rp.ROSC.GetRANDOMBIT()) ^ poly) 38 // TODO: delay a little because the random bit is a little slow 39 } 40 return randomByte 41 }