github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/swarm/api/encrypt.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:46</date>
    10  //</624342668872257536>
    11  
    12  //
    13  //
    14  //
    15  //
    16  //
    17  //
    18  //
    19  //
    20  //
    21  //
    22  //
    23  //
    24  //
    25  //
    26  //
    27  
    28  package api
    29  
    30  import (
    31  	"encoding/binary"
    32  	"errors"
    33  
    34  	"github.com/ethereum/go-ethereum/crypto/sha3"
    35  	"github.com/ethereum/go-ethereum/swarm/storage/encryption"
    36  )
    37  
    38  type RefEncryption struct {
    39  	spanEncryption encryption.Encryption
    40  	dataEncryption encryption.Encryption
    41  	span           []byte
    42  }
    43  
    44  func NewRefEncryption(refSize int) *RefEncryption {
    45  	span := make([]byte, 8)
    46  	binary.LittleEndian.PutUint64(span, uint64(refSize))
    47  	return &RefEncryption{
    48  		spanEncryption: encryption.New(0, uint32(refSize/32), sha3.NewKeccak256),
    49  		dataEncryption: encryption.New(refSize, 0, sha3.NewKeccak256),
    50  		span:           span,
    51  	}
    52  }
    53  
    54  func (re *RefEncryption) Encrypt(ref []byte, key []byte) ([]byte, error) {
    55  	encryptedSpan, err := re.spanEncryption.Encrypt(re.span, key)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  	encryptedData, err := re.dataEncryption.Encrypt(ref, key)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  	encryptedRef := make([]byte, len(ref)+8)
    64  	copy(encryptedRef[:8], encryptedSpan)
    65  	copy(encryptedRef[8:], encryptedData)
    66  
    67  	return encryptedRef, nil
    68  }
    69  
    70  func (re *RefEncryption) Decrypt(ref []byte, key []byte) ([]byte, error) {
    71  	decryptedSpan, err := re.spanEncryption.Decrypt(ref[:8], key)
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  
    76  	size := binary.LittleEndian.Uint64(decryptedSpan)
    77  	if size != uint64(len(ref)-8) {
    78  		return nil, errors.New("invalid span in encrypted reference")
    79  	}
    80  
    81  	decryptedRef, err := re.dataEncryption.Decrypt(ref[8:], key)
    82  	if err != nil {
    83  		return nil, err
    84  	}
    85  
    86  	return decryptedRef, nil
    87  }
    88