Skip to content

Commit

Permalink
Merge pull request #1333 from ZoKratesPlus/jubjub-stdlib
Browse files Browse the repository at this point in the history
Add Jubjub to ECC stdlib
  • Loading branch information
dark64 authored Oct 4, 2023
2 parents 2b35549 + e391fe1 commit 2108ad4
Show file tree
Hide file tree
Showing 31 changed files with 218 additions and 79 deletions.
2 changes: 1 addition & 1 deletion zokrates_core_test/tests/tests/arrays/fun_spread.zok
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import "utils/pack/bool/nonStrictUnpack256.zok" as unpack256;

def main(field[2] inputs) -> bool[512] {
bool[512] preimage512 = [...unpack256(inputs[0]), ...unpack256(inputs[1])];
bool[512] preimage512 = [...unpack256(inputs[0], 254), ...unpack256(inputs[1], 254)];
return preimage512;
}
46 changes: 46 additions & 0 deletions zokrates_stdlib/stdlib/ecc/babyjubjub.zok
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#pragma curve bn128

import "./proofOfOwnership" as edwardsProofOfOwnership;
import "./verifyEddsa" as edwardsSignature;
import "utils/pack/bool/nonStrictUnpack256" as unpack256;


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

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

// The generator point
const field[2] G = [
16540640123574156134436876038791482806971768689494387082833631921987005038935, // Gx
20819045374670962167435360035096875258406992893633759881276124905556507972311 // Gy
];

const u32 bit_size = 254;


def proofOfOwnership(field[2] pk, field sk) -> bool {

return edwardsProofOfOwnership(pk, sk, G, EDWARDS_A, EDWARDS_D, bit_size);
}


def verifyEddsa(field[2] R, field S, field[2] A, u32[8] M0, u32[8] M1) -> bool {

return edwardsSignature(R, S, A, M0, M1, G, EDWARDS_A, EDWARDS_D, bit_size);
}


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

bool[256] xBits = unpack256(x, 254);
bool[256] mut yBits = unpack256(y, 254);

bool sign = xBits[255];
yBits[0] = sign;

return yBits;
}
20 changes: 0 additions & 20 deletions zokrates_stdlib/stdlib/ecc/babyjubjub/compress.zok

This file was deleted.

13 changes: 0 additions & 13 deletions zokrates_stdlib/stdlib/ecc/babyjubjub/params.zok

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#pragma curve bls12_381

import "./proofOfOwnership" as edwardsProofOfOwnership;
import "./verifyEddsa" as edwardsSignature;


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

Expand All @@ -10,4 +14,18 @@ const field EDWARDS_D = 19257038036680949359750312669786877991949435402254120286
const field[2] G = [
11076627216317271660298050606127911965867021807910416450833192264015104452986, // Gx
44412834903739585386157632289020980010620626017712148233229312325549216099227 // Gy
];
];

const u32 bit_size = 255;


def proofOfOwnership(field[2] pk, field sk) -> bool {

return edwardsProofOfOwnership(pk, sk, G, EDWARDS_A, EDWARDS_D, bit_size);
}


