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  }