118 lines
2.9 KiB
Go
118 lines
2.9 KiB
Go
package encoding
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"git.lumeweb.com/LumeWeb/libs5-go/types"
|
|
"git.lumeweb.com/LumeWeb/libs5-go/utils"
|
|
"github.com/vmihailenco/msgpack/v5"
|
|
)
|
|
|
|
type EncryptedCID struct {
|
|
Multibase
|
|
encryptedBlobHash Multihash
|
|
OriginalCID CID
|
|
encryptionAlgorithm byte
|
|
padding uint32
|
|
chunkSizeAsPowerOf2 int
|
|
encryptionKey []byte
|
|
}
|
|
|
|
var _ msgpack.CustomEncoder = (*EncryptedCID)(nil)
|
|
var _ msgpack.CustomDecoder = (*EncryptedCID)(nil)
|
|
var _ json.Marshaler = (*EncryptedCID)(nil)
|
|
var _ json.Unmarshaler = (*EncryptedCID)(nil)
|
|
|
|
func NewEncryptedCID(encryptedBlobHash Multihash, originalCID CID, encryptionKey []byte, padding uint32, chunkSizeAsPowerOf2 int, encryptionAlgorithm byte) *EncryptedCID {
|
|
e := &EncryptedCID{
|
|
encryptedBlobHash: encryptedBlobHash,
|
|
OriginalCID: originalCID,
|
|
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)
|
|
}
|
|
|
|
func EncryptedCIDFromBytes(data []byte) (*EncryptedCID, error) {
|
|
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)...)
|
|
data = append(data, c.OriginalCID.ToBytes()...)
|
|
return data
|
|
}
|
|
func (c EncryptedCID) EncodeMsgpack(enc *msgpack.Encoder) error {
|
|
return enc.EncodeBytes(c.ToBytes())
|
|
}
|
|
|
|
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 := UnmarshalBase64UrlJSON(data)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
decodedCid, err := EncryptedCIDFromBytes(decData)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
*c = *decodedCid
|
|
return nil
|
|
}
|