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

     1  package serialnumbernoprivacy
     2  
     3  import (
     4  	"errors"
     5  	"github.com/incognitochain/go-incognito-sdk/privacy"
     6  	"github.com/incognitochain/go-incognito-sdk/privacy/zkp/utils"
     7  )
     8  
     9  type SerialNumberNoPrivacyStatement struct {
    10  	output *privacy.Point
    11  	vKey   *privacy.Point
    12  	input  *privacy.Scalar
    13  }
    14  
    15  // SNNoPrivacyWitness is a protocol for Zero-knowledge Proof of Knowledge of one out of many commitments containing 0
    16  // include Witness: CommitedValue, r []byte
    17  type SNNoPrivacyWitness struct {
    18  	stmt SerialNumberNoPrivacyStatement
    19  	seed *privacy.Scalar
    20  }
    21  
    22  // serialNumberNNoPrivacyProof contains Proof's value
    23  type SNNoPrivacyProof struct {
    24  	// general info
    25  	stmt SerialNumberNoPrivacyStatement
    26  
    27  	tSeed   *privacy.Point
    28  	tOutput *privacy.Point
    29  
    30  	zSeed *privacy.Scalar
    31  }
    32  
    33  func (proof SNNoPrivacyProof) ValidateSanity() bool {
    34  	if !proof.stmt.output.PointValid() {
    35  		return false
    36  	}
    37  	if !proof.stmt.vKey.PointValid() {
    38  		return false
    39  	}
    40  	if !proof.stmt.input.ScalarValid() {
    41  		return false
    42  	}
    43  
    44  	if !proof.tSeed.PointValid() {
    45  		return false
    46  	}
    47  	if !proof.tOutput.PointValid() {
    48  		return false
    49  	}
    50  	return proof.zSeed.ScalarValid()
    51  }
    52  
    53  func (pro SNNoPrivacyProof) isNil() bool {
    54  	if pro.stmt.output == nil {
    55  		return true
    56  	}
    57  	if pro.stmt.vKey == nil {
    58  		return true
    59  	}
    60  	if pro.stmt.input == nil {
    61  		return true
    62  	}
    63  	if pro.tSeed == nil {
    64  		return true
    65  	}
    66  	if pro.tOutput == nil {
    67  		return true
    68  	}
    69  	if pro.zSeed == nil {
    70  		return true
    71  	}
    72  	return false
    73  }
    74  
    75  func (pro *SNNoPrivacyProof) Init() *SNNoPrivacyProof {
    76  	pro.stmt.output = new(privacy.Point)
    77  	pro.stmt.vKey = new(privacy.Point)
    78  	pro.stmt.input = new(privacy.Scalar)
    79  
    80  	pro.tSeed = new(privacy.Point)
    81  	pro.tOutput = new(privacy.Point)
    82  
    83  	pro.zSeed = new(privacy.Scalar)
    84  
    85  	return pro
    86  }
    87  
    88  func (pro SNNoPrivacyProof) GetVKey() *privacy.Point {
    89  	return pro.stmt.vKey
    90  }
    91  
    92  func (pro SNNoPrivacyProof) GetInput() *privacy.Scalar {
    93  	return pro.stmt.input
    94  }
    95  
    96  func (pro SNNoPrivacyProof) GetOutput() *privacy.Point {
    97  	return pro.stmt.output
    98  }
    99  
   100  // Set sets Witness
   101  func (wit *SNNoPrivacyWitness) Set(
   102  	output *privacy.Point,
   103  	vKey *privacy.Point,
   104  	input *privacy.Scalar,
   105  	seed *privacy.Scalar) {
   106  
   107  	if wit == nil {
   108  		wit = new(SNNoPrivacyWitness)
   109  	}
   110  
   111  	wit.stmt.output = output
   112  	wit.stmt.vKey = vKey
   113  	wit.stmt.input = input
   114  
   115  	wit.seed = seed
   116  }
   117  
   118  // Set sets Proof
   119  func (pro *SNNoPrivacyProof) Set(
   120  	output *privacy.Point,
   121  	vKey *privacy.Point,
   122  	input *privacy.Scalar,
   123  	tSeed *privacy.Point,
   124  	tOutput *privacy.Point,
   125  	zSeed *privacy.Scalar) {
   126  
   127  	if pro == nil {
   128  		pro = new(SNNoPrivacyProof)
   129  	}
   130  
   131  	pro.stmt.output = output
   132  	pro.stmt.vKey = vKey
   133  	pro.stmt.input = input
   134  
   135  	pro.tSeed = tSeed
   136  	pro.tOutput = tOutput
   137  
   138  	pro.zSeed = zSeed
   139  }
   140  
   141  func (pro SNNoPrivacyProof) Bytes() []byte {
   142  	// if proof is nil, return an empty array
   143  	if pro.isNil() {
   144  		return []byte{}
   145  	}
   146  
   147  	var bytes []byte
   148  	bytes = append(bytes, pro.stmt.output.ToBytesS()...)
   149  	bytes = append(bytes, pro.stmt.vKey.ToBytesS()...)
   150  	bytes = append(bytes, pro.stmt.input.ToBytesS()...)
   151  
   152  	bytes = append(bytes, pro.tSeed.ToBytesS()...)
   153  	bytes = append(bytes, pro.tOutput.ToBytesS()...)
   154  
   155  	bytes = append(bytes, pro.zSeed.ToBytesS()...)
   156  
   157  	return bytes
   158  }
   159  
   160  func (pro *SNNoPrivacyProof) SetBytes(bytes []byte) error {
   161  	if len(bytes) == 0 {
   162  		return errors.New("Bytes array is empty")
   163  	}
   164  
   165  	offset := 0
   166  	var err error
   167  	pro.stmt.output, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize])
   168  	if err != nil {
   169  		return err
   170  	}
   171  	offset += privacy.Ed25519KeySize
   172  
   173  	pro.stmt.vKey, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize])
   174  	if err != nil {
   175  		return err
   176  	}
   177  	offset += privacy.Ed25519KeySize
   178  
   179  	pro.stmt.input.FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize])
   180  	offset += privacy.Ed25519KeySize
   181  
   182  	pro.tSeed, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize])
   183  	if err != nil {
   184  		return err
   185  	}
   186  	offset += privacy.Ed25519KeySize
   187  
   188  	pro.tOutput, err = new(privacy.Point).FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize])
   189  	if err != nil {
   190  		return err
   191  	}
   192  	offset += privacy.Ed25519KeySize
   193  
   194  	pro.zSeed.FromBytesS(bytes[offset : offset+privacy.Ed25519KeySize])
   195  
   196  	return nil
   197  }
   198  
   199  func (wit SNNoPrivacyWitness) Prove(mess []byte) (*SNNoPrivacyProof, error) {
   200  	// randomness
   201  	eSK := privacy.RandomScalar()
   202  	// calculate tSeed = g_SK^eSK
   203  	tSK := new(privacy.Point).ScalarMult(privacy.PedCom.G[privacy.PedersenPrivateKeyIndex], eSK)
   204  	// calculate tOutput = sn^eSK
   205  	tE := new(privacy.Point).ScalarMult(wit.stmt.output, eSK)
   206  	x := new(privacy.Scalar)
   207  	if mess == nil {
   208  		// calculate x = hash(tSeed || tInput || tSND2 || tOutput)
   209  		// recheck frombytes is valid scalar
   210  		x = utils.GenerateChallenge([][]byte{wit.stmt.output.ToBytesS(), wit.stmt.vKey.ToBytesS(), tSK.ToBytesS(), tE.ToBytesS()})
   211  	} else {
   212  		x.FromBytesS(mess)
   213  	}
   214  	// Calculate zSeed = SK * x + eSK
   215  	zSK := new(privacy.Scalar).Mul(wit.seed, x)
   216  	zSK.Add(zSK, eSK)
   217  	proof := new(SNNoPrivacyProof).Init()
   218  	proof.Set(wit.stmt.output, wit.stmt.vKey, wit.stmt.input, tSK, tE, zSK)
   219  	return proof, nil
   220  }
   221  
   222  func (pro SNNoPrivacyProof) Verify(mess []byte) (bool, error) {
   223  	// re-calculate x = hash(tSeed || tOutput)
   224  	x := new(privacy.Scalar)
   225  	if mess == nil {
   226  		// calculate x = hash(tSeed || tInput || tSND2 || tOutput)
   227  		x = utils.GenerateChallenge([][]byte{pro.tSeed.ToBytesS(), pro.tOutput.ToBytesS()})
   228  	} else {
   229  		x.FromBytesS(mess)
   230  	}
   231  
   232  	// Check gSK^zSeed = vKey^x * tSeed
   233  	leftPoint1 := new(privacy.Point).ScalarMult(privacy.PedCom.G[privacy.PedersenPrivateKeyIndex], pro.zSeed)
   234  
   235  	rightPoint1 := new(privacy.Point).ScalarMult(pro.stmt.vKey, x)
   236  	rightPoint1 = rightPoint1.Add(rightPoint1, pro.tSeed)
   237  
   238  	if !privacy.IsPointEqual(leftPoint1, rightPoint1) {
   239  		return false, errors.New("verify serial number no privacy proof statement 1 failed")
   240  	}
   241  
   242  	// Check sn^(zSeed + x*input) = gSK^x * tOutput
   243  	tmp := new(privacy.Scalar).Add(pro.zSeed, new(privacy.Scalar).Mul(x, pro.stmt.input))
   244  	leftPoint2 := new(privacy.Point).ScalarMult(pro.stmt.output, tmp)
   245  
   246  	rightPoint2 := new(privacy.Point).ScalarMult(privacy.PedCom.G[privacy.PedersenPrivateKeyIndex], x)
   247  	rightPoint2 = rightPoint2.Add(rightPoint2, pro.tOutput)
   248  
   249  	if !privacy.IsPointEqual(leftPoint2, rightPoint2) {
   250  		return false, errors.New("verify serial number no privacy proof statement 2 failed")
   251  	}
   252  
   253  	return true, nil
   254  }