github.com/jiajun1992/watercarver@v0.0.0-20191031150618-dfc2b17c0c4a/StadiumForWaterCarver/src/SchnorrProof.cpp (about) 1 #include "SchnorrProof.h" 2 3 #include "CurvePoint.h" 4 #include "FakeZZ.h" 5 #include "Functions.h" 6 #include <string.h> 7 #include <openssl/sha.h> 8 NTL_CLIENT 9 10 const ZZ ord = ZZ(NTL::conv<NTL::ZZ>("7237005577332262213973186563042994240857116359379907606001950938285454250989")); 11 12 // TODO: small proof sizes are inefficient (serialized and deserialized twice) 13 ZZ SchnorrProof::fiat_shamir() { 14 // this can be preprocessed in SHA but probably cheap 15 char temp[CurvePoint::bytesize + 32]; 16 CurvePoint bp = curve_basepoint(); 17 bp.serialize(temp); // don't need canonical repr: basepoint is a constant 18 19 memcpy(&temp[CurvePoint::bytesize], this->a_canonical, 32); 20 string s = string(temp, CurvePoint::bytesize+32); 21 unsigned char hash[SHA256_DIGEST_LENGTH]; 22 Functions::sha256(s, hash); 23 24 ZZ c; 25 ZZFromBytes(c, hash, CurvePoint::bytesize+32); 26 return c % ord; 27 } 28 29 // prove and serialize 30 31 SchnorrProof::SchnorrProof(const ZZ& alpha) { 32 ZZ c, w; 33 w = RandomBnd(ord); 34 basepoint_scalarmult(this->a, w); 35 this->a.serialize_canonical(this->a_canonical); 36 c = fiat_shamir(); 37 38 ZZ t1; 39 MulMod(t1, alpha, c, ord); 40 AddMod(this->r, t1, w, ord); 41 } 42 43 void SchnorrProof::serialize(char *output) { 44 unsigned char* o = (unsigned char*) output; 45 this->a.serialize(&output[0]); 46 memcpy(&output[CurvePoint::bytesize], this->a_canonical, 32); 47 BytesFromZZ(&o[CurvePoint::bytesize+32], this->r, 32); 48 } 49 50 // deserialize and verify 51 52 SchnorrProof::SchnorrProof(const char *serialized) { 53 unsigned char* s = (unsigned char*) serialized; 54 this->a.deserialize(&serialized[0]); 55 memcpy(this->a_canonical, &serialized[CurvePoint::bytesize], 32); 56 ZZFromBytes(this->r, &s[CurvePoint::bytesize+32], 32); 57 } 58 59 // given x = g^alpha, g, and proof (r, a) 60 int SchnorrProof::verify(const CurvePoint& x) { 61 ZZ c; 62 c = fiat_shamir(); 63 64 CurvePoint ta0, tg, ta; 65 basepoint_scalarmult(tg, this->r); 66 PowerMod(ta0, x, c, ZZ(0)); // these don't work with fake ZZs 67 MulMod(ta, this->a, ta0, ZZ(0)); 68 69 return ta == tg; 70 }