libs5-go/encoding/encrypted_cid.go

119 lines
2.9 KiB
Go
Raw Normal View History

2024-01-03 13:46:30 +00:00
package encoding
import (
2024-01-04 13:19:26 +00:00
"encoding/json"
2024-01-03 13:46:30 +00:00
"errors"
2024-01-04 13:19:26 +00:00
"git.lumeweb.com/LumeWeb/libs5-go/serialize"
2024-01-03 13:46:30 +00:00
"git.lumeweb.com/LumeWeb/libs5-go/types"
"git.lumeweb.com/LumeWeb/libs5-go/utils"
"github.com/vmihailenco/msgpack/v5"
2024-01-03 13:46:30 +00:00
)
type EncryptedCID struct {
Multibase
encryptedBlobHash Multihash
2024-01-03 20:27:35 +00:00
OriginalCID CID
2024-01-03 13:46:30 +00:00
encryptionAlgorithm byte
padding uint32
chunkSizeAsPowerOf2 int
encryptionKey []byte
}
var _ msgpack.CustomEncoder = (*EncryptedCID)(nil)
var _ msgpack.CustomDecoder = (*EncryptedCID)(nil)
2024-01-04 13:19:26 +00:00
var _ json.Marshaler = (*EncryptedCID)(nil)
var _ json.Unmarshaler = (*EncryptedCID)(nil)
2024-01-03 13:46:30 +00:00
func NewEncryptedCID(encryptedBlobHash Multihash, originalCID CID, encryptionKey []byte, padding uint32, chunkSizeAsPowerOf2 int, encryptionAlgorithm byte) *EncryptedCID {
e := &EncryptedCID{
encryptedBlobHash: encryptedBlobHash,
2024-01-03 20:27:35 +00:00
OriginalCID: originalCID,
2024-01-03 13:46:30 +00:00
encryptionKey: encryptionKey,
padding: padding,
chunkSizeAsPowerOf2: chunkSizeAsPowerOf2,
encryptionAlgorithm: encryptionAlgorithm,
}
m := NewMultibase(e)
e.Multibase = m
return e
}
func DecodeEncryptedCID(cid string) (*EncryptedCID, error) {
data, err := MultibaseDecodeString(cid)
if err != nil {
return nil, err
}
return EncryptedCIDFromBytes(data)
2024-01-03 13:46:30 +00:00
}
func EncryptedCIDFromBytes(data []byte) (*EncryptedCID, error) {
2024-01-03 13:46:30 +00:00
if types.CIDType(data[0]) != types.CIDTypeEncryptedStatic {
return nil, errors.New("Invalid CID type")
}
cid, err := CIDFromBytes(data[72:])
if err != nil {
return nil, err
}
encryptedBlobHash := NewMultihash(data[3:36])
encryptionKey := data[36:68]
padding := utils.DecodeEndian(data[68:72])
chunkSizeAsPowerOf2 := int(data[2])
encryptionAlgorithm := data[1]
return NewEncryptedCID(*encryptedBlobHash, *cid, encryptionKey, padding, chunkSizeAsPowerOf2, encryptionAlgorithm), nil
}
func (c *EncryptedCID) ChunkSize() int {
return 1 << uint(c.chunkSizeAsPowerOf2)
}
func (c *EncryptedCID) ToBytes() []byte {
data := []byte{
byte(types.CIDTypeEncryptedStatic),
c.encryptionAlgorithm,
byte(c.chunkSizeAsPowerOf2),
}
data = append(data, c.encryptedBlobHash.FullBytes...)
data = append(data, c.encryptionKey...)
data = append(data, utils.EncodeEndian(c.padding, 4)...)
2024-01-03 20:27:35 +00:00
data = append(data, c.OriginalCID.ToBytes()...)
2024-01-03 13:46:30 +00:00
return data
}
2024-01-04 13:19:26 +00:00
func (c EncryptedCID) EncodeMsgpack(enc *msgpack.Encoder) error {
return enc.EncodeBytes(c.ToBytes())
}
2024-01-04 13:19:26 +00:00
func (c *EncryptedCID) DecodeMsgpack(dec *msgpack.Decoder) error {
return decodeMsgpackCID(c, dec)
}
func (c EncryptedCID) MarshalJSON() ([]byte, error) {
str, err := c.ToString()
if err != nil {
return nil, err
}
// Delegate to the MarshalJSON method of the encoder
return json.Marshal(str)
}
func (c *EncryptedCID) UnmarshalJSON(data []byte) error {
decData, err := serialize.UnmarshalBase64UrlJSON(data)
if err != nil {
return err
}
decodedCid, err := EncryptedCIDFromBytes(decData)
if err != nil {
return err
}
*c = *decodedCid
return nil
}