Beispiel #1
0
// Point doubling; See http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-mdbl-1987-m
void xz_ge_double(felem xout, felem zout, const felem xin)
{
    static const felem fone = {1};
    felem xx1, t0, t1, t2;
    fsquare_times(xx1, xin, 1);
    fcopy(t0, fone);
    fdifference_backwards(t0, xx1);
    fsquare_times(xout, t0, 1);
    fscalar_product(t1, xin, 486662);
    fsum(t1, xx1);
    fsum(t1, fone);
    fmul(t2, xin, t1);
    fscalar_product(zout, t2, 4);
}
Beispiel #2
0
fmonty(felem *x2,  /* output 2Q */
       felem *x3,  /* output Q + Q' */
       felem *x,    /* input Q */
       felem *xprime,  /* input Q' */
       const felem *qmqp /* input Q - Q' */) {
  felem *const z2 = &x2[5];
  felem *const z3 = &x3[5];
  felem *const z = &x[5];
  felem *const zprime = &xprime[5];
  felem origx[5], origxprime[5], zzz[5], xx[5], zz[5], xxprime[5],
        zzprime[5], zzzprime[5];

  memcpy(origx, x, 5 * sizeof(felem));
  fsum(x, z);
  fdifference_backwards(z, origx);  // does x - z

  memcpy(origxprime, xprime, sizeof(felem) * 5);
  fsum(xprime, zprime);
  fdifference_backwards(zprime, origxprime);
  fmul(xxprime, xprime, z);
  fmul(zzprime, x, zprime);
  memcpy(origxprime, xxprime, sizeof(felem) * 5);
  fsum(xxprime, zzprime);
  fdifference_backwards(zzprime, origxprime);
  fsquare(x3, xxprime);
  fsquare(zzzprime, zzprime);
  fmul(z3, zzzprime, qmqp);

  fsquare(xx, x);
  fsquare(zz, z);
  fmul(x2, xx, zz);
  fdifference_backwards(zz, xx);  // does zz = xx - zz
  fscalar(zzz, zz); // * 121665
  freduce_coefficients(zzz);
  fsum(zzz, xx);
  fmul(z2, zz, zzz);
}
Beispiel #3
0
void zktest()
{
    /*
     # Given the public key of B (remote_pub), shows that the shared secret
     # between A and B was generated by A.
     # Returns zero-knowledge proof of shared Diffie-Hellman secret between A & B.
     def prove_shared_secret(self, remote_pub):
     G = self.G; prover_pub = self.public; phi = self. P - 1;
     secret = self.get_shared_secret(remote_pub)
     
     # Random key in the group Z_q
     randKey = DiffieHellman() # random secret
     commit1 = randKey.public
     commit2 = randKey.get_shared_secret(remote_pub)
     */
    void fdifference_backwards(uint64_t *out, const uint64_t *in); // output = in - output
    void fmul(uint64_t *output,const uint64_t *in,const uint64_t *in2);
    void fcontract(uint8_t *output, const uint64_t *input);
    void fexpand(uint64_t *output, const uint8_t *in);
    bits256 curve25519(bits256,bits256);
    static uint8_t _basepoint[32] = {9};
    bits320 randsecret,challenge,product,response,selfsecret,secret;
    bits256 remote_pub,basepoint,remote_secret,randkey,commit1,commit2,_secret,tmp,buf[8]; int32_t n = 0;
    tmp = GENESIS_PRIVKEY;
    _secret = curve25519(tmp,remote_pub);
    fexpand(secret.ulongs,_secret.bytes);
    randombytes(randkey.bytes,sizeof(randkey)), randkey.bytes[0] &= 248, randkey.bytes[31] &= 127, randkey.bytes[31] |= 64;
    randombytes(remote_secret.bytes,sizeof(remote_secret)), remote_secret.bytes[0] &= 248, remote_secret.bytes[31] &= 127, remote_secret.bytes[31] |= 64;
    memcpy(basepoint.bytes,_basepoint,sizeof(basepoint));
    remote_pub = curve25519(remote_secret,basepoint);
    fexpand(randsecret.ulongs,randkey.bytes);
    curve25519_donna(commit1.bytes,randkey.bytes,_basepoint);
    commit2 = curve25519(randkey,remote_pub);
    /*
     # shift and hash
     concat = str(G) + str(prover_pub) + str(remote_pub) + str(secret) + str(commit1) + str(commit2)
     h = hashlib.md5()
     h.update(concat.encode("utf-8"))
     challenge = int(h.hexdigest(), 16)
     product = (self.secret * challenge) % phi
     response = (randKey.secret - product) % phi
     
     return (secret, challenge, response)*/
    buf[n++] = GENESIS_PRIVKEY, buf[n++] = GENESIS_PUBKEY;
    buf[n++] = remote_pub, buf[n++] = _secret, buf[n++] = commit1, buf[n++] = commit2;
    memset(challenge.bytes,0,sizeof(challenge));
    calc_sha256(0,tmp.bytes,buf[0].bytes,n*sizeof(buf[0]));
    fexpand(challenge.ulongs,tmp.bytes);
    tmp = GENESIS_PRIVKEY;
    fexpand(selfsecret.ulongs,tmp.bytes);
    fmul(product.ulongs,selfsecret.ulongs,challenge.ulongs);
    response = product;
    fdifference_backwards(product.ulongs,randsecret.ulongs);
    /*
     # Verifies proof generated above. Verifier c is showing that
     # shared secret between A and B was generated by A.
     # returns 0 if if verification fails; returns shared secret otherwise
     def verify_shared_secret(self, prover_pub, remote_pub, secret, challenge,
     response):
     P = self.P; G = self.G ; public = self.public
     
     # g^r * (a's public key)^challenge
     commit1 = (pow(G, response, P) * pow(public, challenge, P)) % P
     
     # (b's public key)^response * (secret)^challenge
     commit2 = (pow(remote_pub, response, P) * pow(secret, challenge, P)) % P
     */
    bits256 _commit1b,_commit2b,_tmp2,_challenge,_response; bits320 Tmp,Tmp2,commit2b;
    fcontract(_challenge.bytes,challenge.ulongs);
    fcontract(_response.bytes,response.ulongs);
    tmp = curve25519(_secret,_challenge);
    _tmp2 = curve25519(remote_pub,_response);
    fexpand(Tmp.ulongs,tmp.bytes);
    fexpand(Tmp2.ulongs,_tmp2.bytes);
    fmul(commit2b.ulongs,Tmp.ulongs,Tmp2.ulongs);
    fcontract(_commit2b.bytes,commit2b.ulongs);
    printf("commits %llx %llx vs %llx %llx\n",commit1.txid,commit2.txid,_commit1b.txid,_commit2b.txid);
    /*
     # Shift and hash
     hasher = hashlib.md5()
     concat = str(G) + str(prover_pub) + str(remote_pub) + str(secret) + str(commit1) + str(commit2)
     hasher.update(concat.encode("utf-8"))
     check = int(hasher.hexdigest(), 16)
     
     if challenge == check:
     return secret
     else:
     return 0
     
     def main():
     a = DiffieHellman()
     b = DiffieHellman()
     results = a.prove_shared_secret(b.public)
     assert a.verify_shared_secret(a.public, b.public, results[0],  \
     results[1], results[2])
     */
}