From 28e78ddba6749e7c532e2fac826c24d4e8d3577b Mon Sep 17 00:00:00 2001 From: sdeml Date: Thu, 28 Feb 2019 19:17:02 +0100 Subject: [PATCH 01/22] add babyjubjub and eddsa implementation and tests --- stdlib/ecc/babyjubjubParams.code | 22 +++++ stdlib/ecc/edwardsAdd.code | 18 ++++ stdlib/ecc/edwardsNegate.code | 10 +++ stdlib/ecc/edwardsOnCurve.code | 16 ++++ stdlib/ecc/edwardsOrderCheck.code | 17 ++++ stdlib/ecc/edwardsScalarMult.code | 26 ++++++ stdlib/hashes/sha256/1024bitPadded.code | 15 ++++ stdlib/signatures/verifyEddsa.code | 45 ++++++++++ .../TestStdlib/ecc/testedwardsAdd.code | 35 ++++++++ .../TestStdlib/ecc/testedwardsOnCurve.code | 19 ++++ .../TestStdlib/ecc/testedwardsOrderCheck.code | 31 +++++++ .../TestStdlib/ecc/testedwardsScalarMult.code | 89 +++++++++++++++++++ 12 files changed, 343 insertions(+) create mode 100644 stdlib/ecc/babyjubjubParams.code create mode 100644 stdlib/ecc/edwardsAdd.code create mode 100644 stdlib/ecc/edwardsNegate.code create mode 100644 stdlib/ecc/edwardsOnCurve.code create mode 100644 stdlib/ecc/edwardsOrderCheck.code create mode 100644 stdlib/ecc/edwardsScalarMult.code create mode 100644 stdlib/hashes/sha256/1024bitPadded.code create mode 100644 stdlib/signatures/verifyEddsa.code create mode 100644 zokrates_cli/examples/TestStdlib/ecc/testedwardsAdd.code create mode 100644 zokrates_cli/examples/TestStdlib/ecc/testedwardsOnCurve.code create mode 100644 zokrates_cli/examples/TestStdlib/ecc/testedwardsOrderCheck.code create mode 100644 zokrates_cli/examples/TestStdlib/ecc/testedwardsScalarMult.code diff --git a/stdlib/ecc/babyjubjubParams.code b/stdlib/ecc/babyjubjubParams.code new file mode 100644 index 00000000..4b103c3e --- /dev/null +++ b/stdlib/ecc/babyjubjubParams.code @@ -0,0 +1,22 @@ +// Parameters are based on: https://github.com/HarryR/ethsnarks/tree/master/src/jubjub +// Note: paramters will be update soon to be more compatible with zCash's implementation +def main() -> (field[10]): + +// Order of the curve E + field JUBJUBE = 21888242871839275222246405745257275088614511777268538073601725287587578984328 + field JUBJUBC = 8 // Cofactor + field JUBJUBA = 168700 // Coefficient A + field JUBJUBD = 168696 // Coefficient D + field MONTA = 168698 // int(2*(JUBJUB_A+JUBJUB_D)/(JUBJUB_A-JUBJUB_D)) + field MONTB = 1 // int(4/(JUBJUB_A-JUBJUB_D)) + +// Point at infinity + field[2] infinity = [0, 1] + +// Generator + field Gu = 16540640123574156134436876038791482806971768689494387082833631921987005038935 + field Gv = 20819045374670962167435360035096875258406992893633759881276124905556507972311 + +// Index +// 0 1 2 3 4 5 6 7 8 10 + return [JUBJUBA, JUBJUBD, infinity[0], infinity[1], Gu, Gv, JUBJUBE, JUBJUBC, MONTA, MONTB] \ No newline at end of file diff --git a/stdlib/ecc/edwardsAdd.code b/stdlib/ecc/edwardsAdd.code new file mode 100644 index 00000000..73bc8ba4 --- /dev/null +++ b/stdlib/ecc/edwardsAdd.code @@ -0,0 +1,18 @@ +import "ecc/babyjubjubParams.code" as context +// Function adds two points on a twisted Edwards curve +// Curve parameters are defined with the last argument +// https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Addition_on_twisted_Edwards_curves +def main(field[2] pt1, field[2] pt2, field[10] context) -> (field[2]): + + field a = context[0] + field d = context[1] + + field u1 = pt1[0] + field v1 = pt1[1] + field u2 = pt2[0] + field v2 = pt2[1] + + field uOut = (u1*v2 + v1*u2) / (1 + d*u1*u2*v1*v2) + field vOut = (v1*v2 - a*u1*u2) / (1 - d*u1*u2*v1*v2) + + return [uOut, vOut] \ No newline at end of file diff --git a/stdlib/ecc/edwardsNegate.code b/stdlib/ecc/edwardsNegate.code new file mode 100644 index 00000000..a94f95b6 --- /dev/null +++ b/stdlib/ecc/edwardsNegate.code @@ -0,0 +1,10 @@ +import "ecc/babyjubjubParams.code" as context +// Function negates a given edwards point. +// Curve parameters are defined with the last argument +// Twisted Edwards Curves, BBJLP-2008, section 2 pg 2 +def main(field[2] pt, field[10] context) -> (field[2]): + + field u = pt[0] + field v = pt[1] + + return [0-u, v] \ No newline at end of file diff --git a/stdlib/ecc/edwardsOnCurve.code b/stdlib/ecc/edwardsOnCurve.code new file mode 100644 index 00000000..0652024d --- /dev/null +++ b/stdlib/ecc/edwardsOnCurve.code @@ -0,0 +1,16 @@ +// Function checks if a provided point is on a twisted Edwards curve +// Curve parameters are defined with the last argument +// See appendix 3.3.1 of Zcash protocol specification: +// https://github.com/zcash/zips/blob/master/protocol/protocol.pdf +def main(field[2] pt, field[10] context) -> (field): + + field a = context[0] + field d = context[1] + + field uu = pt[0] * pt[0] + field vv = pt[1] * pt[1] + field uuvv = uu * vv + + a * uu + vv == 1 + d * uuvv + + return 1 diff --git a/stdlib/ecc/edwardsOrderCheck.code b/stdlib/ecc/edwardsOrderCheck.code new file mode 100644 index 00000000..cff778d3 --- /dev/null +++ b/stdlib/ecc/edwardsOrderCheck.code @@ -0,0 +1,17 @@ +import "ecc/edwardsAdd.code" as add +import "ecc/edwardsScalarMult.code" as multiply +// 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 ture if the point is not one of the low-order points. +// https://github.com/zcash-hackworks/sapling-crypto/blob/master/src/jubjub/edwards.rs#L166 +def main(field[2] pt, field[10] context) -> (field): + + // exponentBit = 8 //TODO: use cofactor from context .. currently hardcoded + field[256] cofactorExponent = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0] + + field[2] ptExp = multiply(cofactorExponent, pt, context) + + field out = if ptExp[0] == 0 && ptExp[1] == 1 then 0 else 1 fi + + return out \ No newline at end of file diff --git a/stdlib/ecc/edwardsScalarMult.code b/stdlib/ecc/edwardsScalarMult.code new file mode 100644 index 00000000..c5c08c6b --- /dev/null +++ b/stdlib/ecc/edwardsScalarMult.code @@ -0,0 +1,26 @@ +import "ecc/edwardsAdd.code" as add +import "ecc/edwardsOnCurve.code" as assertOnCurve +// Function that implements scalar multiplication for a given base point +// Curve parameters are defined with the last argument +// https://github.com/zcash-hackworks/sapling-crypto/blob/master/src/jubjub/fs.rs#L555 +def main(field[256] exponent, field[2] pt, field[10] context) -> (field[2]): + //FIXME: how to deal with bool checks + + field[2] infinity = [context[2], context[3]] + + field[2] doubledP = pt + field[2] accumulatedP = infinity + + field j = 255 + accumulatedP = if exponent[j] == 1 then doubledP else accumulatedP fi + + for field i in 1..256 do + j = 255 - i + doubledP = add(doubledP, doubledP, context) + candidateP = add(accumulatedP, doubledP, context) + accumulatedP = if exponent[j] == 1 then candidateP else accumulatedP fi + endfor + + 1 == assertOnCurve(accumulatedP, context) + + return accumulatedP \ No newline at end of file diff --git a/stdlib/hashes/sha256/1024bitPadded.code b/stdlib/hashes/sha256/1024bitPadded.code new file mode 100644 index 00000000..b645373c --- /dev/null +++ b/stdlib/hashes/sha256/1024bitPadded.code @@ -0,0 +1,15 @@ +import "./1536bit.code" as sha256 +// A function that takes 2 field[256] arrays as inputs +// and returns their sha256 full round output as an array of 256 field elements. +def main(field[256] a, field[256] b, field[256] c, field[256] d) -> (field[256]): + + // Hash is computed on the full 512bit block size + // padding does not fit in the primary block + // add dummy block (single "1" followed by "0" + total length) + field[256] dummyblock1 = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + // total length of message is 512 bits: 0b1000000000 + field[256] dummyblock2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + + digest = sha256(a, b, c, d, dummyblock1, dummyblock2) + + return digest \ No newline at end of file diff --git a/stdlib/signatures/verifyEddsa.code b/stdlib/signatures/verifyEddsa.code new file mode 100644 index 00000000..b76b6941 --- /dev/null +++ b/stdlib/signatures/verifyEddsa.code @@ -0,0 +1,45 @@ +// Verify EdDSA Signature +import "hashes/sha256/1024bitPadded.code" as sha256 +import "ecc/edwardsScalarMult.code" as scalarMult +import "ecc/babyjubjubParams.code" as context +import "ecc/edwardsAdd.code" as add + +def hRAM() -> (field[256]): + + field[256] R = [0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0] + field[256] A = [0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1] + field[256] M0 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + field[256] M1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1] + + field[256] digest = sha256(R, A, M0, M1) + + return digest + +def main() -> (field): + + context = context() + field[2] G = [context[4], context[5]] + + //Signature + field[2] R = [2310334251273148205629776852438936186326534611651372548071123108202312784312, 17435915496234440935571912234316592550708735361458479021736016881784475171077] + field[256] S = [0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0] + //TODO: check R on curve? + + //Private Key + field[2] A = [14897476871502190904409029696666322856887678969656209656241038339251270171395, 16668832459046858928951622951481252834155254151733002984053501254009901876174] + //TODO: check A on curve? + + field[256] hRAM = hRAM() + // set 3 MSB to 0 + hRAM[0] = 0 + hRAM[1] = 0 + hRAM[2] = 0 + + field[2] lhs = scalarMult(S, G, context) + + field[2] AhRAM = scalarMult(hRAM, A, context) + field[2] rhs = add(R, AhRAM, context) + + lhs == rhs + + return 1 diff --git a/zokrates_cli/examples/TestStdlib/ecc/testedwardsAdd.code b/zokrates_cli/examples/TestStdlib/ecc/testedwardsAdd.code new file mode 100644 index 00000000..942b9924 --- /dev/null +++ b/zokrates_cli/examples/TestStdlib/ecc/testedwardsAdd.code @@ -0,0 +1,35 @@ +import "ecc/edwardsAdd.code" as add +import "ecc/edwardsNegate.code" as neg +import "ecc/babyjubjubParams.code" as context + +def testDoubleViaAdd() -> (field): + context = context() + field[2] G = [context[4], context[5]] + + field[2] out = add(G, G, context) + + out[0] == 17324563846726889236817837922625232543153115346355010501047597319863650987830 + out[1] == 20022170825455209233733649024450576091402881793145646502279487074566492066831 + + return 1 + +def testIdentities() -> (field): + context = context() + field[2] G = [context[4], context[5]] + field[2] inf = [context[2], context[3]] + + G == add(G, inf, context) + + field[2] nG = neg(G, context) + field[2] nGaddG = add(G, nG, context) + + inf == nGaddG + + return 1 + +def main() -> (field): + + 1 == testDoubleViaAdd() + 1 == testIdentities() + +return 1 \ No newline at end of file diff --git a/zokrates_cli/examples/TestStdlib/ecc/testedwardsOnCurve.code b/zokrates_cli/examples/TestStdlib/ecc/testedwardsOnCurve.code new file mode 100644 index 00000000..85b673a0 --- /dev/null +++ b/zokrates_cli/examples/TestStdlib/ecc/testedwardsOnCurve.code @@ -0,0 +1,19 @@ +import "ecc/babyjubjubParams.code" as context +import "ecc/edwardsOnCurve.code" as onCurve + +def testOnCurveTrue() -> (field): + context = context() + + field testU = 17324563846726889236817837922625232543153115346355010501047597319863650987830 + field testV = 20022170825455209233733649024450576091402881793145646502279487074566492066831 + + 1 == onCurve([testU, testV], context) + + return 1 + +def main() -> (field): + + 1 == testOnCurveTrue() + // onCurve throws for false + + return 1 diff --git a/zokrates_cli/examples/TestStdlib/ecc/testedwardsOrderCheck.code b/zokrates_cli/examples/TestStdlib/ecc/testedwardsOrderCheck.code new file mode 100644 index 00000000..0bd78074 --- /dev/null +++ b/zokrates_cli/examples/TestStdlib/ecc/testedwardsOrderCheck.code @@ -0,0 +1,31 @@ +import "ecc/edwardsOrderCheck.code" as orderCheck +import "ecc/babyjubjubParams.code" as context + +def testOrderCheckTrue() -> (field): + context = context() + + field testU = 17324563846726889236817837922625232543153115346355010501047597319863650987830 + field testV = 20022170825455209233733649024450576091402881793145646502279487074566492066831 + + field out = orderCheck([testU, testV], context) + out == 1 + + return 1 + +def testOrderCheckFalse() -> (field): + context = context() + + field testU = 4342719913949491028786768530115087822524712248835451589697801404893164183326 + field testV = 4826523245007015323400664741523384119579596407052839571721035538011798951543 + + field out = orderCheck([testU, testV], context) + out == 0 + + return 1 + +def main() -> (field): + + 1 == testOrderCheckFalse() + 1 == testOrderCheckTrue() + + return 1 \ No newline at end of file diff --git a/zokrates_cli/examples/TestStdlib/ecc/testedwardsScalarMult.code b/zokrates_cli/examples/TestStdlib/ecc/testedwardsScalarMult.code new file mode 100644 index 00000000..1d0bf98d --- /dev/null +++ b/zokrates_cli/examples/TestStdlib/ecc/testedwardsScalarMult.code @@ -0,0 +1,89 @@ +import "ecc/babyjubjubParams.code" as context +import "ecc/edwardsScalarMult.code" as mul + +def testCyclic() -> (field): + context = context() + field[2] G = [context[4], context[5]] + + // exp = JUBJUB_E + 1 + field[256] exp = [0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1] + field[2] out = mul(exp, G, context) + + G == out + + return 1 + +def testMul2() -> (field): + context = context() + field[2] G = [context[4], context[5]] + + // exp == 2 + field[256] exp = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0] + field[2] out = mul(exp, G, context) + + out[0] == 17324563846726889236817837922625232543153115346355010501047597319863650987830 + out[1] == 20022170825455209233733649024450576091402881793145646502279487074566492066831 + + return 1 + +def testAssociativity() -> (field): + context = context() + field[2] G = [context[4], context[5]] + + // a = 1234 + field[256] a = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0] + // b = 5678 + field[256] b = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0] + // c = 7890 + field[256] c = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0] + + field[2] Ga = mul(a, G, context) + field[2] Gab = mul(b, Ga, context) + field[2] Gabc = mul(c, Gab, context) + + field[2] Gb = mul(b, G, context) + field[2] Gbc = mul(c, Gb, context) + field[2] Gbca = mul(a, Gbc, context) + + field[2] Gc = mul(c, G, context) + field[2] Gca = mul(a, Gc, context) + field[2] Gcab = mul(b, Gca, context) + + Gabc == Gbca + Gbca == Gcab + Gabc == Gcab + + return 1 + +def testMultiplicative() -> (field): + context = context() + field[2] G = [context[4], context[5]] + + // a = 1234 + field[256] a = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0] + // b = 5678 + field[256] b = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0] + // ab = a*b = 7006652 + field[256] ab = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0] + + field[2] Ga = mul(a, G, context) + field[2] Gb = mul(b, G, context) + + field[2] Gab = mul(b, Ga, context) + field[2] Gba = mul(a, Gb, context) + + field[2] Gmab = mul(ab, G, context) + + Gab == Gba + Gba == Gmab + Gab == Gmab + + return 1 + +def main() -> (field): + 1 == testMul2() + 1 == testCyclic() + 1 == testAssociativity() + 1 == testMultiplicative() + + return 1 \ No newline at end of file From db21c672e45be3028d65bdc9f5564f3e0d935c7a Mon Sep 17 00:00:00 2001 From: sdeml Date: Sun, 3 Mar 2019 08:53:19 +0100 Subject: [PATCH 02/22] verifyEddas uses unpack256 --- stdlib/signatures/verifyEddsa.code | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/stdlib/signatures/verifyEddsa.code b/stdlib/signatures/verifyEddsa.code index b76b6941..0f9bd538 100644 --- a/stdlib/signatures/verifyEddsa.code +++ b/stdlib/signatures/verifyEddsa.code @@ -3,17 +3,7 @@ import "hashes/sha256/1024bitPadded.code" as sha256 import "ecc/edwardsScalarMult.code" as scalarMult import "ecc/babyjubjubParams.code" as context import "ecc/edwardsAdd.code" as add - -def hRAM() -> (field[256]): - - field[256] R = [0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0] - field[256] A = [0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1] - field[256] M0 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - field[256] M1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1] - - field[256] digest = sha256(R, A, M0, M1) - - return digest +import "utils/pack/unpack256.code" as unpack256 def main() -> (field): @@ -23,13 +13,18 @@ def main() -> (field): //Signature field[2] R = [2310334251273148205629776852438936186326534611651372548071123108202312784312, 17435915496234440935571912234316592550708735361458479021736016881784475171077] field[256] S = [0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0] - //TODO: check R on curve? + //FIXME: check R on curve? //Private Key field[2] A = [14897476871502190904409029696666322856887678969656209656241038339251270171395, 16668832459046858928951622951481252834155254151733002984053501254009901876174] - //TODO: check A on curve? - field[256] hRAM = hRAM() + field[256] Rx = unpack256(R[0]) + field[256] Ax = unpack256(A[0]) + field[256] M0 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + field[256] M1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1] + + field[256] hRAM = sha256(Rx, Ax, M0, M1) + // set 3 MSB to 0 hRAM[0] = 0 hRAM[1] = 0 From cb5ef4e0fe3214db8ec6c3827d5204330338e19f Mon Sep 17 00:00:00 2001 From: sdeml Date: Mon, 4 Mar 2019 09:54:23 +0100 Subject: [PATCH 03/22] add checks for R and add tests --- stdlib/signatures/verifyEddsa.code | 26 +++++++------------ .../signatures/testverifyEddsa.code | 18 +++++++++++++ 2 files changed, 27 insertions(+), 17 deletions(-) create mode 100644 zokrates_cli/examples/TestStdlib/signatures/testverifyEddsa.code diff --git a/stdlib/signatures/verifyEddsa.code b/stdlib/signatures/verifyEddsa.code index 0f9bd538..1b8ffab4 100644 --- a/stdlib/signatures/verifyEddsa.code +++ b/stdlib/signatures/verifyEddsa.code @@ -4,33 +4,25 @@ import "ecc/edwardsScalarMult.code" as scalarMult import "ecc/babyjubjubParams.code" as context import "ecc/edwardsAdd.code" as add import "utils/pack/unpack256.code" as unpack256 +import "ecc/edwardsOnCurve.code" as onCurve +import "ecc/edwardsOrderCheck.code" as orderCheck -def main() -> (field): +def main(field[2] R, field S, field[2] A, field[256] M0, field[256] M1) -> (field): context = context() field[2] G = [context[4], context[5]] - //Signature - field[2] R = [2310334251273148205629776852438936186326534611651372548071123108202312784312, 17435915496234440935571912234316592550708735361458479021736016881784475171077] - field[256] S = [0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0] - //FIXME: check R on curve? - - //Private Key - field[2] A = [14897476871502190904409029696666322856887678969656209656241038339251270171395, 16668832459046858928951622951481252834155254151733002984053501254009901876174] + // Check if R is on curve and in prime-order sub-group. A is public input and can be checked offline + field isOnCurve = onCurve(R, context) // throws if R is not on curve + field isPrimeOrder = orderCheck(R, context) + 1 == isPrimeOrder field[256] Rx = unpack256(R[0]) field[256] Ax = unpack256(A[0]) - field[256] M0 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - field[256] M1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1] - field[256] hRAM = sha256(Rx, Ax, M0, M1) - // set 3 MSB to 0 - hRAM[0] = 0 - hRAM[1] = 0 - hRAM[2] = 0 - - field[2] lhs = scalarMult(S, G, context) + field[256] sBits = unpack256(S) + field[2] lhs = scalarMult(sBits, G, context) field[2] AhRAM = scalarMult(hRAM, A, context) field[2] rhs = add(R, AhRAM, context) diff --git a/zokrates_cli/examples/TestStdlib/signatures/testverifyEddsa.code b/zokrates_cli/examples/TestStdlib/signatures/testverifyEddsa.code new file mode 100644 index 00000000..f8a4a0ab --- /dev/null +++ b/zokrates_cli/examples/TestStdlib/signatures/testverifyEddsa.code @@ -0,0 +1,18 @@ +import "signatures/verifyEddsa.code" as verifyEddsa + +def main() -> (field): + + field[2] R = [20197911405516193152560090893341588680064377398162745404177962124159545390767, 9171190326927340493105240100684097896571028312802691203521747450053192554927] + field S = 6050429445242986634735172402304257690628456074852538287769363221635064371045 + + // Private Key + field[2] A = [14897476871502190904409029696666322856887678969656209656241038339251270171395, 16668832459046858928951622951481252834155254151733002984053501254009901876174] + + field[256] M0 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + field[256] M1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1] + + + field isVerified = verifyEddsa(R, S, A, M0, M1) + 1 == isVerified + + return 1 \ No newline at end of file From ed2104ba8aa85c02e46288f9ca80b4d3b19e9321 Mon Sep 17 00:00:00 2001 From: sdeml Date: Tue, 5 Mar 2019 09:07:55 +0100 Subject: [PATCH 04/22] make sig a private input --- stdlib/signatures/verifyEddsa.code | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/signatures/verifyEddsa.code b/stdlib/signatures/verifyEddsa.code index 1b8ffab4..fbaaf32a 100644 --- a/stdlib/signatures/verifyEddsa.code +++ b/stdlib/signatures/verifyEddsa.code @@ -7,7 +7,7 @@ import "utils/pack/unpack256.code" as unpack256 import "ecc/edwardsOnCurve.code" as onCurve import "ecc/edwardsOrderCheck.code" as orderCheck -def main(field[2] R, field S, field[2] A, field[256] M0, field[256] M1) -> (field): +def main(private field[2] R, private field S, field[2] A, field[256] M0, field[256] M1) -> (field): context = context() field[2] G = [context[4], context[5]] From 797969d3842b7e7a623423e19e3e6d2108f4b715 Mon Sep 17 00:00:00 2001 From: sdeml Date: Thu, 14 Mar 2019 12:01:09 +0100 Subject: [PATCH 05/22] add proofOfOwnership and tests --- stdlib/ecc/proofOfOwnership.code | 14 +++++++ stdlib/signatures/verifyEddsa.code | 37 +++++++++---------- .../TestStdlib/ecc/testproofOfOwnership.code | 33 +++++++++++++++++ .../signatures/testverifyEddsa.code | 20 +++++----- 4 files changed, 75 insertions(+), 29 deletions(-) create mode 100644 stdlib/ecc/proofOfOwnership.code create mode 100644 zokrates_cli/examples/TestStdlib/ecc/testproofOfOwnership.code diff --git a/stdlib/ecc/proofOfOwnership.code b/stdlib/ecc/proofOfOwnership.code new file mode 100644 index 00000000..9040837a --- /dev/null +++ b/stdlib/ecc/proofOfOwnership.code @@ -0,0 +1,14 @@ +import "ecc/edwardsAdd.code" as add +import "ecc/edwardsScalarMult.code" as multiply +import "utils/pack/unpack256.code" as unpack256 +// Return true for a valid public and private key pair, false otherwise +def main(field[2] pk, field sk, field[10] context) -> (field): + + field[2] G = [context[4], context[5]] + + field[256] skBits = unpack256(sk) + field[2] ptExp = multiply(skBits, G, context) + + field out = if ptExp[0] == pk[0] && ptExp[1] == pk[1] then 1 else 0 fi + + return out \ No newline at end of file diff --git a/stdlib/signatures/verifyEddsa.code b/stdlib/signatures/verifyEddsa.code index fbaaf32a..1166ab98 100644 --- a/stdlib/signatures/verifyEddsa.code +++ b/stdlib/signatures/verifyEddsa.code @@ -1,32 +1,29 @@ -// Verify EdDSA Signature import "hashes/sha256/1024bitPadded.code" as sha256 import "ecc/edwardsScalarMult.code" as scalarMult -import "ecc/babyjubjubParams.code" as context import "ecc/edwardsAdd.code" as add import "utils/pack/unpack256.code" as unpack256 import "ecc/edwardsOnCurve.code" as onCurve import "ecc/edwardsOrderCheck.code" as orderCheck +// Return true for a valid EdDSA Signature, false otherwise +def main(private field[2] R, private field S, field[2] A, field[256] M0, field[256] M1, field[10] context) -> (field): -def main(private field[2] R, private field S, field[2] A, field[256] M0, field[256] M1) -> (field): + field[2] G = [context[4], context[5]] - context = context() - field[2] G = [context[4], context[5]] + // Check if R is on curve and in prime-order sub-group. A is public input and can be checked offline + field isOnCurve = onCurve(R, context) // throws if R is not on curve + field isPrimeOrder = orderCheck(R, context) + 1 == isPrimeOrder - // Check if R is on curve and in prime-order sub-group. A is public input and can be checked offline - field isOnCurve = onCurve(R, context) // throws if R is not on curve - field isPrimeOrder = orderCheck(R, context) - 1 == isPrimeOrder - - field[256] Rx = unpack256(R[0]) - field[256] Ax = unpack256(A[0]) - field[256] hRAM = sha256(Rx, Ax, M0, M1) + field[256] Rx = unpack256(R[0]) + field[256] Ax = unpack256(A[0]) + field[256] hRAM = sha256(Rx, Ax, M0, M1) - field[256] sBits = unpack256(S) - field[2] lhs = scalarMult(sBits, G, context) + field[256] sBits = unpack256(S) + field[2] lhs = scalarMult(sBits, G, context) - field[2] AhRAM = scalarMult(hRAM, A, context) - field[2] rhs = add(R, AhRAM, context) + field[2] AhRAM = scalarMult(hRAM, A, context) + field[2] rhs = add(R, AhRAM, context) - lhs == rhs - - return 1 + field out = if rhs[0] == lhs[0] && rhs[1] == lhs[1] then 1 else 0 fi + + return out diff --git a/zokrates_cli/examples/TestStdlib/ecc/testproofOfOwnership.code b/zokrates_cli/examples/TestStdlib/ecc/testproofOfOwnership.code new file mode 100644 index 00000000..36ec0f55 --- /dev/null +++ b/zokrates_cli/examples/TestStdlib/ecc/testproofOfOwnership.code @@ -0,0 +1,33 @@ +import "ecc/babyjubjubParams.code" as context +import "ecc/proofOfOwnership.code" as proofOfOwnership +import "ecc/edwardsScalarMult.code" as multiply +import "utils/pack/unpack256.code" as unpack256 + +def testOwnershipTrue() -> (field): + context = context() + field[2] G = [context[4], context[5]] + + field[2] Pk = [14897476871502190904409029696666322856887678969656209656241038339251270171395, 16668832459046858928951622951481252834155254151733002984053501254009901876174] + field sk = 1997011358982923168928344992199991480689546837621580239342656433234255379025 + + field out = proofOfOwnership(Pk, sk, context) + + out == 1 + return 1 + +def testtOwnershipFalse() -> (field): + context = context() + + field[256] Pk = [16328093915569409528980874702678312730273137210288183490878184636452430630129, 9377227749598842756429258362864743065769435972445705966557343775367597326529] + field sk = 1997011358982923168928344992199991480689546837621580239342656433234255379025 + field out = proofOfOwnership(Pk, sk, context) + + out == 0 + return 1 + +def main() -> (field): + + 1 == testOwnershipTrue() + 1 == testtOwnershipFalse() + + return 1 \ No newline at end of file diff --git a/zokrates_cli/examples/TestStdlib/signatures/testverifyEddsa.code b/zokrates_cli/examples/TestStdlib/signatures/testverifyEddsa.code index f8a4a0ab..0f9ff8f1 100644 --- a/zokrates_cli/examples/TestStdlib/signatures/testverifyEddsa.code +++ b/zokrates_cli/examples/TestStdlib/signatures/testverifyEddsa.code @@ -1,18 +1,20 @@ import "signatures/verifyEddsa.code" as verifyEddsa +import "ecc/babyjubjubParams.code" as context def main() -> (field): - field[2] R = [20197911405516193152560090893341588680064377398162745404177962124159545390767, 9171190326927340493105240100684097896571028312802691203521747450053192554927] - field S = 6050429445242986634735172402304257690628456074852538287769363221635064371045 +context = context() - // Private Key - field[2] A = [14897476871502190904409029696666322856887678969656209656241038339251270171395, 16668832459046858928951622951481252834155254151733002984053501254009901876174] + field[2] R = [20197911405516193152560090893341588680064377398162745404177962124159545390767, 9171190326927340493105240100684097896571028312802691203521747450053192554927] + field S = 6050429445242986634735172402304257690628456074852538287769363221635064371045 - field[256] M0 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - field[256] M1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1] + // Private Key + field[2] A = [14897476871502190904409029696666322856887678969656209656241038339251270171395, 16668832459046858928951622951481252834155254151733002984053501254009901876174] + field[256] M0 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + field[256] M1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1] - field isVerified = verifyEddsa(R, S, A, M0, M1) - 1 == isVerified + field isVerified = verifyEddsa(R, S, A, M0, M1, context) + isVerified == 1 - return 1 \ No newline at end of file + return 1 \ No newline at end of file From 3a14796dcef16e1c31fce8844354517286844474 Mon Sep 17 00:00:00 2001 From: sdeml Date: Fri, 15 Mar 2019 18:04:57 +0100 Subject: [PATCH 06/22] use stdlib crate --- {stdlib => zokrates_stdlib/stdlib}/ecc/babyjubjubParams.code | 0 {stdlib => zokrates_stdlib/stdlib}/ecc/edwardsAdd.code | 0 {stdlib => zokrates_stdlib/stdlib}/ecc/edwardsNegate.code | 0 {stdlib => zokrates_stdlib/stdlib}/ecc/edwardsOnCurve.code | 0 {stdlib => zokrates_stdlib/stdlib}/ecc/edwardsOrderCheck.code | 0 {stdlib => zokrates_stdlib/stdlib}/ecc/edwardsScalarMult.code | 0 {stdlib => zokrates_stdlib/stdlib}/ecc/proofOfOwnership.code | 0 .../stdlib}/hashes/sha256/1024bitPadded.code | 0 {stdlib => zokrates_stdlib/stdlib}/signatures/verifyEddsa.code | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename {stdlib => zokrates_stdlib/stdlib}/ecc/babyjubjubParams.code (100%) rename {stdlib => zokrates_stdlib/stdlib}/ecc/edwardsAdd.code (100%) rename {stdlib => zokrates_stdlib/stdlib}/ecc/edwardsNegate.code (100%) rename {stdlib => zokrates_stdlib/stdlib}/ecc/edwardsOnCurve.code (100%) rename {stdlib => zokrates_stdlib/stdlib}/ecc/edwardsOrderCheck.code (100%) rename {stdlib => zokrates_stdlib/stdlib}/ecc/edwardsScalarMult.code (100%) rename {stdlib => zokrates_stdlib/stdlib}/ecc/proofOfOwnership.code (100%) rename {stdlib => zokrates_stdlib/stdlib}/hashes/sha256/1024bitPadded.code (100%) rename {stdlib => zokrates_stdlib/stdlib}/signatures/verifyEddsa.code (100%) diff --git a/stdlib/ecc/babyjubjubParams.code b/zokrates_stdlib/stdlib/ecc/babyjubjubParams.code similarity index 100% rename from stdlib/ecc/babyjubjubParams.code rename to zokrates_stdlib/stdlib/ecc/babyjubjubParams.code diff --git a/stdlib/ecc/edwardsAdd.code b/zokrates_stdlib/stdlib/ecc/edwardsAdd.code similarity index 100% rename from stdlib/ecc/edwardsAdd.code rename to zokrates_stdlib/stdlib/ecc/edwardsAdd.code diff --git a/stdlib/ecc/edwardsNegate.code b/zokrates_stdlib/stdlib/ecc/edwardsNegate.code similarity index 100% rename from stdlib/ecc/edwardsNegate.code rename to zokrates_stdlib/stdlib/ecc/edwardsNegate.code diff --git a/stdlib/ecc/edwardsOnCurve.code b/zokrates_stdlib/stdlib/ecc/edwardsOnCurve.code similarity index 100% rename from stdlib/ecc/edwardsOnCurve.code rename to zokrates_stdlib/stdlib/ecc/edwardsOnCurve.code diff --git a/stdlib/ecc/edwardsOrderCheck.code b/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code similarity index 100% rename from stdlib/ecc/edwardsOrderCheck.code rename to zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code diff --git a/stdlib/ecc/edwardsScalarMult.code b/zokrates_stdlib/stdlib/ecc/edwardsScalarMult.code similarity index 100% rename from stdlib/ecc/edwardsScalarMult.code rename to zokrates_stdlib/stdlib/ecc/edwardsScalarMult.code diff --git a/stdlib/ecc/proofOfOwnership.code b/zokrates_stdlib/stdlib/ecc/proofOfOwnership.code similarity index 100% rename from stdlib/ecc/proofOfOwnership.code rename to zokrates_stdlib/stdlib/ecc/proofOfOwnership.code diff --git a/stdlib/hashes/sha256/1024bitPadded.code b/zokrates_stdlib/stdlib/hashes/sha256/1024bitPadded.code similarity index 100% rename from stdlib/hashes/sha256/1024bitPadded.code rename to zokrates_stdlib/stdlib/hashes/sha256/1024bitPadded.code diff --git a/stdlib/signatures/verifyEddsa.code b/zokrates_stdlib/stdlib/signatures/verifyEddsa.code similarity index 100% rename from stdlib/signatures/verifyEddsa.code rename to zokrates_stdlib/stdlib/signatures/verifyEddsa.code From efb79f08ac0080f7a150a095f385a557e1494d2e Mon Sep 17 00:00:00 2001 From: sdeml Date: Fri, 15 Mar 2019 18:13:20 +0100 Subject: [PATCH 07/22] fix test --- zokrates_cli/examples/TestStdlib/ecc/testproofOfOwnership.code | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zokrates_cli/examples/TestStdlib/ecc/testproofOfOwnership.code b/zokrates_cli/examples/TestStdlib/ecc/testproofOfOwnership.code index 36ec0f55..352b6fb7 100644 --- a/zokrates_cli/examples/TestStdlib/ecc/testproofOfOwnership.code +++ b/zokrates_cli/examples/TestStdlib/ecc/testproofOfOwnership.code @@ -18,7 +18,7 @@ def testOwnershipTrue() -> (field): def testtOwnershipFalse() -> (field): context = context() - field[256] Pk = [16328093915569409528980874702678312730273137210288183490878184636452430630129, 9377227749598842756429258362864743065769435972445705966557343775367597326529] + field[2] Pk = [16328093915569409528980874702678312730273137210288183490878184636452430630129, 9377227749598842756429258362864743065769435972445705966557343775367597326529] field sk = 1997011358982923168928344992199991480689546837621580239342656433234255379025 field out = proofOfOwnership(Pk, sk, context) From c09e01c92d47570e1b92c6f80bed27bf349ff67a Mon Sep 17 00:00:00 2001 From: sdeml Date: Fri, 15 Mar 2019 18:22:52 +0100 Subject: [PATCH 08/22] fix 2bit multiplexer test --- .../utils/multiplexer/test2bit.code | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/zokrates_cli/examples/TestStdlib/utils/multiplexer/test2bit.code b/zokrates_cli/examples/TestStdlib/utils/multiplexer/test2bit.code index 7a720e60..46267804 100644 --- a/zokrates_cli/examples/TestStdlib/utils/multiplexer/test2bit.code +++ b/zokrates_cli/examples/TestStdlib/utils/multiplexer/test2bit.code @@ -1,12 +1,28 @@ import "utils/multiplexer/2bit.code" as multiplex -def main() -> (field[2]): - field bit = 1 - - field[2] output = [0, 0] +def left() -> (field): + field bit = 0 //left field[2] a = [0, 1] field[2] b = [1, 0] - + + field[2] output = [0, 1] output == multiplex(bit, a, b) - return output \ No newline at end of file + return 1 + +def right() -> (field): + field bit = 1 //left + field[2] a = [0, 1] + field[2] b = [1, 0] + + field[2] output = [1, 0] + output == multiplex(bit, a, b) + + return 1 + +def main() -> (field): + + 1 == left() + 1 == right() + + return 1 \ No newline at end of file From 0dd9631814ffdfa7931eca4e0710f795865f67ae Mon Sep 17 00:00:00 2001 From: sdeml Date: Fri, 15 Mar 2019 18:27:06 +0100 Subject: [PATCH 09/22] add Stefan to authors --- zokrates_stdlib/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zokrates_stdlib/Cargo.toml b/zokrates_stdlib/Cargo.toml index 81d953f1..b050e243 100644 --- a/zokrates_stdlib/Cargo.toml +++ b/zokrates_stdlib/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "zokrates_stdlib" version = "0.1.0" -authors = ["schaeff "] +authors = ["schaeff ", "Stefan Deml "] edition = "2018" [features] From 999ea97eb1cfc7647a685b846d5a69b38d1d966f Mon Sep 17 00:00:00 2001 From: sdeml Date: Fri, 15 Mar 2019 18:46:46 +0100 Subject: [PATCH 10/22] migrate tests to new testing framework --- .../tests/bench/ecc/edwardsAdd.code | 0 zokrates_stdlib/tests/bench/ecc/edwardsAdd.json | 15 +++++++++++++++ .../tests/bench/ecc/edwardsOnCurve.code | 0 .../tests/bench/ecc/edwardsOnCurve.json | 15 +++++++++++++++ .../tests/bench/ecc/edwardsOrderCheck.code | 0 .../tests/bench/ecc/edwardsOrderCheck.json | 15 +++++++++++++++ .../tests/bench/ecc/edwardsScalarMult.code | 0 .../tests/bench/ecc/edwardsScalarMult.json | 15 +++++++++++++++ .../tests/bench/ecc/proofOfOwnership.code | 0 .../tests/bench/ecc/proofOfOwnership.json | 15 +++++++++++++++ .../tests/bench/hashes/sha256/512bit.code | 0 .../tests/bench/hashes/sha256/512bit.json | 15 +++++++++++++++ .../tests/bench/hashes/sha256/512bitPacked.code | 0 .../{hash => hashes/sha256}/512bitPacked.json | 0 .../tests/bench/hashes/sha256/512bitPacked2.json | 15 +++++++++++++++ .../tests/bench/hashes/sha256/512bitPadded.code | 0 .../tests/bench/hashes/sha256/512bitPadded.json | 15 +++++++++++++++ .../tests/bench/signatures/verifyEddsa.code | 0 .../tests/bench/signatures/verifyEddsa.json | 15 +++++++++++++++ .../tests/bench/utils/multiplexer/2bit.code | 0 .../tests/bench/utils/multiplexer/2bit.json | 15 +++++++++++++++ .../tests/bench/utils/pack/pack128.code | 0 .../tests/bench/utils/pack/pack128.json | 15 +++++++++++++++ .../tests/bench/utils/pack/unpack128.code | 0 .../tests/bench/utils/pack/unpack128.json | 15 +++++++++++++++ .../tests/bench/utils/pack/unpack256.code | 0 .../tests/bench/utils/pack/unpack256.json | 15 +++++++++++++++ 27 files changed, 195 insertions(+) rename zokrates_cli/examples/TestStdlib/ecc/testedwardsAdd.code => zokrates_stdlib/tests/bench/ecc/edwardsAdd.code (100%) create mode 100644 zokrates_stdlib/tests/bench/ecc/edwardsAdd.json rename zokrates_cli/examples/TestStdlib/ecc/testedwardsOnCurve.code => zokrates_stdlib/tests/bench/ecc/edwardsOnCurve.code (100%) create mode 100644 zokrates_stdlib/tests/bench/ecc/edwardsOnCurve.json rename zokrates_cli/examples/TestStdlib/ecc/testedwardsOrderCheck.code => zokrates_stdlib/tests/bench/ecc/edwardsOrderCheck.code (100%) create mode 100644 zokrates_stdlib/tests/bench/ecc/edwardsOrderCheck.json rename zokrates_cli/examples/TestStdlib/ecc/testedwardsScalarMult.code => zokrates_stdlib/tests/bench/ecc/edwardsScalarMult.code (100%) create mode 100644 zokrates_stdlib/tests/bench/ecc/edwardsScalarMult.json rename zokrates_cli/examples/TestStdlib/ecc/testproofOfOwnership.code => zokrates_stdlib/tests/bench/ecc/proofOfOwnership.code (100%) create mode 100644 zokrates_stdlib/tests/bench/ecc/proofOfOwnership.json rename zokrates_cli/examples/TestStdlib/hashes/sha256/test512bit.code => zokrates_stdlib/tests/bench/hashes/sha256/512bit.code (100%) create mode 100644 zokrates_stdlib/tests/bench/hashes/sha256/512bit.json rename zokrates_cli/examples/TestStdlib/hashes/sha256/test512bitPacked.code => zokrates_stdlib/tests/bench/hashes/sha256/512bitPacked.code (100%) rename zokrates_stdlib/tests/bench/{hash => hashes/sha256}/512bitPacked.json (100%) create mode 100644 zokrates_stdlib/tests/bench/hashes/sha256/512bitPacked2.json rename zokrates_cli/examples/TestStdlib/hashes/sha256/test512bitPadded.code => zokrates_stdlib/tests/bench/hashes/sha256/512bitPadded.code (100%) create mode 100644 zokrates_stdlib/tests/bench/hashes/sha256/512bitPadded.json rename zokrates_cli/examples/TestStdlib/signatures/testverifyEddsa.code => zokrates_stdlib/tests/bench/signatures/verifyEddsa.code (100%) create mode 100644 zokrates_stdlib/tests/bench/signatures/verifyEddsa.json rename zokrates_cli/examples/TestStdlib/utils/multiplexer/test2bit.code => zokrates_stdlib/tests/bench/utils/multiplexer/2bit.code (100%) create mode 100644 zokrates_stdlib/tests/bench/utils/multiplexer/2bit.json rename zokrates_cli/examples/TestStdlib/utils/pack/testpack128.code => zokrates_stdlib/tests/bench/utils/pack/pack128.code (100%) create mode 100644 zokrates_stdlib/tests/bench/utils/pack/pack128.json rename zokrates_cli/examples/TestStdlib/utils/pack/testunpack128.code => zokrates_stdlib/tests/bench/utils/pack/unpack128.code (100%) create mode 100644 zokrates_stdlib/tests/bench/utils/pack/unpack128.json rename zokrates_cli/examples/TestStdlib/utils/pack/testunpack256.code => zokrates_stdlib/tests/bench/utils/pack/unpack256.code (100%) create mode 100644 zokrates_stdlib/tests/bench/utils/pack/unpack256.json diff --git a/zokrates_cli/examples/TestStdlib/ecc/testedwardsAdd.code b/zokrates_stdlib/tests/bench/ecc/edwardsAdd.code similarity index 100% rename from zokrates_cli/examples/TestStdlib/ecc/testedwardsAdd.code rename to zokrates_stdlib/tests/bench/ecc/edwardsAdd.code diff --git a/zokrates_stdlib/tests/bench/ecc/edwardsAdd.json b/zokrates_stdlib/tests/bench/ecc/edwardsAdd.json new file mode 100644 index 00000000..7cb11a64 --- /dev/null +++ b/zokrates_stdlib/tests/bench/ecc/edwardsAdd.json @@ -0,0 +1,15 @@ +{ + "entry_point": "./tests/bench/ecc/edwardsAdd.code", + "tests": [ + { + "input": { + "values": [] + }, + "output": { + "Ok": { + "values": ["1"] + } + } + } + ] +} \ No newline at end of file diff --git a/zokrates_cli/examples/TestStdlib/ecc/testedwardsOnCurve.code b/zokrates_stdlib/tests/bench/ecc/edwardsOnCurve.code similarity index 100% rename from zokrates_cli/examples/TestStdlib/ecc/testedwardsOnCurve.code rename to zokrates_stdlib/tests/bench/ecc/edwardsOnCurve.code diff --git a/zokrates_stdlib/tests/bench/ecc/edwardsOnCurve.json b/zokrates_stdlib/tests/bench/ecc/edwardsOnCurve.json new file mode 100644 index 00000000..e4c42198 --- /dev/null +++ b/zokrates_stdlib/tests/bench/ecc/edwardsOnCurve.json @@ -0,0 +1,15 @@ +{ + "entry_point": "./tests/bench/ecc/edwardsOnCurve.code", + "tests": [ + { + "input": { + "values": [] + }, + "output": { + "Ok": { + "values": ["1"] + } + } + } + ] +} \ No newline at end of file diff --git a/zokrates_cli/examples/TestStdlib/ecc/testedwardsOrderCheck.code b/zokrates_stdlib/tests/bench/ecc/edwardsOrderCheck.code similarity index 100% rename from zokrates_cli/examples/TestStdlib/ecc/testedwardsOrderCheck.code rename to zokrates_stdlib/tests/bench/ecc/edwardsOrderCheck.code diff --git a/zokrates_stdlib/tests/bench/ecc/edwardsOrderCheck.json b/zokrates_stdlib/tests/bench/ecc/edwardsOrderCheck.json new file mode 100644 index 00000000..e38b3112 --- /dev/null +++ b/zokrates_stdlib/tests/bench/ecc/edwardsOrderCheck.json @@ -0,0 +1,15 @@ +{ + "entry_point": "./tests/bench/ecc/edwardsOrderCheck.code", + "tests": [ + { + "input": { + "values": [] + }, + "output": { + "Ok": { + "values": ["1"] + } + } + } + ] +} \ No newline at end of file diff --git a/zokrates_cli/examples/TestStdlib/ecc/testedwardsScalarMult.code b/zokrates_stdlib/tests/bench/ecc/edwardsScalarMult.code similarity index 100% rename from zokrates_cli/examples/TestStdlib/ecc/testedwardsScalarMult.code rename to zokrates_stdlib/tests/bench/ecc/edwardsScalarMult.code diff --git a/zokrates_stdlib/tests/bench/ecc/edwardsScalarMult.json b/zokrates_stdlib/tests/bench/ecc/edwardsScalarMult.json new file mode 100644 index 00000000..3d97c84d --- /dev/null +++ b/zokrates_stdlib/tests/bench/ecc/edwardsScalarMult.json @@ -0,0 +1,15 @@ +{ + "entry_point": "./tests/bench/ecc/edwardsScalarMult.code", + "tests": [ + { + "input": { + "values": [] + }, + "output": { + "Ok": { + "values": ["1"] + } + } + } + ] +} \ No newline at end of file diff --git a/zokrates_cli/examples/TestStdlib/ecc/testproofOfOwnership.code b/zokrates_stdlib/tests/bench/ecc/proofOfOwnership.code similarity index 100% rename from zokrates_cli/examples/TestStdlib/ecc/testproofOfOwnership.code rename to zokrates_stdlib/tests/bench/ecc/proofOfOwnership.code diff --git a/zokrates_stdlib/tests/bench/ecc/proofOfOwnership.json b/zokrates_stdlib/tests/bench/ecc/proofOfOwnership.json new file mode 100644 index 00000000..9d55955c --- /dev/null +++ b/zokrates_stdlib/tests/bench/ecc/proofOfOwnership.json @@ -0,0 +1,15 @@ +{ + "entry_point": "./tests/bench/ecc/proofOfOwnership.code", + "tests": [ + { + "input": { + "values": [] + }, + "output": { + "Ok": { + "values": ["1"] + } + } + } + ] +} \ No newline at end of file diff --git a/zokrates_cli/examples/TestStdlib/hashes/sha256/test512bit.code b/zokrates_stdlib/tests/bench/hashes/sha256/512bit.code similarity index 100% rename from zokrates_cli/examples/TestStdlib/hashes/sha256/test512bit.code rename to zokrates_stdlib/tests/bench/hashes/sha256/512bit.code diff --git a/zokrates_stdlib/tests/bench/hashes/sha256/512bit.json b/zokrates_stdlib/tests/bench/hashes/sha256/512bit.json new file mode 100644 index 00000000..af201acd --- /dev/null +++ b/zokrates_stdlib/tests/bench/hashes/sha256/512bit.json @@ -0,0 +1,15 @@ +{ + "entry_point": "./tests/bench/hashes/sha256/512bit.code", + "tests": [ + { + "input": { + "values": [] + }, + "output": { + "Ok": { + "values": ["1"] + } + } + } + ] +} \ No newline at end of file diff --git a/zokrates_cli/examples/TestStdlib/hashes/sha256/test512bitPacked.code b/zokrates_stdlib/tests/bench/hashes/sha256/512bitPacked.code similarity index 100% rename from zokrates_cli/examples/TestStdlib/hashes/sha256/test512bitPacked.code rename to zokrates_stdlib/tests/bench/hashes/sha256/512bitPacked.code diff --git a/zokrates_stdlib/tests/bench/hash/512bitPacked.json b/zokrates_stdlib/tests/bench/hashes/sha256/512bitPacked.json similarity index 100% rename from zokrates_stdlib/tests/bench/hash/512bitPacked.json rename to zokrates_stdlib/tests/bench/hashes/sha256/512bitPacked.json diff --git a/zokrates_stdlib/tests/bench/hashes/sha256/512bitPacked2.json b/zokrates_stdlib/tests/bench/hashes/sha256/512bitPacked2.json new file mode 100644 index 00000000..55f11390 --- /dev/null +++ b/zokrates_stdlib/tests/bench/hashes/sha256/512bitPacked2.json @@ -0,0 +1,15 @@ +{ + "entry_point": "./tests/bench/hashes/sha256/512bitPacked.code", + "tests": [ + { + "input": { + "values": [] + }, + "output": { + "Ok": { + "values": ["1"] + } + } + } + ] +} \ No newline at end of file diff --git a/zokrates_cli/examples/TestStdlib/hashes/sha256/test512bitPadded.code b/zokrates_stdlib/tests/bench/hashes/sha256/512bitPadded.code similarity index 100% rename from zokrates_cli/examples/TestStdlib/hashes/sha256/test512bitPadded.code rename to zokrates_stdlib/tests/bench/hashes/sha256/512bitPadded.code diff --git a/zokrates_stdlib/tests/bench/hashes/sha256/512bitPadded.json b/zokrates_stdlib/tests/bench/hashes/sha256/512bitPadded.json new file mode 100644 index 00000000..7a54a824 --- /dev/null +++ b/zokrates_stdlib/tests/bench/hashes/sha256/512bitPadded.json @@ -0,0 +1,15 @@ +{ + "entry_point": "./tests/bench/hashes/sha256/512bitPadded.code", + "tests": [ + { + "input": { + "values": [] + }, + "output": { + "Ok": { + "values": ["1"] + } + } + } + ] +} \ No newline at end of file diff --git a/zokrates_cli/examples/TestStdlib/signatures/testverifyEddsa.code b/zokrates_stdlib/tests/bench/signatures/verifyEddsa.code similarity index 100% rename from zokrates_cli/examples/TestStdlib/signatures/testverifyEddsa.code rename to zokrates_stdlib/tests/bench/signatures/verifyEddsa.code diff --git a/zokrates_stdlib/tests/bench/signatures/verifyEddsa.json b/zokrates_stdlib/tests/bench/signatures/verifyEddsa.json new file mode 100644 index 00000000..6ae3bcb2 --- /dev/null +++ b/zokrates_stdlib/tests/bench/signatures/verifyEddsa.json @@ -0,0 +1,15 @@ +{ + "entry_point": "./tests/bench/signatures/verifyEddsa.code", + "tests": [ + { + "input": { + "values": [] + }, + "output": { + "Ok": { + "values": ["1"] + } + } + } + ] +} \ No newline at end of file diff --git a/zokrates_cli/examples/TestStdlib/utils/multiplexer/test2bit.code b/zokrates_stdlib/tests/bench/utils/multiplexer/2bit.code similarity index 100% rename from zokrates_cli/examples/TestStdlib/utils/multiplexer/test2bit.code rename to zokrates_stdlib/tests/bench/utils/multiplexer/2bit.code diff --git a/zokrates_stdlib/tests/bench/utils/multiplexer/2bit.json b/zokrates_stdlib/tests/bench/utils/multiplexer/2bit.json new file mode 100644 index 00000000..e8c8d0f4 --- /dev/null +++ b/zokrates_stdlib/tests/bench/utils/multiplexer/2bit.json @@ -0,0 +1,15 @@ +{ + "entry_point": "./tests/bench/utils/multiplexer/2bit.code", + "tests": [ + { + "input": { + "values": [] + }, + "output": { + "Ok": { + "values": ["1"] + } + } + } + ] +} \ No newline at end of file diff --git a/zokrates_cli/examples/TestStdlib/utils/pack/testpack128.code b/zokrates_stdlib/tests/bench/utils/pack/pack128.code similarity index 100% rename from zokrates_cli/examples/TestStdlib/utils/pack/testpack128.code rename to zokrates_stdlib/tests/bench/utils/pack/pack128.code diff --git a/zokrates_stdlib/tests/bench/utils/pack/pack128.json b/zokrates_stdlib/tests/bench/utils/pack/pack128.json new file mode 100644 index 00000000..0bde19b2 --- /dev/null +++ b/zokrates_stdlib/tests/bench/utils/pack/pack128.json @@ -0,0 +1,15 @@ +{ + "entry_point": "./tests/bench/utils/pack/pack128.code", + "tests": [ + { + "input": { + "values": [] + }, + "output": { + "Ok": { + "values": ["1"] + } + } + } + ] +} \ No newline at end of file diff --git a/zokrates_cli/examples/TestStdlib/utils/pack/testunpack128.code b/zokrates_stdlib/tests/bench/utils/pack/unpack128.code similarity index 100% rename from zokrates_cli/examples/TestStdlib/utils/pack/testunpack128.code rename to zokrates_stdlib/tests/bench/utils/pack/unpack128.code diff --git a/zokrates_stdlib/tests/bench/utils/pack/unpack128.json b/zokrates_stdlib/tests/bench/utils/pack/unpack128.json new file mode 100644 index 00000000..c5c5d323 --- /dev/null +++ b/zokrates_stdlib/tests/bench/utils/pack/unpack128.json @@ -0,0 +1,15 @@ +{ + "entry_point": "./tests/bench/utils/pack/unpack128.code", + "tests": [ + { + "input": { + "values": [] + }, + "output": { + "Ok": { + "values": ["1"] + } + } + } + ] +} \ No newline at end of file diff --git a/zokrates_cli/examples/TestStdlib/utils/pack/testunpack256.code b/zokrates_stdlib/tests/bench/utils/pack/unpack256.code similarity index 100% rename from zokrates_cli/examples/TestStdlib/utils/pack/testunpack256.code rename to zokrates_stdlib/tests/bench/utils/pack/unpack256.code diff --git a/zokrates_stdlib/tests/bench/utils/pack/unpack256.json b/zokrates_stdlib/tests/bench/utils/pack/unpack256.json new file mode 100644 index 00000000..3ffea57e --- /dev/null +++ b/zokrates_stdlib/tests/bench/utils/pack/unpack256.json @@ -0,0 +1,15 @@ +{ + "entry_point": "./tests/bench/utils/pack/unpack256.code", + "tests": [ + { + "input": { + "values": [] + }, + "output": { + "Ok": { + "values": ["1"] + } + } + } + ] +} \ No newline at end of file From 730a912e0ed5c5a538f7138ef4077df6070332b0 Mon Sep 17 00:00:00 2001 From: sdeml Date: Fri, 15 Mar 2019 19:00:10 +0100 Subject: [PATCH 11/22] make edwardsOrderCheck generic --- zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code b/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code index cff778d3..f7763570 100644 --- a/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code +++ b/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code @@ -1,14 +1,16 @@ import "ecc/edwardsAdd.code" as add import "ecc/edwardsScalarMult.code" as multiply +import "utils/pack/unpack256.code" as unpack256 // 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 ture if the point is not one of the low-order points. +// Curve parameters are defined with the last argument // https://github.com/zcash-hackworks/sapling-crypto/blob/master/src/jubjub/edwards.rs#L166 def main(field[2] pt, field[10] context) -> (field): - // exponentBit = 8 //TODO: use cofactor from context .. currently hardcoded - field[256] cofactorExponent = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0] + field cofactor = context[7] + field[256] cofactorExponent = unpack256(cofactor) field[2] ptExp = multiply(cofactorExponent, pt, context) From 133919b77eba030af10f0b83e189b0fcc253dc78 Mon Sep 17 00:00:00 2001 From: sdeml Date: Fri, 15 Mar 2019 19:13:40 +0100 Subject: [PATCH 12/22] update docs --- zokrates_stdlib/stdlib/ecc/edwardsScalarMult.code | 2 +- zokrates_stdlib/stdlib/ecc/proofOfOwnership.code | 4 +++- zokrates_stdlib/stdlib/signatures/verifyEddsa.code | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/zokrates_stdlib/stdlib/ecc/edwardsScalarMult.code b/zokrates_stdlib/stdlib/ecc/edwardsScalarMult.code index c5c08c6b..72aae420 100644 --- a/zokrates_stdlib/stdlib/ecc/edwardsScalarMult.code +++ b/zokrates_stdlib/stdlib/ecc/edwardsScalarMult.code @@ -2,9 +2,9 @@ import "ecc/edwardsAdd.code" as add import "ecc/edwardsOnCurve.code" as assertOnCurve // Function that implements scalar multiplication for a given base point // Curve parameters are defined with the last argument +// Note that the exponent array is not check to be boolean in this gadget // https://github.com/zcash-hackworks/sapling-crypto/blob/master/src/jubjub/fs.rs#L555 def main(field[256] exponent, field[2] pt, field[10] context) -> (field[2]): - //FIXME: how to deal with bool checks field[2] infinity = [context[2], context[3]] diff --git a/zokrates_stdlib/stdlib/ecc/proofOfOwnership.code b/zokrates_stdlib/stdlib/ecc/proofOfOwnership.code index 9040837a..6d4e152d 100644 --- a/zokrates_stdlib/stdlib/ecc/proofOfOwnership.code +++ b/zokrates_stdlib/stdlib/ecc/proofOfOwnership.code @@ -1,7 +1,9 @@ import "ecc/edwardsAdd.code" as add import "ecc/edwardsScalarMult.code" as multiply import "utils/pack/unpack256.code" as unpack256 -// Return true for a valid public and private key pair, false otherwise +// Gadget to proof ownership of a private key for a given public key +// Returns true for a valid public and private key pair, false otherwise +// Curve parameters are defined with the last argument def main(field[2] pk, field sk, field[10] context) -> (field): field[2] G = [context[4], context[5]] diff --git a/zokrates_stdlib/stdlib/signatures/verifyEddsa.code b/zokrates_stdlib/stdlib/signatures/verifyEddsa.code index 1166ab98..e03c8f0d 100644 --- a/zokrates_stdlib/stdlib/signatures/verifyEddsa.code +++ b/zokrates_stdlib/stdlib/signatures/verifyEddsa.code @@ -4,7 +4,9 @@ import "ecc/edwardsAdd.code" as add import "utils/pack/unpack256.code" as unpack256 import "ecc/edwardsOnCurve.code" as onCurve import "ecc/edwardsOrderCheck.code" as orderCheck + // Return true for a valid EdDSA Signature, false otherwise +// Curve parameters are defined with the last argument def main(private field[2] R, private field S, field[2] A, field[256] M0, field[256] M1, field[10] context) -> (field): field[2] G = [context[4], context[5]] From b983a57fe44591e9139fdf5bd1945c8fb48863a8 Mon Sep 17 00:00:00 2001 From: sdeml Date: Mon, 18 Mar 2019 14:17:54 +0100 Subject: [PATCH 13/22] improve docs --- .../stdlib/ecc/babyjubjubParams.code | 34 +++++++++---------- .../stdlib/ecc/edwardsOrderCheck.code | 2 +- .../stdlib/ecc/proofOfOwnership.code | 18 ++++++++-- .../stdlib/signatures/verifyEddsa.code | 20 +++++++++-- 4 files changed, 51 insertions(+), 23 deletions(-) diff --git a/zokrates_stdlib/stdlib/ecc/babyjubjubParams.code b/zokrates_stdlib/stdlib/ecc/babyjubjubParams.code index 4b103c3e..bee7e3c1 100644 --- a/zokrates_stdlib/stdlib/ecc/babyjubjubParams.code +++ b/zokrates_stdlib/stdlib/ecc/babyjubjubParams.code @@ -1,22 +1,22 @@ // Parameters are based on: https://github.com/HarryR/ethsnarks/tree/master/src/jubjub -// Note: paramters will be update soon to be more compatible with zCash's implementation +// Note: parameters will be update soon to be more compatible with zCash's implementation def main() -> (field[10]): -// Order of the curve E - field JUBJUBE = 21888242871839275222246405745257275088614511777268538073601725287587578984328 - field JUBJUBC = 8 // Cofactor - field JUBJUBA = 168700 // Coefficient A - field JUBJUBD = 168696 // Coefficient D - field MONTA = 168698 // int(2*(JUBJUB_A+JUBJUB_D)/(JUBJUB_A-JUBJUB_D)) - field MONTB = 1 // int(4/(JUBJUB_A-JUBJUB_D)) - -// Point at infinity - field[2] infinity = [0, 1] +// Order of the curve E + field JUBJUBE = 21888242871839275222246405745257275088614511777268538073601725287587578984328 + field JUBJUBC = 8 // Cofactor + field JUBJUBA = 168700 // Coefficient A + field JUBJUBD = 168696 // Coefficient D + field MONTA = 168698 // int(2*(JUBJUB_A+JUBJUB_D)/(JUBJUB_A-JUBJUB_D)) + field MONTB = 1 // int(4/(JUBJUB_A-JUBJUB_D)) + +// Point at infinity + field[2] infinity = [0, 1] -// Generator - field Gu = 16540640123574156134436876038791482806971768689494387082833631921987005038935 - field Gv = 20819045374670962167435360035096875258406992893633759881276124905556507972311 +// Generator + field Gu = 16540640123574156134436876038791482806971768689494387082833631921987005038935 + field Gv = 20819045374670962167435360035096875258406992893633759881276124905556507972311 -// Index -// 0 1 2 3 4 5 6 7 8 10 - return [JUBJUBA, JUBJUBD, infinity[0], infinity[1], Gu, Gv, JUBJUBE, JUBJUBC, MONTA, MONTB] \ No newline at end of file +// Index +// 0 1 2 3 4 5 6 7 8 10 +return [JUBJUBA, JUBJUBD, infinity[0], infinity[1], Gu, Gv, JUBJUBE, JUBJUBC, MONTA, MONTB] \ No newline at end of file diff --git a/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code b/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code index f7763570..153e19fe 100644 --- a/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code +++ b/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code @@ -4,7 +4,7 @@ import "utils/pack/unpack256.code" as unpack256 // 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 ture if the point is not one of the low-order points. +// Returns true if the point is not one of the low-order points, false otherwise. // Curve parameters are defined with the last argument // https://github.com/zcash-hackworks/sapling-crypto/blob/master/src/jubjub/edwards.rs#L166 def main(field[2] pt, field[10] context) -> (field): diff --git a/zokrates_stdlib/stdlib/ecc/proofOfOwnership.code b/zokrates_stdlib/stdlib/ecc/proofOfOwnership.code index 6d4e152d..4156b10e 100644 --- a/zokrates_stdlib/stdlib/ecc/proofOfOwnership.code +++ b/zokrates_stdlib/stdlib/ecc/proofOfOwnership.code @@ -1,9 +1,21 @@ import "ecc/edwardsAdd.code" as add import "ecc/edwardsScalarMult.code" as multiply import "utils/pack/unpack256.code" as unpack256 -// Gadget to proof ownership of a private key for a given public key -// Returns true for a valid public and private key pair, false otherwise -// Curve parameters are defined with the last argument + +/// Verifies correctness 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 * is denotes scalar multiplication +/// +/// Arguments: +/// pk: Curve point. Public key. +/// sk: Field element. Private key. +/// context: Curve parameters (including generator G) used to create keypair. +/// +/// Returns: +/// Return true for pk/sk being a valid keypair, false otherwise. def main(field[2] pk, field sk, field[10] context) -> (field): field[2] G = [context[4], context[5]] diff --git a/zokrates_stdlib/stdlib/signatures/verifyEddsa.code b/zokrates_stdlib/stdlib/signatures/verifyEddsa.code index e03c8f0d..4eaa87f5 100644 --- a/zokrates_stdlib/stdlib/signatures/verifyEddsa.code +++ b/zokrates_stdlib/stdlib/signatures/verifyEddsa.code @@ -5,8 +5,24 @@ import "utils/pack/unpack256.code" as unpack256 import "ecc/edwardsOnCurve.code" as onCurve import "ecc/edwardsOrderCheck.code" as orderCheck -// Return true for a valid EdDSA Signature, false otherwise -// Curve parameters are defined with the last argument +/// Verifies the correctness of EdDSA Signature. +/// +/// Checks the correctness of a given EdDSA Signature (R,S) for the provided +/// public key(A) and message (M0 and M1). +/// For more information see: +/// https://en.wikipedia.org/wiki/EdDSA +/// https://eprint.iacr.org/2015/677.pdf +/// +/// Arguments: +/// 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. +/// +/// Returns: +/// Return true for S being a valid EdDSA Signature, false otherwise. def main(private field[2] R, private field S, field[2] A, field[256] M0, field[256] M1, field[10] context) -> (field): field[2] G = [context[4], context[5]] From 75d873b26caed6da1137fe65bb67b734521343bb Mon Sep 17 00:00:00 2001 From: sdeml Date: Mon, 18 Mar 2019 14:24:50 +0100 Subject: [PATCH 14/22] fix indentation and add docs --- zokrates_stdlib/stdlib/ecc/edwardsAdd.code | 18 +++++++++--------- zokrates_stdlib/stdlib/ecc/edwardsNegate.code | 6 +++--- zokrates_stdlib/stdlib/ecc/edwardsOnCurve.code | 18 +++++++++--------- .../stdlib/ecc/edwardsOrderCheck.code | 10 +++++----- .../tests/bench/ecc/edwardsAdd.code | 2 ++ .../tests/bench/ecc/edwardsOnCurve.code | 2 ++ .../tests/bench/ecc/edwardsOrderCheck.code | 2 ++ .../tests/bench/ecc/edwardsScalarMult.code | 2 ++ .../tests/bench/ecc/proofOfOwnership.code | 2 ++ .../tests/bench/signatures/verifyEddsa.code | 2 ++ 10 files changed, 38 insertions(+), 26 deletions(-) diff --git a/zokrates_stdlib/stdlib/ecc/edwardsAdd.code b/zokrates_stdlib/stdlib/ecc/edwardsAdd.code index 73bc8ba4..6640cf60 100644 --- a/zokrates_stdlib/stdlib/ecc/edwardsAdd.code +++ b/zokrates_stdlib/stdlib/ecc/edwardsAdd.code @@ -4,15 +4,15 @@ import "ecc/babyjubjubParams.code" as context // https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Addition_on_twisted_Edwards_curves def main(field[2] pt1, field[2] pt2, field[10] context) -> (field[2]): - field a = context[0] + field a = context[0] field d = context[1] - field u1 = pt1[0] - field v1 = pt1[1] - field u2 = pt2[0] - field v2 = pt2[1] + field u1 = pt1[0] + field v1 = pt1[1] + field u2 = pt2[0] + field v2 = pt2[1] - field uOut = (u1*v2 + v1*u2) / (1 + d*u1*u2*v1*v2) - field vOut = (v1*v2 - a*u1*u2) / (1 - d*u1*u2*v1*v2) - - return [uOut, vOut] \ No newline at end of file + field uOut = (u1*v2 + v1*u2) / (1 + d*u1*u2*v1*v2) + field vOut = (v1*v2 - a*u1*u2) / (1 - d*u1*u2*v1*v2) + + return [uOut, vOut] \ No newline at end of file diff --git a/zokrates_stdlib/stdlib/ecc/edwardsNegate.code b/zokrates_stdlib/stdlib/ecc/edwardsNegate.code index a94f95b6..a9d5698b 100644 --- a/zokrates_stdlib/stdlib/ecc/edwardsNegate.code +++ b/zokrates_stdlib/stdlib/ecc/edwardsNegate.code @@ -4,7 +4,7 @@ import "ecc/babyjubjubParams.code" as context // Twisted Edwards Curves, BBJLP-2008, section 2 pg 2 def main(field[2] pt, field[10] context) -> (field[2]): - field u = pt[0] - field v = pt[1] + field u = pt[0] + field v = pt[1] - return [0-u, v] \ No newline at end of file + return [0-u, v] \ No newline at end of file diff --git a/zokrates_stdlib/stdlib/ecc/edwardsOnCurve.code b/zokrates_stdlib/stdlib/ecc/edwardsOnCurve.code index 0652024d..78c9f868 100644 --- a/zokrates_stdlib/stdlib/ecc/edwardsOnCurve.code +++ b/zokrates_stdlib/stdlib/ecc/edwardsOnCurve.code @@ -4,13 +4,13 @@ // https://github.com/zcash/zips/blob/master/protocol/protocol.pdf def main(field[2] pt, field[10] context) -> (field): - field a = context[0] - field d = context[1] + field a = context[0] + field d = context[1] - field uu = pt[0] * pt[0] - field vv = pt[1] * pt[1] - field uuvv = uu * vv - - a * uu + vv == 1 + d * uuvv - - return 1 + field uu = pt[0] * pt[0] + field vv = pt[1] * pt[1] + field uuvv = uu * vv + + a * uu + vv == 1 + d * uuvv + + return 1 diff --git a/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code b/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code index 153e19fe..9ae0e863 100644 --- a/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code +++ b/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code @@ -9,11 +9,11 @@ import "utils/pack/unpack256.code" as unpack256 // https://github.com/zcash-hackworks/sapling-crypto/blob/master/src/jubjub/edwards.rs#L166 def main(field[2] pt, field[10] context) -> (field): - field cofactor = context[7] - field[256] cofactorExponent = unpack256(cofactor) + field cofactor = context[7] + field[256] cofactorExponent = unpack256(cofactor) - field[2] ptExp = multiply(cofactorExponent, pt, context) + field[2] ptExp = multiply(cofactorExponent, pt, context) - field out = if ptExp[0] == 0 && ptExp[1] == 1 then 0 else 1 fi + field out = if ptExp[0] == 0 && ptExp[1] == 1 then 0 else 1 fi - return out \ No newline at end of file + return out \ No newline at end of file diff --git a/zokrates_stdlib/tests/bench/ecc/edwardsAdd.code b/zokrates_stdlib/tests/bench/ecc/edwardsAdd.code index 942b9924..6fa0ea1a 100644 --- a/zokrates_stdlib/tests/bench/ecc/edwardsAdd.code +++ b/zokrates_stdlib/tests/bench/ecc/edwardsAdd.code @@ -2,6 +2,8 @@ import "ecc/edwardsAdd.code" as add import "ecc/edwardsNegate.code" as neg import "ecc/babyjubjubParams.code" as context +// Code to create test cases: +// https://github.com/stefandeml/zokrates-pycrypto/blob/master/tests/test_babyjubjub.py def testDoubleViaAdd() -> (field): context = context() field[2] G = [context[4], context[5]] diff --git a/zokrates_stdlib/tests/bench/ecc/edwardsOnCurve.code b/zokrates_stdlib/tests/bench/ecc/edwardsOnCurve.code index 85b673a0..8436bb7a 100644 --- a/zokrates_stdlib/tests/bench/ecc/edwardsOnCurve.code +++ b/zokrates_stdlib/tests/bench/ecc/edwardsOnCurve.code @@ -1,6 +1,8 @@ import "ecc/babyjubjubParams.code" as context import "ecc/edwardsOnCurve.code" as onCurve +// Code to create test cases: +// https://github.com/stefandeml/zokrates-pycrypto/blob/master/tests/test_babyjubjub.py def testOnCurveTrue() -> (field): context = context() diff --git a/zokrates_stdlib/tests/bench/ecc/edwardsOrderCheck.code b/zokrates_stdlib/tests/bench/ecc/edwardsOrderCheck.code index 0bd78074..853565c6 100644 --- a/zokrates_stdlib/tests/bench/ecc/edwardsOrderCheck.code +++ b/zokrates_stdlib/tests/bench/ecc/edwardsOrderCheck.code @@ -1,6 +1,8 @@ import "ecc/edwardsOrderCheck.code" as orderCheck import "ecc/babyjubjubParams.code" as context +// Code to create test cases: +// https://github.com/stefandeml/zokrates-pycrypto/blob/master/tests/test_babyjubjub.py def testOrderCheckTrue() -> (field): context = context() diff --git a/zokrates_stdlib/tests/bench/ecc/edwardsScalarMult.code b/zokrates_stdlib/tests/bench/ecc/edwardsScalarMult.code index 1d0bf98d..364f56f4 100644 --- a/zokrates_stdlib/tests/bench/ecc/edwardsScalarMult.code +++ b/zokrates_stdlib/tests/bench/ecc/edwardsScalarMult.code @@ -1,6 +1,8 @@ import "ecc/babyjubjubParams.code" as context import "ecc/edwardsScalarMult.code" as mul +// Code to create test cases: +// https://github.com/stefandeml/zokrates-pycrypto/blob/master/tests/test_babyjubjub.py def testCyclic() -> (field): context = context() field[2] G = [context[4], context[5]] diff --git a/zokrates_stdlib/tests/bench/ecc/proofOfOwnership.code b/zokrates_stdlib/tests/bench/ecc/proofOfOwnership.code index 352b6fb7..c3d358f7 100644 --- a/zokrates_stdlib/tests/bench/ecc/proofOfOwnership.code +++ b/zokrates_stdlib/tests/bench/ecc/proofOfOwnership.code @@ -3,6 +3,8 @@ import "ecc/proofOfOwnership.code" as proofOfOwnership import "ecc/edwardsScalarMult.code" as multiply import "utils/pack/unpack256.code" as unpack256 +// Code to create test cases: +// https://github.com/stefandeml/zokrates-pycrypto/blob/master/tests/test_babyjubjub.py def testOwnershipTrue() -> (field): context = context() field[2] G = [context[4], context[5]] diff --git a/zokrates_stdlib/tests/bench/signatures/verifyEddsa.code b/zokrates_stdlib/tests/bench/signatures/verifyEddsa.code index 0f9ff8f1..63f6b9d9 100644 --- a/zokrates_stdlib/tests/bench/signatures/verifyEddsa.code +++ b/zokrates_stdlib/tests/bench/signatures/verifyEddsa.code @@ -1,6 +1,8 @@ import "signatures/verifyEddsa.code" as verifyEddsa import "ecc/babyjubjubParams.code" as context +// Code to create test case: +// https://github.com/stefandeml/zokrates-pycrypto/blob/master/tests/test_eddsa.py def main() -> (field): context = context() From 5ae83103313c43b29a1751195b527675fa91f2bf Mon Sep 17 00:00:00 2001 From: sdeml Date: Mon, 18 Mar 2019 15:03:33 +0100 Subject: [PATCH 15/22] update mdbook --- zokrates_book/src/concepts/stdlib.md | 36 ++++++++++++++++--- .../stdlib/ecc/proofOfOwnership.code | 4 +-- .../stdlib/signatures/verifyEddsa.code | 2 +- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/zokrates_book/src/concepts/stdlib.md b/zokrates_book/src/concepts/stdlib.md index fada26e0..624cb0ba 100644 --- a/zokrates_book/src/concepts/stdlib.md +++ b/zokrates_book/src/concepts/stdlib.md @@ -4,6 +4,8 @@ ZoKrates comes with a number of reusable components which are defined at `./stdl The following section highlights a subset of available imports: +### Hashes + #### sha256 ```zokrates @@ -26,14 +28,32 @@ There also is support for 2 round (1024bit input) and and 3 round (1536bit input #### sha256packed ```zokrates -import "hashes/sha256/512bitPacked.code" +import "hashes/sha256/512bitPacked.code" ``` A function that takes an array of 4 field elements as inputs, unpacks each of them to 128 bits (big endian), concatenates them and applies sha256. It then returns an array of 2 field elements, each representing 128 bits of the result. -### Direct imports +### Public-key Cryptography -Some components of the standard library cannot yet be efficiently represented in the ZoKrates DSL language. Those functions are injected at compile-time and are available by default. +#### Proof of private-key ownership + +```zokrates +import "ecc/proofOfOwnership.code" +``` + +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. + +#### Signature verification + +```zokrates +import "signatures/verifyEddsa.code" +``` + +Verifies an EdDSA Signature. Checks the correctness of a given EdDSA Signature (`R,S`) for the provided public key(`A`) and message (`M0` and `M1`). + +### Packing / Unpacking #### pack128 @@ -49,4 +69,12 @@ Packs 128 field elements as one. import "utils/pack/unpack128" ``` -Unpacks a field element to 128 field elements. \ No newline at end of file +Unpacks a field element to 128 field elements. + +#### unpack256 + +```zokrates +import "utils/pack/unpack256" +``` + +Unpacks a field element to 256 field elements. \ No newline at end of file diff --git a/zokrates_stdlib/stdlib/ecc/proofOfOwnership.code b/zokrates_stdlib/stdlib/ecc/proofOfOwnership.code index 4156b10e..e258c608 100644 --- a/zokrates_stdlib/stdlib/ecc/proofOfOwnership.code +++ b/zokrates_stdlib/stdlib/ecc/proofOfOwnership.code @@ -2,12 +2,12 @@ import "ecc/edwardsAdd.code" as add import "ecc/edwardsScalarMult.code" as multiply import "utils/pack/unpack256.code" as unpack256 -/// Verifies correctness of a given public/private keypair. +/// 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 * is denotes scalar multiplication +/// and * denotes scalar multiplication /// /// Arguments: /// pk: Curve point. Public key. diff --git a/zokrates_stdlib/stdlib/signatures/verifyEddsa.code b/zokrates_stdlib/stdlib/signatures/verifyEddsa.code index 4eaa87f5..55023346 100644 --- a/zokrates_stdlib/stdlib/signatures/verifyEddsa.code +++ b/zokrates_stdlib/stdlib/signatures/verifyEddsa.code @@ -5,7 +5,7 @@ import "utils/pack/unpack256.code" as unpack256 import "ecc/edwardsOnCurve.code" as onCurve import "ecc/edwardsOrderCheck.code" as orderCheck -/// Verifies the correctness of EdDSA Signature. +/// Verifies an EdDSA Signature. /// /// Checks the correctness of a given EdDSA Signature (R,S) for the provided /// public key(A) and message (M0 and M1). From a139e379ad47b0e7348e3bb78a917311d82021e9 Mon Sep 17 00:00:00 2001 From: Thibaut Schaeffer Date: Tue, 19 Mar 2019 12:46:22 +0100 Subject: [PATCH 16/22] Apply suggestions from code review thanks @Schaeff Co-Authored-By: stefandeml --- zokrates_book/src/concepts/stdlib.md | 6 +++--- zokrates_stdlib/Cargo.toml | 2 +- zokrates_stdlib/stdlib/ecc/babyjubjubParams.code | 4 ++-- zokrates_stdlib/stdlib/ecc/edwardsAdd.code | 4 ++-- zokrates_stdlib/stdlib/ecc/edwardsNegate.code | 4 ++-- zokrates_stdlib/stdlib/ecc/edwardsOnCurve.code | 2 +- zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code | 4 ++-- zokrates_stdlib/stdlib/ecc/proofOfOwnership.code | 6 +++--- zokrates_stdlib/stdlib/hashes/sha256/1024bitPadded.code | 4 ++-- zokrates_stdlib/stdlib/signatures/verifyEddsa.code | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/zokrates_book/src/concepts/stdlib.md b/zokrates_book/src/concepts/stdlib.md index 624cb0ba..e4dbe690 100644 --- a/zokrates_book/src/concepts/stdlib.md +++ b/zokrates_book/src/concepts/stdlib.md @@ -43,7 +43,7 @@ import "ecc/proofOfOwnership.code" 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. +where `G` is the chosen base point of the subgroup and `*` denotes scalar multiplication in the subgroup. #### Signature verification @@ -51,7 +51,7 @@ where `G` is the chosen base point of the subgroup and `*` denotes scalar multip import "signatures/verifyEddsa.code" ``` -Verifies an EdDSA Signature. Checks the correctness of a given EdDSA Signature (`R,S`) for the provided public key(`A`) and message (`M0` and `M1`). +Verifies an EdDSA Signature. Checks the correctness of a given EdDSA Signature `(R,S)` for the provided public key `A` and message `(M0, M1)`. ### Packing / Unpacking @@ -77,4 +77,4 @@ Unpacks a field element to 128 field elements. import "utils/pack/unpack256" ``` -Unpacks a field element to 256 field elements. \ No newline at end of file +Unpacks a field element to 256 field elements. diff --git a/zokrates_stdlib/Cargo.toml b/zokrates_stdlib/Cargo.toml index b050e243..a336b112 100644 --- a/zokrates_stdlib/Cargo.toml +++ b/zokrates_stdlib/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "zokrates_stdlib" version = "0.1.0" -authors = ["schaeff ", "Stefan Deml "] +authors = ["Stefan Deml ", "schaeff "] edition = "2018" [features] diff --git a/zokrates_stdlib/stdlib/ecc/babyjubjubParams.code b/zokrates_stdlib/stdlib/ecc/babyjubjubParams.code index bee7e3c1..60ce23dd 100644 --- a/zokrates_stdlib/stdlib/ecc/babyjubjubParams.code +++ b/zokrates_stdlib/stdlib/ecc/babyjubjubParams.code @@ -1,5 +1,5 @@ // Parameters are based on: https://github.com/HarryR/ethsnarks/tree/master/src/jubjub -// Note: parameters will be update soon to be more compatible with zCash's implementation +// Note: parameters will be updated soon to be more compatible with zCash's implementation def main() -> (field[10]): // Order of the curve E @@ -19,4 +19,4 @@ def main() -> (field[10]): // Index // 0 1 2 3 4 5 6 7 8 10 -return [JUBJUBA, JUBJUBD, infinity[0], infinity[1], Gu, Gv, JUBJUBE, JUBJUBC, MONTA, MONTB] \ No newline at end of file +return [JUBJUBA, JUBJUBD, infinity[0], infinity[1], Gu, Gv, JUBJUBE, JUBJUBC, MONTA, MONTB] diff --git a/zokrates_stdlib/stdlib/ecc/edwardsAdd.code b/zokrates_stdlib/stdlib/ecc/edwardsAdd.code index 6640cf60..9027fcc1 100644 --- a/zokrates_stdlib/stdlib/ecc/edwardsAdd.code +++ b/zokrates_stdlib/stdlib/ecc/edwardsAdd.code @@ -1,5 +1,5 @@ import "ecc/babyjubjubParams.code" as context -// Function adds two points on a twisted Edwards curve +// Add two points on a twisted Edwards curve // Curve parameters are defined with the last argument // https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Addition_on_twisted_Edwards_curves def main(field[2] pt1, field[2] pt2, field[10] context) -> (field[2]): @@ -15,4 +15,4 @@ def main(field[2] pt1, field[2] pt2, field[10] context) -> (field[2]): field uOut = (u1*v2 + v1*u2) / (1 + d*u1*u2*v1*v2) field vOut = (v1*v2 - a*u1*u2) / (1 - d*u1*u2*v1*v2) - return [uOut, vOut] \ No newline at end of file + return [uOut, vOut] diff --git a/zokrates_stdlib/stdlib/ecc/edwardsNegate.code b/zokrates_stdlib/stdlib/ecc/edwardsNegate.code index a9d5698b..49911c5d 100644 --- a/zokrates_stdlib/stdlib/ecc/edwardsNegate.code +++ b/zokrates_stdlib/stdlib/ecc/edwardsNegate.code @@ -1,5 +1,5 @@ import "ecc/babyjubjubParams.code" as context -// Function negates a given edwards point. +// Negate a point on an Edwards curve // Curve parameters are defined with the last argument // Twisted Edwards Curves, BBJLP-2008, section 2 pg 2 def main(field[2] pt, field[10] context) -> (field[2]): @@ -7,4 +7,4 @@ def main(field[2] pt, field[10] context) -> (field[2]): field u = pt[0] field v = pt[1] - return [0-u, v] \ No newline at end of file + return [0-u, v] diff --git a/zokrates_stdlib/stdlib/ecc/edwardsOnCurve.code b/zokrates_stdlib/stdlib/ecc/edwardsOnCurve.code index 78c9f868..67f1ded3 100644 --- a/zokrates_stdlib/stdlib/ecc/edwardsOnCurve.code +++ b/zokrates_stdlib/stdlib/ecc/edwardsOnCurve.code @@ -1,4 +1,4 @@ -// Function checks if a provided point is on a twisted Edwards curve +// Check if a point is on a twisted Edwards curve // Curve parameters are defined with the last argument // See appendix 3.3.1 of Zcash protocol specification: // https://github.com/zcash/zips/blob/master/protocol/protocol.pdf diff --git a/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code b/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code index 9ae0e863..7288be85 100644 --- a/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code +++ b/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code @@ -4,7 +4,7 @@ import "utils/pack/unpack256.code" as unpack256 // 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. +// Returns 1 if the point is not one of the low-order points, 0 otherwise. // Curve parameters are defined with the last argument // https://github.com/zcash-hackworks/sapling-crypto/blob/master/src/jubjub/edwards.rs#L166 def main(field[2] pt, field[10] context) -> (field): @@ -16,4 +16,4 @@ def main(field[2] pt, field[10] context) -> (field): field out = if ptExp[0] == 0 && ptExp[1] == 1 then 0 else 1 fi - return out \ No newline at end of file + return out diff --git a/zokrates_stdlib/stdlib/ecc/proofOfOwnership.code b/zokrates_stdlib/stdlib/ecc/proofOfOwnership.code index e258c608..d9010d9f 100644 --- a/zokrates_stdlib/stdlib/ecc/proofOfOwnership.code +++ b/zokrates_stdlib/stdlib/ecc/proofOfOwnership.code @@ -7,7 +7,7 @@ import "utils/pack/unpack256.code" as unpack256 /// 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 +/// and * denotes scalar multiplication in the subgroup /// /// Arguments: /// pk: Curve point. Public key. @@ -15,7 +15,7 @@ import "utils/pack/unpack256.code" as unpack256 /// context: Curve parameters (including generator G) used to create keypair. /// /// Returns: -/// Return true for pk/sk being a valid keypair, false otherwise. +/// Return 1 for pk/sk being a valid keypair, 0 otherwise. def main(field[2] pk, field sk, field[10] context) -> (field): field[2] G = [context[4], context[5]] @@ -25,4 +25,4 @@ def main(field[2] pk, field sk, field[10] context) -> (field): field out = if ptExp[0] == pk[0] && ptExp[1] == pk[1] then 1 else 0 fi - return out \ No newline at end of file + return out diff --git a/zokrates_stdlib/stdlib/hashes/sha256/1024bitPadded.code b/zokrates_stdlib/stdlib/hashes/sha256/1024bitPadded.code index b645373c..4191d150 100644 --- a/zokrates_stdlib/stdlib/hashes/sha256/1024bitPadded.code +++ b/zokrates_stdlib/stdlib/hashes/sha256/1024bitPadded.code @@ -1,5 +1,5 @@ import "./1536bit.code" as sha256 -// A function that takes 2 field[256] arrays as inputs +// Take two field[256] arrays as input // and returns their sha256 full round output as an array of 256 field elements. def main(field[256] a, field[256] b, field[256] c, field[256] d) -> (field[256]): @@ -12,4 +12,4 @@ def main(field[256] a, field[256] b, field[256] c, field[256] d) -> (field[256]) digest = sha256(a, b, c, d, dummyblock1, dummyblock2) - return digest \ No newline at end of file + return digest diff --git a/zokrates_stdlib/stdlib/signatures/verifyEddsa.code b/zokrates_stdlib/stdlib/signatures/verifyEddsa.code index 55023346..22649b59 100644 --- a/zokrates_stdlib/stdlib/signatures/verifyEddsa.code +++ b/zokrates_stdlib/stdlib/signatures/verifyEddsa.code @@ -8,7 +8,7 @@ import "ecc/edwardsOrderCheck.code" as orderCheck /// Verifies an EdDSA Signature. /// /// Checks the correctness of a given EdDSA Signature (R,S) for the provided -/// public key(A) and message (M0 and M1). +/// public key A and message (M0, M1). /// For more information see: /// https://en.wikipedia.org/wiki/EdDSA /// https://eprint.iacr.org/2015/677.pdf @@ -22,7 +22,7 @@ import "ecc/edwardsOrderCheck.code" as orderCheck /// context: Curve parameters used to create S. /// /// Returns: -/// Return true for S being a valid EdDSA Signature, false otherwise. +/// Return 1 for S being a valid EdDSA Signature, 0 otherwise. def main(private field[2] R, private field S, field[2] A, field[256] M0, field[256] M1, field[10] context) -> (field): field[2] G = [context[4], context[5]] From 00f65b28a38eb0e107dcbb333c6dc7a8a97e7c7c Mon Sep 17 00:00:00 2001 From: sdeml Date: Tue, 19 Mar 2019 13:36:48 +0100 Subject: [PATCH 17/22] Add review suggestions --- zokrates_stdlib/stdlib/ecc/babyjubjubParams.code | 2 +- zokrates_stdlib/stdlib/ecc/edwardsScalarMult.code | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/zokrates_stdlib/stdlib/ecc/babyjubjubParams.code b/zokrates_stdlib/stdlib/ecc/babyjubjubParams.code index 60ce23dd..cd9386f4 100644 --- a/zokrates_stdlib/stdlib/ecc/babyjubjubParams.code +++ b/zokrates_stdlib/stdlib/ecc/babyjubjubParams.code @@ -1,4 +1,4 @@ -// Parameters are based on: https://github.com/HarryR/ethsnarks/tree/master/src/jubjub +// Parameters are based on: https://github.com/HarryR/ethsnarks/tree/9cdf0117c2e42c691e75b98979cb29b099eca998/src/jubjub // Note: parameters will be updated soon to be more compatible with zCash's implementation def main() -> (field[10]): diff --git a/zokrates_stdlib/stdlib/ecc/edwardsScalarMult.code b/zokrates_stdlib/stdlib/ecc/edwardsScalarMult.code index 72aae420..c9b0e7e4 100644 --- a/zokrates_stdlib/stdlib/ecc/edwardsScalarMult.code +++ b/zokrates_stdlib/stdlib/ecc/edwardsScalarMult.code @@ -9,16 +9,13 @@ def main(field[256] exponent, field[2] pt, field[10] context) -> (field[2]): field[2] infinity = [context[2], context[3]] field[2] doubledP = pt - field[2] accumulatedP = infinity - - field j = 255 - accumulatedP = if exponent[j] == 1 then doubledP else accumulatedP fi + field[2] accumulatedP = infinity - for field i in 1..256 do - j = 255 - i - doubledP = add(doubledP, doubledP, context) + for field i in 0..256 do + field j = 255 - i candidateP = add(accumulatedP, doubledP, context) accumulatedP = if exponent[j] == 1 then candidateP else accumulatedP fi + doubledP = add(doubledP, doubledP, context) endfor 1 == assertOnCurve(accumulatedP, context) From 79233a6e0ccca1bfcb52a83f1458c2a3fadc1075 Mon Sep 17 00:00:00 2001 From: sdeml Date: Thu, 21 Mar 2019 17:12:54 +0100 Subject: [PATCH 18/22] hardcode co-factor in edwardsOrderCheck --- zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code b/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code index 7288be85..31dbe71f 100644 --- a/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code +++ b/zokrates_stdlib/stdlib/ecc/edwardsOrderCheck.code @@ -10,10 +10,16 @@ import "utils/pack/unpack256.code" as unpack256 def main(field[2] pt, field[10] context) -> (field): field cofactor = context[7] - field[256] cofactorExponent = unpack256(cofactor) - - field[2] ptExp = multiply(cofactorExponent, pt, context) + // Co-factor currently hard-coded to 8 for efficiency reasons + // See discussion here: https://github.com/Zokrates/ZoKrates/pull/301#discussion_r267203391 + // Generic code: + // field[256] cofactorExponent = unpack256(cofactor) + // field[2] ptExp = multiply(cofactorExponent, pt, context) + field[2] ptExp = add(pt, pt, context) // 2*pt + ptExp = add(ptExp, ptExp, context) // 4*pt + ptExp = add(ptExp, ptExp, context) // 8*pt + field out = if ptExp[0] == 0 && ptExp[1] == 1 then 0 else 1 fi return out From 2412c6265c893536ce52d4edd686268b450d7f8d Mon Sep 17 00:00:00 2001 From: sdeml Date: Thu, 21 Mar 2019 17:22:19 +0100 Subject: [PATCH 19/22] fix docs --- zokrates_stdlib/stdlib/signatures/verifyEddsa.code | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zokrates_stdlib/stdlib/signatures/verifyEddsa.code b/zokrates_stdlib/stdlib/signatures/verifyEddsa.code index 22649b59..82b5a5b6 100644 --- a/zokrates_stdlib/stdlib/signatures/verifyEddsa.code +++ b/zokrates_stdlib/stdlib/signatures/verifyEddsa.code @@ -27,7 +27,7 @@ def main(private field[2] R, private field S, field[2] A, field[256] M0, field[2 field[2] G = [context[4], context[5]] - // Check if R is on curve and in prime-order sub-group. A is public input and can be checked offline + // Check if R is on curve and if it is not in a small subgroup. A is public input and can be checked offline field isOnCurve = onCurve(R, context) // throws if R is not on curve field isPrimeOrder = orderCheck(R, context) 1 == isPrimeOrder From d7c50f7959b4bd5f7b48181c21dfd26af84c9f7d Mon Sep 17 00:00:00 2001 From: William Entriken Date: Mon, 25 Mar 2019 19:25:43 -0400 Subject: [PATCH 20/22] Hyphenate numbers --- zokrates_book/src/concepts/stdlib.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zokrates_book/src/concepts/stdlib.md b/zokrates_book/src/concepts/stdlib.md index 98c6e1cb..9c60906d 100644 --- a/zokrates_book/src/concepts/stdlib.md +++ b/zokrates_book/src/concepts/stdlib.md @@ -21,7 +21,7 @@ import "hashes/sha256/512bit.code" A function that takes 2 `field[256]` arrays as inputs and returns their sha256 compression function as an array of 256 field elements. The difference with `sha256` is that no padding is added at the end of the message, which makes it more efficient but also less compatible with Solidity. -There also is support for 2 round (1024bit input) and and 3 round (1536bit input) variants, using `hashes/1024bit.code` or `hashes/1536bit.code` respectively. +There also is support for 2-round (1024-bit input) and and 3-round (1536-bit input) variants, using `hashes/1024bit.code` or `hashes/1536bit.code` respectively. #### sha256packed @@ -49,4 +49,4 @@ Packs 128 field elements as one. import "PACKING/unpack128" ``` -Unpacks a field element to 128 field elements. \ No newline at end of file +Unpacks a field element to 128 field elements. From 727f1b572f3de7bb64d2bb7a5b2a9af0c5bd7847 Mon Sep 17 00:00:00 2001 From: sdeml Date: Fri, 29 Mar 2019 08:51:11 +0100 Subject: [PATCH 21/22] change link to new pycrypt repo --- zokrates_stdlib/tests/bench/ecc/edwardsAdd.code | 2 +- zokrates_stdlib/tests/bench/ecc/edwardsOnCurve.code | 2 +- zokrates_stdlib/tests/bench/ecc/edwardsOrderCheck.code | 2 +- zokrates_stdlib/tests/bench/ecc/edwardsScalarMult.code | 2 +- zokrates_stdlib/tests/bench/ecc/proofOfOwnership.code | 2 +- zokrates_stdlib/tests/bench/signatures/verifyEddsa.code | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/zokrates_stdlib/tests/bench/ecc/edwardsAdd.code b/zokrates_stdlib/tests/bench/ecc/edwardsAdd.code index 6fa0ea1a..4641c266 100644 --- a/zokrates_stdlib/tests/bench/ecc/edwardsAdd.code +++ b/zokrates_stdlib/tests/bench/ecc/edwardsAdd.code @@ -3,7 +3,7 @@ import "ecc/edwardsNegate.code" as neg import "ecc/babyjubjubParams.code" as context // Code to create test cases: -// https://github.com/stefandeml/zokrates-pycrypto/blob/master/tests/test_babyjubjub.py +// https://github.com/Zokrates/pycrypto def testDoubleViaAdd() -> (field): context = context() field[2] G = [context[4], context[5]] diff --git a/zokrates_stdlib/tests/bench/ecc/edwardsOnCurve.code b/zokrates_stdlib/tests/bench/ecc/edwardsOnCurve.code index 8436bb7a..5da13a9a 100644 --- a/zokrates_stdlib/tests/bench/ecc/edwardsOnCurve.code +++ b/zokrates_stdlib/tests/bench/ecc/edwardsOnCurve.code @@ -2,7 +2,7 @@ import "ecc/babyjubjubParams.code" as context import "ecc/edwardsOnCurve.code" as onCurve // Code to create test cases: -// https://github.com/stefandeml/zokrates-pycrypto/blob/master/tests/test_babyjubjub.py +// https://github.com/Zokrates/pycrypto def testOnCurveTrue() -> (field): context = context() diff --git a/zokrates_stdlib/tests/bench/ecc/edwardsOrderCheck.code b/zokrates_stdlib/tests/bench/ecc/edwardsOrderCheck.code index 853565c6..1a2456f1 100644 --- a/zokrates_stdlib/tests/bench/ecc/edwardsOrderCheck.code +++ b/zokrates_stdlib/tests/bench/ecc/edwardsOrderCheck.code @@ -2,7 +2,7 @@ import "ecc/edwardsOrderCheck.code" as orderCheck import "ecc/babyjubjubParams.code" as context // Code to create test cases: -// https://github.com/stefandeml/zokrates-pycrypto/blob/master/tests/test_babyjubjub.py +// https://github.com/Zokrates/pycrypto def testOrderCheckTrue() -> (field): context = context() diff --git a/zokrates_stdlib/tests/bench/ecc/edwardsScalarMult.code b/zokrates_stdlib/tests/bench/ecc/edwardsScalarMult.code index 364f56f4..8c6cdbd8 100644 --- a/zokrates_stdlib/tests/bench/ecc/edwardsScalarMult.code +++ b/zokrates_stdlib/tests/bench/ecc/edwardsScalarMult.code @@ -2,7 +2,7 @@ import "ecc/babyjubjubParams.code" as context import "ecc/edwardsScalarMult.code" as mul // Code to create test cases: -// https://github.com/stefandeml/zokrates-pycrypto/blob/master/tests/test_babyjubjub.py +// https://github.com/Zokrates/pycrypto def testCyclic() -> (field): context = context() field[2] G = [context[4], context[5]] diff --git a/zokrates_stdlib/tests/bench/ecc/proofOfOwnership.code b/zokrates_stdlib/tests/bench/ecc/proofOfOwnership.code index c3d358f7..0e6168eb 100644 --- a/zokrates_stdlib/tests/bench/ecc/proofOfOwnership.code +++ b/zokrates_stdlib/tests/bench/ecc/proofOfOwnership.code @@ -4,7 +4,7 @@ import "ecc/edwardsScalarMult.code" as multiply import "utils/pack/unpack256.code" as unpack256 // Code to create test cases: -// https://github.com/stefandeml/zokrates-pycrypto/blob/master/tests/test_babyjubjub.py +// https://github.com/Zokrates/pycrypto def testOwnershipTrue() -> (field): context = context() field[2] G = [context[4], context[5]] diff --git a/zokrates_stdlib/tests/bench/signatures/verifyEddsa.code b/zokrates_stdlib/tests/bench/signatures/verifyEddsa.code index 63f6b9d9..bc4e79c3 100644 --- a/zokrates_stdlib/tests/bench/signatures/verifyEddsa.code +++ b/zokrates_stdlib/tests/bench/signatures/verifyEddsa.code @@ -2,7 +2,7 @@ import "signatures/verifyEddsa.code" as verifyEddsa import "ecc/babyjubjubParams.code" as context // Code to create test case: -// https://github.com/stefandeml/zokrates-pycrypto/blob/master/tests/test_eddsa.py +// https://github.com/Zokrates/pycrypto def main() -> (field): context = context() From 5cc19c3ca962c8a5a165b040f851c50fdc402c97 Mon Sep 17 00:00:00 2001 From: sdeml Date: Fri, 29 Mar 2019 09:06:29 +0100 Subject: [PATCH 22/22] doc updates --- zokrates_book/src/concepts/stdlib.md | 2 +- zokrates_stdlib/stdlib/ecc/edwardsScalarMult.code | 6 ++++-- zokrates_stdlib/stdlib/signatures/verifyEddsa.code | 3 +++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/zokrates_book/src/concepts/stdlib.md b/zokrates_book/src/concepts/stdlib.md index e4dbe690..a761ae41 100644 --- a/zokrates_book/src/concepts/stdlib.md +++ b/zokrates_book/src/concepts/stdlib.md @@ -51,7 +51,7 @@ where `G` is the chosen base point of the subgroup and `*` denotes scalar multip import "signatures/verifyEddsa.code" ``` -Verifies an EdDSA Signature. Checks the correctness of a given EdDSA Signature `(R,S)` for the provided public key `A` and message `(M0, M1)`. +Verifies an EdDSA Signature. Checks the correctness of a given EdDSA Signature `(R,S)` for the provided public key `A` and message `(M0, M1)`. Check out this [python repository](https://github.com/Zokrates/pycrypto) for tooling to create valid signatures. ### Packing / Unpacking diff --git a/zokrates_stdlib/stdlib/ecc/edwardsScalarMult.code b/zokrates_stdlib/stdlib/ecc/edwardsScalarMult.code index c9b0e7e4..b7cea471 100644 --- a/zokrates_stdlib/stdlib/ecc/edwardsScalarMult.code +++ b/zokrates_stdlib/stdlib/ecc/edwardsScalarMult.code @@ -1,9 +1,11 @@ import "ecc/edwardsAdd.code" as add import "ecc/edwardsOnCurve.code" as assertOnCurve -// Function that implements scalar multiplication for a given base point +// Function that implements scalar multiplication for a fixed base point // Curve parameters are defined with the last argument +// The exponent is hard-coded to a 256bit scalar, hence we allow wrapping around the group for certain +// curve parameters. // Note that the exponent array is not check to be boolean in this gadget -// https://github.com/zcash-hackworks/sapling-crypto/blob/master/src/jubjub/fs.rs#L555 +// Reference: https://github.com/zcash-hackworks/sapling-crypto/blob/master/src/jubjub/fs.rs#L555 def main(field[256] exponent, field[2] pt, field[10] context) -> (field[2]): field[2] infinity = [context[2], context[3]] diff --git a/zokrates_stdlib/stdlib/signatures/verifyEddsa.code b/zokrates_stdlib/stdlib/signatures/verifyEddsa.code index 82b5a5b6..4670ae28 100644 --- a/zokrates_stdlib/stdlib/signatures/verifyEddsa.code +++ b/zokrates_stdlib/stdlib/signatures/verifyEddsa.code @@ -9,6 +9,9 @@ import "ecc/edwardsOrderCheck.code" as orderCheck /// /// Checks the correctness of a given EdDSA Signature (R,S) for the provided /// public key A and message (M0, M1). +/// This python repo provides the tooling for creating valid signatures: +/// https://github.com/Zokrates/pycrypto +/// /// For more information see: /// https://en.wikipedia.org/wiki/EdDSA /// https://eprint.iacr.org/2015/677.pdf