def verifyEddsa(field[2] R, field S, field[2] A, u32[8] M0, u32[8] M1) -> bool {

return edwardsSignature(R, S, A, M0, M1, G, EDWARDS_A, EDWARDS_D, bit_size);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import "utils/pack/bool/nonStrictUnpack256" as unpack256;
from "./params" import EDWARDS_A, EDWARDS_D, G;
from "ecc/edwards" import scalarMul;

/// Verifies match of a given public/private keypair.
Expand All @@ -14,8 +13,8 @@ from "ecc/edwards" import scalarMul;
/// sk: Private key
///
/// Returns true for pk/sk being a valid keypair, false otherwise.
def main(field[2] pk, field sk) -> bool {
bool[256] sk_bits = unpack256(sk);
def main(field[2] pk, field sk, field[2] G, field EDWARDS_A, field EDWARDS_D, u32 bit_size) -> bool {
bool[256] sk_bits = unpack256(sk, bit_size);
field[2] res = scalarMul(sk_bits, G, EDWARDS_A, EDWARDS_D);
return (res[0] == pk[0] && res[1] == pk[1]);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import "utils/pack/bool/nonStrictUnpack256" as unpack256bool;
import "utils/pack/u32/nonStrictUnpack256" as unpack256u;
from "utils/casts" import cast;
from "ecc/edwards" import add, scalarMul, onCurve, orderCheck;
from "./params" import EDWARDS_A, EDWARDS_D, G;

/// Verifies an EdDSA Signature.
///
Expand All @@ -25,18 +24,18 @@ from "./params" import EDWARDS_A, EDWARDS_D, G;
///
/// Returns:
/// Return true for S being a valid EdDSA Signature, false otherwise.
def main(field[2] R, field S, field[2] A, u32[8] M0, u32[8] M1) -> bool {
def main(field[2] R, field S, field[2] A, u32[8] M0, u32[8] M1, field[2] G, field EDWARDS_A, field EDWARDS_D, u32 bit_size) -> bool {
// Check if R is on curve and if it is not in a small subgroup. A is public input and can be checked offline
assert(onCurve(R, EDWARDS_A, EDWARDS_D)); // throws if R is not on curve
assert(orderCheck(R, EDWARDS_A, EDWARDS_D));

u32[8] Rx = unpack256u(R[0]);
u32[8] Ax = unpack256u(A[0]);
u32[8] Rx = unpack256u(R[0], bit_size);
u32[8] Ax = unpack256u(A[0], bit_size);

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

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

field[2] AhRAM = scalarMul(hRAM, A, EDWARDS_A, EDWARDS_D);
Expand Down
3 changes: 1 addition & 2 deletions zokrates_stdlib/stdlib/hashes/pedersen/512bitBool.zok
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import "utils/multiplexer/lookup3bitSigned" as sel3s;
import "utils/multiplexer/lookup2bit" as sel2;
import "ecc/babyjubjub/compress";
from "ecc/edwards" import add;
from "ecc/babyjubjub/params" import EDWARDS_A, EDWARDS_D;
from "ecc/babyjubjub" import EDWARDS_A, EDWARDS_D, compress;

// Code to export generators used in this example:
// import bitstring
Expand Down
10 changes: 5 additions & 5 deletions zokrates_stdlib/stdlib/utils/pack/bool/nonStrictUnpack256.zok
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#pragma curve bn128

import "./unpack_unchecked";

// Unpack a field element as 256 big-endian bits
// Note: uniqueness of the output is not guaranteed
// For example, `0` can map to `[0, 0, ..., 0]` or to `bits(p)`
def main(field i) -> bool[256] {
bool[254] b = unpack_unchecked(i);
return [false, false, ...b];
def main(field i, u32 bit_size) -> bool[256] {
assert(bit_size <= 256);
u32 padding_size = 256 - bit_size;
bool[bit_size] b = unpack_unchecked(i);
return [...[false; padding_size], ...b];
}
1 change: 0 additions & 1 deletion zokrates_stdlib/stdlib/utils/pack/bool/pack256.zok
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#pragma curve bn128

import "./pack" as pack;

Expand Down
6 changes: 2 additions & 4 deletions zokrates_stdlib/stdlib/utils/pack/u32/nonStrictUnpack256.zok
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
#pragma curve bn128

import "../bool/nonStrictUnpack256" as unpack;
import "../../casts/bool_256_to_u32_8" as from_bits;

// Unpack a field element as a u32[8] (big-endian)
// Note: uniqueness of the output is not guaranteed
// For example, `0` can map to `[0, 0, ..., 0]` or to `bits(p)`
def main(field i) -> u32[8] {
return from_bits(unpack(i));
def main(field i, u32 bit_size) -> u32[8] {
return from_bits(unpack(i, bit_size));
}
3 changes: 1 addition & 2 deletions zokrates_stdlib/tests/tests/ecc/babyjubjub/compress.zok
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import "ecc/babyjubjub/compress";
from "ecc/babyjubjub/params" import G;
from "ecc/babyjubjub" import G, compress;

// Code to create test cases:
// https://github.com/Zokrates/pycrypto
Expand Down
2 changes: 1 addition & 1 deletion zokrates_stdlib/tests/tests/ecc/babyjubjub/edwardsAdd.zok
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from "ecc/edwards" import add, negate;
from "ecc/babyjubjub/params" import G, EDWARDS_A, EDWARDS_D;
from "ecc/babyjubjub" import G, EDWARDS_A, EDWARDS_D;

// Code to create test cases:
// https://github.com/Zokrates/pycrypto
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from "ecc/edwards" import onCurve;
from "ecc/babyjubjub/params" import EDWARDS_A, EDWARDS_D;
from "ecc/babyjubjub" import EDWARDS_A, EDWARDS_D;

// Code to create test cases:
// https://github.com/Zokrates/pycrypto
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from "ecc/edwards" import orderCheck;
from "ecc/babyjubjub/params" import EDWARDS_A, EDWARDS_D;
from "ecc/babyjubjub" import EDWARDS_A, EDWARDS_D;

// Code to create test cases:
// https://github.com/Zokrates/pycrypto
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from "ecc/edwards" import scalarMul as mul;
from "ecc/babyjubjub/params" import G, EDWARDS_A, EDWARDS_D;
from "ecc/babyjubjub" import G, EDWARDS_A, EDWARDS_D;

// Code to create test cases:
// https://github.com/Zokrates/pycrypto
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import "ecc/babyjubjub/proofOfOwnership" as proofOfOwnership;
from "ecc/edwards" import scalarMul;
from "ecc/babyjubjub" import proofOfOwnership;


// Code to create test cases:
// https://github.com/Zokrates/pycrypto
Expand Down
2 changes: 1 addition & 1 deletion zokrates_stdlib/tests/tests/ecc/babyjubjub/verifyEddsa.zok
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import "ecc/babyjubjub/verifyEddsa" as verifyEddsa;
from "ecc/babyjubjub" import verifyEddsa;

// Code to create test case:
// https://github.com/Zokrates/pycrypto
Expand Down
2 changes: 1 addition & 1 deletion zokrates_stdlib/tests/tests/ecc/jubjub/edwardsAdd.zok
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from "ecc/edwards" import add, negate;
from "ecc/jubjub/params" import G, EDWARDS_A, EDWARDS_D;
from "ecc/jubjub" import G, EDWARDS_A, EDWARDS_D;

def testDoubleViaAdd() -> bool {
field[2] out = add(G, G, EDWARDS_A, EDWARDS_D);
Expand Down
2 changes: 1 addition & 1 deletion zokrates_stdlib/tests/tests/ecc/jubjub/edwardsOnCurve.zok
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from "ecc/edwards" import onCurve;
from "ecc/jubjub/params" import EDWARDS_A, EDWARDS_D;
from "ecc/jubjub" import EDWARDS_A, EDWARDS_D;

def main() {
field u = 11076627216317271660298050606127911965867021807910416450833192264015104452986;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from "ecc/edwards" import orderCheck;
from "ecc/jubjub/params" import EDWARDS_A, EDWARDS_D;
from "ecc/jubjub" import EDWARDS_A, EDWARDS_D;

def testOrderCheckTrue() -> bool {
field u = 11076627216317271660298050606127911965867021807910416450833192264015104452986;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from "ecc/edwards" import scalarMul as mul;
from "ecc/jubjub/params" import G, EDWARDS_A, EDWARDS_D;
from "ecc/jubjub" import G, EDWARDS_A, EDWARDS_D;

/*
def testCyclic() -> bool {
Expand Down
16 changes: 16 additions & 0 deletions zokrates_stdlib/tests/tests/ecc/jubjub/proofOfOwnership.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"entry_point": "./tests/tests/ecc/jubjub/proofOfOwnership.zok",
"curves": ["Bls12_381"],
"tests": [
{
"input": {
"values": []
},
"output": {
"Ok": {
"value": []
}
}
}
]
}
29 changes: 29 additions & 0 deletions zokrates_stdlib/tests/tests/ecc/jubjub/proofOfOwnership.zok
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from "ecc/jubjub" import proofOfOwnership;


// Code to create test cases:
// https://github.com/Zokrates/pycrypto
def testOwnershipTrue() -> bool {
field[2] pk = [14197449566532409051373899088449039913101429151158365207762164998470111126084, 39815292783067036895376009933490224522172606808755118734518018525613835149403];
field sk = 24537266074035586913841246471742714563414767347802800698790739697702568093815;

bool out = proofOfOwnership(pk, sk);

assert(out);
return true;
}

def testOwnershipFalse() -> bool {
field[2] pk = [14197449566532409051373899088449039913101429151158365207762164998470111126084, 39815292783067036895376009933490224522172606808755118734518018525613835149403];
field sk = 47423927973606838312622698773159954626747140530476271492884670927146733875544;

bool out = proofOfOwnership(pk, sk);

assert(!out);
return true;
}

def main() {
assert(testOwnershipTrue());
assert(testOwnershipFalse());
}
16 changes: 16 additions & 0 deletions zokrates_stdlib/tests/tests/ecc/jubjub/verifyEddsa.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"entry_point": "./tests/tests/ecc/jubjub/verifyEddsa.zok",
"curves": ["Bls12_381"],
"tests": [
{
"input": {
"values": []
},
"output": {
"Ok": {
"value": []
}
}
}
]
}
21 changes: 21 additions & 0 deletions zokrates_stdlib/tests/tests/ecc/jubjub/verifyEddsa.zok
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from "ecc/jubjub" import verifyEddsa;


// Code to create test case:
// https://github.com/Zokrates/pycrypto
def main() {

// TODO: Jubjub currently work only for keys <=254 bit long
// With the following keys should also work:
field[2] R = [32866767109220564315580607107081162920517672350707254238793964527466586251974, 31852087390335520207922973662676180854641055992940928475111512263314053365736];
field S = 43627586196239283173178511316555190744314536456808505435494185841008559853678;

// Public Key
field[2] A = [26479653887939839327536384197110148123933856719900448942651733342668343953867, 21757919891968253927635241665494706427345455214116275076018069565740804326091];

u32[8] M0 = [0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000];
u32[8] M1 = [0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000005];

bool isVerified = verifyEddsa(R, S, A, M0, M1);
assert(isVerified);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"entry_point": "./tests/tests/utils/pack/bool/nonStrictUnpack256.zok",
"curves": ["Bn128"],
"curves": ["Bls12_381"],
"tests": [
{
"input": {
Expand Down
Loading

0 comments on commit 2108ad4

Please sign in to comment.