Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
dark64 committed Jan 4, 2023
1 parent a9d6e97 commit 2b35549
Show file tree
Hide file tree
Showing 40 changed files with 615 additions and 514 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import "utils/pack/bool/nonStrictUnpack256" as unpack256;

// Compress JubJub Curve Point to 256bit array using big endianness bit order
// Python reference code from pycrypto:
// Compress curve point to a 256-bit boolean array using the big-endian bit order
// Python code reference:
// def compress(self):
// x = self.x.n
// y = self.y.n
// return int.to_bytes(y | ((x & 1) << 255), 32, "big")

def main(field[2] pt) -> bool[256] {
def main(field[2] pt) -> bool[256] {
field x = pt[0];
field y = pt[1];

Expand All @@ -18,4 +17,4 @@ def main(field[2] pt) -> bool[256] {
yBits[0] = sign;

return yBits;
}
}
13 changes: 13 additions & 0 deletions zokrates_stdlib/stdlib/ecc/babyjubjub/params.zok
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma curve bn128

// The `a` coefficient of the twisted Edwards curve
const field EDWARDS_A = 168700;

// The `d` coefficient of the twisted Edwards curve
const field EDWARDS_D = 168696;

// The generator point
const field[2] G = [
16540640123574156134436876038791482806971768689494387082833631921987005038935, // Gx
20819045374670962167435360035096875258406992893633759881276124905556507972311 // Gy
];
21 changes: 21 additions & 0 deletions zokrates_stdlib/stdlib/ecc/babyjubjub/proofOfOwnership.zok
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import "utils/pack/bool/nonStrictUnpack256" as unpack256;
from "./params" import EDWARDS_A, EDWARDS_D, G;
from "ecc/edwards" import scalarMul;

/// Verifies match of a given public/private keypair.
///
/// Checks if the following equation holds for the provided keypair:
/// pk = sk*G
/// where G is the chosen base point of the subgroup
/// and * denotes scalar multiplication in the subgroup
///
/// Arguments:
/// pk: Curve point (public key)
/// sk: Private key
///
/// Returns true for pk/sk being a valid keypair, false otherwise.
def main(field[2] pk, field sk) -> bool {
bool[256] sk_bits = unpack256(sk);
field[2] res = scalarMul(sk_bits, G, EDWARDS_A, EDWARDS_D);
return (res[0] == pk[0] && res[1] == pk[1]);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import "hashes/sha256/1024bitPadded" as sha256;
import "ecc/edwardsScalarMult" as scalarMult;
import "ecc/edwardsAdd" as add;
import "utils/pack/bool/nonStrictUnpack256" as unpack256bool;
import "utils/pack/u32/nonStrictUnpack256" as unpack256u;
import "ecc/edwardsOnCurve" as onCurve;
import "ecc/edwardsOrderCheck" as orderCheck;
from "ecc/babyjubjubParams" import BabyJubJubParams;
import "utils/casts/u32_8_to_bool_256";
from "utils/casts" import cast;
from "ecc/edwards" import add, scalarMul, onCurve, orderCheck;
from "./params" import EDWARDS_A, EDWARDS_D, G;

/// Verifies an EdDSA Signature.
///
Expand All @@ -23,29 +20,27 @@ import "utils/casts/u32_8_to_bool_256";
/// R: Curve point. Hidden version of the per-message nonce.
/// S: Field element. Signature to be verified.
/// A: Curve point. Public part of the key used to create S.
/// M0: 256bit array. First 256bits of the message used to create S .
/// M1: 256bit array. Trailing 256bits of the message used to create S .
/// context: Curve parameters used to create S.
/// M0: 256bit array. First 256bits of the message used to create S.
/// M1: 256bit array. Trailing 256bits of the message used to create S.
///
/// Returns:
/// Return true for S being a valid EdDSA Signature, false otherwise.
def main(field[2] R, field S, field[2] A, u32[8] M0, u32[8] M1, BabyJubJubParams context) -> bool {
field[2] G = [context.Gu, context.Gv];

def main(field[2] R, field S, field[2] A, u32[8] M0, u32[8] M1) -> bool {
// Check if R is on curve and if it is not in a small subgroup. A is public input and can be checked offline
assert(onCurve(R, context)); // throws if R is not on curve
assert(orderCheck(R, context));
assert(onCurve(R, EDWARDS_A, EDWARDS_D)); // throws if R is not on curve
assert(orderCheck(R, EDWARDS_A, EDWARDS_D));

u32[8] Rx = unpack256u(R[0]);
u32[8] Ax = unpack256u(A[0]);
bool[256] hRAM = u32_8_to_bool_256(sha256(Rx, Ax, M0, M1));

u32[8] h = sha256(Rx, Ax, M0, M1);
bool[256] hRAM = cast(h);

bool[256] sBits = unpack256bool(S);
field[2] lhs = scalarMult(sBits, G, context);
field[2] lhs = scalarMul(sBits, G, EDWARDS_A, EDWARDS_D);

field[2] AhRAM = scalarMult(hRAM, A, context);
field[2] rhs = add(R, AhRAM, context);
field[2] AhRAM = scalarMul(hRAM, A, EDWARDS_A, EDWARDS_D);
field[2] rhs = add(R, AhRAM, EDWARDS_A, EDWARDS_D);

bool out = rhs[0] == lhs[0] && rhs[1] == lhs[1];
return out;
}
return (rhs[0] == lhs[0] && rhs[1] == lhs[1]);
}
37 changes: 0 additions & 37 deletions zokrates_stdlib/stdlib/ecc/babyjubjubParams.zok

This file was deleted.

61 changes: 61 additions & 0 deletions zokrates_stdlib/stdlib/ecc/edwards.zok
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Add two points on a twisted Edwards curve
// https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Addition_on_twisted_Edwards_curves
def add(field[2] pt1, field[2] pt2, field a, field d) -> field[2] {
field u1 = pt1[0];
field v1 = pt1[1];
field u2 = pt2[0];
field v2 = pt2[1];

field u = (u1*v2 + v1*u2) / (1 + d*u1*u2*v1*v2);
field v = (v1*v2 - a*u1*u2) / (1 - d*u1*u2*v1*v2);
return [u, v];
}

// Check if a point is on a twisted Edwards curve
// See appendix 3.3.1 of Zcash protocol specification:
// https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
def onCurve(field[2] pt, field a, field d) -> bool {
field uu = pt[0] * pt[0];
field vv = pt[1] * pt[1];
field uuvv = uu * vv;

assert(a * uu + vv == 1 + d * uuvv);
return true;
}

// Function that implements scalar multiplication for a fixed base point
// Reference: https://github.com/zcash-hackworks/sapling-crypto/blob/master/src/jubjub/fs.rs#L555
def scalarMul<N>(bool[N] exponent, field[2] pt, field a, field d) -> field[2] {
field[2] mut res = pt;
field[2] mut acc = [0, 1];

for u32 i in 0..N {
u32 j = N - i - 1;
field[2] candidate = add(acc, res, a, d);
acc = exponent[j] ? candidate : acc;
res = add(res, res, a, d);
}

assert(onCurve(acc, a, d));
return acc;
}

// Negate a point on an Edwards curve
// Twisted Edwards Curves, BBJLP-2008, section 2 pg 2
def negate(field[2] pt) -> field[2] {
field u = pt[0];
field v = pt[1];
return [-u, v];
}

// Verifies that the point is not one of the low-order points.
// If any of the points is multiplied by the cofactor, the resulting point will be infinity.
// Returns true if the point is not one of the low-order points, false otherwise.
// Cofactor is hard-coded to 8 for efficiency reasons
// Reference: https://github.com/zcash-hackworks/sapling-crypto/blob/master/src/jubjub/edwards.rs#L166
def orderCheck(field[2] pt, field a, field d) -> bool {
field[2] mut res = add(pt, pt, a, d); // 2*pt
res = add(res, res, a, d); // 4*pt
res = add(res, res, a, d); // 8*pt
return !(res[0] == 0 && res[1] == 1);
}
20 changes: 0 additions & 20 deletions zokrates_stdlib/stdlib/ecc/edwardsAdd.zok

This file was deleted.

9 changes: 0 additions & 9 deletions zokrates_stdlib/stdlib/ecc/edwardsNegate.zok

This file was deleted.

17 changes: 0 additions & 17 deletions zokrates_stdlib/stdlib/ecc/edwardsOnCurve.zok

This file was deleted.

26 changes: 0 additions & 26 deletions zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.zok

This file was deleted.

26 changes: 0 additions & 26 deletions zokrates_stdlib/stdlib/ecc/edwardsScalarMult.zok

This file was deleted.

13 changes: 13 additions & 0 deletions zokrates_stdlib/stdlib/ecc/jubjub/params.zok
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma curve bls12_381

// The `a` coefficient of the twisted Edwards curve
const field EDWARDS_A = -1;

// The `d` coefficient of the twisted Edwards curve (-10240/10241 mod p)
const field EDWARDS_D = 19257038036680949359750312669786877991949435402254120286184196891950884077233;

// The generator point
const field[2] G = [
11076627216317271660298050606127911965867021807910416450833192264015104452986, // Gx
44412834903739585386157632289020980010620626017712148233229312325549216099227 // Gy
];
28 changes: 0 additions & 28 deletions zokrates_stdlib/stdlib/ecc/proofOfOwnership.zok

This file was deleted.

Loading

0 comments on commit 2b35549

Please sign in to comment.