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 }