/// This zksnark is to be used to verify that an operator has choosen /// the lowest bid that was actually submitted by an approved supplier was choosen /// by the operator for the work. For this proof of concept, we will structure the /// proof to use 3 suppliers only.
/// Inputs for the SNARK
/// PUBLIC FIELDS /// input_of_py: field[3] public keys for each supplier - should be EDDSA public keys /// * A: Curve point. Public part of the key used to create S.
/// PRIVATE FIELDS /// input_of_py: field[3] actual bid from each supplier /// input_of_py: Requires per each EDDSA signatures per supplier /// * R: Curve point. Hidden version of the per-message nonce. /// * S: Field element. Signature to be verified. /// input_of_py: a secret to aide in building out the merkel tree of the results
/// * context: Curve parameters used to create S. Tells you which curve was used. /// The context can be generated from the babyjubjub curve.
/// Returns for the SNARK /// return: a merkel tree including... /// 1. private key of choosen supplier /// 2. secret /// 3. A: Curve point. Public part of the key used to create S.
// In the vectors, the supplier order should be kept the same to compare/access (i.e. supplier one has first bid, supplier two second bid, etc.)
defmain(private field[6] R, \ field[6] A, \ field[3] S, \ private field secret, \ private field bidone, \ private field bidtwo, \ private field bidthree) -> (field[2]):
//Since each message is constructed from the bids, no way to input_of_py a faulty bid
//Reconstruct messages: //Note: Field element can be a value between 0and p (p upper limit: 2^254) //Makes an assumption that every bid will be 64 bit number //Message in the signature should be 512 bits
//Lowest bid should correllate with supplier //To Do: write the simplest implementation to simplify, each of the below would be a range proof field[3] lowestbidder = [...[0; 3]] //Save supplier and the lowest bid lowestbidder = if bidone < bidtwo && bidone < bidthree then [A[0], A[1], bidone] else [...[0; 3]] fi lowestbidder = if bidtwo < bidone && bidtwo < bidthree then [A[2], A[3], bidtwo] else [...[0; 3]] fi lowestbidder = if bidthree < bidone && bidthree < bidtwo then [A[4], A[5], bidthree] else [...[0; 3]] fi
//Now we have the lowest bid, supplier sig verified, and secret --> ready for the merkle tree //512bitpadded - same merkle tree as ethereum //Leaf One: lowest bid + secret //Makes an assumption that every secret will be 64 bit number field lowest = lowestbidder[2] field[256] lowestbidunpacked = unpack256(lowest) field[256] secretunpacked = unpack256(secret) field[256] leafone = sha256(lowestbidunpacked, secretunpacked)
//Leaf Two: Curve point A: A[0] + A[1] //We know that A[0] and A[1] will be 64 bit numbers, need to unpack to 256 field[256] a0unpacked = unpack256(A[0]) field[256] a1unpacked = unpack256(A[1]) field[256] leaftwo = sha256(a0unpacked, a1unpacked)
//Build the root of leaf one + leaf two field[256] root = sha256(leafone, leaftwo)
//Before returning, compress back to field element root - split off 128 bits res0 = pack128(root[..128]) res1 = pack128(root[128..])
return [res0, res1]
2.编译
zokrates compile -i verifybid.code
生成 out 和 out.code 文件。其中 out 文件为 102M,out.code 文件为 60M,文件 size 较大。
-a 后面为执行程序的参数,即对应着verifybid.code中的入参 private field[6] R, field[6] A, field[3] S, private field secret, private field bidone, private field bidtwo, private field bidthree