Skip to content

Commit

Permalink
Merge pull request #2706 from onflow/tarak/new-unsafeRandom-signature
Browse files Browse the repository at this point in the history
Update randomness runtime interface method
  • Loading branch information
tarakby authored Aug 16, 2023
2 parents af119ed + d68565d commit e287ab0
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 18 deletions.
4 changes: 2 additions & 2 deletions runtime/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,8 @@ func (e *interpreterEnvironment) ProgramLog(message string) error {
return e.runtimeInterface.ProgramLog(message)
}

func (e *interpreterEnvironment) UnsafeRandom() (uint64, error) {
return e.runtimeInterface.UnsafeRandom()
func (e *interpreterEnvironment) ReadRandom(buffer []byte) error {
return e.runtimeInterface.ReadRandom(buffer)
}

func (e *interpreterEnvironment) GetBlockAtHeight(height uint64) (block stdlib.Block, exists bool, err error) {
Expand Down
5 changes: 2 additions & 3 deletions runtime/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,8 @@ type Interface interface {
GetCurrentBlockHeight() (uint64, error)
// GetBlockAtHeight returns the block at the given height.
GetBlockAtHeight(height uint64) (block Block, exists bool, err error)
// UnsafeRandom returns a random uint64, where the process of random number derivation is not cryptographically
// secure.
UnsafeRandom() (uint64, error)
// ReadRandom reads pseudo-random bytes into the input slice, using distributed randomness.
ReadRandom([]byte) error
// VerifySignature returns true if the given signature was produced by signing the given tag + data
// using the given public key, signature algorithm, and hash algorithm.
VerifySignature(
Expand Down
15 changes: 8 additions & 7 deletions runtime/runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ type testRuntimeInterface struct {
programParsed func(location Location, duration time.Duration)
programChecked func(location Location, duration time.Duration)
programInterpreted func(location Location, duration time.Duration)
unsafeRandom func() (uint64, error)
readRandom func([]byte) error
verifySignature func(
signature []byte,
tag string,
Expand Down Expand Up @@ -513,11 +513,11 @@ func (i *testRuntimeInterface) GetBlockAtHeight(height uint64) (block stdlib.Blo
return block, true, nil
}

func (i *testRuntimeInterface) UnsafeRandom() (uint64, error) {
if i.unsafeRandom == nil {
return 0, nil
func (i *testRuntimeInterface) ReadRandom(buffer []byte) error {
if i.readRandom == nil {
return nil
}
return i.unsafeRandom()
return i.readRandom(buffer)
}

func (i *testRuntimeInterface) VerifySignature(
Expand Down Expand Up @@ -4752,8 +4752,9 @@ func TestRuntimeUnsafeRandom(t *testing.T) {
var loggedMessages []string

runtimeInterface := &testRuntimeInterface{
unsafeRandom: func() (uint64, error) {
return 7558174677681708339, nil
readRandom: func(buffer []byte) error {
binary.LittleEndian.PutUint64(buffer, 7558174677681708339)
return nil
},
log: func(message string) {
loggedMessages = append(loggedMessages, message)
Expand Down
13 changes: 7 additions & 6 deletions runtime/stdlib/random.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
package stdlib

import (
"encoding/binary"

"github.com/onflow/cadence/runtime/errors"
"github.com/onflow/cadence/runtime/interpreter"
"github.com/onflow/cadence/runtime/sema"
Expand All @@ -39,9 +41,8 @@ var unsafeRandomFunctionType = &sema.FunctionType{
}

type UnsafeRandomGenerator interface {
// UnsafeRandom returns a random uint64,
// where the process of random number derivation is not cryptographically secure.
UnsafeRandom() (uint64, error)
// ReadRandom reads pseudo-random bytes into the input slice, using distributed randomness.
ReadRandom([]byte) error
}

func NewUnsafeRandomFunction(generator UnsafeRandomGenerator) StandardLibraryValue {
Expand All @@ -53,15 +54,15 @@ func NewUnsafeRandomFunction(generator UnsafeRandomGenerator) StandardLibraryVal
return interpreter.NewUInt64Value(
invocation.Interpreter,
func() uint64 {
var rand uint64
var buffer [8]byte
var err error
errors.WrapPanic(func() {
rand, err = generator.UnsafeRandom()
err = generator.ReadRandom(buffer[:])
})
if err != nil {
panic(interpreter.WrappedExternalError(err))
}
return rand
return binary.LittleEndian.Uint64(buffer[:])
},
)
},
Expand Down

0 comments on commit e287ab0

Please sign in to comment.