github.com/incognitochain/go-incognito-sdk@v1.0.1/privacy/zkp/payment.go (about)

     1  package zkp
     2  
     3  import (
     4  	"encoding/base64"
     5  	"encoding/json"
     6  	"github.com/pkg/errors"
     7  	"math/big"
     8  
     9  	"github.com/incognitochain/go-incognito-sdk/common"
    10  	"github.com/incognitochain/go-incognito-sdk/privacy"
    11  	"github.com/incognitochain/go-incognito-sdk/privacy/zkp/aggregaterange"
    12  	"github.com/incognitochain/go-incognito-sdk/privacy/zkp/oneoutofmany"
    13  	"github.com/incognitochain/go-incognito-sdk/privacy/zkp/serialnumbernoprivacy"
    14  	"github.com/incognitochain/go-incognito-sdk/privacy/zkp/serialnumberprivacy"
    15  	"github.com/incognitochain/go-incognito-sdk/privacy/zkp/utils"
    16  )
    17  
    18  // PaymentProof contains all of PoK for spending coin
    19  type PaymentProof struct {
    20  	// for input coins
    21  	oneOfManyProof    []*oneoutofmany.OneOutOfManyProof
    22  	serialNumberProof []*serialnumberprivacy.SNPrivacyProof
    23  	// it is exits when tx has no privacy
    24  	serialNumberNoPrivacyProof []*serialnumbernoprivacy.SNNoPrivacyProof
    25  
    26  	// for output coins
    27  	// for proving each value and sum of them are less than a threshold value
    28  	aggregatedRangeProof *aggregaterange.AggregatedRangeProof
    29  
    30  	inputCoins  []*privacy.InputCoin
    31  	outputCoins []*privacy.OutputCoin
    32  
    33  	commitmentOutputValue   []*privacy.Point
    34  	commitmentOutputSND     []*privacy.Point
    35  	commitmentOutputShardID []*privacy.Point
    36  
    37  	commitmentInputSecretKey *privacy.Point
    38  	commitmentInputValue     []*privacy.Point
    39  	commitmentInputSND       []*privacy.Point
    40  	commitmentInputShardID   *privacy.Point
    41  
    42  	commitmentIndices []uint64
    43  }
    44  
    45  // GET/SET function
    46  func (paymentProof PaymentProof) GetOneOfManyProof() []*oneoutofmany.OneOutOfManyProof {
    47  	return paymentProof.oneOfManyProof
    48  }
    49  
    50  func (paymentProof PaymentProof) GetSerialNumberProof() []*serialnumberprivacy.SNPrivacyProof {
    51  	return paymentProof.serialNumberProof
    52  }
    53  
    54  func (paymentProof PaymentProof) GetSerialNumberNoPrivacyProof() []*serialnumbernoprivacy.SNNoPrivacyProof {
    55  	return paymentProof.serialNumberNoPrivacyProof
    56  }
    57  
    58  func (paymentProof PaymentProof) GetAggregatedRangeProof() *aggregaterange.AggregatedRangeProof {
    59  	return paymentProof.aggregatedRangeProof
    60  }
    61  
    62  func (paymentProof PaymentProof) GetCommitmentOutputValue() []*privacy.Point {
    63  	return paymentProof.commitmentOutputValue
    64  }
    65  
    66  func (paymentProof PaymentProof) GetCommitmentOutputSND() []*privacy.Point {
    67  	return paymentProof.commitmentOutputSND
    68  }
    69  
    70  func (paymentProof PaymentProof) GetCommitmentOutputShardID() []*privacy.Point {
    71  	return paymentProof.commitmentOutputShardID
    72  }
    73  
    74  func (paymentProof PaymentProof) GetCommitmentInputSecretKey() *privacy.Point {
    75  	return paymentProof.commitmentInputSecretKey
    76  }
    77  
    78  func (paymentProof PaymentProof) GetCommitmentInputValue() []*privacy.Point {
    79  	return paymentProof.commitmentInputValue
    80  }
    81  
    82  func (paymentProof PaymentProof) GetCommitmentInputSND() []*privacy.Point {
    83  	return paymentProof.commitmentInputSND
    84  }
    85  
    86  func (paymentProof PaymentProof) GetCommitmentInputShardID() *privacy.Point {
    87  	return paymentProof.commitmentInputShardID
    88  }
    89  
    90  func (paymentProof PaymentProof) GetCommitmentIndices() []uint64 {
    91  	return paymentProof.commitmentIndices
    92  }
    93  
    94  func (paymentProof PaymentProof) GetInputCoins() []*privacy.InputCoin {
    95  	return paymentProof.inputCoins
    96  }
    97  
    98  func (paymentProof *PaymentProof) SetInputCoins(v []*privacy.InputCoin) {
    99  	paymentProof.inputCoins = v
   100  }
   101  
   102  func (paymentProof PaymentProof) GetOutputCoins() []*privacy.OutputCoin {
   103  	return paymentProof.outputCoins
   104  }
   105  
   106  func (paymentProof *PaymentProof) SetOutputCoins(v []*privacy.OutputCoin) {
   107  	paymentProof.outputCoins = v
   108  }
   109  
   110  func (paymentProof *PaymentProof) SetAggregatedRangeProof(p *aggregaterange.AggregatedRangeProof ) {
   111  	paymentProof.aggregatedRangeProof = p
   112  }
   113  
   114  func (paymentProof *PaymentProof) SetSerialNumberProof(p []*serialnumberprivacy.SNPrivacyProof)  {
   115  	paymentProof.serialNumberProof = p
   116  }
   117  
   118  func (paymentProof *PaymentProof) SetOneOfManyProof(p []*oneoutofmany.OneOutOfManyProof) {
   119  	paymentProof.oneOfManyProof = p
   120  }
   121  
   122  func (paymentProof *PaymentProof) SetSerialNumberNoPrivacyProof(p []*serialnumbernoprivacy.SNNoPrivacyProof)  {
   123  	paymentProof.serialNumberNoPrivacyProof = p
   124  }
   125  
   126  
   127  // End GET/SET function
   128  
   129  // Init
   130  func (proof *PaymentProof) Init() {
   131  	aggregatedRangeProof := &aggregaterange.AggregatedRangeProof{}
   132  	aggregatedRangeProof.Init()
   133  	proof.oneOfManyProof = []*oneoutofmany.OneOutOfManyProof{}
   134  	proof.serialNumberProof = []*serialnumberprivacy.SNPrivacyProof{}
   135  	proof.aggregatedRangeProof = aggregatedRangeProof
   136  	proof.inputCoins = []*privacy.InputCoin{}
   137  	proof.outputCoins = []*privacy.OutputCoin{}
   138  
   139  	proof.commitmentOutputValue = []*privacy.Point{}
   140  	proof.commitmentOutputSND = []*privacy.Point{}
   141  	proof.commitmentOutputShardID = []*privacy.Point{}
   142  
   143  	proof.commitmentInputSecretKey = new(privacy.Point)
   144  	proof.commitmentInputValue = []*privacy.Point{}
   145  	proof.commitmentInputSND = []*privacy.Point{}
   146  	proof.commitmentInputShardID = new(privacy.Point)
   147  
   148  }
   149  
   150  // MarshalJSON - override function
   151  func (proof PaymentProof) MarshalJSON() ([]byte, error) {
   152  	data := proof.Bytes()
   153  	//temp := base58.Base58Check{}.Encode(data, common.ZeroByte)
   154  	temp := base64.StdEncoding.EncodeToString(data)
   155  	return json.Marshal(temp)
   156  }
   157  
   158  // UnmarshalJSON - override function
   159  func (proof *PaymentProof) UnmarshalJSON(data []byte) error {
   160  	dataStr := common.EmptyString
   161  	errJson := json.Unmarshal(data, &dataStr)
   162  	if errJson != nil {
   163  		return errJson
   164  	}
   165  	//temp, _, err := base58.Base58Check{}.Decode(dataStr)
   166  	temp, err := base64.StdEncoding.DecodeString(dataStr)
   167  	if err != nil {
   168  		return err
   169  	}
   170  
   171  	err = proof.SetBytes(temp)
   172  	if err.(*privacy.PrivacyError) != nil {
   173  		return err
   174  	}
   175  	return nil
   176  }
   177  
   178  func (proof *PaymentProof) Bytes() []byte {
   179  	var bytes []byte
   180  	hasPrivacy := len(proof.oneOfManyProof) > 0
   181  
   182  	// OneOfManyProofSize
   183  	bytes = append(bytes, byte(len(proof.oneOfManyProof)))
   184  	for i := 0; i < len(proof.oneOfManyProof); i++ {
   185  		oneOfManyProof := proof.oneOfManyProof[i].Bytes()
   186  		bytes = append(bytes, common.IntToBytes(utils.OneOfManyProofSize)...)
   187  		bytes = append(bytes, oneOfManyProof...)
   188  	}
   189  
   190  	// SerialNumberProofSize
   191  	bytes = append(bytes, byte(len(proof.serialNumberProof)))
   192  	for i := 0; i < len(proof.serialNumberProof); i++ {
   193  		serialNumberProof := proof.serialNumberProof[i].Bytes()
   194  		bytes = append(bytes, common.IntToBytes(utils.SnPrivacyProofSize)...)
   195  		bytes = append(bytes, serialNumberProof...)
   196  	}
   197  
   198  	// SNNoPrivacyProofSize
   199  	bytes = append(bytes, byte(len(proof.serialNumberNoPrivacyProof)))
   200  	for i := 0; i < len(proof.serialNumberNoPrivacyProof); i++ {
   201  		snNoPrivacyProof := proof.serialNumberNoPrivacyProof[i].Bytes()
   202  		bytes = append(bytes, byte(utils.SnNoPrivacyProofSize))
   203  		bytes = append(bytes, snNoPrivacyProof...)
   204  	}
   205  
   206  	//ComOutputMultiRangeProofSize
   207  	if hasPrivacy {
   208  		comOutputMultiRangeProof := proof.aggregatedRangeProof.Bytes()
   209  		bytes = append(bytes, common.IntToBytes(len(comOutputMultiRangeProof))...)
   210  		bytes = append(bytes, comOutputMultiRangeProof...)
   211  	} else {
   212  		bytes = append(bytes, []byte{0, 0}...)
   213  	}
   214  
   215  	// InputCoins
   216  	bytes = append(bytes, byte(len(proof.inputCoins)))
   217  	for i := 0; i < len(proof.inputCoins); i++ {
   218  		inputCoins := proof.inputCoins[i].Bytes()
   219  		bytes = append(bytes, byte(len(inputCoins)))
   220  		bytes = append(bytes, inputCoins...)
   221  	}
   222  
   223  	// OutputCoins
   224  	bytes = append(bytes, byte(len(proof.outputCoins)))
   225  	for i := 0; i < len(proof.outputCoins); i++ {
   226  		outputCoins := proof.outputCoins[i].Bytes()
   227  		lenOutputCoins := len(outputCoins)
   228  		lenOutputCoinsBytes := []byte{}
   229  		if lenOutputCoins < 256 {
   230  			lenOutputCoinsBytes = []byte{byte(lenOutputCoins)}
   231  		} else {
   232  			lenOutputCoinsBytes = common.IntToBytes(lenOutputCoins)
   233  		}
   234  
   235  		bytes = append(bytes, lenOutputCoinsBytes...)
   236  		bytes = append(bytes, outputCoins...)
   237  	}
   238  
   239  	// ComOutputValue
   240  	bytes = append(bytes, byte(len(proof.commitmentOutputValue)))
   241  	for i := 0; i < len(proof.commitmentOutputValue); i++ {
   242  		comOutputValue := proof.commitmentOutputValue[i].ToBytesS()
   243  		bytes = append(bytes, byte(privacy.Ed25519KeySize))
   244  		bytes = append(bytes, comOutputValue...)
   245  	}
   246  
   247  	// ComOutputSND
   248  	bytes = append(bytes, byte(len(proof.commitmentOutputSND)))
   249  	for i := 0; i < len(proof.commitmentOutputSND); i++ {
   250  		comOutputSND := proof.commitmentOutputSND[i].ToBytesS()
   251  		bytes = append(bytes, byte(privacy.Ed25519KeySize))
   252  		bytes = append(bytes, comOutputSND...)
   253  	}
   254  
   255  	// ComOutputShardID
   256  	bytes = append(bytes, byte(len(proof.commitmentOutputShardID)))
   257  	for i := 0; i < len(proof.commitmentOutputShardID); i++ {
   258  		comOutputShardID := proof.commitmentOutputShardID[i].ToBytesS()
   259  		bytes = append(bytes, byte(privacy.Ed25519KeySize))
   260  		bytes = append(bytes, comOutputShardID...)
   261  	}
   262  
   263  	//ComInputSK 				*privacy.Point
   264  	if proof.commitmentInputSecretKey != nil {
   265  		comInputSK := proof.commitmentInputSecretKey.ToBytesS()
   266  		bytes = append(bytes, byte(privacy.Ed25519KeySize))
   267  		bytes = append(bytes, comInputSK...)
   268  	} else {
   269  		bytes = append(bytes, byte(0))
   270  	}
   271  
   272  	//ComInputValue 		[]*privacy.Point
   273  	bytes = append(bytes, byte(len(proof.commitmentInputValue)))
   274  	for i := 0; i < len(proof.commitmentInputValue); i++ {
   275  		comInputValue := proof.commitmentInputValue[i].ToBytesS()
   276  		bytes = append(bytes, byte(privacy.Ed25519KeySize))
   277  		bytes = append(bytes, comInputValue...)
   278  	}
   279  
   280  	//ComInputSND 			[]*privacy.Point
   281  	bytes = append(bytes, byte(len(proof.commitmentInputSND)))
   282  	for i := 0; i < len(proof.commitmentInputSND); i++ {
   283  		comInputSND := proof.commitmentInputSND[i].ToBytesS()
   284  		bytes = append(bytes, byte(privacy.Ed25519KeySize))
   285  		bytes = append(bytes, comInputSND...)
   286  	}
   287  
   288  	//ComInputShardID 	*privacy.Point
   289  	if proof.commitmentInputShardID != nil {
   290  		comInputShardID := proof.commitmentInputShardID.ToBytesS()
   291  		bytes = append(bytes, byte(privacy.Ed25519KeySize))
   292  		bytes = append(bytes, comInputShardID...)
   293  	} else {
   294  		bytes = append(bytes, byte(0))
   295  	}
   296  
   297  	// convert commitment index to bytes array
   298  	for i := 0; i < len(proof.commitmentIndices); i++ {
   299  		bytes = append(bytes, common.AddPaddingBigInt(big.NewInt(int64(proof.commitmentIndices[i])), common.Uint64Size)...)
   300  	}
   301  	//fmt.Printf("BYTES ------------------ %v\n", bytes)
   302  	//fmt.Printf("LEN BYTES ------------------ %v\n", len(bytes))
   303  
   304  	return bytes
   305  }
   306  
   307  func (proof *PaymentProof) SetBytes(proofbytes []byte) *privacy.PrivacyError {
   308  	if len(proofbytes) == 0 {
   309  		return privacy.NewPrivacyErr(privacy.InvalidInputToSetBytesErr, nil)
   310  	}
   311  
   312  	offset := 0
   313  
   314  	// Set OneOfManyProofSize
   315  	if offset >= len(proofbytes) {
   316  		return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range one out of many proof"))
   317  	}
   318  	lenOneOfManyProofArray := int(proofbytes[offset])
   319  	offset += 1
   320  	proof.oneOfManyProof = make([]*oneoutofmany.OneOutOfManyProof, lenOneOfManyProofArray)
   321  	for i := 0; i < lenOneOfManyProofArray; i++ {
   322  		if offset+2 > len(proofbytes) {
   323  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range one out of many proof"))
   324  		}
   325  		lenOneOfManyProof := common.BytesToInt(proofbytes[offset : offset+2])
   326  		offset += 2
   327  		proof.oneOfManyProof[i] = new(oneoutofmany.OneOutOfManyProof).Init()
   328  
   329  		if offset+lenOneOfManyProof > len(proofbytes) {
   330  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range one out of many proof"))
   331  		}
   332  		err := proof.oneOfManyProof[i].SetBytes(proofbytes[offset : offset+lenOneOfManyProof])
   333  		if err != nil {
   334  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, err)
   335  		}
   336  		offset += lenOneOfManyProof
   337  	}
   338  
   339  	// Set serialNumberProofSize
   340  	if offset >= len(proofbytes) {
   341  		return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range serial number proof"))
   342  	}
   343  	lenSerialNumberProofArray := int(proofbytes[offset])
   344  	offset += 1
   345  	proof.serialNumberProof = make([]*serialnumberprivacy.SNPrivacyProof, lenSerialNumberProofArray)
   346  	for i := 0; i < lenSerialNumberProofArray; i++ {
   347  		if offset+2 > len(proofbytes) {
   348  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range serial number proof"))
   349  		}
   350  		lenSerialNumberProof := common.BytesToInt(proofbytes[offset : offset+2])
   351  		offset += 2
   352  		proof.serialNumberProof[i] = new(serialnumberprivacy.SNPrivacyProof).Init()
   353  
   354  		if offset+lenSerialNumberProof > len(proofbytes) {
   355  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range serial number proof"))
   356  		}
   357  		err := proof.serialNumberProof[i].SetBytes(proofbytes[offset : offset+lenSerialNumberProof])
   358  		if err != nil {
   359  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, err)
   360  		}
   361  		offset += lenSerialNumberProof
   362  	}
   363  
   364  	// Set SNNoPrivacyProofSize
   365  	if offset >= len(proofbytes) {
   366  		return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range serial number no privacy proof"))
   367  	}
   368  	lenSNNoPrivacyProofArray := int(proofbytes[offset])
   369  	offset += 1
   370  	proof.serialNumberNoPrivacyProof = make([]*serialnumbernoprivacy.SNNoPrivacyProof, lenSNNoPrivacyProofArray)
   371  	for i := 0; i < lenSNNoPrivacyProofArray; i++ {
   372  		if offset >= len(proofbytes) {
   373  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range serial number no privacy proof"))
   374  		}
   375  		lenSNNoPrivacyProof := int(proofbytes[offset])
   376  		offset += 1
   377  
   378  		proof.serialNumberNoPrivacyProof[i] = new(serialnumbernoprivacy.SNNoPrivacyProof).Init()
   379  		if offset+lenSNNoPrivacyProof >= len(proofbytes) {
   380  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range serial number no privacy proof"))
   381  		}
   382  		err := proof.serialNumberNoPrivacyProof[i].SetBytes(proofbytes[offset : offset+lenSNNoPrivacyProof])
   383  		if err != nil {
   384  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, err)
   385  		}
   386  		offset += lenSNNoPrivacyProof
   387  	}
   388  
   389  	//ComOutputMultiRangeProofSize *aggregatedRangeProof
   390  	if offset+2 >= len(proofbytes) {
   391  		return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range aggregated range proof"))
   392  	}
   393  	lenComOutputMultiRangeProof := common.BytesToInt(proofbytes[offset : offset+2])
   394  	offset += 2
   395  	if lenComOutputMultiRangeProof > 0 {
   396  		aggregatedRangeProof := &aggregaterange.AggregatedRangeProof{}
   397  		aggregatedRangeProof.Init()
   398  		proof.aggregatedRangeProof = aggregatedRangeProof
   399  		if offset+lenComOutputMultiRangeProof >= len(proofbytes) {
   400  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range aggregated range proof"))
   401  		}
   402  		err := proof.aggregatedRangeProof.SetBytes(proofbytes[offset : offset+lenComOutputMultiRangeProof])
   403  		if err != nil {
   404  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, err)
   405  		}
   406  		offset += lenComOutputMultiRangeProof
   407  	}
   408  
   409  	//InputCoins  []*privacy.InputCoin
   410  	if offset >= len(proofbytes) {
   411  		return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range input coins"))
   412  	}
   413  	lenInputCoinsArray := int(proofbytes[offset])
   414  	offset += 1
   415  	proof.inputCoins = make([]*privacy.InputCoin, lenInputCoinsArray)
   416  	for i := 0; i < lenInputCoinsArray; i++ {
   417  		if offset >= len(proofbytes) {
   418  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range input coins"))
   419  		}
   420  		lenInputCoin := int(proofbytes[offset])
   421  		offset += 1
   422  
   423  		proof.inputCoins[i] = new(privacy.InputCoin)
   424  		if offset+lenInputCoin >= len(proofbytes) {
   425  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range input coins"))
   426  		}
   427  		err := proof.inputCoins[i].SetBytes(proofbytes[offset : offset+lenInputCoin])
   428  		if err != nil {
   429  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, err)
   430  		}
   431  		offset += lenInputCoin
   432  	}
   433  
   434  	//OutputCoins []*privacy.OutputCoin
   435  	if offset >= len(proofbytes) {
   436  		return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range output coins"))
   437  	}
   438  	lenOutputCoinsArray := int(proofbytes[offset])
   439  	offset += 1
   440  	proof.outputCoins = make([]*privacy.OutputCoin, lenOutputCoinsArray)
   441  	for i := 0; i < lenOutputCoinsArray; i++ {
   442  		proof.outputCoins[i] = new(privacy.OutputCoin)
   443  		// try get 1-byte for len
   444  		if offset >= len(proofbytes) {
   445  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range output coins"))
   446  		}
   447  		lenOutputCoin := int(proofbytes[offset])
   448  		offset += 1
   449  
   450  		if offset+lenOutputCoin >= len(proofbytes) {
   451  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range output coins"))
   452  		}
   453  		err := proof.outputCoins[i].SetBytes(proofbytes[offset : offset+lenOutputCoin])
   454  		if err != nil {
   455  			// 1-byte is wrong
   456  			// try get 2-byte for len
   457  			if offset+1 >= len(proofbytes) {
   458  				return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range output coins"))
   459  			}
   460  			lenOutputCoin = common.BytesToInt(proofbytes[offset-1 : offset+1])
   461  			offset += 1
   462  
   463  			if offset+lenOutputCoin >= len(proofbytes) {
   464  				return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range output coins"))
   465  			}
   466  			err1 := proof.outputCoins[i].SetBytes(proofbytes[offset : offset+lenOutputCoin])
   467  			if err1 != nil {
   468  				return privacy.NewPrivacyErr(privacy.SetBytesProofErr, err)
   469  			}
   470  		}
   471  		offset += lenOutputCoin
   472  	}
   473  	//ComOutputValue   []*privacy.Point
   474  	if offset >= len(proofbytes) {
   475  		return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment output coins value"))
   476  	}
   477  	lenComOutputValueArray := int(proofbytes[offset])
   478  	offset += 1
   479  	proof.commitmentOutputValue = make([]*privacy.Point, lenComOutputValueArray)
   480  	var err error
   481  	for i := 0; i < lenComOutputValueArray; i++ {
   482  		if offset >= len(proofbytes) {
   483  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment output coins value"))
   484  		}
   485  		lenComOutputValue := int(proofbytes[offset])
   486  		offset += 1
   487  
   488  		if offset+lenComOutputValue >= len(proofbytes) {
   489  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment output coins value"))
   490  		}
   491  		proof.commitmentOutputValue[i], err = new(privacy.Point).FromBytesS(proofbytes[offset : offset+lenComOutputValue])
   492  		if err != nil {
   493  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, err)
   494  		}
   495  		offset += lenComOutputValue
   496  	}
   497  	//ComOutputSND     []*privacy.Point
   498  	if offset >= len(proofbytes) {
   499  		return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment output coins snd"))
   500  	}
   501  	lenComOutputSNDArray := int(proofbytes[offset])
   502  	offset += 1
   503  	proof.commitmentOutputSND = make([]*privacy.Point, lenComOutputSNDArray)
   504  	for i := 0; i < lenComOutputSNDArray; i++ {
   505  		if offset >= len(proofbytes) {
   506  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment output coins snd"))
   507  		}
   508  		lenComOutputSND := int(proofbytes[offset])
   509  		offset += 1
   510  
   511  		if offset+lenComOutputSND >= len(proofbytes) {
   512  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment output coins snd"))
   513  		}
   514  		proof.commitmentOutputSND[i], err = new(privacy.Point).FromBytesS(proofbytes[offset : offset+lenComOutputSND])
   515  
   516  		if err != nil {
   517  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, err)
   518  		}
   519  		offset += lenComOutputSND
   520  	}
   521  
   522  	// commitmentOutputShardID
   523  	if offset >= len(proofbytes) {
   524  		return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment output coins shardid"))
   525  	}
   526  	lenComOutputShardIdArray := int(proofbytes[offset])
   527  	offset += 1
   528  	proof.commitmentOutputShardID = make([]*privacy.Point, lenComOutputShardIdArray)
   529  	for i := 0; i < lenComOutputShardIdArray; i++ {
   530  		if offset >= len(proofbytes) {
   531  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment output coins shardid"))
   532  		}
   533  		lenComOutputShardId := int(proofbytes[offset])
   534  		offset += 1
   535  
   536  		if offset+lenComOutputShardId >= len(proofbytes) {
   537  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment output coins shardid"))
   538  		}
   539  		proof.commitmentOutputShardID[i], err = new(privacy.Point).FromBytesS(proofbytes[offset : offset+lenComOutputShardId])
   540  
   541  		if err != nil {
   542  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, err)
   543  		}
   544  		offset += lenComOutputShardId
   545  	}
   546  
   547  	//ComInputSK 				*privacy.Point
   548  	if offset >= len(proofbytes) {
   549  		return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment input coins private key"))
   550  	}
   551  	lenComInputSK := int(proofbytes[offset])
   552  	offset += 1
   553  	if lenComInputSK > 0 {
   554  		if offset+lenComInputSK >= len(proofbytes) {
   555  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment input coins private key"))
   556  		}
   557  		proof.commitmentInputSecretKey, err = new(privacy.Point).FromBytesS(proofbytes[offset : offset+lenComInputSK])
   558  
   559  		if err != nil {
   560  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, err)
   561  		}
   562  		offset += lenComInputSK
   563  	}
   564  	//ComInputValue 		[]*privacy.Point
   565  	if offset >= len(proofbytes) {
   566  		return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment input coins value"))
   567  	}
   568  	lenComInputValueArr := int(proofbytes[offset])
   569  	offset += 1
   570  	proof.commitmentInputValue = make([]*privacy.Point, lenComInputValueArr)
   571  	for i := 0; i < lenComInputValueArr; i++ {
   572  		if offset >= len(proofbytes) {
   573  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment input coins value"))
   574  		}
   575  		lenComInputValue := int(proofbytes[offset])
   576  		offset += 1
   577  
   578  		if offset+lenComInputValue >= len(proofbytes) {
   579  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment input coins value"))
   580  		}
   581  		proof.commitmentInputValue[i], err = new(privacy.Point).FromBytesS(proofbytes[offset : offset+lenComInputValue])
   582  
   583  		if err != nil {
   584  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, err)
   585  		}
   586  		offset += lenComInputValue
   587  	}
   588  	//ComInputSND 			[]*privacy.Point
   589  	if offset >= len(proofbytes) {
   590  		return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment input coins snd"))
   591  	}
   592  	lenComInputSNDArr := int(proofbytes[offset])
   593  	offset += 1
   594  	proof.commitmentInputSND = make([]*privacy.Point, lenComInputSNDArr)
   595  	for i := 0; i < lenComInputSNDArr; i++ {
   596  		if offset >= len(proofbytes) {
   597  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment input coins snd"))
   598  		}
   599  		lenComInputSND := int(proofbytes[offset])
   600  		offset += 1
   601  
   602  		if offset+lenComInputSND >= len(proofbytes) {
   603  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment input coins snd"))
   604  		}
   605  		proof.commitmentInputSND[i], err = new(privacy.Point).FromBytesS(proofbytes[offset : offset+lenComInputSND])
   606  
   607  		if err != nil {
   608  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, err)
   609  		}
   610  		offset += lenComInputSND
   611  	}
   612  	//ComInputShardID 	*privacy.Point
   613  	if offset >= len(proofbytes) {
   614  		return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment input coins shardid"))
   615  	}
   616  	lenComInputShardID := int(proofbytes[offset])
   617  	offset += 1
   618  	if lenComInputShardID > 0 {
   619  		if offset+lenComInputShardID > len(proofbytes) {
   620  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment input coins shardid"))
   621  		}
   622  		proof.commitmentInputShardID, err = new(privacy.Point).FromBytesS(proofbytes[offset : offset+lenComInputShardID])
   623  
   624  		if err != nil {
   625  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, err)
   626  		}
   627  		offset += lenComInputShardID
   628  	}
   629  
   630  	// get commitments list
   631  	proof.commitmentIndices = make([]uint64, len(proof.oneOfManyProof)*privacy.CommitmentRingSize)
   632  	for i := 0; i < len(proof.oneOfManyProof)*privacy.CommitmentRingSize; i++ {
   633  		if offset+common.Uint64Size > len(proofbytes) {
   634  			return privacy.NewPrivacyErr(privacy.SetBytesProofErr, errors.New("Out of range commitment indices"))
   635  		}
   636  		proof.commitmentIndices[i] = new(big.Int).SetBytes(proofbytes[offset : offset+common.Uint64Size]).Uint64()
   637  		offset = offset + common.Uint64Size
   638  	}
   639  
   640  	//fmt.Printf("SETBYTES ------------------ %v\n", proof.Bytes())
   641  
   642  	return nil
   643  }