git.gammaspectra.live/P2Pool/consensus/v3@v3.8.0/monero/crypto/random.go (about) 1 package crypto 2 3 import ( 4 "crypto/rand" 5 "encoding/binary" 6 "git.gammaspectra.live/P2Pool/consensus/v3/types" 7 "git.gammaspectra.live/P2Pool/edwards25519" 8 "unsafe" 9 ) 10 11 func RandomScalar() *edwards25519.Scalar { 12 buf := make([]byte, 32) 13 for { 14 if _, err := rand.Read(buf); err != nil { 15 return nil 16 } 17 18 if !less32(buf, limit) { 19 continue 20 } 21 22 scalar := BytesToScalar(buf) 23 if scalar.Equal(zeroScalar) == 0 { 24 return scalar 25 } 26 } 27 } 28 29 // DeterministicScalar consensus way of generating a deterministic scalar from given entropy 30 // Slice entropy will have data appended 31 func DeterministicScalar(entropy []byte) *edwards25519.Scalar { 32 33 var counter uint32 34 35 entropy = append(entropy, make([]byte, int(unsafe.Sizeof(counter)))...) 36 n := len(entropy) - int(unsafe.Sizeof(counter)) 37 h := GetKeccak256Hasher() 38 defer PutKeccak256Hasher(h) 39 var hash types.Hash 40 41 scalar := GetEdwards25519Scalar() 42 43 for { 44 h.Reset() 45 counter++ 46 binary.LittleEndian.PutUint32(entropy[n:], counter) 47 _, _ = h.Write(entropy) 48 HashFastSum(h, hash[:]) 49 if !less32(hash[:], limit) { 50 continue 51 } 52 scReduce32(hash[:]) 53 scalar, _ = scalar.SetCanonicalBytes(hash[:]) 54 55 if scalar.Equal(zeroScalar) == 0 { 56 return scalar 57 } 58 } 59 }