You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@milagro.apache.org by sa...@apache.org on 2020/02/07 12:57:31 UTC
[incubator-milagro-MPC] 11/11: Add random challenge generation for
interactive ZK proofs
This is an automated email from the ASF dual-hosted git repository.
sandreoli pushed a commit to branch add-mta-zk-proofs
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-MPC.git
commit 990b4edbd066af1ca96a8a191a85bd6b21f05802
Author: Samuele Andreoli <sa...@yahoo.it>
AuthorDate: Thu Feb 6 10:24:44 2020 +0000
Add random challenge generation for interactive ZK proofs
---
examples/example_mta_zk_interactive.c | 247 +++++++++++++++++++++++++++++
include/amcl/mta.h | 16 ++
src/mta.c | 12 ++
test/smoke/test_mta_zk_interactive_smoke.c | 136 ++++++++++++++++
4 files changed, 411 insertions(+)
diff --git a/examples/example_mta_zk_interactive.c b/examples/example_mta_zk_interactive.c
new file mode 100644
index 0000000..6729f8f
--- /dev/null
+++ b/examples/example_mta_zk_interactive.c
@@ -0,0 +1,247 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+#include <string.h>
+#include "amcl/mta.h"
+#include "amcl/commitments.h"
+
+/* MTA interactive ZK Proof example
+ *
+ * This example uses the Receiver ZK Proof, but the
+ * same procedure can be used for the Range Proof and
+ * the Receiver ZK Proof with check
+ */
+
+// Primes for Paillier key
+char *P_hex = "94f689d07ba20cf7c7ca7ccbed22ae6b40c426db74eaee4ce0ced2b6f52a5e136663f5f1ef379cdbb0c4fdd6e4074d6cff21082d4803d43d89e42fd8dfa82b135aa31a8844ffea25f255f956cbc1b9d8631d01baf1010d028a190b94ce40f3b72897e8196df19edf1ff62e6556f2701d52cef1442e3301db7608ecbdcca703db";
+char *Q_hex = "9a9ad73f246df853e129c589925fdad9df05606a61081e62e72be4fb33f6e5ec492cc734f28bfb71fbe2ba9a11e4c02e2c0d103a5cbb0a9d6402c07de63b1b995dd72ac8f29825d66923a088b421fb4d52b0b855d2f5dde2be9b0ca0cee6f7a94e5566735fe6cff1fcad3199602f88528d19aa8d0263adff8f5053c38254a2a3";
+
+// Safe primes for BC setup
+char *PT_hex = "CA5F37B7C0DDF6530B30A41116588218DE95F1F36B807FD7C28E4C467EE3F35967BC01D28B71F8A627A353675A81C86A1FF03DCECAF1686891183FA317BA34A4A1148D40A89F1F3AC0C200511C6CFE02342CD75354C25A2E069886DD4FB73BD365660D163F1282B143119AB8F375A73875EC16B634F52593B73BC6D875F2D3EF";
+char *QT_hex = "C2FC545C1C803F6C7625FBC4ECF9355734D6B6058FD714816D3ECFB93F1F705C9CE90D4F8796A05148AB5ABC201F90889231CC6BF5F68ED15EE4D901F603930A280EEABF10C613BFCB67A816363C839EB902B02607EB48AB8325E2B72620D4D294A232803217090DFB50AF8C620D4679E77CE3053437ED518F4F68840DCF1AA3";
+
+// Paillier ciphertext and plaintext
+char* X_hex = "0000000000000000000000000000000000000000000000000000000000000003";
+char* Y_hex = "0000000000000000000000000000000000000000000000000000000000000004";
+char* C1_hex = "19c8b725dbd74b7dcaf72bd9ff2cd207b47cb1095393685906171af9e2f2959e7f68729e0e40f97a22bbca93373d618ad51dd077c0d102938598a8ecc8a656e978ebd14007da99db8e691d85fc18a428097ee8a63dcf95b84b660294474a20ed2edcf2b1b4f305c1cc25860a08d1348c2a4d24cc1a97b51f920e2985b8108b3392a5eafc443cf3449e288eb49dbde2228a56233afa5a6643e5ae6ec6aa8937a666ef74a30625c35bb22c3cc57b700f8eae7690f8d37edbfd27ccb2e882f70d0d85e0cc825347453a28e98e877ab1eeaa6efa09f034bc8976bffb86420106978066ff52221b315f71eb32cbf608d2 [...]
+char* C2_hex = "1f1f087e749c85aacdacaace8659a33b53baad5eec1e56628435d335a8b150f96865d6e090f53146e120e7089b6f4a91c762622b24d0d2fba0e703301170a0b826a1336d4d6bb83dccd29ad9ef0936614bf14e992ea4daa202c63ace9bd3f95b9a8a6edd7949e89ec165541e7c01bd41395baf3e2fe7f3a9611af8b5ed8639c02a2bfc236c17a136bef6d09f966db718f3df9d6f4f40b618b4b6058b4e4ec241e6c2424404d0aee0ef5cd666e5c4253a62ae9deb09289fb84657109e0b933f58871ba7ea77190d6ea45a04be68360478adf43a85851cf583c5575543578635996d2dcd020aeceabf18be6ff8b45e [...]
+char* R_hex = "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 [...]
+
+int main()
+{
+ int rc;
+
+ PAILLIER_private_key priv_key;
+ PAILLIER_public_key pub_key;
+ COMMITMENTS_BC_priv_modulus priv_mod;
+ COMMITMENTS_BC_pub_modulus pub_mod;
+
+ MTA_ZK_commitment c;
+ MTA_ZK_commitment_rv rv;
+ MTA_ZK_proof proof;
+
+ char c1[2*FS_2048];
+ octet C1 = {0, sizeof(c1), c1};
+
+ char c2[2*FS_2048];
+ octet C2 = {0, sizeof(c2), c2};
+
+ char r[2*FS_2048];
+ octet R = {0, sizeof(r), r};
+
+ char x[MODBYTES_256_56];
+ octet X = {0, sizeof(x), x};
+
+ char y[MODBYTES_256_56];
+ octet Y = {0, sizeof(y), y};
+
+ char e[MODBYTES_256_56];
+ octet E = {0, sizeof(e), e};
+
+ char p[HFS_2048];
+ octet P = {0, sizeof(p), p};
+
+ char q[HFS_2048];
+ octet Q = {0, sizeof(q), q};
+
+ char z[FS_2048];
+ octet Z = {0, sizeof(z), z};
+
+ char z1[FS_2048];
+ octet Z1 = {0, sizeof(z1), z1};
+
+ char t[FS_2048];
+ octet T = {0, sizeof(t), t};
+
+ char v[2 * FS_2048];
+ octet V = {0, sizeof(v), v};
+
+ char w[FS_2048];
+ octet W = {0, sizeof(w), w};
+
+ char s[FS_2048];
+ octet S = {0, sizeof(s), s};
+
+ char s1[HFS_2048];
+ octet S1 = {0, sizeof(s1), s1};
+
+ char s2[FS_2048 + HFS_2048];
+ octet S2 = {0, sizeof(s2), s2};
+
+ char t1[FS_2048];
+ octet T1 = {0, sizeof(t1), t1};
+
+ char t2[FS_2048 + HFS_2048];
+ octet T2 = {0, sizeof(t2), t2};
+
+ // Deterministic RNG for testing
+ char seed[32] = {0};
+ csprng RNG;
+ RAND_seed(&RNG, 32, seed);
+
+ // Load paillier key
+ OCT_fromHex(&P, P_hex);
+ OCT_fromHex(&Q, Q_hex);
+
+ PAILLIER_KEY_PAIR(NULL, &P, &Q, &pub_key, &priv_key);
+
+ printf("Run MTA Range Proof\nParameters:\n");
+ printf("\tPaillier Key\n");
+ printf("\t\tP = ");
+ OCT_output(&P);
+ printf("\t\tQ = ");
+ OCT_output(&Q);
+
+ // Generate BC commitment modulus
+ OCT_fromHex(&P, PT_hex);
+ OCT_fromHex(&Q, QT_hex);
+ COMMITMENTS_BC_setup(&RNG, &priv_mod, &P, &Q, NULL, NULL);
+
+ COMMITMENTS_BC_export_public_modulus(&pub_mod, &priv_mod);
+
+ FF_2048_output(priv_mod.alpha, FFLEN_2048);
+ printf("\n");
+ FF_2048_output(priv_mod.b0, FFLEN_2048);
+
+ printf("\n\tBit Commitment Modulus\n");
+ printf("\t\tP = ");
+ OCT_output(&P);
+ printf("\t\tQ = ");
+ OCT_output(&Q);
+
+ // Load Paillier encryption values
+ OCT_fromHex(&X, X_hex);
+ OCT_fromHex(&Y, Y_hex);
+ OCT_fromHex(&R, R_hex);
+ OCT_fromHex(&C1, C1_hex);
+ OCT_fromHex(&C2, C2_hex);
+
+ printf("\nInput:\n");
+ printf("\t\tX = ");
+ OCT_output(&X);
+ printf("\t\tY = ");
+ OCT_output(&Y);
+ printf("\t\tC1 = ");
+ OCT_output(&C1);
+ printf("\t\tC2 = ");
+ OCT_output(&C2);
+ printf("\t\tR = ");
+ OCT_output(&R);
+
+ // Prover - commit to values for the proof and output
+ // the commitment to octets for transmission
+ MTA_ZK_commit(&RNG, &pub_key, &pub_mod, &X, &Y, &C1, &c, &rv);
+ MTA_ZK_commitment_toOctets(&Z, &Z1, &T, &V, &W, &c);
+
+ printf("\n[Prover] Commitment Phase\n");
+ printf("\tGenerate Random Values:");
+ printf("\n\t\tALPHA = ");
+ FF_2048_output(rv.alpha, HFLEN_2048);
+ printf("\n\t\tBETA = ");
+ FF_2048_output(rv.beta, FFLEN_2048);
+ printf("\n\t\tGAMMA = ");
+ FF_2048_output(rv.gamma, FFLEN_2048);
+ printf("\n\t\tRHO = ");
+ FF_2048_output(rv.rho, FFLEN_2048 + HFLEN_2048);
+ printf("\n\t\tRHO1 = ");
+ FF_2048_output(rv.rho1, FFLEN_2048 + HFLEN_2048);
+ printf("\n\t\tSIGMA = ");
+ FF_2048_output(rv.sigma, FFLEN_2048 + HFLEN_2048);
+ printf("\n\t\tTAU = ");
+ FF_2048_output(rv.tau, FFLEN_2048 + HFLEN_2048);
+ printf("\n\n\tGenerate Commitment:\n");
+ printf("\t\tZ = ");
+ OCT_output(&Z);
+ printf("\t\tZ1 = ");
+ OCT_output(&Z1);
+ printf("\t\tT = ");
+ OCT_output(&T);
+ printf("\t\tV = ");
+ OCT_output(&V);
+ printf("\t\tW = ");
+ OCT_output(&W);
+
+ // Verifier - compute deterministic challenge and send it
+ // back to the prover
+ MTA_ZK_random_challenge(&RNG, &E);
+
+ printf("\n[Verifier] Compute random challenge\n");
+ printf("\t\tE = ");
+ OCT_output(&E);
+
+ // Prover - generate proof and otuput it to octets for transmission
+ MTA_ZK_prove(&pub_key, &rv, &X, &Y, &R, &E, &proof);
+ MTA_ZK_proof_toOctets(&S, &S1, &S2, &T1, &T2, &proof);
+
+ printf("\n[Prover] Proof Phase\n");
+ printf("\t\tS = ");
+ OCT_output(&S);
+ printf("\t\tS1 = ");
+ OCT_output(&S1);
+ printf("\t\tS2 = ");
+ OCT_output(&S2);
+ printf("\t\tT1 = ");
+ OCT_output(&T1);
+ printf("\t\tT2 = ");
+ OCT_output(&T2);
+
+ // Prover - clean random values
+ MTA_ZK_commitment_rv_kill(&rv);
+
+ // Transmit the proof and commitment to the verifier
+
+ // Verifier - read commitment and proof from octets
+ MTA_ZK_proof_fromOctets(&proof, &S, &S1, &S2, &T1, &T2);
+ MTA_ZK_commitment_fromOctets(&c, &Z, &Z1, &T, &V, &W);
+
+ // Verifier - compute deterministic challenge
+ MTA_ZK_challenge(&pub_key, &pub_mod, &C1, &C2, &c, &E);
+
+ printf("\n[Verifier] Verification\n");
+
+ rc = MTA_ZK_verify(&priv_key, &priv_mod, &C1, &C2, &E, &c, &proof);
+ if (rc == MTA_OK)
+ {
+ printf("\t\tSuccess!\n");
+ }
+ else
+ {
+ printf("\t\tFailure!\n");
+ }
+}
diff --git a/include/amcl/mta.h b/include/amcl/mta.h
index a78593f..824989e 100644
--- a/include/amcl/mta.h
+++ b/include/amcl/mta.h
@@ -111,6 +111,22 @@ void MPC_SUM_MTA(octet *A, octet *B, octet *ALPHA, octet *BETA, octet *SUM);
// The protocols require a BC modulus (Pt, Qt, Nt, h1, h2) and a Paillier PK (N, g)
+/** \brief Random challenge for any of the ZK Proofs
+ *
+ * Generate a random challenge for any of the ZK Proofs
+ * below. This can be used instead of the deterministic challenges
+ * produced for each specific proof to make any of the proofs
+ * interactive and be interoperable with other implementations.
+ *
+ * <ol>
+ * <li> \f$ e \in_R [0, \ldots, q] \f$
+ * <ol>
+ *
+ * @param RNG csprng for random generation
+ * @param E Destination octet for the challenge.
+ */
+void MTA_ZK_random_challenge(csprng *RNG, octet *E);
+
/* Range Proof API */
/** \brief Secret random values for the Range Proof commitment */
diff --git a/src/mta.c b/src/mta.c
index 3022be0..1a7cd4c 100644
--- a/src/mta.c
+++ b/src/mta.c
@@ -336,6 +336,18 @@ void MPC_SUM_MTA(octet *A, octet *B, octet *ALPHA, octet *BETA, octet *SUM)
BIG_256_56_toBytes(SUM->val,sum);
}
+void MTA_ZK_random_challenge(csprng *RNG, octet *E)
+{
+ BIG_256_56 e;
+ BIG_256_56 q;
+
+ BIG_256_56_rcopy(q, CURVE_Order_SECP256K1);
+ BIG_256_56_randomnum(e, q, RNG);
+
+ BIG_256_56_toBytes(E->val, e);
+ E->len = EGS_SECP256K1;
+}
+
void MTA_RP_commit(csprng *RNG, PAILLIER_private_key *key, COMMITMENTS_BC_pub_modulus *mod, octet *M, MTA_RP_commitment *c, MTA_RP_commitment_rv *rv)
{
BIG_1024_58 n[FFLEN_2048];
diff --git a/test/smoke/test_mta_zk_interactive_smoke.c b/test/smoke/test_mta_zk_interactive_smoke.c
new file mode 100644
index 0000000..6ceb1ec
--- /dev/null
+++ b/test/smoke/test_mta_zk_interactive_smoke.c
@@ -0,0 +1,136 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+#include <string.h>
+#include "amcl/mta.h"
+#include "amcl/commitments.h"
+
+void ff_2048_cleaned(BIG_1024_58 *a, char *name, int n)
+{
+ if(!FF_2048_iszilch(a, n))
+ {
+ fprintf(stderr, "FAILURE MTA_ZK_commitment_rv_kill. %s was not cleaned\n", name);
+ exit(EXIT_FAILURE);
+ }
+}
+
+/* MTA ZKP interactive smoke tests */
+
+// Primes for Paillier key
+char *P_hex = "94f689d07ba20cf7c7ca7ccbed22ae6b40c426db74eaee4ce0ced2b6f52a5e136663f5f1ef379cdbb0c4fdd6e4074d6cff21082d4803d43d89e42fd8dfa82b135aa31a8844ffea25f255f956cbc1b9d8631d01baf1010d028a190b94ce40f3b72897e8196df19edf1ff62e6556f2701d52cef1442e3301db7608ecbdcca703db";
+char *Q_hex = "9a9ad73f246df853e129c589925fdad9df05606a61081e62e72be4fb33f6e5ec492cc734f28bfb71fbe2ba9a11e4c02e2c0d103a5cbb0a9d6402c07de63b1b995dd72ac8f29825d66923a088b421fb4d52b0b855d2f5dde2be9b0ca0cee6f7a94e5566735fe6cff1fcad3199602f88528d19aa8d0263adff8f5053c38254a2a3";
+
+// Safe primes for BC setup
+char *PT_hex = "CA5F37B7C0DDF6530B30A41116588218DE95F1F36B807FD7C28E4C467EE3F35967BC01D28B71F8A627A353675A81C86A1FF03DCECAF1686891183FA317BA34A4A1148D40A89F1F3AC0C200511C6CFE02342CD75354C25A2E069886DD4FB73BD365660D163F1282B143119AB8F375A73875EC16B634F52593B73BC6D875F2D3EF";
+char *QT_hex = "C2FC545C1C803F6C7625FBC4ECF9355734D6B6058FD714816D3ECFB93F1F705C9CE90D4F8796A05148AB5ABC201F90889231CC6BF5F68ED15EE4D901F603930A280EEABF10C613BFCB67A816363C839EB902B02607EB48AB8325E2B72620D4D294A232803217090DFB50AF8C620D4679E77CE3053437ED518F4F68840DCF1AA3";
+
+// Paillier ciphertext and plaintext
+char* X_hex = "0000000000000000000000000000000000000000000000000000000000000003";
+char* Y_hex = "0000000000000000000000000000000000000000000000000000000000000004";
+char* C1_hex = "19c8b725dbd74b7dcaf72bd9ff2cd207b47cb1095393685906171af9e2f2959e7f68729e0e40f97a22bbca93373d618ad51dd077c0d102938598a8ecc8a656e978ebd14007da99db8e691d85fc18a428097ee8a63dcf95b84b660294474a20ed2edcf2b1b4f305c1cc25860a08d1348c2a4d24cc1a97b51f920e2985b8108b3392a5eafc443cf3449e288eb49dbde2228a56233afa5a6643e5ae6ec6aa8937a666ef74a30625c35bb22c3cc57b700f8eae7690f8d37edbfd27ccb2e882f70d0d85e0cc825347453a28e98e877ab1eeaa6efa09f034bc8976bffb86420106978066ff52221b315f71eb32cbf608d2 [...]
+char* C2_hex = "1f1f087e749c85aacdacaace8659a33b53baad5eec1e56628435d335a8b150f96865d6e090f53146e120e7089b6f4a91c762622b24d0d2fba0e703301170a0b826a1336d4d6bb83dccd29ad9ef0936614bf14e992ea4daa202c63ace9bd3f95b9a8a6edd7949e89ec165541e7c01bd41395baf3e2fe7f3a9611af8b5ed8639c02a2bfc236c17a136bef6d09f966db718f3df9d6f4f40b618b4b6058b4e4ec241e6c2424404d0aee0ef5cd666e5c4253a62ae9deb09289fb84657109e0b933f58871ba7ea77190d6ea45a04be68360478adf43a85851cf583c5575543578635996d2dcd020aeceabf18be6ff8b45e [...]
+char* R_hex = "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 [...]
+
+int main()
+{
+ int rc;
+
+ PAILLIER_private_key priv_key;
+ PAILLIER_public_key pub_key;
+ COMMITMENTS_BC_priv_modulus priv_mod;
+ COMMITMENTS_BC_pub_modulus pub_mod;
+
+ MTA_ZK_commitment c;
+ MTA_ZK_commitment_rv rv;
+ MTA_ZK_proof proof;
+
+ char c1[2*FS_2048];
+ octet C1 = {0, sizeof(c1), c1};
+
+ char c2[2*FS_2048];
+ octet C2 = {0, sizeof(c2), c2};
+
+ char r[2*FS_2048];
+ octet R = {0, sizeof(r), r};
+
+ char x[MODBYTES_256_56];
+ octet X = {0, sizeof(x), x};
+
+ char y[MODBYTES_256_56];
+ octet Y = {0, sizeof(y), y};
+
+ char e[MODBYTES_256_56];
+ octet E = {0, sizeof(e), e};
+
+ char p[HFS_2048];
+ octet P = {0, sizeof(p), p};
+
+ char q[HFS_2048];
+ octet Q = {0, sizeof(q), q};
+
+ // Deterministic RNG for testing
+ char seed[32] = {0};
+ csprng RNG;
+ RAND_seed(&RNG, 32, seed);
+
+ // Load paillier key
+ OCT_fromHex(&P, P_hex);
+ OCT_fromHex(&Q, Q_hex);
+
+ PAILLIER_KEY_PAIR(NULL, &P, &Q, &pub_key, &priv_key);
+
+ // Generate BC commitment modulus
+ OCT_fromHex(&P, PT_hex);
+ OCT_fromHex(&Q, QT_hex);
+ COMMITMENTS_BC_setup(&RNG, &priv_mod, &P, &Q, NULL, NULL);
+
+ COMMITMENTS_BC_export_public_modulus(&pub_mod, &priv_mod);
+
+ // Load Paillier encryption values
+ OCT_fromHex(&X, X_hex);
+ OCT_fromHex(&Y, Y_hex);
+ OCT_fromHex(&R, R_hex);
+ OCT_fromHex(&C1, C1_hex);
+ OCT_fromHex(&C2, C2_hex);
+
+ // Run smoke test
+ MTA_ZK_commit(&RNG, &pub_key, &pub_mod, &X, &Y, &C1, &c, &rv);
+ MTA_ZK_random_challenge(&RNG, &E);
+ MTA_ZK_prove(&pub_key, &rv, &X, &Y, &R, &E, &proof);
+
+ rc = MTA_ZK_verify(&priv_key, &priv_mod, &C1, &C2, &E, &c, &proof);
+ if (rc != MTA_OK)
+ {
+ printf("FAILURE MTA_ZK interactive smoke test. rc = %d\n", rc);
+ exit(EXIT_FAILURE);
+ }
+
+ // Clean random values
+ MTA_ZK_commitment_rv_kill(&rv);
+
+ ff_2048_cleaned(rv.alpha, "rv.alpha", FFLEN_2048);
+ ff_2048_cleaned(rv.beta, "rv.beta", FFLEN_2048);
+ ff_2048_cleaned(rv.gamma, "rv.gamma", FFLEN_2048);
+ ff_2048_cleaned(rv.rho, "rv.rho", FFLEN_2048 + HFLEN_2048);
+ ff_2048_cleaned(rv.sigma, "rv.sigma", FFLEN_2048 + HFLEN_2048);
+ ff_2048_cleaned(rv.tau, "rv.tau", FFLEN_2048 + HFLEN_2048);
+
+ printf("SUCCESS");
+ exit(EXIT_SUCCESS);
+}