diff --git a/packages/binary/drng/payload/collectiveBeacon/collective_beacon.go b/packages/binary/drng/payload/collectiveBeacon/collective_beacon.go
new file mode 100644
index 0000000000000000000000000000000000000000..56013c99d24394ab267f043024a9efcd26563e18
--- /dev/null
+++ b/packages/binary/drng/payload/collectiveBeacon/collective_beacon.go
@@ -0,0 +1,197 @@
+package collectiveBeacon
+
+import (
+	"sync"
+
+	"github.com/iotaledger/hive.go/stringify"
+
+	drngPayload "github.com/iotaledger/goshimmer/packages/binary/drng/payload"
+	"github.com/iotaledger/goshimmer/packages/binary/drng/payload/header"
+	"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
+	"github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction/payload"
+)
+
+type Payload struct {
+	//objectstorage.StorableObjectFlags
+
+	header header.Header
+
+	round         uint64 // round of the current beacon
+	prevSignature []byte // collective signature of the previous beacon
+	signature     []byte // collective signature of the current beacon
+	dpk           []byte // distributed public key
+	bytes         []byte
+	bytesMutex    sync.RWMutex
+}
+
+func New(instanceID uint32, round uint64, prevSignature, signature, dpk []byte) *Payload {
+	return &Payload{
+		header:        header.New(header.CollectiveBeaconType(), instanceID),
+		round:         round,
+		prevSignature: prevSignature,
+		signature:     signature,
+		dpk:           dpk,
+	}
+}
+
+func (p *Payload) SubType() header.Type {
+	return p.header.PayloadType()
+}
+
+func (payload *Payload) Instance() uint32 {
+	return payload.header.Instance()
+}
+
+func (payload *Payload) Round() uint64 {
+	return payload.round
+}
+
+func (payload *Payload) PrevSignature() []byte {
+	return payload.prevSignature
+}
+
+func (payload *Payload) Signature() []byte {
+	return payload.signature
+}
+
+func (payload *Payload) DistributedPK() []byte {
+	return payload.dpk
+}
+
+// FromBytes parses the marshaled version of a Payload into an object.
+// It either returns a new Payload or fills an optionally provided Payload with the parsed information.
+func FromBytes(bytes []byte, optionalTargetObject ...*Payload) (result *Payload, err error, consumedBytes int) {
+	// determine the target object that will hold the unmarshaled information
+	switch len(optionalTargetObject) {
+	case 0:
+		result = &Payload{}
+	case 1:
+		result = optionalTargetObject[0]
+	default:
+		panic("too many arguments in call to OutputFromBytes")
+	}
+
+	// initialize helper
+	marshalUtil := marshalutil.New(bytes)
+
+	// read information that are required to identify the payload from the outside
+	if _, err = marshalUtil.ReadUint32(); err != nil {
+		return
+	}
+	if _, err = marshalUtil.ReadUint32(); err != nil {
+		return
+	}
+
+	// parse header
+	if result.header, err = header.Parse(marshalUtil); err != nil {
+		return
+	}
+
+	// parse round
+	if result.round, err = marshalUtil.ReadUint64(); err != nil {
+		return
+	}
+
+	// parse prevSignature
+	if result.prevSignature, err = marshalUtil.ReadBytes(SignatureSize); err != nil {
+		return
+	}
+
+	// parse current signature
+	if result.signature, err = marshalUtil.ReadBytes(SignatureSize); err != nil {
+		return
+	}
+
+	// parse distributed public key
+	if result.dpk, err = marshalUtil.ReadBytes(PublicKeySize); err != nil {
+		return
+	}
+
+	// return the number of bytes we processed
+	consumedBytes = marshalUtil.ReadOffset()
+
+	// store bytes, so we don't have to marshal manually
+	result.bytes = bytes[:consumedBytes]
+
+	return
+}
+
+func (payload *Payload) Bytes() (bytes []byte) {
+	// acquire lock for reading bytes
+	payload.bytesMutex.RLock()
+
+	// return if bytes have been determined already
+	if bytes = payload.bytes; bytes != nil {
+		defer payload.bytesMutex.RUnlock()
+		return
+	}
+
+	// switch to write lock
+	payload.bytesMutex.RUnlock()
+	payload.bytesMutex.Lock()
+	defer payload.bytesMutex.Unlock()
+
+	// return if bytes have been determined in the mean time
+	if bytes = payload.bytes; bytes != nil {
+		return
+	}
+
+	// marshal fields
+	payloadLength := header.Length + marshalutil.UINT64_SIZE + SignatureSize*2 + PublicKeySize
+	marshalUtil := marshalutil.New(marshalutil.UINT32_SIZE + marshalutil.UINT32_SIZE + payloadLength)
+	marshalUtil.WriteUint32(drngPayload.Type)
+	marshalUtil.WriteUint32(uint32(payloadLength))
+	marshalUtil.WriteBytes(payload.header.Bytes())
+	marshalUtil.WriteUint64(payload.Round())
+	marshalUtil.WriteBytes(payload.PrevSignature())
+	marshalUtil.WriteBytes(payload.Signature())
+	marshalUtil.WriteBytes(payload.DistributedPK())
+
+	bytes = marshalUtil.Bytes()
+
+	// store result
+	payload.bytes = bytes
+
+	return
+}
+
+func (payload *Payload) String() string {
+	return stringify.Struct("Payload",
+		stringify.StructField("type", payload.SubType()),
+		stringify.StructField("instance", payload.Instance()),
+		stringify.StructField("round", payload.Round()),
+		stringify.StructField("prevSignature", payload.PrevSignature()),
+		stringify.StructField("signature", payload.Signature()),
+		stringify.StructField("distributedPK", payload.DistributedPK()),
+	)
+}
+
+// region Payload implementation ///////////////////////////////////////////////////////////////////////////////////////
+
+func (payload *Payload) GetType() payload.Type {
+	return drngPayload.Type
+}
+
+func (payload *Payload) MarshalBinary() (bytes []byte, err error) {
+	return payload.Bytes(), nil
+}
+
+func (payload *Payload) UnmarshalBinary(data []byte) (err error) {
+	_, err, _ = FromBytes(data, payload)
+
+	return
+}
+
+// func init() {
+// 	payload.RegisterType(drngPayload.Type, func(data []byte) (payload payload.Payload, err error) {
+// 		payload = &Payload{}
+// 		err = payload.UnmarshalBinary(data)
+
+// 		return
+// 	})
+// }
+
+// define contract (ensure that the struct fulfills the corresponding interface)
+var _ payload.Payload = &Payload{}
+
+// // endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/packages/binary/drng/payload/collectiveBeacon/collective_beacon_test.go b/packages/binary/drng/payload/collectiveBeacon/collective_beacon_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..aaf92bf39ede92656814977e47ee12d92bf98f9f
--- /dev/null
+++ b/packages/binary/drng/payload/collectiveBeacon/collective_beacon_test.go
@@ -0,0 +1,32 @@
+package collectiveBeacon
+
+import (
+	"testing"
+
+	"github.com/iotaledger/goshimmer/packages/binary/drng/payload/header"
+	"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
+	"github.com/stretchr/testify/require"
+)
+
+func TestParse(t *testing.T) {
+	header := header.New(header.CollectiveBeaconType(), 0)
+	payload := New(header.Instance(),
+		0,
+		[]byte("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), // prevSignature
+		[]byte("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"), // signature
+		[]byte("CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC")) // distributed PK
+	bytes := payload.Bytes()
+
+	marshalUtil := marshalutil.New(bytes)
+	parsedpayload, err := marshalUtil.Parse(func(data []byte) (interface{}, error, int) { return FromBytes(data) })
+	require.NoError(t, err)
+
+	cb := parsedpayload.(*Payload)
+
+	require.Equal(t, payload.SubType(), cb.SubType())
+	require.Equal(t, payload.Instance(), cb.Instance())
+	require.Equal(t, payload.Round(), cb.Round())
+	require.Equal(t, payload.PrevSignature(), cb.PrevSignature())
+	require.Equal(t, payload.Signature(), cb.Signature())
+	require.Equal(t, payload.DistributedPK(), cb.DistributedPK())
+}
diff --git a/packages/binary/drng/payload/collectiveBeacon/common.go b/packages/binary/drng/payload/collectiveBeacon/common.go
new file mode 100644
index 0000000000000000000000000000000000000000..4d6a78058f050438e3daef9b3c8124b34b56404b
--- /dev/null
+++ b/packages/binary/drng/payload/collectiveBeacon/common.go
@@ -0,0 +1,8 @@
+package collectiveBeacon
+
+const (
+	// BLS Signature size in bytes
+	SignatureSize = 32
+	// BLS Public Key size in bytes
+	PublicKeySize = 32
+)
diff --git a/packages/binary/drng/payload/header/header.go b/packages/binary/drng/payload/header/header.go
new file mode 100644
index 0000000000000000000000000000000000000000..789c0a454f7c07cb0c2e38a71cf0cbd49f887d75
--- /dev/null
+++ b/packages/binary/drng/payload/header/header.go
@@ -0,0 +1,99 @@
+package header
+
+import (
+	"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
+)
+
+type Type = byte
+
+type payloadType struct {
+	CollectiveBeacon Type
+}
+
+var drngTypes = &payloadType{
+	CollectiveBeacon: Type(1),
+}
+
+const Length = 5
+
+func CollectiveBeaconType() Type {
+	return drngTypes.CollectiveBeacon
+}
+
+type Header struct {
+	payloadType Type   // message type
+	instanceID  uint32 // identifier of the dRAND instance
+}
+
+func New(payloadType Type, instanceID uint32) Header {
+	return Header{
+		payloadType: payloadType,
+		instanceID:  instanceID,
+	}
+}
+
+func (h Header) PayloadType() Type {
+	return h.payloadType
+}
+
+func (h Header) Instance() uint32 {
+	return h.instanceID
+}
+
+// Parse is a wrapper for simplified unmarshaling in a byte stream using the marshalUtil package.
+func Parse(marshalUtil *marshalutil.MarshalUtil) (Header, error) {
+	if header, err := marshalUtil.Parse(func(data []byte) (interface{}, error, int) { return FromBytes(data) }); err != nil {
+		return Header{}, err
+	} else {
+		return header.(Header), nil
+	}
+}
+
+// FromBytes unmarshals a header from a sequence of bytes.
+// It either creates a new header or fills the optionally provided object with the parsed information.
+func FromBytes(bytes []byte, optionalTargetObject ...*Header) (result Header, err error, consumedBytes int) {
+	// determine the target object that will hold the unmarshaled information
+	var targetObject *Header
+	switch len(optionalTargetObject) {
+	case 0:
+		targetObject = &result
+	case 1:
+		targetObject = optionalTargetObject[0]
+	default:
+		panic("too many arguments in call to FromBytes")
+	}
+
+	// initialize helper
+	marshalUtil := marshalutil.New(bytes)
+
+	// read payload type from bytes
+	if targetObject.payloadType, err = marshalUtil.ReadByte(); err != nil {
+		return
+	}
+
+	// read instance ID from bytes
+	if targetObject.instanceID, err = marshalUtil.ReadUint32(); err != nil {
+		return
+	}
+
+	// copy result if we have provided a target object
+	result = *targetObject
+
+	// return the number of bytes we processed
+	consumedBytes = marshalUtil.ReadOffset()
+
+	return
+}
+
+func (header *Header) Bytes() (bytes []byte) {
+	// initialize helper
+	marshalUtil := marshalutil.New()
+
+	// marshal the payload specific information
+	marshalUtil.WriteByte(header.PayloadType())
+	marshalUtil.WriteUint32(header.Instance())
+
+	bytes = marshalUtil.Bytes()
+
+	return
+}
diff --git a/packages/binary/drng/payload/header/header_test.go b/packages/binary/drng/payload/header/header_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..b5778db91e87a77464d55aa9d79ec44fa4aa9a8d
--- /dev/null
+++ b/packages/binary/drng/payload/header/header_test.go
@@ -0,0 +1,19 @@
+package header
+
+import (
+	"testing"
+
+	"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
+	"github.com/stretchr/testify/require"
+)
+
+func TestParse(t *testing.T) {
+	header := New(CollectiveBeaconType(), 0)
+	bytes := header.Bytes()
+
+	marshalUtil := marshalutil.New(bytes)
+	parsedHeader, err := Parse(marshalUtil)
+	require.NoError(t, err)
+
+	require.Equal(t, header, parsedHeader)
+}
diff --git a/packages/binary/drng/payload/payload.go b/packages/binary/drng/payload/payload.go
new file mode 100644
index 0000000000000000000000000000000000000000..9637cbcba98b222c302bacdf548ec539ffee1520
--- /dev/null
+++ b/packages/binary/drng/payload/payload.go
@@ -0,0 +1,152 @@
+package payload
+
+import (
+	"sync"
+
+	"github.com/iotaledger/goshimmer/packages/binary/drng/payload/header"
+	"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
+	"github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction/payload"
+	"github.com/iotaledger/hive.go/stringify"
+)
+
+type Payload struct {
+	header header.Header
+	data   []byte
+
+	bytes      []byte
+	bytesMutex sync.RWMutex
+}
+
+func New(header header.Header, data []byte) *Payload {
+	return &Payload{
+		header: header,
+		data:   data,
+	}
+}
+
+func (p *Payload) SubType() header.Type {
+	return p.header.PayloadType()
+}
+
+func (payload *Payload) Instance() uint32 {
+	return payload.header.Instance()
+}
+
+func (payload *Payload) Data() []byte {
+	return payload.data
+}
+
+// FromBytes parses the marshaled version of a Payload into an object.
+// It either returns a new Payload or fills an optionally provided Payload with the parsed information.
+func FromBytes(bytes []byte, optionalTargetObject ...*Payload) (result *Payload, err error, consumedBytes int) {
+	// determine the target object that will hold the unmarshaled information
+	switch len(optionalTargetObject) {
+	case 0:
+		result = &Payload{}
+	case 1:
+		result = optionalTargetObject[0]
+	default:
+		panic("too many arguments in call to OutputFromBytes")
+	}
+
+	// initialize helper
+	marshalUtil := marshalutil.New(bytes)
+
+	// read information that are required to identify the payload from the outside
+	if _, err = marshalUtil.ReadUint32(); err != nil {
+		return
+	}
+
+	len, err := marshalUtil.ReadUint32()
+	if err != nil {
+		return
+	}
+
+	// parse header
+	if result.header, err = header.Parse(marshalUtil); err != nil {
+		return
+	}
+
+	// parse data
+	if result.data, err = marshalUtil.ReadBytes(int(len - header.Length)); err != nil {
+		return
+	}
+
+	// store bytes, so we don't have to marshal manually
+	result.bytes = bytes[:consumedBytes]
+
+	return
+}
+
+func (payload *Payload) Bytes() (bytes []byte) {
+	// acquire lock for reading bytes
+	payload.bytesMutex.RLock()
+
+	// return if bytes have been determined already
+	if bytes = payload.bytes; bytes != nil {
+		defer payload.bytesMutex.RUnlock()
+		return
+	}
+
+	// switch to write lock
+	payload.bytesMutex.RUnlock()
+	payload.bytesMutex.Lock()
+	defer payload.bytesMutex.Unlock()
+
+	// return if bytes have been determined in the mean time
+	if bytes = payload.bytes; bytes != nil {
+		return
+	}
+	// initialize helper
+	marshalUtil := marshalutil.New()
+
+	// marshal the payload specific information
+	marshalUtil.WriteUint32(Type)
+	marshalUtil.WriteUint32(uint32(len(payload.data) + header.Length))
+	marshalUtil.WriteBytes(payload.header.Bytes())
+	marshalUtil.WriteBytes(payload.data[:])
+
+	bytes = marshalUtil.Bytes()
+
+	return
+}
+
+func (payload *Payload) String() string {
+	return stringify.Struct("Payload",
+		stringify.StructField("type", payload.SubType()),
+		stringify.StructField("instance", payload.Instance()),
+		stringify.StructField("data", payload.Data()),
+	)
+}
+
+// region Payload implementation ///////////////////////////////////////////////////////////////////////////////////////
+
+var Type = payload.Type(111)
+
+func (payload *Payload) GetType() payload.Type {
+	return Type
+}
+
+func (payload *Payload) MarshalBinary() (bytes []byte, err error) {
+	return payload.Bytes(), nil
+}
+
+func (payload *Payload) UnmarshalBinary(data []byte) (err error) {
+	_, err, _ = FromBytes(data, payload)
+
+	return
+}
+
+func init() {
+	payload.RegisterType(Type, func(data []byte) (payload payload.Payload, err error) {
+		payload = &Payload{}
+		err = payload.UnmarshalBinary(data)
+
+		return
+	})
+}
+
+// define contract (ensure that the struct fulfills the corresponding interface)
+var _ payload.Payload = &Payload{}
+
+// // endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/packages/binary/drng/payload/payload_test.go b/packages/binary/drng/payload/payload_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..16aa567b99b065d3dc9f1f335c9751e30f6e7f43
--- /dev/null
+++ b/packages/binary/drng/payload/payload_test.go
@@ -0,0 +1,26 @@
+package payload
+
+import (
+	"testing"
+
+	"github.com/iotaledger/goshimmer/packages/binary/drng/payload/header"
+	"github.com/iotaledger/goshimmer/packages/binary/marshalutil"
+	"github.com/stretchr/testify/require"
+)
+
+func TestParse(t *testing.T) {
+	header := header.New(header.CollectiveBeaconType(), 0)
+	data := []byte("test")
+	payload := New(header, data)
+	bytes := payload.Bytes()
+
+	marshalUtil := marshalutil.New(bytes)
+	parsedpayload, err := marshalUtil.Parse(func(data []byte) (interface{}, error, int) { return FromBytes(data) })
+	require.NoError(t, err)
+
+	cb := parsedpayload.(*Payload)
+
+	require.Equal(t, payload.SubType(), cb.SubType())
+	require.Equal(t, payload.Instance(), cb.Instance())
+	require.Equal(t, payload.Data(), cb.Data())
+}